From 1b18218fc7dfe0250d1376dab0ccb2e5d41f80ea Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 5 Feb 2024 16:58:28 +0100 Subject: [PATCH 1/6] [#549] Add int function in Kotlin code --- .../main/java/com/orange/ods/app/ui/utilities/code/KotlinCode.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/orange/ods/app/ui/utilities/code/KotlinCode.kt b/app/src/main/java/com/orange/ods/app/ui/utilities/code/KotlinCode.kt index 80e8e2078..c08468da4 100644 --- a/app/src/main/java/com/orange/ods/app/ui/utilities/code/KotlinCode.kt +++ b/app/src/main/java/com/orange/ods/app/ui/utilities/code/KotlinCode.kt @@ -189,6 +189,7 @@ class ParametersBuilder { fun string(name: String, textValue: String) = add(StringParameter(name, textValue)) fun lambda(name: String, value: String = "") = add(LambdaParameter(name, value)) fun float(name: String, value: Float) = add(FloatParameter(name, value)) + fun int(name: String, value: Int) = add(SimpleParameter(name, value.toString())) fun mutableState(name: String, stateValue: String) = add(MutableStateParameter(name, stateValue)) fun > enum(name: String, value: T) = add(EnumParameter(name, value)) inline fun classInstance(name: String, noinline parameters: ParametersBuilder.() -> Unit) = From ed770f80a864e5c89ace3f9485a24842d64d67b5 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 5 Feb 2024 16:58:54 +0100 Subject: [PATCH 2/6] [#549] Display code implementation on tabs first page --- .../app/ui/components/tabs/ComponentTabs.kt | 77 ++++++++++++++----- .../tabs/MainTabsCustomizationState.kt | 10 +-- 2 files changed, 63 insertions(+), 24 deletions(-) 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 175b2d71e..e3248d67f 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 @@ -15,9 +15,12 @@ package com.orange.ods.app.ui.components.tabs import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableIntStateOf @@ -32,7 +35,10 @@ import com.orange.ods.app.ui.TabsConfiguration 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.code.CodeImplementationColumn +import com.orange.ods.app.ui.utilities.code.FunctionCallCode import com.orange.ods.app.ui.utilities.composable.Subtitle +import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow import com.orange.ods.compose.component.listitem.OdsListItem import com.orange.ods.compose.component.tab.OdsTabRow @@ -65,7 +71,7 @@ fun ComponentTabs(variant: Variant) { with(tabsCustomizationState) { val appBarManager = LocalAppBarManager.current appBarManager.updateAppBarTabs( - TabsConfiguration(scrollableTabs, tabs, pagerState, tabsIconPosition.value, tabIconEnabled.value, tabTextEnabled.value) + TabsConfiguration(scrollableTabs, tabs, pagerState, tabIconPosition.value, tabIconEnabled.value, tabTextEnabled.value) ) ComponentCustomizationBottomSheetScaffold( @@ -81,14 +87,18 @@ fun ComponentTabs(variant: Variant) { ) Subtitle(textRes = R.string.component_tabs_icon_position, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChoiceChipIndex = OdsTabRow.Tab.Icon.Position.entries.indexOf(tabsIconPosition.value), + selectedChoiceChipIndex = OdsTabRow.Tab.Icon.Position.entries.indexOf(tabIconPosition.value), modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), choiceChips = OdsTabRow.Tab.Icon.Position.entries.map { tabsIconPosition -> val textResId = when (tabsIconPosition) { OdsTabRow.Tab.Icon.Position.Top -> R.string.component_tabs_icon_position_top OdsTabRow.Tab.Icon.Position.Leading -> R.string.component_tabs_icon_position_leading } - OdsChoiceChipsFlowRow.ChoiceChip(stringResource(id = textResId), { this.tabsIconPosition.value = tabsIconPosition }, isTabsIconPositionEnabled) + OdsChoiceChipsFlowRow.ChoiceChip( + stringResource(id = textResId), + { this.tabIconPosition.value = tabsIconPosition }, + isTabIconPositionEnabled + ) } ) @@ -101,23 +111,52 @@ fun ComponentTabs(variant: Variant) { minCount = tabCountMin, maxCount = tabCountMax ) - }) { + } + ) { + HorizontalPager(state = pagerState) { pageIndex -> + val modifier = if (pageIndex == 0) { + Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) + } else { + Modifier + .fillMaxSize() + .wrapContentSize(Alignment.Center) + } - HorizontalPager(state = pagerState) { page -> - val textResId = tabs[page].textResId - TabsPagerContentScreen(stringResource(id = textResId)) + Column(modifier = modifier) { + if (pageIndex == 0) { + // Display code implementation on first page only + CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin))) { + FunctionCallCode( + name = if (scrollableTabs) OdsComposable.OdsScrollableTabRow.name else OdsComposable.OdsTabRow.name, + parameters = { + int("selectedTabIndex", pageIndex) + list("tabs") { + tabs.forEach { tab -> + classInstance { + if (tabIconEnabled.value) { + classInstance("icon") { + painter() + } + } + if (tabTextEnabled.value) { + text(tab.name) + } + onClick() + } + } + } + enum("tabIconPosition", tabIconPosition.value) + } + ) + } + } else { + OdsText(text = stringResource(tabs[pageIndex].textResId), style = OdsTextStyle.BodyL) + } + } } } } -} - -@Composable -private fun TabsPagerContentScreen(text: String) { - Column( - modifier = Modifier - .fillMaxSize() - .wrapContentSize(Alignment.Center) - ) { - OdsText(text = text, style = OdsTextStyle.BodyL) - } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt index 86ff97810..b1a1a14a2 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt @@ -33,12 +33,12 @@ fun rememberMainTabsCustomizationState( bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(), tabsCount: MutableIntState, pagerState: PagerState = rememberPagerState { tabsCount.intValue.coerceAtLeast(0) }, - selectedTabsIconPosition: MutableState = rememberSaveable { mutableStateOf(OdsTabRow.Tab.Icon.Position.Top) }, + selectedTabIconPosition: MutableState = rememberSaveable { mutableStateOf(OdsTabRow.Tab.Icon.Position.Top) }, tabIconEnabled: MutableState = rememberSaveable { mutableStateOf(true) }, tabTextEnabled: MutableState = rememberSaveable { mutableStateOf(true) } ) = - remember(bottomSheetScaffoldState, pagerState, tabsCount, selectedTabsIconPosition, tabIconEnabled, tabTextEnabled) { - MainTabsCustomizationState(bottomSheetScaffoldState, pagerState, tabsCount, selectedTabsIconPosition, tabIconEnabled, tabTextEnabled) + remember(bottomSheetScaffoldState, pagerState, tabsCount, selectedTabIconPosition, tabIconEnabled, tabTextEnabled) { + MainTabsCustomizationState(bottomSheetScaffoldState, pagerState, tabsCount, selectedTabIconPosition, tabIconEnabled, tabTextEnabled) } @OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) @@ -46,7 +46,7 @@ class MainTabsCustomizationState( val bottomSheetScaffoldState: BottomSheetScaffoldState, val pagerState: PagerState, val tabsCount: MutableIntState, - val tabsIconPosition: MutableState, + val tabIconPosition: MutableState, val tabIconEnabled: MutableState, val tabTextEnabled: MutableState ) { @@ -56,7 +56,7 @@ class MainTabsCustomizationState( val isTabIconCustomizationEnabled: Boolean get() = tabTextEnabled.value - val isTabsIconPositionEnabled: Boolean + val isTabIconPositionEnabled: Boolean get() = isTabIconCustomizationEnabled && isTabTextCustomizationEnabled val tabs: List From 499bcd479778c4ef23ae258cf3684a4e6786821a Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 5 Feb 2024 17:02:38 +0100 Subject: [PATCH 3/6] [#549] Update changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 2a843d593..26c4a8f77 100644 --- a/changelog.md +++ b/changelog.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - \[App\] Display third party libraries in the About section ([#485](https://github.com/Orange-OpenSource/ods-android/issues/485)) - \[App\] Display XML code implementation for components with an XML version available ([#788](https://github.com/Orange-OpenSource/ods-android/issues/788)) +- \[App\] Display Compose code implementation for `OdsTabRow` and `OdsScrollableTabRow` ([#549](https://github.com/Orange-OpenSource/ods-android/issues/549)) - \[Doc\] Add XML integration documentation for components with an XML version ([#540](https://github.com/Orange-OpenSource/ods-android/issues/540)) - \[Lib\] Add `OdsSearchTopAppBar` component variant ([#577](https://github.com/Orange-OpenSource/ods-android/issues/577)) - \[Lib\] Add `OdsEmptyStateView` module ([#119](https://github.com/Orange-OpenSource/ods-android/issues/119)) From e8633c3f182a2bfe013c62ee5af8fa6a32ef1e81 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 15 Feb 2024 11:04:38 +0100 Subject: [PATCH 4/6] [#549] Review: Rename selectedTabIconPosition into tabIconPosition --- .../app/ui/components/tabs/MainTabsCustomizationState.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt index b1a1a14a2..252457e83 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/tabs/MainTabsCustomizationState.kt @@ -33,12 +33,12 @@ fun rememberMainTabsCustomizationState( bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(), tabsCount: MutableIntState, pagerState: PagerState = rememberPagerState { tabsCount.intValue.coerceAtLeast(0) }, - selectedTabIconPosition: MutableState = rememberSaveable { mutableStateOf(OdsTabRow.Tab.Icon.Position.Top) }, + tabIconPosition: MutableState = rememberSaveable { mutableStateOf(OdsTabRow.Tab.Icon.Position.Top) }, tabIconEnabled: MutableState = rememberSaveable { mutableStateOf(true) }, tabTextEnabled: MutableState = rememberSaveable { mutableStateOf(true) } ) = - remember(bottomSheetScaffoldState, pagerState, tabsCount, selectedTabIconPosition, tabIconEnabled, tabTextEnabled) { - MainTabsCustomizationState(bottomSheetScaffoldState, pagerState, tabsCount, selectedTabIconPosition, tabIconEnabled, tabTextEnabled) + remember(bottomSheetScaffoldState, pagerState, tabsCount, tabIconPosition, tabIconEnabled, tabTextEnabled) { + MainTabsCustomizationState(bottomSheetScaffoldState, pagerState, tabsCount, tabIconPosition, tabIconEnabled, tabTextEnabled) } @OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) From 12843564b170521a97a567af0a77f2f0da1fa4c2 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 15 Feb 2024 11:07:12 +0100 Subject: [PATCH 5/6] [#549] Review: Rename tabsIconPosition into tabIconPosition --- .../com/orange/ods/app/ui/components/tabs/ComponentTabs.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 e3248d67f..202489ef1 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 @@ -89,14 +89,14 @@ fun ComponentTabs(variant: Variant) { OdsChoiceChipsFlowRow( selectedChoiceChipIndex = OdsTabRow.Tab.Icon.Position.entries.indexOf(tabIconPosition.value), modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), - choiceChips = OdsTabRow.Tab.Icon.Position.entries.map { tabsIconPosition -> - val textResId = when (tabsIconPosition) { + choiceChips = OdsTabRow.Tab.Icon.Position.entries.map { tabIconPosition -> + val textResId = when (tabIconPosition) { OdsTabRow.Tab.Icon.Position.Top -> R.string.component_tabs_icon_position_top OdsTabRow.Tab.Icon.Position.Leading -> R.string.component_tabs_icon_position_leading } OdsChoiceChipsFlowRow.ChoiceChip( stringResource(id = textResId), - { this.tabIconPosition.value = tabsIconPosition }, + { this.tabIconPosition.value = tabIconPosition }, isTabIconPositionEnabled ) } From 032110ca83d9659254601a62304a300cb3e56005 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 15 Feb 2024 11:42:27 +0100 Subject: [PATCH 6/6] [#549] Review: Fix UI bug when scrolling from the first to the second tab --- .../com/orange/ods/app/ui/components/tabs/ComponentTabs.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 202489ef1..c92fb160d 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 @@ -15,7 +15,6 @@ package com.orange.ods.app.ui.components.tabs import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.pager.HorizontalPager @@ -116,7 +115,7 @@ fun ComponentTabs(variant: Variant) { HorizontalPager(state = pagerState) { pageIndex -> val modifier = if (pageIndex == 0) { Modifier - .fillMaxWidth() + .fillMaxSize() .verticalScroll(rememberScrollState()) .padding(top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) } else {