feat: non ideal state composable
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
00e66ea939
commit
1d5516a1a0
|
|
@ -0,0 +1,118 @@
|
||||||
|
package chat.revolt.components.generic
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Close
|
||||||
|
import androidx.compose.material.icons.filled.Star
|
||||||
|
import androidx.compose.material.icons.filled.Warning
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.LocalTextStyle
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
private val NoneLambda = @Composable { throw UnsupportedOperationException() }
|
||||||
|
@Composable
|
||||||
|
fun NonIdealState(
|
||||||
|
icon: @Composable () -> Unit,
|
||||||
|
title: @Composable () -> Unit,
|
||||||
|
description: @Composable () -> Unit = NoneLambda,
|
||||||
|
actions: @Composable () -> Unit = NoneLambda
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 32.dp)
|
||||||
|
) {
|
||||||
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.primary) {
|
||||||
|
icon()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description != NoneLambda) Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.headlineMedium) {
|
||||||
|
title()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description != NoneLambda) {
|
||||||
|
CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodyMedium) {
|
||||||
|
description()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actions != NoneLambda) {
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
|
||||||
|
) {
|
||||||
|
actions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun NonIdealStatePreview() {
|
||||||
|
NonIdealState(
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Star,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
},
|
||||||
|
title = { Text("Channel") },
|
||||||
|
description = { Text("You are not in any channels.") },
|
||||||
|
actions = {
|
||||||
|
Button(onClick = {}) {
|
||||||
|
Text("Create a channel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun NonIdealStatePreviewNoActions() {
|
||||||
|
NonIdealState(
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Close,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
},
|
||||||
|
title = { Text("Error") },
|
||||||
|
description = { Text("Could not load channels.") },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun NonIdealStatePreviewNoDescription() {
|
||||||
|
NonIdealState(
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Warning,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
},
|
||||||
|
title = { Text("No channels") },
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue