From 4d947cb193e3d078f0fa090d84a8a48665d3b92a Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 17 Aug 2023 11:56:18 +0200 Subject: [PATCH 01/13] [#603] Remove outlined parameter from OdsChip public API cause it is managed by OdsTheme --- .../ods/app/ui/components/chips/Chip.kt | 1 - docs/components/Chips.md | 93 +++++++++---------- .../ods/compose/component/chip/OdsChip.kt | 39 ++++++-- .../component/chip/OdsChoiceChipsFlowRow.kt | 1 - 4 files changed, 78 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt index 21377c57b..5b99462bf 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt @@ -149,7 +149,6 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { OdsChip( text = recipe?.title.orEmpty(), onClick = { clickOnElement(context, recipe?.title.orEmpty()) }, - outlined = outlinedChips, leadingIcon = if (isActionChip || hasLeadingIcon) recipe?.iconResId?.let { painterResource(id = it) } else null, leadingAvatar = if (hasLeadingAvatar) { rememberAsyncImagePainter( diff --git a/docs/components/Chips.md b/docs/components/Chips.md index 1200e4ed2..e93deb0c1 100644 --- a/docs/components/Chips.md +++ b/docs/components/Chips.md @@ -11,12 +11,12 @@ description: Chips are compact elements that represent an input, attribute, or a * [Specifications references](#specifications-references) * [Accessibility](#accessibility) * [Variants](#variants) - * [Input chip](#input-chip) - * [Choice chip](#choice-chip) - * [Filter chip](#filter-chip) - * [Action chip](#action-chip) + * [Input chip](#input-chip) + * [Choice chip](#choice-chip) + * [Filter chip](#filter-chip) + * [Action chip](#action-chip) * [Modules](#modules) - * [Choice chips flow row](#choice-chips-flow-row) + * [Choice chips flow row](#choice-chips-flow-row) * [Component specific tokens](#component-specific-tokens) --- @@ -43,13 +43,15 @@ Input chips (referred to as **entry** chips in Android) represent a complex piec compact form, such as an entity (person, place, or thing) or text. They enable user input and verify that input by converting text into chips. - ![Light input chip](images/chips_input_light.png) ![Dark input chip](images/chips_input_dark.png) +![Light input chip](images/chips_input_light.png) ![Dark input chip](images/chips_input_dark.png) - ![Light outlined input chip](images/chips_input_outlined_light.png) ![Dark outlined input chip](images/chips_input_outlined_dark.png) +![Light outlined input chip](images/chips_input_outlined_light.png) ![Dark outlined input chip](images/chips_input_outlined_dark.png) > **Jetpack Compose implementation** -Use the `OdsChip` composable: +Use the `OdsChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. ```kotlin OdsChip( @@ -57,10 +59,9 @@ OdsChip( onClick = { // Something executed on chip click }, - outlined = false, // Set it to `true` to display an outlined chip leadingAvatar = painterResource(id = R.drawable.avatar), enabled = true, // Set it to `false` to disabled the chip - onCancel = { + onCancel = { // Something executed on cancel cross click } ) @@ -76,12 +77,9 @@ In the layout: ```xml - + ``` @@ -93,15 +91,18 @@ Choice chips allow selection of a single chip from a set of options. Choice chips clearly delineate and display options in a compact area. They are a good alternative to toggle buttons, radio buttons, and single select menus. -**Note: To display a set of choice chips please see [Choice chips flow row](#choice-chips-flow-row)** +**Note: To display a set of choice chips please see [Choice chips flow row](#choice-chips-flow-row) +** - ![Light choice chips](images/chips_choice_light.png) ![Dark choice chips](images/chips_choice_dark.png) +![Light choice chips](images/chips_choice_light.png) ![Dark choice chips](images/chips_choice_dark.png) - ![Light outlined choice chips](images/chips_choice_outlined_light.png) ![Dark outlined choice chips](images/chips_choice_outlined_dark.png) +![Light outlined choice chips](images/chips_choice_outlined_light.png) ![Dark outlined choice chips](images/chips_choice_outlined_dark.png) > **Jetpack Compose implementation** -Use the `OdsChip` composable: +Use the `OdsChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. ```kotlin OdsChip( @@ -124,14 +125,11 @@ In the layout: ```xml - - - + + + ``` ### Filter chip @@ -141,9 +139,9 @@ Filter chips use tags or descriptive words to filter content. Filter chips clearly delineate and display options in a compact area. They are a good alternative to toggle buttons or checkboxes. - ![Light filter chips](images/chips_filter_light.png) ![Dark filter chips](images/chips_filter_dark.png) +![Light filter chips](images/chips_filter_light.png) ![Dark filter chips](images/chips_filter_dark.png) - ![Light filter chips with avatar](images/chips_filter_avatar_light.png) ![Dark filter chips with avatar](images/chips_filter_avatar_dark.png) +![Light filter chips with avatar](images/chips_filter_avatar_light.png) ![Dark filter chips with avatar](images/chips_filter_avatar_dark.png) > **Jetpack Compose implementation** @@ -170,13 +168,11 @@ layout and set `style` property to `@style/Widget.MaterialComponents.Chip.Filter In the layout: ```xml + - + ``` @@ -188,13 +184,15 @@ contextually in a UI. An alternative to action chips are buttons, which should appear persistently and consistently. - ![Light action chip](images/chips_action_light.png) ![Dark action chip](images/chips_action_dark.png) +![Light action chip](images/chips_action_light.png) ![Dark action chip](images/chips_action_dark.png) - ![Light outlined action chip](images/chips_action_outlined_light.png) ![Dark outlined action chip](images/chips_action_outlined_dark.png) +![Light outlined action chip](images/chips_action_outlined_light.png) ![Dark outlined action chip](images/chips_action_outlined_dark.png) > **Jetpack Compose implementation** -Use the `OdsChip` composable: +Use the `OdsChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. ```kotlin OdsChip( @@ -218,12 +216,9 @@ In the layout: ```xml - + ``` @@ -236,11 +231,13 @@ The ODS library provides some modules directly related to chips. This is a full width `FlowRow` containing selectable chips. It works like radio buttons, only one chip of the set can be selected. - ![Light choice chips flow row](images/chips_choice_flow_row_light.png) +![Light choice chips flow row](images/chips_choice_flow_row_light.png) - ![Dark choice chips flow row](images/chips_choice_flow_row_dark.png) +![Dark choice chips flow row](images/chips_choice_flow_row_dark.png) -Use `OdsChoiceChipsFlowRow` composable: +Use `OdsChoiceChipsFlowRow` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. ```kotlin OdsChoiceChipsFlowRow( diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index 2b69b8b8b..a2293152f 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -43,6 +43,7 @@ import com.orange.ods.compose.component.utilities.selectionStateDescription import com.orange.ods.compose.theme.OdsTheme import com.orange.ods.compose.utilities.extension.enable import com.orange.ods.compose.utilities.extension.noRippleClickable +import com.orange.ods.theme.OdsComponentsConfiguration /** @@ -50,13 +51,13 @@ import com.orange.ods.compose.utilities.extension.noRippleClickable * * Chips are small components containing a number of elements that represent a calendar event or contact. * The [OdsChip] is used to display input chips, choice chips and action chips. To display filter chips please use [OdsFilterChip]. + * Note that [OdsChip] is displayed outlined or filled according to your [OdsTheme] component configuration, outlined by default. * * Use Accompanist's [Flow Layouts](https://google.github.io/accompanist/flowlayout/) to wrap chips to a new line. * * @param text Text to display in the chip. * @param onClick called when the chip is clicked. * @param modifier Modifier to be applied to the chip - * @param outlined If true, a border will be drawn around the chip otherwise a filled chip will be displayed. * @param enabled When disabled, chip will not respond to user input. It will also appear visually * disabled and disabled to accessibility services. * @param selected When selected the chip is highlighted (useful for choice chips). @@ -65,14 +66,12 @@ import com.orange.ods.compose.utilities.extension.noRippleClickable * @param leadingContentDescription Content description associated to the leading element. * @param onCancel called when the cancel cross of the chip is clicked. Pass `null` here for no cancel cross. */ -@OptIn(ExperimentalMaterialApi::class) @Composable @OdsComposable fun OdsChip( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, - outlined: Boolean = true, enabled: Boolean = true, selected: Boolean = false, leadingIcon: Painter? = null, @@ -80,8 +79,36 @@ fun OdsChip( leadingContentDescription: String? = null, onCancel: (() -> Unit)? = null ) { - val chipStateDescription = selectionStateDescription(selected) + OdsChip( + text = text, + onClick = onClick, + outlined = OdsTheme.componentsConfiguration.chipStyle == OdsComponentsConfiguration.ComponentStyle.Outlined, + modifier = modifier, + enabled = enabled, + selected = selected, + leadingIcon = leadingIcon, + leadingAvatar = leadingAvatar, + leadingContentDescription = leadingContentDescription, + onCancel = onCancel + ) +} +@OptIn(ExperimentalMaterialApi::class) +@Composable +@OdsComposable +private fun OdsChip( + text: String, + onClick: () -> Unit, + outlined: Boolean, + modifier: Modifier = Modifier, + enabled: Boolean = true, + selected: Boolean = false, + leadingIcon: Painter? = null, + leadingAvatar: Painter? = null, + leadingContentDescription: String? = null, + onCancel: (() -> Unit)? = null +) { + val chipStateDescription = selectionStateDescription(selected) Chip( onClick = onClick, modifier = modifier.semantics { @@ -162,10 +189,10 @@ private fun PreviewOdsChip(@PreviewParameter(OdsChipPreviewParameterProvider::cl var selected by remember { mutableStateOf(false) } OdsChip( text = "Text", + outlined = outlined, selected = selected, onClick = { selected = !selected }, - leadingAvatar = painterResource(id = R.drawable.placeholder_small), - outlined = outlined + leadingAvatar = painterResource(id = R.drawable.placeholder_small) ) } diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt index ad1ac5264..e3fe58550 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt @@ -76,7 +76,6 @@ fun OdsChoiceChipsFlowRowScope.OdsChoiceChip(text: String, value: T, modi }, selected = selected, onClick = { selectedChip.value = value }, - outlined = outlinedChips, enabled = enabled ) } From f02d6d04873dc1605bf16432247d18c60d1cc001 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 17 Aug 2023 17:14:04 +0200 Subject: [PATCH 02/13] [#603] Update OdsChip API --- .../ods/app/ui/components/chips/Chip.kt | 30 ++++--- docs/components/Chips.md | 13 ++- .../ods/compose/component/chip/OdsChip.kt | 47 +++++------ .../compose/component/chip/OdsChipCommon.kt | 79 +++++++++++++++++++ 4 files changed, 127 insertions(+), 42 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt diff --git a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt index 5b99462bf..1c655adb0 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt @@ -37,10 +37,11 @@ import com.orange.ods.app.ui.components.utilities.clickOnElement import com.orange.ods.app.ui.utilities.DrawableManager import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode -import com.orange.ods.app.ui.utilities.composable.ImagePainterValue import com.orange.ods.app.ui.utilities.composable.Subtitle import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.chip.OdsChip +import com.orange.ods.compose.component.chip.OdsChipLeadingAvatar +import com.orange.ods.compose.component.chip.OdsChipLeadingIcon import com.orange.ods.compose.component.chip.OdsChoiceChip import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow import com.orange.ods.compose.component.list.OdsListItem @@ -149,12 +150,14 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { OdsChip( text = recipe?.title.orEmpty(), onClick = { clickOnElement(context, recipe?.title.orEmpty()) }, - leadingIcon = if (isActionChip || hasLeadingIcon) recipe?.iconResId?.let { painterResource(id = it) } else null, + leadingIcon = if (isActionChip || hasLeadingIcon) recipe?.iconResId?.let { OdsChipLeadingIcon(painterResource(id = it), "") } else null, leadingAvatar = if (hasLeadingAvatar) { - rememberAsyncImagePainter( - model = recipe?.imageUrl, - placeholder = painterResource(id = DrawableManager.getPlaceholderSmallResId()), - error = painterResource(id = DrawableManager.getPlaceholderSmallResId(error = true)) + OdsChipLeadingAvatar( + rememberAsyncImagePainter( + model = recipe?.imageUrl, + placeholder = painterResource(id = DrawableManager.getPlaceholderSmallResId()), + error = painterResource(id = DrawableManager.getPlaceholderSmallResId(error = true)) + ), "" ) } else null, enabled = isEnabled, @@ -171,9 +174,18 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { exhaustiveParameters = false, parameters = { text(recipe?.title.orEmpty()) - if (!outlinedChips) stringRepresentation("outlined", outlinedChips) - if (isActionChip || hasLeadingIcon) icon() - if (hasLeadingAvatar) simple("leadingAvatar", ImagePainterValue) + if (isActionChip || hasLeadingIcon) { + classInstance("leadingIcon", OdsChipLeadingIcon::class.java) { + painter() + contentDescription("") + } + } + if (hasLeadingAvatar) { + classInstance("leadingAvatar", OdsChipLeadingAvatar::class.java) { + image() + contentDescription("") + } + } if (!isEnabled) enabled(false) onClick() if (isInputChip) lambda("onCancel") diff --git a/docs/components/Chips.md b/docs/components/Chips.md index e93deb0c1..ce5226304 100644 --- a/docs/components/Chips.md +++ b/docs/components/Chips.md @@ -59,7 +59,11 @@ OdsChip( onClick = { // Something executed on chip click }, - leadingAvatar = painterResource(id = R.drawable.avatar), + leadingIcon = null, + leadingAvatar = OdsChipLeadingAvatar( + painterResource(id = R.drawable.avatar), + "Avatar" + ), // set it to `null` for no avatar or provide a `leadingIcon` enabled = true, // Set it to `false` to disabled the chip onCancel = { // Something executed on cancel cross click @@ -110,7 +114,6 @@ OdsChip( onClick = { // Something executed on chip click }, - outlined = false, // Set it to `true` to display an outlined chip enabled = true, // Set it to `false` to disabled the chip ) ``` @@ -200,8 +203,10 @@ OdsChip( onClick = { // Something executed on chip click }, - leadingIcon = painterResource(id = R.drawable.ic_heart), // set it to `null` for no icon - outlined = false, // Set it to `true` to display an outlined chip + leadingIcon = OdsChipLeadingIcon( + painterResource(id = R.drawable.ic_heart), + "Heart" + ), // set it to `null` for no icon enabled = true, // Set it to `false` to disabled the chip ) ``` diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index a2293152f..2e1098ced 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -13,6 +13,7 @@ package com.orange.ods.compose.component.chip import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Chip import androidx.compose.material.ChipColors import androidx.compose.material.ChipDefaults.LeadingIconOpacity @@ -25,7 +26,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.semantics @@ -36,12 +38,10 @@ import com.orange.ods.R import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.chip.OdsChipDefaults.SurfaceOverlayOpacity import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider -import com.orange.ods.compose.component.utilities.OdsImageCircleShape import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.component.utilities.selectionStateDescription import com.orange.ods.compose.theme.OdsTheme -import com.orange.ods.compose.utilities.extension.enable import com.orange.ods.compose.utilities.extension.noRippleClickable import com.orange.ods.theme.OdsComponentsConfiguration @@ -56,15 +56,14 @@ import com.orange.ods.theme.OdsComponentsConfiguration * Use Accompanist's [Flow Layouts](https://google.github.io/accompanist/flowlayout/) to wrap chips to a new line. * * @param text Text to display in the chip. - * @param onClick called when the chip is clicked. + * @param onClick Called when the chip is clicked. * @param modifier Modifier to be applied to the chip * @param enabled When disabled, chip will not respond to user input. It will also appear visually * disabled and disabled to accessibility services. * @param selected When selected the chip is highlighted (useful for choice chips). - * @param leadingIcon Optional icon at the start of the chip, preceding the content text. - * @param leadingAvatar Optional avatar at the start of the chip, preceding the content text. - * @param leadingContentDescription Content description associated to the leading element. - * @param onCancel called when the cancel cross of the chip is clicked. Pass `null` here for no cancel cross. + * @param leadingIcon Icon at the start of the chip, preceding the content text. + * @param leadingAvatar Avatar at the start of the chip displayed in a circle shape, preceding the content text. + * @param onCancel Called when the cancel cross of the chip is clicked. Pass `null` here for no cancel cross. */ @Composable @OdsComposable @@ -74,9 +73,8 @@ fun OdsChip( modifier: Modifier = Modifier, enabled: Boolean = true, selected: Boolean = false, - leadingIcon: Painter? = null, - leadingAvatar: Painter? = null, - leadingContentDescription: String? = null, + leadingIcon: OdsChipLeadingIcon? = null, + leadingAvatar: OdsChipLeadingAvatar? = null, onCancel: (() -> Unit)? = null ) { OdsChip( @@ -88,7 +86,6 @@ fun OdsChip( selected = selected, leadingIcon = leadingIcon, leadingAvatar = leadingAvatar, - leadingContentDescription = leadingContentDescription, onCancel = onCancel ) } @@ -103,9 +100,8 @@ private fun OdsChip( modifier: Modifier = Modifier, enabled: Boolean = true, selected: Boolean = false, - leadingIcon: Painter? = null, - leadingAvatar: Painter? = null, - leadingContentDescription: String? = null, + leadingIcon: OdsChipLeadingIcon? = null, + leadingAvatar: OdsChipLeadingAvatar? = null, onCancel: (() -> Unit)? = null ) { val chipStateDescription = selectionStateDescription(selected) @@ -121,22 +117,15 @@ private fun OdsChip( colors = odsChipColors(outlined, selected), leadingIcon = when { leadingIcon != null -> { - { - Icon( - modifier = Modifier.size(dimensionResource(id = R.dimen.chip_icon_size)), - painter = leadingIcon, - contentDescription = leadingContentDescription, - tint = if (enabled) OdsTheme.colors.onSurface else OdsTheme.colors.onSurface.enable(enabled = false) - ) - } + { leadingIcon.Content(modifier = Modifier.size(dimensionResource(id = R.dimen.chip_icon_size))) } } leadingAvatar != null -> { { - OdsImageCircleShape( - painter = leadingAvatar, - contentDescription = leadingContentDescription, - circleSize = dimensionResource(id = R.dimen.icon_size), - alpha = if (enabled) 1f else LeadingIconOpacity + leadingAvatar.Content( + modifier = modifier + .size(dimensionResource(id = R.dimen.icon_size)) + .clip(CircleShape) + .alpha(if (enabled) 1f else LeadingIconOpacity), ) } } @@ -192,7 +181,7 @@ private fun PreviewOdsChip(@PreviewParameter(OdsChipPreviewParameterProvider::cl outlined = outlined, selected = selected, onClick = { selected = !selected }, - leadingAvatar = painterResource(id = R.drawable.placeholder_small) + leadingAvatar = OdsChipLeadingAvatar(painterResource(id = R.drawable.placeholder_small), "") ) } diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt new file mode 100644 index 000000000..4f0d06b84 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt @@ -0,0 +1,79 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.chip + +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.layout.ContentScale +import com.orange.ods.compose.component.content.OdsComponentIcon +import com.orange.ods.compose.component.content.OdsComponentImage + +/** + * A leading icon in an [OdsChip]. + */ +class OdsChipLeadingIcon : OdsComponentIcon { + + /** + * Creates an instance of [OdsChipLeadingIcon]. + * + * @param painter The painter to draw. + * @param contentDescription The content description associated to this [OdsChipLeadingIcon]. + */ + constructor(painter: Painter, contentDescription: String) : super(painter as Any, contentDescription) + + /** + * Creates an instance of [OdsChipLeadingIcon]. + * + * @param imageVector The image vector to draw. + * @param contentDescription The content description associated to this [OdsChipLeadingIcon]. + */ + constructor(imageVector: ImageVector, contentDescription: String) : super(imageVector as Any, contentDescription) + + /** + * Creates an instance of [OdsChipLeadingIcon]. + * + * @param bitmap The image bitmap to draw. + * @param contentDescription The content description associated to this [OdsChipLeadingIcon]. + */ + constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap as Any, contentDescription) +} + +/** + * A leading icon in an [OdsChip]. + */ +class OdsChipLeadingAvatar : OdsComponentImage { + + /** + * Creates an instance of [OdsChipLeadingAvatar]. + * + * @param painter The painter to draw. + * @param contentDescription The content description associated to this [OdsChipLeadingAvatar]. + */ + constructor(painter: Painter, contentDescription: String) : super(painter as Any, contentDescription, ContentScale.Crop) + + /** + * Creates an instance of [OdsChipLeadingAvatar]. + * + * @param imageVector The image vector to draw. + * @param contentDescription The content description associated to this [OdsChipLeadingAvatar]. + */ + constructor(imageVector: ImageVector, contentDescription: String) : super(imageVector as Any, contentDescription, ContentScale.Crop) + + /** + * Creates an instance of [OdsChipLeadingAvatar]. + * + * @param bitmap The image bitmap to draw. + * @param contentDescription The content description associated to this [OdsChipLeadingAvatar]. + */ + constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap as Any, contentDescription, ContentScale.Crop) + +} From 0fb9e6825ea93465b1729175090b5fcfc15067c1 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 17 Aug 2023 17:28:00 +0200 Subject: [PATCH 03/13] [#603] Update OdsChoiceChipsFlowRow API --- .../appbars/top/ComponentTopAppBar.kt | 2 -- .../ui/components/buttons/ComponentButtons.kt | 2 -- .../app/ui/components/cards/ComponentCard.kt | 11 +++++------ .../orange/ods/app/ui/components/chips/Chip.kt | 7 +------ .../ods/app/ui/components/chips/ChipFilter.kt | 1 - .../ComponentFloatingActionButton.kt | 1 - .../components/imagetile/ComponentImageTile.kt | 1 - .../ui/components/listitem/ComponentListItem.kt | 2 -- .../navigationdrawers/ComponentModalDrawers.kt | 2 -- .../ui/components/progress/ProgressCircular.kt | 1 - .../ui/components/progress/ProgressLinear.kt | 1 - .../components/sheets/ComponentSheetsBottom.kt | 1 - .../ods/app/ui/components/tabs/ComponentTabs.kt | 1 - .../components/textfields/ComponentTextField.kt | 6 ------ docs/components/Chips.md | 8 ++++---- .../component/chip/OdsChoiceChipsFlowRow.kt | 17 ++++++----------- 16 files changed, 16 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt b/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt index 824632300..f4f8fe432 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt @@ -189,7 +189,6 @@ private fun CustomizationBottomSheetContent(customizationState: TopAppBarCustomi OdsChoiceChipsFlowRow( selectedChip = scrollBehavior, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_app_bars_top_large_scroll_behavior_none, value = TopAppBarCustomizationState.ScrollBehavior.None) OdsChoiceChip( @@ -227,7 +226,6 @@ private fun CustomizationBottomSheetContent(customizationState: TopAppBarCustomi modifier = Modifier .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) .padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_app_bars_top_large_title_one_line, value = TopAppBarCustomizationState.Title.Short) OdsChoiceChip(textRes = R.string.component_app_bars_top_large_title_two_lines, value = TopAppBarCustomizationState.Title.TwoLines) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt index 9d7955355..84b24e9c5 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt @@ -65,7 +65,6 @@ fun ComponentButtons(variant: Variant) { OdsChoiceChipsFlowRow( selectedChip = buttonStyle, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_button_style_functional_positive, value = OdsButtonStyle.FunctionalPositive) OdsChoiceChip(textRes = R.string.component_button_style_functional_negative, value = OdsButtonStyle.FunctionalNegative) @@ -76,7 +75,6 @@ fun ComponentButtons(variant: Variant) { OdsChoiceChipsFlowRow( selectedChip = textButtonStyle, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_button_style_primary, value = OdsTextButtonStyle.Primary) OdsChoiceChip(textRes = R.string.component_button_style_default, value = OdsTextButtonStyle.Default) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt b/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt index 763e5c812..9277d2b15 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt @@ -17,16 +17,16 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource -import com.orange.ods.compose.component.card.OdsHorizontalCardImagePosition -import com.orange.ods.compose.component.chip.OdsChoiceChip -import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow -import com.orange.ods.compose.component.list.OdsListItem -import com.orange.ods.compose.component.list.OdsSwitchTrailing import com.orange.ods.app.R import com.orange.ods.app.ui.components.Variant import com.orange.ods.app.ui.components.utilities.ComponentCountRow import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold import com.orange.ods.app.ui.utilities.composable.Subtitle +import com.orange.ods.compose.component.card.OdsHorizontalCardImagePosition +import com.orange.ods.compose.component.chip.OdsChoiceChip +import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow +import com.orange.ods.compose.component.list.OdsListItem +import com.orange.ods.compose.component.list.OdsSwitchTrailing @OptIn(ExperimentalMaterialApi::class) @Composable @@ -51,7 +51,6 @@ fun ComponentCard(variant: Variant) { OdsChoiceChipsFlowRow( selectedChip = imagePosition, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_card_horizontal_image_position_start, value = OdsHorizontalCardImagePosition.Start) OdsChoiceChip(textRes = R.string.component_card_horizontal_image_position_end, value = OdsHorizontalCardImagePosition.End) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt index 1c655adb0..305be1c2e 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt @@ -28,7 +28,6 @@ import androidx.compose.ui.res.stringResource import coil.compose.rememberAsyncImagePainter import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes -import com.orange.ods.app.ui.LocalThemeManager import com.orange.ods.app.ui.components.Variant import com.orange.ods.app.ui.components.chips.ChipCustomizationState.ChipType import com.orange.ods.app.ui.components.chips.ChipCustomizationState.LeadingElement @@ -47,7 +46,6 @@ import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsSwitchTrailing import com.orange.ods.compose.text.OdsTextBody2 -import com.orange.ods.theme.OdsComponentsConfiguration.ComponentStyle @OptIn(ExperimentalMaterialApi::class) @Composable @@ -63,7 +61,6 @@ fun Chip(variant: Variant) { OdsChoiceChipsFlowRow( selectedChip = leadingElement, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_element_none, value = LeadingElement.None) OdsChoiceChip(textRes = R.string.component_element_avatar, value = LeadingElement.Avatar) @@ -108,13 +105,12 @@ fun ChipTypeDemo(chipType: ChipType, content: @Composable () -> Unit) { @Composable private fun Chip(chipCustomizationState: ChipCustomizationState) { val context = LocalContext.current - val outlinedChips = LocalThemeManager.current.currentThemeConfiguration.componentsConfiguration.chipStyle == ComponentStyle.Outlined val cancelCrossLabel = stringResource(id = R.string.component_element_cancel_cross) val recipes = LocalRecipes.current.take(4) with(chipCustomizationState) { if (isChoiceChip) { - OdsChoiceChipsFlowRow(selectedChip = choiceChipIndexSelected, outlinedChips = outlinedChips) { + OdsChoiceChipsFlowRow(selectedChip = choiceChipIndexSelected) { recipes.forEachIndexed { index, recipe -> OdsChoiceChip( text = recipe.title, @@ -131,7 +127,6 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { name = OdsComposable.OdsChoiceChipsFlowRow.name, parameters = { mutableState("selectedChip", choiceChipIndexSelected.value.toString()) - if (!outlinedChips) stringRepresentation("outlinedChips", outlinedChips) } ) { recipes.forEachIndexed { index, recipe -> diff --git a/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt b/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt index 53ce9a3f1..e40a9e964 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt @@ -60,7 +60,6 @@ fun ChipFilter() { OdsChoiceChipsFlowRow( selectedChip = leadingElement, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_element_none, value = ChipCustomizationState.LeadingElement.None) OdsChoiceChip(textRes = R.string.component_element_avatar, value = ChipCustomizationState.LeadingElement.Avatar) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt b/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt index 5c430b8ec..3c868ef7c 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt @@ -95,7 +95,6 @@ fun ComponentFloatingActionButton() { OdsChoiceChipsFlowRow( selectedChip = size, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_floating_action_button_size_default, value = FabCustomizationState.Size.Default) OdsChoiceChip(textRes = R.string.component_floating_action_button_size_mini, value = FabCustomizationState.Size.Mini) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt b/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt index de8451496..2f083440a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt @@ -72,7 +72,6 @@ fun ComponentImageTile() { OdsChoiceChipsFlowRow( selectedChip = type, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { Subtitle(textRes = R.string.component_image_tile_legend_area_display_type) OdsChoiceChip(textRes = R.string.component_image_tile_legend_area_display_type_overlay, value = OdsImageTileLegendAreaDisplayType.Overlay) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index 4ae57cbef..8972fc141 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -80,7 +80,6 @@ private fun ComponentListItemBottomSheetContent(listItemCustomizationState: List OdsChoiceChipsFlowRow( selectedChip = listItemCustomizationState.selectedLeading, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_list_leading_none, value = ListItemCustomizationState.Leading.None) OdsChoiceChip(textRes = R.string.component_list_leading_icon, value = ListItemCustomizationState.Leading.Icon) @@ -93,7 +92,6 @@ private fun ComponentListItemBottomSheetContent(listItemCustomizationState: List OdsChoiceChipsFlowRow( selectedChip = listItemCustomizationState.selectedTrailing, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { listItemCustomizationState.trailings.forEach { trailing -> OdsChoiceChip(textRes = trailing.textResId, value = trailing) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt b/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt index 806105800..e6cfc1d39 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt @@ -117,7 +117,6 @@ fun ComponentModalDrawers() { ) OdsChoiceChipsFlowRow( selectedChip = header, - outlinedChips = true, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), ) { Subtitle(textRes = R.string.component_modal_drawer_header_image) @@ -144,7 +143,6 @@ fun ComponentModalDrawers() { ) OdsChoiceChipsFlowRow( selectedChip = content, - outlinedChips = true, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), ) { Subtitle(textRes = R.string.component_modal_drawer_list_example) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt index d8d641484..36a451241 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt @@ -62,7 +62,6 @@ fun ProgressCircular() { OdsChoiceChipsFlowRow( selectedChip = type, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { Subtitle(textRes = R.string.component_element_type) OdsChoiceChip(textRes = R.string.component_progress_determinate, value = ProgressCustomizationState.Type.Determinate) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt index f9e834400..3cc1b8371 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt @@ -65,7 +65,6 @@ fun ProgressLinear() { OdsChoiceChipsFlowRow( selectedChip = type, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { Subtitle(textRes = R.string.component_element_type) OdsChoiceChip(textRes = R.string.component_progress_determinate, value = ProgressCustomizationState.Type.Determinate) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt b/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt index 81670c8e0..6dd65b49c 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt @@ -78,7 +78,6 @@ fun ComponentSheetsBottom() { OdsChoiceChipsFlowRow( selectedChip = content, - outlinedChips = true, modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)) ) { OdsChoiceChip(textRes = R.string.component_element_empty, value = SheetsBottomCustomizationState.Content.Empty) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt index e1bc85c04..5fa148d6d 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt @@ -81,7 +81,6 @@ fun ComponentTabs(variant: Variant, upPress: () -> Unit) { OdsChoiceChipsFlowRow( selectedChip = tabsCustomizationState.tabIconType, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true ) { OdsChoiceChip( textRes = R.string.component_tab_icon_leading, diff --git a/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt b/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt index 1462b899f..5dc59e11a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt @@ -133,7 +133,6 @@ private fun ComponentCustomizationContent(textFieldCustomizationState: TextField OdsChoiceChipsFlowRow( selectedChip = textFieldCustomizationState.inputType, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_text_field_input_type_single_line, value = TextFieldCustomizationState.InputType.SingleLine) OdsChoiceChip(textRes = R.string.component_text_field_input_type_multiline, value = TextFieldCustomizationState.InputType.Multiline) @@ -152,7 +151,6 @@ private fun ComponentCustomizationContent(textFieldCustomizationState: TextField OdsChoiceChipsFlowRow( selectedChip = textFieldCustomizationState.trailingElement, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_element_none, value = TextFieldCustomizationState.TrailingElement.None) OdsChoiceChip(textRes = R.string.component_element_icon, value = TextFieldCustomizationState.TrailingElement.Icon) @@ -172,7 +170,6 @@ private fun KeyboardCustomizationContent(textFieldCustomizationState: TextFieldC selectedChip = textFieldCustomizationState.softKeyboardType, modifier = Modifier .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { TextFieldCustomizationState.SoftKeyboardType.values().forEach { softKeyboardType -> OdsChoiceChip(text = stringResource(id = softKeyboardType.labelRes), value = softKeyboardType) @@ -188,13 +185,11 @@ private fun KeyboardCustomizationContent(textFieldCustomizationState: TextFieldC OdsChoiceChipsFlowRow( selectedChip = textFieldCustomizationState.softKeyboardAction, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - outlinedChips = true ) { TextFieldCustomizationState.SoftKeyboardAction.values().forEach { softKeyboardAction -> OdsChoiceChip(text = stringResource(id = softKeyboardAction.labelRes), value = softKeyboardAction) } } - } @Composable @@ -203,7 +198,6 @@ private fun DisplayTypeCustomization(displayType: MutableState OdsChoiceChipsFlowRow( selectedChip: MutableState, modifier: Modifier = Modifier, - outlinedChips: Boolean = true, content: @Composable OdsChoiceChipsFlowRowScope.() -> Unit ) { FlowRow( @@ -52,7 +50,7 @@ fun OdsChoiceChipsFlowRow( .fillMaxWidth() .selectableGroup(), mainAxisSpacing = dimensionResource(id = R.dimen.spacing_s), - content = { OdsChoiceChipsFlowRowScope(selectedChip, outlinedChips).content() } + content = { OdsChoiceChipsFlowRowScope(selectedChip).content() } ) } @@ -96,11 +94,11 @@ fun OdsChoiceChipsFlowRowScope.OdsChoiceChip(@StringRes textRes: Int, val /** * Scope for the children of [OdsChoiceChipsFlowRow]. */ -data class OdsChoiceChipsFlowRowScope(val selectedChip: MutableState, val outlinedChips: Boolean) +data class OdsChoiceChipsFlowRowScope(val selectedChip: MutableState) @UiModePreviews.Default @Composable -private fun PreviewOdsChoiceChipsFlowRow(@PreviewParameter(OdsChoiceChipsFlowRowPreviewParameterProvider::class) outlinedChips: Boolean) = Preview { +private fun PreviewOdsChoiceChipsFlowRow() = Preview { data class ChoiceChip(val text: String, val enabled: Boolean, val value: Int) val choiceChips = listOf( @@ -113,7 +111,6 @@ private fun PreviewOdsChoiceChipsFlowRow(@PreviewParameter(OdsChoiceChipsFlowRow val selectedChip = remember { mutableStateOf(choiceChips.first().value) } OdsChoiceChipsFlowRow( selectedChip = selectedChip, - outlinedChips = outlinedChips ) { choiceChips.forEach { choiceChip -> with(choiceChip) { @@ -121,6 +118,4 @@ private fun PreviewOdsChoiceChipsFlowRow(@PreviewParameter(OdsChoiceChipsFlowRow } } } -} - -private class OdsChoiceChipsFlowRowPreviewParameterProvider : BasicPreviewParameterProvider(false, true) +} \ No newline at end of file From 36f70dab1a6a94084d7b6b0922bd7e541f29a04c Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Fri, 18 Aug 2023 09:50:50 +0200 Subject: [PATCH 04/13] [#603] Update OdsFilterChip API --- .../ods/app/ui/components/chips/ChipFilter.kt | 26 ++++++------ docs/components/Chips.md | 10 +++-- .../ods/compose/component/chip/OdsChip.kt | 12 ++---- .../compose/component/chip/OdsChipCommon.kt | 18 ++++++++ .../compose/component/chip/OdsFilterChip.kt | 41 ++++++++++++++----- .../com/orange/ods/extension/ContextExt.kt | 18 ++++++++ 6 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/extension/ContextExt.kt diff --git a/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt b/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt index e40a9e964..aa2319b9c 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt @@ -28,20 +28,18 @@ import coil.compose.rememberAsyncImagePainter import com.google.accompanist.flowlayout.FlowRow import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes -import com.orange.ods.app.ui.LocalThemeManager import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold import com.orange.ods.app.ui.utilities.DrawableManager import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode -import com.orange.ods.app.ui.utilities.composable.ImagePainterValue import com.orange.ods.app.ui.utilities.composable.Subtitle import com.orange.ods.compose.OdsComposable +import com.orange.ods.compose.component.chip.OdsChipLeadingAvatar import com.orange.ods.compose.component.chip.OdsChoiceChip import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow import com.orange.ods.compose.component.chip.OdsFilterChip import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsSwitchTrailing -import com.orange.ods.theme.OdsComponentsConfiguration.ComponentStyle @OptIn(ExperimentalMaterialApi::class) @Composable @@ -49,7 +47,6 @@ fun ChipFilter() { val chipCustomizationState = rememberChipCustomizationState(chipType = rememberSaveable { mutableStateOf(ChipCustomizationState.ChipType.Filter) }) val recipes = LocalRecipes.current val recipe = rememberSaveable { recipes.filter { it.ingredients.count() >= 3 }.random() } - val outlinedChips = LocalThemeManager.current.currentThemeConfiguration.componentsConfiguration.chipStyle == ComponentStyle.Outlined with(chipCustomizationState) { ComponentCustomizationBottomSheetScaffold( @@ -79,16 +76,17 @@ fun ChipFilter() { OdsFilterChip( text = ingredient.food.name, leadingAvatar = if (hasLeadingAvatar) { - rememberAsyncImagePainter( - model = ingredient.food.imageUrl, - placeholder = painterResource(id = DrawableManager.getPlaceholderSmallResId()), - error = painterResource(id = DrawableManager.getPlaceholderSmallResId(error = true)) + OdsChipLeadingAvatar( + rememberAsyncImagePainter( + model = ingredient.food.imageUrl, + placeholder = painterResource(id = DrawableManager.getPlaceholderSmallResId()), + error = painterResource(id = DrawableManager.getPlaceholderSmallResId(error = true)) + ), "" ) } else null, onClick = { selectedChipIndexes = with(selectedChipIndexes) { if (contains(index)) minus(index) else plus(index) } }, - outlined = outlinedChips, selected = selectedChipIndexes.contains(index), enabled = isEnabled, ) @@ -100,7 +98,7 @@ fun ChipFilter() { CodeImplementationColumn { FunctionCallCode( name = "FlowRow", - parameters = { simple("mainAxisSpacing", "dimensionResource(id = com.orange.ods.R.dimen.spacing_s))") } + parameters = { simple("mainAxisSpacing", "8.dp") } ) { recipe.ingredients.forEachIndexed { index, ingredient -> FunctionCallCode( @@ -108,9 +106,13 @@ fun ChipFilter() { exhaustiveParameters = false, parameters = { text(ingredient.food.name) - if (hasLeadingAvatar) simple("leadingAvatar", ImagePainterValue) + if (hasLeadingAvatar) { + classInstance("leadingAvatar", OdsChipLeadingAvatar::class.java) { + image() + contentDescription("") + } + } onClick() - if (!outlinedChips) stringRepresentation("outlined", outlinedChips) if (selectedChipIndexes.contains(index)) selected(true) if (!isEnabled) enabled(false) }) diff --git a/docs/components/Chips.md b/docs/components/Chips.md index ca4a43143..5ae31e542 100644 --- a/docs/components/Chips.md +++ b/docs/components/Chips.md @@ -148,7 +148,9 @@ toggle buttons or checkboxes. > **Jetpack Compose implementation** -Use the `OdsFilterChip` composable: +Use the `OdsFilterChip` composable. +Note that the chip style is outlined or filled according to your OdsTheme component configuration, +outlined by default. ```kotlin OdsFilterChip( @@ -156,9 +158,11 @@ OdsFilterChip( onClick = { // Something executed on chip click }, - leadingAvatar = painterResource(id = R.drawable.avatar), // set it to `null` for no avatar + leadingAvatar = OdsChipLeadingAvatar( + painterResource(id = R.drawable.avatar), + "" + ), // set it to `null` for no avatar selected = false, // `true` to display the chip selected - outlined = false, // Set it to `true` to display an outlined chip enabled = true, // Set it to `false` to disabled the chip ) ``` diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index 2e1098ced..9007b8592 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -13,10 +13,8 @@ package com.orange.ods.compose.component.chip import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Chip import androidx.compose.material.ChipColors -import androidx.compose.material.ChipDefaults.LeadingIconOpacity import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.material.Text @@ -26,8 +24,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.semantics @@ -104,7 +101,9 @@ private fun OdsChip( leadingAvatar: OdsChipLeadingAvatar? = null, onCancel: (() -> Unit)? = null ) { + val context = LocalContext.current val chipStateDescription = selectionStateDescription(selected) + Chip( onClick = onClick, modifier = modifier.semantics { @@ -122,10 +121,7 @@ private fun OdsChip( leadingAvatar != null -> { { leadingAvatar.Content( - modifier = modifier - .size(dimensionResource(id = R.dimen.icon_size)) - .clip(CircleShape) - .alpha(if (enabled) 1f else LeadingIconOpacity), + modifier = modifier.odsChipAvatar(context, enabled), ) } } diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt index 4f0d06b84..6efa93b0e 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt @@ -10,12 +10,23 @@ package com.orange.ods.compose.component.chip +import android.content.Context +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.ChipDefaults +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.dp +import com.orange.ods.R import com.orange.ods.compose.component.content.OdsComponentIcon import com.orange.ods.compose.component.content.OdsComponentImage +import com.orange.ods.extension.getDpFromPx /** * A leading icon in an [OdsChip]. @@ -77,3 +88,10 @@ class OdsChipLeadingAvatar : OdsComponentImage { constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap as Any, contentDescription, ContentScale.Crop) } + +@OptIn(ExperimentalMaterialApi::class) +fun Modifier.odsChipAvatar(context: Context, enabled: Boolean): Modifier { + return this.size(context.getDpFromPx(context.resources.getDimensionPixelSize(R.dimen.icon_size)).dp) + .clip(CircleShape) + .alpha(if (enabled) 1f else ChipDefaults.LeadingIconOpacity) +} \ No newline at end of file diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt index 195f8e321..35facb7b9 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt @@ -30,7 +30,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.ColorPainter -import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -44,38 +44,60 @@ import com.orange.ods.compose.component.utilities.OdsImageCircleShape import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.theme.OdsTheme +import com.orange.ods.theme.OdsComponentsConfiguration /** * ODS Chips. * * Chips are small components containing a number of elements that represent a calendar event or contact. + * Note that [OdsFilterChip] is displayed outlined or filled according to your [OdsTheme] component configuration, outlined by default. * * Use Accompanist's [Flow Layouts](https://google.github.io/accompanist/flowlayout/) to wrap chips to a new line. * * @param text Text to display in the chip. * @param onClick called when the chip is clicked. * @param modifier Modifier to be applied to the chip - * @param outlined If true, a border will be drawn around the chip otherwise the chip will be filled. * @param enabled When disabled, chip will not respond to user input. It will also appear visually * disabled and disabled to accessibility services. * @param selected Highlight the chip and display a selected icon if set to true. * @param leadingAvatar Optional avatar at the start of the chip, preceding the content text. * @param leadingContentDescription Content description associated to the leading element. */ -@OptIn(ExperimentalMaterialApi::class) @Composable @OdsComposable fun OdsFilterChip( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + selected: Boolean = false, + leadingAvatar: OdsChipLeadingAvatar? = null +) { + OdsFilterChip( + text = text, + onClick = onClick, + modifier = modifier, + outlined = OdsTheme.componentsConfiguration.chipStyle == OdsComponentsConfiguration.ComponentStyle.Outlined, + enabled = enabled, + selected = selected, + leadingAvatar = leadingAvatar + ) +} + +@OptIn(ExperimentalMaterialApi::class) +@Composable +@OdsComposable +private fun OdsFilterChip( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, outlined: Boolean = true, enabled: Boolean = true, selected: Boolean = false, - leadingAvatar: Painter? = null, - leadingContentDescription: String? = null + leadingAvatar: OdsChipLeadingAvatar? = null, ) { val emptyAction = {} + val context = LocalContext.current FilterChip( selected = selected, @@ -91,11 +113,8 @@ fun OdsFilterChip( leadingAvatar != null -> { { Box(contentAlignment = Alignment.Center) { - OdsImageCircleShape( - painter = leadingAvatar, - contentDescription = leadingContentDescription, - circleSize = dimensionResource(id = R.dimen.icon_size), - alpha = if (enabled) 1f else LeadingIconOpacity + leadingAvatar.Content( + modifier = modifier.odsChipAvatar(context, enabled), ) if (selected) { OdsImageCircleShape( @@ -144,7 +163,7 @@ private fun PreviewOdsFilterChip(@PreviewParameter(OdsFilterChipPreviewParameter text = "Text", selected = selected, onClick = { selected = !selected }, - leadingAvatar = painterResource(id = R.drawable.ic_check), + leadingAvatar = OdsChipLeadingAvatar(painterResource(id = R.drawable.ic_check), "selected"), outlined = outlined ) } diff --git a/lib/src/main/java/com/orange/ods/extension/ContextExt.kt b/lib/src/main/java/com/orange/ods/extension/ContextExt.kt new file mode 100644 index 000000000..db3ad930a --- /dev/null +++ b/lib/src/main/java/com/orange/ods/extension/ContextExt.kt @@ -0,0 +1,18 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.extension + +import android.content.Context + +/** + * @return the dp corresponding to the given [pixelSize] + */ +fun Context.getDpFromPx(pixelSize: Int) = pixelSize / this.resources.displayMetrics.density \ No newline at end of file From b290440cb5a50034e31dc78562387be746b89e64 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Fri, 18 Aug 2023 09:52:54 +0200 Subject: [PATCH 05/13] [#603] Update changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 32bdb70b4..6f82b2862 100644 --- a/changelog.md +++ b/changelog.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - \[Lib\] Update `OdsFloatingActionButton` and `OdsExtendedFloatingActionButton` APIs ([#611](https://github.com/Orange-OpenSource/ods-android/issues/611)) - \[Lib\] Update `OdsLinearProgressIndicator` and `OdsCircularProgressIndicator` APIs ([#607](https://github.com/Orange-OpenSource/ods-android/issues/607)) - \[Lib\] Update `OdsImageItem` API and rename it into `OdsImageTile` ([#609](https://github.com/Orange-OpenSource/ods-android/issues/609)) +- \[Lib\] Update `OdsChip`, `OdsChoiceChipsFlowRow`and `OdsFilterChip` APIs ([#603](https://github.com/Orange-OpenSource/ods-android/issues/603)) ### Fixed From 4451d391b80ffe5e1ad01a0c0cc3342c96cce579 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 6 Sep 2023 09:59:24 +0200 Subject: [PATCH 06/13] [#603] Review: Remove unnecessary Context extension --- .../ods/compose/component/chip/OdsChip.kt | 2 +- .../compose/component/chip/OdsChipCommon.kt | 9 ++++----- .../compose/component/chip/OdsFilterChip.kt | 2 +- .../com/orange/ods/extension/ContextExt.kt | 18 ------------------ 4 files changed, 6 insertions(+), 25 deletions(-) delete mode 100644 lib/src/main/java/com/orange/ods/extension/ContextExt.kt diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index 9007b8592..5ee48ac74 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -121,7 +121,7 @@ private fun OdsChip( leadingAvatar != null -> { { leadingAvatar.Content( - modifier = modifier.odsChipAvatar(context, enabled), + modifier = modifier.odsChipAvatar(enabled), ) } } diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt index 6efa93b0e..3c4055345 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt @@ -10,23 +10,22 @@ package com.orange.ods.compose.component.chip -import android.content.Context import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.ChipDefaults import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.ui.Modifier +import androidx.compose.ui.composed import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.unit.dp +import androidx.compose.ui.res.dimensionResource import com.orange.ods.R import com.orange.ods.compose.component.content.OdsComponentIcon import com.orange.ods.compose.component.content.OdsComponentImage -import com.orange.ods.extension.getDpFromPx /** * A leading icon in an [OdsChip]. @@ -90,8 +89,8 @@ class OdsChipLeadingAvatar : OdsComponentImage { } @OptIn(ExperimentalMaterialApi::class) -fun Modifier.odsChipAvatar(context: Context, enabled: Boolean): Modifier { - return this.size(context.getDpFromPx(context.resources.getDimensionPixelSize(R.dimen.icon_size)).dp) +fun Modifier.odsChipAvatar(enabled: Boolean): Modifier = composed { + this.size(dimensionResource(R.dimen.icon_size)) .clip(CircleShape) .alpha(if (enabled) 1f else ChipDefaults.LeadingIconOpacity) } \ No newline at end of file diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt index 35facb7b9..7de6c7d53 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt @@ -114,7 +114,7 @@ private fun OdsFilterChip( { Box(contentAlignment = Alignment.Center) { leadingAvatar.Content( - modifier = modifier.odsChipAvatar(context, enabled), + modifier = modifier.odsChipAvatar(enabled), ) if (selected) { OdsImageCircleShape( diff --git a/lib/src/main/java/com/orange/ods/extension/ContextExt.kt b/lib/src/main/java/com/orange/ods/extension/ContextExt.kt deleted file mode 100644 index db3ad930a..000000000 --- a/lib/src/main/java/com/orange/ods/extension/ContextExt.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * - * Copyright 2021 Orange - * - * Use of this source code is governed by an MIT-style - * license that can be found in the LICENSE file or at - * https://opensource.org/licenses/MIT. - * / - */ - -package com.orange.ods.extension - -import android.content.Context - -/** - * @return the dp corresponding to the given [pixelSize] - */ -fun Context.getDpFromPx(pixelSize: Int) = pixelSize / this.resources.displayMetrics.density \ No newline at end of file From 46c79496530f1b7bbafa5c20d22ac94326389577 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 6 Sep 2023 10:04:40 +0200 Subject: [PATCH 07/13] [#603] Review: Remove configuration parameter from previews cause it is directly managed by a variable in build.gradle --- gradle.properties | 3 +-- .../com/orange/ods/compose/component/chip/OdsChip.kt | 11 +++-------- .../ods/compose/component/chip/OdsFilterChip.kt | 11 ++--------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/gradle.properties b/gradle.properties index c614d3401..323b29004 100644 --- a/gradle.properties +++ b/gradle.properties @@ -29,5 +29,4 @@ android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official kapt.incremental.apt=true -version=0.14.0 -previewThemeClass=com.orange.ods.theme.orange.OrangeThemeConfiguration \ No newline at end of file +version=0.14.0 \ No newline at end of file diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index 5ee48ac74..3d56dedeb 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -29,12 +29,10 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription -import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import com.orange.ods.R import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.chip.OdsChipDefaults.SurfaceOverlayOpacity -import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.component.utilities.selectionStateDescription @@ -103,7 +101,7 @@ private fun OdsChip( ) { val context = LocalContext.current val chipStateDescription = selectionStateDescription(selected) - + Chip( onClick = onClick, modifier = modifier.semantics { @@ -170,15 +168,12 @@ private fun odsChipBorderColor(selected: Boolean, enabled: Boolean) = when { @UiModePreviews.Chip @Composable -private fun PreviewOdsChip(@PreviewParameter(OdsChipPreviewParameterProvider::class) outlined: Boolean) = Preview { +private fun PreviewOdsChip() = Preview { var selected by remember { mutableStateOf(false) } OdsChip( text = "Text", - outlined = outlined, selected = selected, onClick = { selected = !selected }, leadingAvatar = OdsChipLeadingAvatar(painterResource(id = R.drawable.placeholder_small), "") ) -} - -private class OdsChipPreviewParameterProvider : BasicPreviewParameterProvider(false, true) +} \ No newline at end of file diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt index 7de6c7d53..db13dddb7 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt @@ -30,15 +30,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.ColorPainter -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import com.orange.ods.R import com.orange.ods.compose.component.OdsComposable -import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.DisabledInteractionSource import com.orange.ods.compose.component.utilities.OdsImageCircleShape import com.orange.ods.compose.component.utilities.Preview @@ -97,7 +94,6 @@ private fun OdsFilterChip( leadingAvatar: OdsChipLeadingAvatar? = null, ) { val emptyAction = {} - val context = LocalContext.current FilterChip( selected = selected, @@ -157,15 +153,12 @@ private fun OdsChipSelectedIcon(tint: Color = LocalContentColor.current.copy(alp @UiModePreviews.Chip @Composable -private fun PreviewOdsFilterChip(@PreviewParameter(OdsFilterChipPreviewParameterProvider::class) outlined: Boolean) = Preview { +private fun PreviewOdsFilterChip() = Preview { var selected by remember { mutableStateOf(false) } OdsFilterChip( text = "Text", selected = selected, onClick = { selected = !selected }, leadingAvatar = OdsChipLeadingAvatar(painterResource(id = R.drawable.ic_check), "selected"), - outlined = outlined ) -} - -private class OdsFilterChipPreviewParameterProvider : BasicPreviewParameterProvider(false, true) +} \ No newline at end of file From 25f9079153cac58b3d15839c1b017648cba44dd1 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 6 Sep 2023 10:06:50 +0200 Subject: [PATCH 08/13] [#603] Review: Fix kdoc --- .../com/orange/ods/compose/component/chip/OdsChipCommon.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt index 3c4055345..20f92da4a 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt @@ -58,7 +58,7 @@ class OdsChipLeadingIcon : OdsComponentIcon { } /** - * A leading icon in an [OdsChip]. + * A leading avatar in an [OdsChip]. */ class OdsChipLeadingAvatar : OdsComponentImage { @@ -90,7 +90,8 @@ class OdsChipLeadingAvatar : OdsComponentImage { @OptIn(ExperimentalMaterialApi::class) fun Modifier.odsChipAvatar(enabled: Boolean): Modifier = composed { - this.size(dimensionResource(R.dimen.icon_size)) + this + .size(dimensionResource(R.dimen.icon_size)) .clip(CircleShape) .alpha(if (enabled) 1f else ChipDefaults.LeadingIconOpacity) } \ No newline at end of file From dfeb27fc4345904cb9b152ce19e1ad5f1469fced Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 6 Sep 2023 10:08:35 +0200 Subject: [PATCH 09/13] [#603] Review: Set method to internal --- .../java/com/orange/ods/compose/component/chip/OdsChipCommon.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt index 20f92da4a..351a0166a 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt @@ -89,7 +89,7 @@ class OdsChipLeadingAvatar : OdsComponentImage { } @OptIn(ExperimentalMaterialApi::class) -fun Modifier.odsChipAvatar(enabled: Boolean): Modifier = composed { +internal fun Modifier.odsChipAvatar(enabled: Boolean): Modifier = composed { this .size(dimensionResource(R.dimen.icon_size)) .clip(CircleShape) From b587e0fbef1d7efc3b6583bb96274021d3d12cf4 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 6 Sep 2023 10:19:16 +0200 Subject: [PATCH 10/13] [#603] Review: Set leading icon size in OdsChipLeadingIcon Content() method --- .../java/com/orange/ods/compose/component/chip/OdsChip.kt | 4 +--- .../com/orange/ods/compose/component/chip/OdsChipCommon.kt | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index 3d56dedeb..6f1fa9fcb 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -24,7 +24,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.semantics @@ -99,7 +98,6 @@ private fun OdsChip( leadingAvatar: OdsChipLeadingAvatar? = null, onCancel: (() -> Unit)? = null ) { - val context = LocalContext.current val chipStateDescription = selectionStateDescription(selected) Chip( @@ -114,7 +112,7 @@ private fun OdsChip( colors = odsChipColors(outlined, selected), leadingIcon = when { leadingIcon != null -> { - { leadingIcon.Content(modifier = Modifier.size(dimensionResource(id = R.dimen.chip_icon_size))) } + { leadingIcon.Content() } } leadingAvatar != null -> { { diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt index 351a0166a..eb7d473fd 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.ChipDefaults import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.draw.alpha @@ -55,6 +56,11 @@ class OdsChipLeadingIcon : OdsComponentIcon { * @param contentDescription The content description associated to this [OdsChipLeadingIcon]. */ constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap as Any, contentDescription) + + @Composable + override fun Content(modifier: Modifier) { + super.Content(modifier.size(dimensionResource(id = R.dimen.chip_icon_size))) + } } /** From f5ffedffafb7913a577c50dd174757241f3c186b Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 6 Sep 2023 10:27:39 +0200 Subject: [PATCH 11/13] [#603] Review: Factorize code --- .../java/com/orange/ods/compose/component/chip/OdsChip.kt | 6 +----- .../com/orange/ods/compose/component/chip/OdsChipCommon.kt | 5 +++++ .../com/orange/ods/compose/component/chip/OdsFilterChip.kt | 4 +--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index 6f1fa9fcb..9086a149d 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -115,11 +115,7 @@ private fun OdsChip( { leadingIcon.Content() } } leadingAvatar != null -> { - { - leadingAvatar.Content( - modifier = modifier.odsChipAvatar(enabled), - ) - } + { leadingAvatar.Content(enabled) } } else -> null } diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt index eb7d473fd..089570f57 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChipCommon.kt @@ -92,6 +92,11 @@ class OdsChipLeadingAvatar : OdsComponentImage { */ constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap as Any, contentDescription, ContentScale.Crop) + @Composable + fun Content(enabled: Boolean) { + this.Content(modifier = Modifier.odsChipAvatar(enabled)) + } + } @OptIn(ExperimentalMaterialApi::class) diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt index db13dddb7..8bff263c0 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsFilterChip.kt @@ -109,9 +109,7 @@ private fun OdsFilterChip( leadingAvatar != null -> { { Box(contentAlignment = Alignment.Center) { - leadingAvatar.Content( - modifier = modifier.odsChipAvatar(enabled), - ) + leadingAvatar.Content(enabled) if (selected) { OdsImageCircleShape( painter = ColorPainter(color = Color.Black), From 4d1a708e99261582f031c91cba508efbce15a106 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Fri, 8 Sep 2023 11:24:09 +0200 Subject: [PATCH 12/13] [#603] Review: Improve OdsChoiceChipsFlowRow signature --- .../appbars/top/ComponentTopAppBar.kt | 47 +++++--- .../ui/components/buttons/ComponentButtons.kt | 28 +++-- .../app/ui/components/cards/ComponentCard.kt | 14 ++- .../ods/app/ui/components/chips/Chip.kt | 49 ++++---- .../ods/app/ui/components/chips/ChipFilter.kt | 14 ++- .../ComponentFloatingActionButton.kt | 15 ++- .../imagetile/ComponentImageTile.kt | 22 ++-- .../components/listitem/ComponentListItem.kt | 33 +++--- .../ComponentModalDrawers.kt | 65 +++++----- .../components/progress/ProgressCircular.kt | 17 +-- .../ui/components/progress/ProgressLinear.kt | 14 ++- .../sheets/ComponentSheetsBottom.kt | 15 +-- .../app/ui/components/tabs/ComponentTabs.kt | 37 +++--- .../textfields/ComponentTextField.kt | 100 ++++++++++------ docs/components/Chips.md | 15 +-- .../component/chip/OdsChoiceChipsFlowRow.kt | 112 +++++++++--------- 16 files changed, 334 insertions(+), 263 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt b/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt index f4f8fe432..85b4568c8 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/appbars/top/ComponentTopAppBar.kt @@ -187,15 +187,20 @@ private fun CustomizationBottomSheetContent(customizationState: TopAppBarCustomi if (isLarge) { Subtitle(textRes = R.string.component_app_bars_top_large_scroll_behavior, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = scrollBehavior, + value = scrollBehavior.value, + onValueChange = { value -> scrollBehavior.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - OdsChoiceChip(textRes = R.string.component_app_bars_top_large_scroll_behavior_none, value = TopAppBarCustomizationState.ScrollBehavior.None) - OdsChoiceChip( - textRes = R.string.component_app_bars_top_large_scroll_behavior_collapsible, - value = TopAppBarCustomizationState.ScrollBehavior.Collapsible + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_app_bars_top_large_scroll_behavior_none), + value = TopAppBarCustomizationState.ScrollBehavior.None + ), + OdsChoiceChip( + text = stringResource(R.string.component_app_bars_top_large_scroll_behavior_collapsible), + value = TopAppBarCustomizationState.ScrollBehavior.Collapsible + ) ) - } + ) } OdsListItem( text = stringResource(id = R.string.component_app_bars_top_element_navigation_icon), @@ -222,18 +227,24 @@ private fun CustomizationBottomSheetContent(customizationState: TopAppBarCustomi if (isLarge) { Subtitle(textRes = R.string.component_element_title, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = title, - modifier = Modifier - .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) - .padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), - ) { - OdsChoiceChip(textRes = R.string.component_app_bars_top_large_title_one_line, value = TopAppBarCustomizationState.Title.Short) - OdsChoiceChip(textRes = R.string.component_app_bars_top_large_title_two_lines, value = TopAppBarCustomizationState.Title.TwoLines) - OdsChoiceChip( - textRes = R.string.component_app_bars_top_large_title_truncated, - value = TopAppBarCustomizationState.Title.Long + value = title.value, + onValueChange = { value -> title.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_app_bars_top_large_title_one_line), + value = TopAppBarCustomizationState.Title.Short + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_app_bars_top_large_title_two_lines), + value = TopAppBarCustomizationState.Title.TwoLines + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_app_bars_top_large_title_truncated), + value = TopAppBarCustomizationState.Title.Long + ) ) - } + ) } } } diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt index 84b24e9c5..c6e46bc87 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ComponentButtons.kt @@ -63,22 +63,26 @@ fun ComponentButtons(variant: Variant) { Variant.ButtonsFunctional -> { Subtitle(textRes = R.string.component_button_style_functional, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = buttonStyle, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - OdsChoiceChip(textRes = R.string.component_button_style_functional_positive, value = OdsButtonStyle.FunctionalPositive) - OdsChoiceChip(textRes = R.string.component_button_style_functional_negative, value = OdsButtonStyle.FunctionalNegative) - } + value = buttonStyle.value, + onValueChange = { value -> buttonStyle.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_button_style_functional_positive), value = OdsButtonStyle.FunctionalPositive), + OdsChoiceChip(text = stringResource(id = R.string.component_button_style_functional_negative), value = OdsButtonStyle.FunctionalNegative) + ) + ) } Variant.ButtonsText -> { Subtitle(textRes = R.string.component_style, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = textButtonStyle, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - OdsChoiceChip(textRes = R.string.component_button_style_primary, value = OdsTextButtonStyle.Primary) - OdsChoiceChip(textRes = R.string.component_button_style_default, value = OdsTextButtonStyle.Default) - } + value = textButtonStyle.value, + onValueChange = { value -> textButtonStyle.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_button_style_primary), value = OdsTextButtonStyle.Primary), + OdsChoiceChip(text = stringResource(id = R.string.component_button_style_default), value = OdsTextButtonStyle.Default) + ) + ) } Variant.ButtonsTextToggleGroup -> { ComponentCountRow( diff --git a/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt b/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt index 9277d2b15..a7925f5f5 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/cards/ComponentCard.kt @@ -49,12 +49,14 @@ fun ComponentCard(variant: Variant) { } else if (variant == Variant.CardHorizontal) { Subtitle(textRes = R.string.component_card_horizontal_image_position, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = imagePosition, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - OdsChoiceChip(textRes = R.string.component_card_horizontal_image_position_start, value = OdsHorizontalCardImagePosition.Start) - OdsChoiceChip(textRes = R.string.component_card_horizontal_image_position_end, value = OdsHorizontalCardImagePosition.End) - } + value = imagePosition.value, + onValueChange = { value -> imagePosition.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_card_horizontal_image_position_start), value = OdsHorizontalCardImagePosition.Start), + OdsChoiceChip(text = stringResource(id = R.string.component_card_horizontal_image_position_end), value = OdsHorizontalCardImagePosition.End) + ) + ) } OdsListItem( text = stringResource(id = R.string.component_element_subtitle), diff --git a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt index 305be1c2e..28a771c68 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/chips/Chip.kt @@ -59,13 +59,15 @@ fun Chip(variant: Variant) { if (isInputChip) { Subtitle(textRes = R.string.component_element_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = leadingElement, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - OdsChoiceChip(textRes = R.string.component_element_none, value = LeadingElement.None) - OdsChoiceChip(textRes = R.string.component_element_avatar, value = LeadingElement.Avatar) - OdsChoiceChip(textRes = R.string.component_element_icon, value = LeadingElement.Icon) - } + value = leadingElement.value, + onValueChange = { value -> leadingElement.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_element_none), value = LeadingElement.None), + OdsChoiceChip(text = stringResource(id = R.string.component_element_avatar), value = LeadingElement.Avatar), + OdsChoiceChip(text = stringResource(id = R.string.component_element_icon), value = LeadingElement.Icon) + ) + ) } else { resetLeadingElement() } @@ -110,15 +112,18 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { with(chipCustomizationState) { if (isChoiceChip) { - OdsChoiceChipsFlowRow(selectedChip = choiceChipIndexSelected) { - recipes.forEachIndexed { index, recipe -> + OdsChoiceChipsFlowRow( + value = choiceChipIndexSelected.value, + onValueChange = { value -> choiceChipIndexSelected.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = recipes.mapIndexed { index, recipe -> OdsChoiceChip( text = recipe.title, value = index, enabled = isEnabled ) } - } + ) Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) @@ -126,19 +131,19 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { FunctionCallCode( name = OdsComposable.OdsChoiceChipsFlowRow.name, parameters = { - mutableState("selectedChip", choiceChipIndexSelected.value.toString()) - } - ) { - recipes.forEachIndexed { index, recipe -> - FunctionCallCode( - name = OdsComposable.OdsChoiceChip.name, - parameters = { - text(recipe.title) - stringRepresentation("value", index) - if (!isEnabled) enabled(false) - }) + stringRepresentation("value", choiceChipIndexSelected.value.toString()) + lambda("onValueChange") + list("chips") { + recipes.forEachIndexed { index, recipe -> + classInstance(OdsChoiceChip::class.java) { + text(recipe.title) + stringRepresentation("value", index) + if (!isEnabled) enabled(false) + } + } + } } - } + ) } } else { val recipe = recipes.firstOrNull() diff --git a/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt b/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt index aa2319b9c..d12945744 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/chips/ChipFilter.kt @@ -55,12 +55,14 @@ fun ChipFilter() { Subtitle(textRes = R.string.component_element_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = leadingElement, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - OdsChoiceChip(textRes = R.string.component_element_none, value = ChipCustomizationState.LeadingElement.None) - OdsChoiceChip(textRes = R.string.component_element_avatar, value = ChipCustomizationState.LeadingElement.Avatar) - } + value = leadingElement.value, + onValueChange = { value -> leadingElement.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_element_none), value = ChipCustomizationState.LeadingElement.None), + OdsChoiceChip(text = stringResource(id = R.string.component_element_avatar), value = ChipCustomizationState.LeadingElement.Avatar), + ) + ) OdsListItem( text = stringResource(id = R.string.component_state_enabled), diff --git a/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt b/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt index 3c868ef7c..502f78b6d 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/floatingactionbuttons/ComponentFloatingActionButton.kt @@ -93,12 +93,17 @@ fun ComponentFloatingActionButton() { bottomSheetContent = { Subtitle(textRes = R.string.component_size, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = size, + value = size.value, + onValueChange = { value -> size.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - OdsChoiceChip(textRes = R.string.component_floating_action_button_size_default, value = FabCustomizationState.Size.Default) - OdsChoiceChip(textRes = R.string.component_floating_action_button_size_mini, value = FabCustomizationState.Size.Mini) - } + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_floating_action_button_size_default), + value = FabCustomizationState.Size.Default + ), + OdsChoiceChip(text = stringResource(id = R.string.component_floating_action_button_size_mini), value = FabCustomizationState.Size.Mini) + ) + ) OdsListItem( text = stringResource(id = R.string.component_element_text), trailing = OdsSwitchTrailing(checked = text, enabled = isTextEnabled) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt b/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt index 2f083440a..335b04d3e 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt @@ -69,15 +69,23 @@ fun ComponentImageTile() { ComponentCustomizationBottomSheetScaffold( bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { + Subtitle(textRes = R.string.component_image_tile_legend_area_display_type, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = type, + value = type.value, + onValueChange = { value -> type.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - Subtitle(textRes = R.string.component_image_tile_legend_area_display_type) - OdsChoiceChip(textRes = R.string.component_image_tile_legend_area_display_type_overlay, value = OdsImageTileLegendAreaDisplayType.Overlay) - OdsChoiceChip(textRes = R.string.component_image_tile_legend_area_display_type_below, value = OdsImageTileLegendAreaDisplayType.Below) - OdsChoiceChip(textRes = R.string.component_element_none, value = OdsImageTileLegendAreaDisplayType.None) - } + chips = listOf( + OdsChoiceChip( + text = stringResource(R.string.component_image_tile_legend_area_display_type_overlay), + value = OdsImageTileLegendAreaDisplayType.Overlay + ), + OdsChoiceChip( + text = stringResource(R.string.component_image_tile_legend_area_display_type_below), + value = OdsImageTileLegendAreaDisplayType.Below + ), + OdsChoiceChip(text = stringResource(R.string.component_element_none), value = OdsImageTileLegendAreaDisplayType.None), + ) + ) OdsListItem( text = stringResource(id = R.string.component_element_icon), trailing = OdsSwitchTrailing(checked = iconDisplayed, enabled = hasText) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index 8972fc141..63d00aee7 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -78,26 +78,27 @@ private fun ComponentListItemBottomSheetContent(listItemCustomizationState: List Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = listItemCustomizationState.selectedLeading, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - OdsChoiceChip(textRes = R.string.component_list_leading_none, value = ListItemCustomizationState.Leading.None) - OdsChoiceChip(textRes = R.string.component_list_leading_icon, value = ListItemCustomizationState.Leading.Icon) - OdsChoiceChip(textRes = R.string.component_list_leading_circular_image, value = ListItemCustomizationState.Leading.CircularImage) - OdsChoiceChip(textRes = R.string.component_list_leading_square_image, value = ListItemCustomizationState.Leading.SquareImage) - OdsChoiceChip(textRes = R.string.component_list_leading_wide_image, value = ListItemCustomizationState.Leading.WideImage) - } + value = listItemCustomizationState.selectedLeading.value, + onValueChange = { value -> listItemCustomizationState.selectedLeading.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_list_leading_none), value = ListItemCustomizationState.Leading.None), + OdsChoiceChip(text = stringResource(id = R.string.component_list_leading_icon), value = ListItemCustomizationState.Leading.Icon), + OdsChoiceChip(text = stringResource(id = R.string.component_list_leading_circular_image), value = ListItemCustomizationState.Leading.CircularImage), + OdsChoiceChip(text = stringResource(id = R.string.component_list_leading_square_image), value = ListItemCustomizationState.Leading.SquareImage), + OdsChoiceChip(text = stringResource(id = R.string.component_list_leading_wide_image), value = ListItemCustomizationState.Leading.WideImage), + ) + ) Subtitle(textRes = R.string.component_list_trailing, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = listItemCustomizationState.selectedTrailing, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - listItemCustomizationState.trailings.forEach { trailing -> - OdsChoiceChip(textRes = trailing.textResId, value = trailing) + value = listItemCustomizationState.selectedTrailing.value, + onValueChange = { value -> listItemCustomizationState.selectedTrailing.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listItemCustomizationState.trailings.map { trailing -> + OdsChoiceChip(text = stringResource(id = trailing.textResId), value = trailing) } - } - + ) } @Composable diff --git a/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt b/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt index e6cfc1d39..5f7443c1a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/navigationdrawers/ComponentModalDrawers.kt @@ -115,18 +115,26 @@ fun ComponentModalDrawers() { text = stringResource(id = R.string.component_modal_drawer_content_example), trailing = OdsSwitchTrailing(checked = contentExampleChecked) ) + Subtitle(textRes = R.string.component_modal_drawer_header_image, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = header, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - Subtitle(textRes = R.string.component_modal_drawer_header_image) - OdsChoiceChip(textRes = R.string.component_element_avatar, value = ComponentNavigationDrawersContentState.HeaderImage.Avatar) - OdsChoiceChip( - textRes = R.string.component_modal_drawer_background, - value = ComponentNavigationDrawersContentState.HeaderImage.Background + value = header.value, + onValueChange = { value -> header.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_element_avatar), + value = ComponentNavigationDrawersContentState.HeaderImage.Avatar + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_modal_drawer_background), + value = ComponentNavigationDrawersContentState.HeaderImage.Background + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_element_none), + value = ComponentNavigationDrawersContentState.HeaderImage.None + ) ) - OdsChoiceChip(textRes = R.string.component_element_none, value = ComponentNavigationDrawersContentState.HeaderImage.None) - } + ) OdsListItem( text = stringResource(id = R.string.component_modal_drawer_subtitle), trailing = OdsSwitchTrailing( @@ -141,27 +149,26 @@ fun ComponentModalDrawers() { enabled = isContentExampleChecked ), ) + Subtitle(textRes = R.string.component_modal_drawer_list_example, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = content, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - Subtitle(textRes = R.string.component_modal_drawer_list_example) - OdsChoiceChip( - textRes = R.string.component_element_divider, - value = ComponentNavigationDrawersContentState.SectionListExample.Divider, - enabled = isContentExampleChecked - ) - OdsChoiceChip( - textRes = R.string.component_element_label, - value = ComponentNavigationDrawersContentState.SectionListExample.Label, - enabled = isContentExampleChecked + value = content.value, + onValueChange = { value -> content.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_element_divider), + value = ComponentNavigationDrawersContentState.SectionListExample.Divider + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_element_label), + value = ComponentNavigationDrawersContentState.SectionListExample.Label + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_element_none), + value = ComponentNavigationDrawersContentState.SectionListExample.None + ) ) - OdsChoiceChip( - textRes = R.string.component_element_none, - value = ComponentNavigationDrawersContentState.SectionListExample.None, - enabled = isContentExampleChecked - ) - } + ) }) { Column { ComponentLaunchContentColumn( diff --git a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt index 36a451241..1a4d2f348 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressCircular.kt @@ -52,21 +52,24 @@ fun ProgressCircular() { var determinateProgressValue by remember { mutableStateOf(0f) } val determinateProgressAnimation by animateFloatAsState( targetValue = determinateProgressValue, - animationSpec = tween(durationMillis = DeterminateProgressAnimDuration, easing = FastOutSlowInEasing) + animationSpec = tween(durationMillis = DeterminateProgressAnimDuration, easing = FastOutSlowInEasing), + label = "" ) with(customizationState) { ComponentCustomizationBottomSheetScaffold( bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { + Subtitle(textRes = R.string.component_element_type, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = type, + value = type.value, + onValueChange = { value -> type.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - Subtitle(textRes = R.string.component_element_type) - OdsChoiceChip(textRes = R.string.component_progress_determinate, value = ProgressCustomizationState.Type.Determinate) - OdsChoiceChip(textRes = R.string.component_progress_indeterminate, value = ProgressCustomizationState.Type.Indeterminate) - } + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_progress_determinate), value = ProgressCustomizationState.Type.Determinate), + OdsChoiceChip(text = stringResource(id = R.string.component_progress_indeterminate), value = ProgressCustomizationState.Type.Indeterminate) + ) + ) OdsListItem( text = stringResource(id = R.string.component_element_label), trailing = OdsSwitchTrailing(checked = label) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt index 3cc1b8371..c4992342a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/progress/ProgressLinear.kt @@ -62,14 +62,16 @@ fun ProgressLinear() { ComponentCustomizationBottomSheetScaffold( bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { + Subtitle(textRes = R.string.component_element_type, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = type, + value = type.value, + onValueChange = { value -> type.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - Subtitle(textRes = R.string.component_element_type) - OdsChoiceChip(textRes = R.string.component_progress_determinate, value = ProgressCustomizationState.Type.Determinate) - OdsChoiceChip(textRes = R.string.component_progress_indeterminate, value = ProgressCustomizationState.Type.Indeterminate) - } + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_progress_determinate), value = ProgressCustomizationState.Type.Determinate), + OdsChoiceChip(text = stringResource(id = R.string.component_progress_indeterminate), value = ProgressCustomizationState.Type.Indeterminate) + ) + ) OdsListItem( text = stringResource(id = R.string.component_element_label), trailing = OdsSwitchTrailing(checked = label) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt b/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt index 6dd65b49c..50a88a420 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/sheets/ComponentSheetsBottom.kt @@ -75,14 +75,15 @@ fun ComponentSheetsBottom() { text = stringResource(id = R.string.component_element_content), modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) ) - OdsChoiceChipsFlowRow( - selectedChip = content, - modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)) - ) { - OdsChoiceChip(textRes = R.string.component_element_empty, value = SheetsBottomCustomizationState.Content.Empty) - OdsChoiceChip(textRes = R.string.component_element_example, value = SheetsBottomCustomizationState.Content.Example) - } + value = content.value, + onValueChange = { value -> content.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = stringResource(id = R.string.component_element_empty), value = SheetsBottomCustomizationState.Content.Empty), + OdsChoiceChip(text = stringResource(id = R.string.component_element_example), value = SheetsBottomCustomizationState.Content.Example) + ) + ) } CodeImplementationColumn { diff --git a/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt index 5fa148d6d..679dab4d4 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt @@ -79,26 +79,25 @@ fun ComponentTabs(variant: Variant, upPress: () -> Unit) { bottomSheetContent = { Subtitle(textRes = R.string.component_element_icon, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = tabsCustomizationState.tabIconType, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - ) { - OdsChoiceChip( - textRes = R.string.component_tab_icon_leading, - value = MainTabsCustomizationState.TabIconType.Leading, - enabled = tabsCustomizationState.isTabIconCustomizationEnabled + value = tabsCustomizationState.tabIconType.value, + onValueChange = { value -> tabsCustomizationState.tabIconType.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_tab_icon_leading), value = MainTabsCustomizationState.TabIconType.Leading, + enabled = tabsCustomizationState.isTabIconCustomizationEnabled + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_tab_icon_top), value = MainTabsCustomizationState.TabIconType.Top, + enabled = tabsCustomizationState.isTabIconCustomizationEnabled + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_element_none), value = MainTabsCustomizationState.TabIconType.None, + enabled = tabsCustomizationState.isTabIconCustomizationEnabled + ) ) - OdsChoiceChip( - textRes = R.string.component_tab_icon_top, - value = MainTabsCustomizationState.TabIconType.Top, - enabled = tabsCustomizationState.isTabIconCustomizationEnabled - ) - OdsChoiceChip( - textRes = R.string.component_element_none, - value = MainTabsCustomizationState.TabIconType.None, - enabled = tabsCustomizationState.isTabIconCustomizationEnabled - ) - } - + ) + OdsListItem( text = stringResource(id = R.string.component_element_text), trailing = OdsSwitchTrailing(checked = tabsCustomizationState.tabTextEnabled, enabled = tabsCustomizationState.isTabTextCustomizationEnabled) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt b/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt index 5dc59e11a..eaf1fae65 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt @@ -131,32 +131,45 @@ private fun ComponentCustomizationContent(textFieldCustomizationState: TextField Subtitle(textRes = R.string.component_text_field_input_type, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = textFieldCustomizationState.inputType, + value = textFieldCustomizationState.inputType.value, + onValueChange = { value -> textFieldCustomizationState.inputType.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - OdsChoiceChip(textRes = R.string.component_text_field_input_type_single_line, value = TextFieldCustomizationState.InputType.SingleLine) - OdsChoiceChip(textRes = R.string.component_text_field_input_type_multiline, value = TextFieldCustomizationState.InputType.Multiline) - // Note: TextArea chip is disabled cause there is no parameter allowing text area in Jetpack Compose sdk for now - // https://issuetracker.google.com/issues/122476634 - OdsChoiceChip( - textRes = R.string.component_text_field_input_type_text_area, - value = TextFieldCustomizationState.InputType.TextArea, - enabled = false + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_text_field_input_type_single_line), value = TextFieldCustomizationState.InputType.SingleLine + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_text_field_input_type_multiline), value = TextFieldCustomizationState.InputType.Multiline + ), + // Note: TextArea chip is disabled cause there is no parameter allowing text area in Jetpack Compose sdk for now + // https://issuetracker.google.com/issues/122476634 + OdsChoiceChip( + text = stringResource(id = R.string.component_text_field_input_type_text_area), + value = TextFieldCustomizationState.InputType.TextArea, + enabled = false + ), ) - } + ) DisplayTypeCustomization(textFieldCustomizationState.displayType) Subtitle(textRes = R.string.component_element_trailing, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = textFieldCustomizationState.trailingElement, + value = textFieldCustomizationState.trailingElement.value, + onValueChange = { value -> textFieldCustomizationState.trailingElement.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - OdsChoiceChip(textRes = R.string.component_element_none, value = TextFieldCustomizationState.TrailingElement.None) - OdsChoiceChip(textRes = R.string.component_element_icon, value = TextFieldCustomizationState.TrailingElement.Icon) - OdsChoiceChip(textRes = R.string.component_element_text, value = TextFieldCustomizationState.TrailingElement.Text) - } - + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_element_none), value = TextFieldCustomizationState.TrailingElement.None + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_element_icon), value = TextFieldCustomizationState.TrailingElement.Icon + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_element_text), value = TextFieldCustomizationState.TrailingElement.Text + ), + ) + ) OdsListItem( text = stringResource(id = R.string.component_text_field_character_counter), trailing = OdsSwitchTrailing(checked = textFieldCustomizationState.characterCounter) @@ -167,14 +180,13 @@ private fun ComponentCustomizationContent(textFieldCustomizationState: TextField private fun KeyboardCustomizationContent(textFieldCustomizationState: TextFieldCustomizationState) { Subtitle(textRes = R.string.component_text_field_keyboard_type, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = textFieldCustomizationState.softKeyboardType, - modifier = Modifier - .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - TextFieldCustomizationState.SoftKeyboardType.values().forEach { softKeyboardType -> + value = textFieldCustomizationState.softKeyboardType.value, + onValueChange = { value -> textFieldCustomizationState.softKeyboardType.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = TextFieldCustomizationState.SoftKeyboardType.values().map { softKeyboardType -> OdsChoiceChip(text = stringResource(id = softKeyboardType.labelRes), value = softKeyboardType) } - } + ) OdsListItem( text = stringResource(id = R.string.component_text_field_keyboard_capitalization), @@ -183,31 +195,41 @@ private fun KeyboardCustomizationContent(textFieldCustomizationState: TextFieldC Subtitle(textRes = R.string.component_text_field_keyboard_action, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = textFieldCustomizationState.softKeyboardAction, + value = textFieldCustomizationState.softKeyboardAction.value, + onValueChange = { value -> textFieldCustomizationState.softKeyboardAction.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - TextFieldCustomizationState.SoftKeyboardAction.values().forEach { softKeyboardAction -> + chips = TextFieldCustomizationState.SoftKeyboardAction.values().map { softKeyboardAction -> OdsChoiceChip(text = stringResource(id = softKeyboardAction.labelRes), value = softKeyboardAction) } - } + ) } @Composable private fun DisplayTypeCustomization(displayType: MutableState) { + val context = LocalContext.current Subtitle(textRes = R.string.component_state, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = displayType, + value = displayType.value, + onValueChange = { value -> displayType.value = value }, modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - ) { - val context = LocalContext.current - OdsChoiceChip(textRes = R.string.component_state_default, value = TextFieldCustomizationState.DisplayType.Default) - OdsChoiceChip(textRes = R.string.component_state_error, value = TextFieldCustomizationState.DisplayType.Error, modifier = Modifier.semantics { - if (displayType.value == TextFieldCustomizationState.DisplayType.Error) { - error(context.getString(R.string.component_text_field_error_message)) - } - }) - OdsChoiceChip(textRes = R.string.component_state_disabled, value = TextFieldCustomizationState.DisplayType.Disabled) - } + chips = listOf( + OdsChoiceChip( + text = stringResource(id = R.string.component_state_default), value = TextFieldCustomizationState.DisplayType.Default + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_state_error), + value = TextFieldCustomizationState.DisplayType.Error, + modifier = Modifier.semantics { + if (displayType.value == TextFieldCustomizationState.DisplayType.Error) { + error(context.getString(R.string.component_text_field_error_message)) + } + } + ), + OdsChoiceChip( + text = stringResource(id = R.string.component_state_disabled), value = TextFieldCustomizationState.DisplayType.Disabled + ), + ) + ) } private enum class CustomizationTab(@StringRes val titleRes: Int) { diff --git a/docs/components/Chips.md b/docs/components/Chips.md index 5ae31e542..99420dd5f 100644 --- a/docs/components/Chips.md +++ b/docs/components/Chips.md @@ -250,13 +250,14 @@ outlined by default. ```kotlin OdsChoiceChipsFlowRow( - selectedChip = iconTypeState, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) -) { - OdsChoiceChip(textRes = R.string.component_icon_leading, value = IconType.Leading) - OdsChoiceChip(textRes = R.string.component_icon_top, value = IconType.Top) - OdsChoiceChip(textRes = R.string.component_element_none, value = IconType.None) -} + value = chipValue, + onValueChange = { value -> chipValue = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = listOf( + OdsChoiceChip(text = "Choice chip 1", value = 1), + OdsChoiceChip(text = "Choice chip 2", value = 2) + ) +) ``` ## Component specific tokens diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt index db4b203de..c8cfc0ada 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt @@ -10,16 +10,16 @@ package com.orange.ods.compose.component.chip -import androidx.annotation.StringRes import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.selection.selectableGroup import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState +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 androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription import com.google.accompanist.flowlayout.FlowRow @@ -31,91 +31,89 @@ import com.orange.ods.compose.component.utilities.selectionStateDescription import com.orange.ods.compose.theme.OdsTheme /** - * Displays a full width [FlowRow] containing customized choice chips [OdsChoiceChipsFlowRowScope.OdsChoiceChip]. + * Displays a full width [FlowRow] containing customized [OdsChoiceChip]s. + * Only one chip can be selected at a time. When the OdsChoiceChipsFlowRow value changes, [onValueChange] method is invoked. + * * Note that [OdsChoiceChip] are displayed outlined or filled according to your [OdsTheme] component configuration, outlined by default. * - * @param selectedChip The selected chips value state. + * @param value The initial value of this OdsChoiceChipsFlowRow. + * @param onValueChange The callback that is triggered when the value change. * @param modifier Modifier to be applied to the flow row. - * @param content The content of the choice chips [FlowRow]. + * @param chips The list of [OdsChoiceChip]s displayed inside this OdsChoiceChipsFlowRow. */ @Composable @OdsComposable fun OdsChoiceChipsFlowRow( - selectedChip: MutableState, + value: T, + onValueChange: (value: T) -> Unit, modifier: Modifier = Modifier, - content: @Composable OdsChoiceChipsFlowRowScope.() -> Unit + chips: List> ) { + var selectedChipValue by remember { mutableStateOf(value) } + FlowRow( modifier = modifier .fillMaxWidth() .selectableGroup(), mainAxisSpacing = dimensionResource(id = R.dimen.spacing_s), - content = { OdsChoiceChipsFlowRowScope(selectedChip).content() } + content = { + chips.forEachIndexed { index, odsChoiceChip -> + odsChoiceChip.Content(selected = selectedChipValue == odsChoiceChip.value) { selected -> + if (selected) { + selectedChipValue = chips[index].value + onValueChange(chips[index].value) + } + } + } + } ) } /** - * A selectable chip to display in an [OdsChoiceChipsFlowRow] + * OdsChoiceChip used in a [OdsChoiceChipsFlowRow] * * @param text Text displayed in the chip * @param value The chip value - * @param modifier The modifier applied to the OdsChoiceChip - * @param enabled If set to false, the chip is no more clickable and appears as disabled + * @param enabled If set to false, the chip is no more clickable and appears as disabled. True by default. + * @param modifier The Modifier applied on choice chip display */ -@Composable -@OdsComposable -fun OdsChoiceChipsFlowRowScope.OdsChoiceChip(text: String, value: T, modifier: Modifier = Modifier, enabled: Boolean = true) { - val selected = selectedChip.value == value - val chipStateDescription = selectionStateDescription(selected = selected) - OdsChip( - text = text, - modifier = modifier.semantics { - stateDescription = chipStateDescription - }, - selected = selected, - onClick = { selectedChip.value = value }, - enabled = enabled - ) -} +class OdsChoiceChip( + val text: String, + val value: T, + val enabled: Boolean = true, + val modifier: Modifier = Modifier +) { -/** - * A selectable chip to display in an [OdsChoiceChipsFlowRow] - * - * @param textRes Text resource identifier to display in the chip - * @param value The chip value - * @param modifier The modifier applied to the OdsChoiceChip - * @param enabled If set to false, the chip is no more clickable and appears as disabled - */ -@Composable -fun OdsChoiceChipsFlowRowScope.OdsChoiceChip(@StringRes textRes: Int, value: T, modifier: Modifier = Modifier, enabled: Boolean = true) { - OdsChoiceChip(text = stringResource(id = textRes), value = value, modifier = modifier, enabled = enabled) + @Composable + fun Content(selected: Boolean, onSelectedStateChange: (selected: Boolean) -> Unit) { + val chipStateDescription = selectionStateDescription(selected = selected) + OdsChip( + text = text, + modifier = modifier.semantics { + stateDescription = chipStateDescription + }, + selected = selected, + onClick = { onSelectedStateChange(!selected) }, + enabled = enabled + ) + } } -/** - * Scope for the children of [OdsChoiceChipsFlowRow]. - */ -data class OdsChoiceChipsFlowRowScope(val selectedChip: MutableState) - @UiModePreviews.Default @Composable private fun PreviewOdsChoiceChipsFlowRow() = Preview { - data class ChoiceChip(val text: String, val enabled: Boolean, val value: Int) - val choiceChips = listOf( - ChoiceChip("First", true, 1), - ChoiceChip("Second", true, 2), - ChoiceChip("Third", false, 3), - ChoiceChip("Fourth", true, 4) + OdsChoiceChip(text = "First", value = 1), + OdsChoiceChip("Second", value = 2), + OdsChoiceChip("Third", value = 3, enabled = false), + OdsChoiceChip("Fourth", value = 4) ) val selectedChip = remember { mutableStateOf(choiceChips.first().value) } OdsChoiceChipsFlowRow( - selectedChip = selectedChip, - ) { - choiceChips.forEach { choiceChip -> - with(choiceChip) { - OdsChoiceChip(text = text, value = value, enabled = enabled) - } - } - } + value = selectedChip.value, + onValueChange = { value -> selectedChip.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + chips = choiceChips + ) } \ No newline at end of file From ae0233b02d9ff111a8f10837dd1c0c69bbc0bd01 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 11 Sep 2023 13:41:05 +0200 Subject: [PATCH 13/13] [#603] Review: Replace modifier parameter by semantics --- .../app/ui/components/textfields/ComponentTextField.kt | 3 +-- .../ods/compose/component/chip/OdsChoiceChipsFlowRow.kt | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt b/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt index eaf1fae65..78f20e8d1 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/textfields/ComponentTextField.kt @@ -30,7 +30,6 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.error -import androidx.compose.ui.semantics.semantics import com.orange.ods.app.R import com.orange.ods.app.ui.components.Variant import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold @@ -219,7 +218,7 @@ private fun DisplayTypeCustomization(displayType: MutableState OdsChoiceChipsFlowRow( * @param text Text displayed in the chip * @param value The chip value * @param enabled If set to false, the chip is no more clickable and appears as disabled. True by default. - * @param modifier The Modifier applied on choice chip display + * @param semantics The semantics applied on this choice chip */ class OdsChoiceChip( val text: String, val value: T, val enabled: Boolean = true, - val modifier: Modifier = Modifier + val semantics: SemanticsPropertyReceiver.() -> Unit = {} ) { @Composable @@ -89,8 +90,9 @@ class OdsChoiceChip( val chipStateDescription = selectionStateDescription(selected = selected) OdsChip( text = text, - modifier = modifier.semantics { + modifier = Modifier.semantics { stateDescription = chipStateDescription + semantics() }, selected = selected, onClick = { onSelectedStateChange(!selected) },