Loading app-ui-catalog/src/main/kotlin/net/thunderbird/ui/catalog/ui/page/atom/items/ButtonItems.kt +27 −0 Original line number Diff line number Diff line Loading @@ -2,17 +2,24 @@ package net.thunderbird.ui.catalog.ui.page.atom.items import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.LazyGridScope import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonElevated import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilled import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilledTonal import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonOutlined import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonSegmentedSingleChoice import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons import kotlinx.collections.immutable.persistentListOf import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem import net.thunderbird.ui.catalog.ui.page.common.list.wideItem @Suppress("LongMethod") fun LazyGridScope.buttonItems() { Loading Loading @@ -117,4 +124,24 @@ fun LazyGridScope.buttonItems() { modifier = Modifier.padding(defaultItemPadding()), ) } sectionHeaderItem(text = "Button - Segmented Single Choice") wideItem { val options = persistentListOf( "Option 1", "Option 2", "Option 3", ) var selectedOption by remember { mutableStateOf(options[0]) } ButtonSegmentedSingleChoice( modifier = Modifier.padding(defaultItemPadding()), onClick = { selectedOption = it }, options = options, optionTitle = { it }, selectedOption = selectedOption, ) } } core/ui/compose/designsystem/src/debug/kotlin/app/k9mail/core/ui/compose/designsystem/atom/button/ButtonSegmentedSingleChoicePreview.kt 0 → 100644 +55 −0 Original line number Diff line number Diff line package app.k9mail.core.ui.compose.designsystem.atom.button import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes import kotlinx.collections.immutable.persistentListOf private val options = persistentListOf<String>( "Option 1", "Option 2", "Option 3", ) @Composable @Preview(showBackground = true) internal fun ButtonSegmentedSingleChoicePreview() { PreviewWithThemes { ButtonSegmentedSingleChoice( modifier = Modifier, onClick = {}, options = options, optionTitle = { it }, selectedOption = null, ) } } @Composable @Preview(showBackground = true) internal fun ButtonSegmentedSingleChoiceWithSelectionPreview() { PreviewWithThemes { ButtonSegmentedSingleChoice( modifier = Modifier, onClick = {}, options = options, optionTitle = { it }, selectedOption = options[1], ) } } @Composable @Preview(showBackground = true) internal fun ButtonSegmentedSingleChoiceEmptyPreview() { PreviewWithThemes { ButtonSegmentedSingleChoice( modifier = Modifier, onClick = {}, options = persistentListOf<String>(), optionTitle = { it }, selectedOption = null, ) } } core/ui/compose/designsystem/src/main/kotlin/app/k9mail/core/ui/compose/designsystem/atom/button/ButtonSegmentedSingleChoice.kt 0 → 100644 +53 −0 Original line number Diff line number Diff line package app.k9mail.core.ui.compose.designsystem.atom.button import androidx.compose.material3.SegmentedButton import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelLarge import kotlinx.collections.immutable.ImmutableList /** * A segmented button group that allows the user to select a single option from a list of options. * * @param onClick The callback to be invoked when an option is clicked. * @param options The list of options to be displayed. * @param optionTitle A function that returns the title of an option. * @param modifier The [Modifier] to be applied to the segmented button group. * @param selectedOption The currently selected option. If null, no option is selected. */ @Composable fun <T> ButtonSegmentedSingleChoice( onClick: (T) -> Unit, options: ImmutableList<T>, optionTitle: (T) -> String, modifier: Modifier = Modifier, selectedOption: T? = null, ) { if (options.isEmpty()) { return } SingleChoiceSegmentedButtonRow( modifier = modifier, ) { options.forEachIndexed { index, option -> SegmentedButton( shape = SegmentedButtonDefaults.itemShape( index = index, count = options.size, ), onClick = { onClick(option) }, selected = option == selectedOption, label = { TextLabelLarge( text = optionTitle(option), ) }, ) } } } core/ui/compose/preference/src/debug/kotlin/net/thunderbird/core/ui/compose/preference/ui/components/list/PreferenceItemSingleChoiceViewPreview.kt 0 → 100644 +28 −0 Original line number Diff line number Diff line package net.thunderbird.core.ui.compose.preference.ui.components.list import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes import net.thunderbird.core.ui.compose.preference.ui.fake.FakePreferenceData @Composable @Preview(showBackground = true) internal fun PreferenceItemSingleChoiceViewPreview() { PreviewWithThemes { PreferenceItemSingleChoiceView( preference = FakePreferenceData.singleChoicePreference.copy(description = { null }), onPreferenceChange = {}, ) } } @Composable @Preview(showBackground = true) internal fun PreferenceItemSingleChoiceViewWithDescriptionPreview() { PreviewWithThemes { PreferenceItemSingleChoiceView( preference = FakePreferenceData.singleChoicePreference, onPreferenceChange = {}, ) } } core/ui/compose/preference/src/debug/kotlin/net/thunderbird/core/ui/compose/preference/ui/fake/FakePreferenceData.kt +17 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ package net.thunderbird.core.ui.compose.preference.ui.fake import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons import kotlinx.collections.immutable.persistentListOf import net.thunderbird.core.ui.compose.preference.api.PreferenceSetting import net.thunderbird.core.ui.compose.preference.api.PreferenceSetting.SingleChoice.Choice internal object FakePreferenceData { Loading @@ -20,15 +21,30 @@ internal object FakePreferenceData { title = { "Title" }, description = { "Description" }, value = 0xFFFF0000.toInt(), colors = listOf( colors = persistentListOf( 0xFFFF0000.toInt(), 0xFF00FF00.toInt(), 0xFF0000FF.toInt(), ), ) private val choices = persistentListOf<Choice>( Choice("1") { "Choice 1" }, Choice("2") { "Choice 2" }, Choice("3") { "Choice 3" }, ) val singleChoicePreference = PreferenceSetting.SingleChoice( id = "single_choice", title = { "Title" }, description = { "Description" }, value = choices[1], options = choices, ) val preferences = persistentListOf( textPreference, colorPreference, singleChoicePreference, ) } Loading
app-ui-catalog/src/main/kotlin/net/thunderbird/ui/catalog/ui/page/atom/items/ButtonItems.kt +27 −0 Original line number Diff line number Diff line Loading @@ -2,17 +2,24 @@ package net.thunderbird.ui.catalog.ui.page.atom.items import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.LazyGridScope import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonElevated import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilled import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilledTonal import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonOutlined import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonSegmentedSingleChoice import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons import kotlinx.collections.immutable.persistentListOf import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem import net.thunderbird.ui.catalog.ui.page.common.list.wideItem @Suppress("LongMethod") fun LazyGridScope.buttonItems() { Loading Loading @@ -117,4 +124,24 @@ fun LazyGridScope.buttonItems() { modifier = Modifier.padding(defaultItemPadding()), ) } sectionHeaderItem(text = "Button - Segmented Single Choice") wideItem { val options = persistentListOf( "Option 1", "Option 2", "Option 3", ) var selectedOption by remember { mutableStateOf(options[0]) } ButtonSegmentedSingleChoice( modifier = Modifier.padding(defaultItemPadding()), onClick = { selectedOption = it }, options = options, optionTitle = { it }, selectedOption = selectedOption, ) } }
core/ui/compose/designsystem/src/debug/kotlin/app/k9mail/core/ui/compose/designsystem/atom/button/ButtonSegmentedSingleChoicePreview.kt 0 → 100644 +55 −0 Original line number Diff line number Diff line package app.k9mail.core.ui.compose.designsystem.atom.button import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes import kotlinx.collections.immutable.persistentListOf private val options = persistentListOf<String>( "Option 1", "Option 2", "Option 3", ) @Composable @Preview(showBackground = true) internal fun ButtonSegmentedSingleChoicePreview() { PreviewWithThemes { ButtonSegmentedSingleChoice( modifier = Modifier, onClick = {}, options = options, optionTitle = { it }, selectedOption = null, ) } } @Composable @Preview(showBackground = true) internal fun ButtonSegmentedSingleChoiceWithSelectionPreview() { PreviewWithThemes { ButtonSegmentedSingleChoice( modifier = Modifier, onClick = {}, options = options, optionTitle = { it }, selectedOption = options[1], ) } } @Composable @Preview(showBackground = true) internal fun ButtonSegmentedSingleChoiceEmptyPreview() { PreviewWithThemes { ButtonSegmentedSingleChoice( modifier = Modifier, onClick = {}, options = persistentListOf<String>(), optionTitle = { it }, selectedOption = null, ) } }
core/ui/compose/designsystem/src/main/kotlin/app/k9mail/core/ui/compose/designsystem/atom/button/ButtonSegmentedSingleChoice.kt 0 → 100644 +53 −0 Original line number Diff line number Diff line package app.k9mail.core.ui.compose.designsystem.atom.button import androidx.compose.material3.SegmentedButton import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelLarge import kotlinx.collections.immutable.ImmutableList /** * A segmented button group that allows the user to select a single option from a list of options. * * @param onClick The callback to be invoked when an option is clicked. * @param options The list of options to be displayed. * @param optionTitle A function that returns the title of an option. * @param modifier The [Modifier] to be applied to the segmented button group. * @param selectedOption The currently selected option. If null, no option is selected. */ @Composable fun <T> ButtonSegmentedSingleChoice( onClick: (T) -> Unit, options: ImmutableList<T>, optionTitle: (T) -> String, modifier: Modifier = Modifier, selectedOption: T? = null, ) { if (options.isEmpty()) { return } SingleChoiceSegmentedButtonRow( modifier = modifier, ) { options.forEachIndexed { index, option -> SegmentedButton( shape = SegmentedButtonDefaults.itemShape( index = index, count = options.size, ), onClick = { onClick(option) }, selected = option == selectedOption, label = { TextLabelLarge( text = optionTitle(option), ) }, ) } } }
core/ui/compose/preference/src/debug/kotlin/net/thunderbird/core/ui/compose/preference/ui/components/list/PreferenceItemSingleChoiceViewPreview.kt 0 → 100644 +28 −0 Original line number Diff line number Diff line package net.thunderbird.core.ui.compose.preference.ui.components.list import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes import net.thunderbird.core.ui.compose.preference.ui.fake.FakePreferenceData @Composable @Preview(showBackground = true) internal fun PreferenceItemSingleChoiceViewPreview() { PreviewWithThemes { PreferenceItemSingleChoiceView( preference = FakePreferenceData.singleChoicePreference.copy(description = { null }), onPreferenceChange = {}, ) } } @Composable @Preview(showBackground = true) internal fun PreferenceItemSingleChoiceViewWithDescriptionPreview() { PreviewWithThemes { PreferenceItemSingleChoiceView( preference = FakePreferenceData.singleChoicePreference, onPreferenceChange = {}, ) } }
core/ui/compose/preference/src/debug/kotlin/net/thunderbird/core/ui/compose/preference/ui/fake/FakePreferenceData.kt +17 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ package net.thunderbird.core.ui.compose.preference.ui.fake import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons import kotlinx.collections.immutable.persistentListOf import net.thunderbird.core.ui.compose.preference.api.PreferenceSetting import net.thunderbird.core.ui.compose.preference.api.PreferenceSetting.SingleChoice.Choice internal object FakePreferenceData { Loading @@ -20,15 +21,30 @@ internal object FakePreferenceData { title = { "Title" }, description = { "Description" }, value = 0xFFFF0000.toInt(), colors = listOf( colors = persistentListOf( 0xFFFF0000.toInt(), 0xFF00FF00.toInt(), 0xFF0000FF.toInt(), ), ) private val choices = persistentListOf<Choice>( Choice("1") { "Choice 1" }, Choice("2") { "Choice 2" }, Choice("3") { "Choice 3" }, ) val singleChoicePreference = PreferenceSetting.SingleChoice( id = "single_choice", title = { "Title" }, description = { "Description" }, value = choices[1], options = choices, ) val preferences = persistentListOf( textPreference, colorPreference, singleChoicePreference, ) }