diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/NavGraph.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/NavGraph.kt index 129792009..767e21d25 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/NavGraph.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/NavGraph.kt @@ -21,6 +21,7 @@ import kiwi.orbit.compose.catalog.screens.DialogsScreen import kiwi.orbit.compose.catalog.screens.EmptyStateScreen import kiwi.orbit.compose.catalog.screens.IconsScreen import kiwi.orbit.compose.catalog.screens.IllustrationsScreen +import kiwi.orbit.compose.catalog.screens.KeyValueScreen import kiwi.orbit.compose.catalog.screens.LinearProgressIndicatorScreen import kiwi.orbit.compose.catalog.screens.ListChoiceScreen import kiwi.orbit.compose.catalog.screens.LoadingScreen @@ -53,6 +54,7 @@ private object MainDestinations { const val DIALOGS = "dialogs" const val DIALOGS_MATERIAL_DIALOG = "dialogs_material_dialog" const val EMPTY_STATE = "empty_state" + const val KEY_VALUE = "key_value" const val LINEAR_PROGRESS_INDICATOR = "linear_progress_indicator" const val LIST_CHOICE = "list_choice" const val LOADING = "loading" @@ -126,6 +128,9 @@ fun NavGraph( composable(MainDestinations.EMPTY_STATE) { EmptyStateScreen(actions::navigateUp) } + composable(MainDestinations.KEY_VALUE) { + KeyValueScreen(actions::navigateUp) + } composable(MainDestinations.LINEAR_PROGRESS_INDICATOR) { LinearProgressIndicatorScreen(actions::navigateUp) } @@ -230,6 +235,10 @@ class MainActions( navController.navigate(MainDestinations.EMPTY_STATE) } + fun showKeyValue() { + navController.navigate(MainDestinations.KEY_VALUE) + } + fun showLinearProgressIndicator() { navController.navigate(MainDestinations.LINEAR_PROGRESS_INDICATOR) } diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/KeyValueScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/KeyValueScreen.kt new file mode 100644 index 000000000..12486f14b --- /dev/null +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/KeyValueScreen.kt @@ -0,0 +1,52 @@ +package kiwi.orbit.compose.catalog.screens + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.Screen +import kiwi.orbit.compose.ui.controls.KeyValue +import kiwi.orbit.compose.ui.controls.KeyValueLarge + +@Composable +fun KeyValueScreen(onNavigateUp: () -> Unit) { + Screen( + title = "KeyValue", + onNavigateUp = onNavigateUp, + ) { contentPadding -> + Box( + Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .padding(contentPadding) + ) { + KeyValueScreenInner() + } + } +} + +@Preview +@Composable +private fun KeyValueScreenInner() { + Column( + modifier = Modifier.padding(16.dp), + ) { + KeyValue( + key = "Key", + value = "Value", + ) + Spacer(modifier = Modifier.height(16.dp)) + KeyValueLarge( + key = "Large key", + value = "Large value", + ) + } +} diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt index 161f8a7b7..89b842278 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.material.icons.rounded.Article import androidx.compose.material.icons.rounded.Ballot import androidx.compose.material.icons.rounded.BrightnessMedium import androidx.compose.material.icons.rounded.CheckBox +import androidx.compose.material.icons.rounded.DragHandle import androidx.compose.material.icons.rounded.FormatSize import androidx.compose.material.icons.rounded.Keyboard import androidx.compose.material.icons.rounded.LabelImportant @@ -65,6 +66,7 @@ fun MainScreen( Triple("Choice Tile", { Icon(MaterialIcons.Ballot, null) }, actions::showChoiceTile), Triple("Dialogs", { Icon(Icons.Chat, null) }, actions::showDialogs), Triple("EmptyState", { Icon(MaterialIcons.SignalWifiOff, null) }, actions::showEmptyState), + Triple("KeyValue", { Icon(MaterialIcons.DragHandle, null) }, actions::showKeyValue), Triple("ListChoice", { Icon(Icons.MenuHamburger, null) }, actions::showListChoice), Triple("Loading", { Icon(Icons.MenuMeatballs, null) }, actions::showLoading), Triple( diff --git a/component-status.yaml b/component-status.yaml index 152b6c43c..b6fee49e0 100644 --- a/component-status.yaml +++ b/component-status.yaml @@ -30,6 +30,8 @@ android: Released - component: InputField android: Released +- component: KeyValue + android: Released - component: ListChoice android: Released - component: NavigationBar diff --git a/ui/screenshots/debug/kiwi.orbit.compose.ui.ScreenshotTest_keyValue.png b/ui/screenshots/debug/kiwi.orbit.compose.ui.ScreenshotTest_keyValue.png new file mode 100644 index 000000000..fb2c72dd4 Binary files /dev/null and b/ui/screenshots/debug/kiwi.orbit.compose.ui.ScreenshotTest_keyValue.png differ diff --git a/ui/src/androidTest/kotlin/kiwi/orbit/compose/ui/ScreenshotTest.kt b/ui/src/androidTest/kotlin/kiwi/orbit/compose/ui/ScreenshotTest.kt index 98e82fcec..12e6b4040 100644 --- a/ui/src/androidTest/kotlin/kiwi/orbit/compose/ui/ScreenshotTest.kt +++ b/ui/src/androidTest/kotlin/kiwi/orbit/compose/ui/ScreenshotTest.kt @@ -25,6 +25,7 @@ import kiwi.orbit.compose.ui.controls.ClickableFieldPreview import kiwi.orbit.compose.ui.controls.CountryFlagPreview import kiwi.orbit.compose.ui.controls.EmptyStatePreview import kiwi.orbit.compose.ui.controls.InlineLoadingPreview +import kiwi.orbit.compose.ui.controls.KeyValuePreview import kiwi.orbit.compose.ui.controls.LinearProgressIndicatorPreview import kiwi.orbit.compose.ui.controls.PasswordTextFieldPreview import kiwi.orbit.compose.ui.controls.RadioFieldPreview @@ -180,6 +181,11 @@ internal class ScreenshotTest : ScreenshotTest { snapshot { LinearProgressIndicatorPreview() } } + @Test + fun keyValue() { + snapshot { KeyValuePreview() } + } + @Test fun passwordTextField() { snapshot { PasswordTextFieldPreview() } diff --git a/ui/src/main/java/kiwi/orbit/compose/ui/controls/KeyValue.kt b/ui/src/main/java/kiwi/orbit/compose/ui/controls/KeyValue.kt new file mode 100644 index 000000000..55414fb4b --- /dev/null +++ b/ui/src/main/java/kiwi/orbit/compose/ui/controls/KeyValue.kt @@ -0,0 +1,97 @@ +package kiwi.orbit.compose.ui.controls + +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import kiwi.orbit.compose.ui.OrbitTheme +import kiwi.orbit.compose.ui.controls.internal.Preview +import kiwi.orbit.compose.ui.foundation.ContentEmphasis +import kiwi.orbit.compose.ui.foundation.LocalContentEmphasis +import kiwi.orbit.compose.ui.foundation.LocalTextStyle + +@Composable +public fun KeyValue( + key: @Composable () -> Unit, + value: @Composable () -> Unit, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier) { + CompositionLocalProvider( + LocalTextStyle provides OrbitTheme.typography.bodySmall, + LocalContentEmphasis provides ContentEmphasis.Minor, + ) { + key() + } + CompositionLocalProvider( + LocalTextStyle provides OrbitTheme.typography.bodyNormalMedium, + LocalContentEmphasis provides ContentEmphasis.Normal, + ) { + value() + } + } +} + +@Composable +public fun KeyValueLarge( + key: @Composable () -> Unit, + value: @Composable () -> Unit, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier) { + CompositionLocalProvider( + LocalTextStyle provides OrbitTheme.typography.bodyNormal, + LocalContentEmphasis provides ContentEmphasis.Minor, + ) { + key() + } + CompositionLocalProvider( + LocalTextStyle provides OrbitTheme.typography.bodyLargeMedium, + LocalContentEmphasis provides ContentEmphasis.Normal, + ) { + value() + } + } +} + +@Composable +public fun KeyValue( + key: String, + value: String, + modifier: Modifier = Modifier, +) { + KeyValue( + key = { Text(text = key) }, + value = { Text(text = value) }, + modifier = modifier, + ) +} + +@Composable +public fun KeyValueLarge( + key: String, + value: String, + modifier: Modifier = Modifier, +) { + KeyValueLarge( + key = { Text(text = key) }, + value = { Text(text = value) }, + modifier = modifier, + ) +} + +@Preview +@Composable +internal fun KeyValuePreview() { + Preview { + KeyValue( + key = "Key", + value = "Value", + ) + KeyValueLarge( + key = "Large key", + value = "Large value", + ) + } +}