diff --git a/.github/actions/app-distribution/action.yml b/.github/actions/app-distribution/action.yml index eb1870425..4783a1e10 100644 --- a/.github/actions/app-distribution/action.yml +++ b/.github/actions/app-distribution/action.yml @@ -31,7 +31,7 @@ runs: BRANCH_SHA=${{ github.event.pull_request.head.sha }} COMMIT_SHA=${BRANCH_SHA:-$GITHUB_SHA} [ ${{ inputs.append-git-sha-to-version-name }} == 'true' ] && VERSION_NAME_SUFFIX=-${COMMIT_SHA::7} || VERSION_NAME_SUFFIX='' - ./gradlew app:appDistributionUpload -PversionNameSuffix=$VERSION_NAME_SUFFIX -PversionCode=$GITHUB_RUN_NUMBER -PappDistributionVariants=release -PappDistributionGitTagPrefix=${{ inputs.git-tag-prefix }} -PappDistributionGroup=${{ inputs.group }} -PappDistributionGitTagSha=$COMMIT_SHA --stacktrace + ./gradlew app:appDistributionUpload -PversionNameSuffix=$VERSION_NAME_SUFFIX -PversionCode=$GITHUB_RUN_NUMBER -PappDistributionVariants=qualifRelease -PappDistributionGitTagPrefix=${{ inputs.git-tag-prefix }} -PappDistributionGroup=${{ inputs.group }} -PappDistributionGitTagSha=$COMMIT_SHA --stacktrace env: GITHUB_TOKEN: ${{ inputs.github-token }} FIREBASE_TOKEN: ${{ inputs.firebase-token }} diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 6b7a4b6bb..6fe625bd0 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -27,7 +27,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Set up signing configuration uses: ./.github/actions/setup-signing @@ -52,7 +52,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: app - path: app/build/outputs/apk/*/*.apk + path: app/build/outputs/apk/*/*/*.apk - name: Store lib artifacts uses: actions/upload-artifact@v3 @@ -95,7 +95,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Set up signing configuration uses: ./.github/actions/setup-signing @@ -131,7 +131,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Set up signing configuration uses: ./.github/actions/setup-signing @@ -163,17 +163,17 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Publish release to Google Play Store run: | ./gradlew assembleRelease bundleRelease - curl -F 'file=@app/build/outputs/bundle/release/app-release.aab' https://oma-portal.orange.fr/oma/api/v1/external/applications/${{ secrets.OMA_APP_ID }}/artifacts -H "apiKey:${{ secrets.OMA_APP_TOKEN }}" + curl -F 'file=@app/build/outputs/bundle/prodRelease/app-prod-release.aab' https://oma-portal.orange.fr/oma/api/v1/external/applications/${{ secrets.OMA_APP_ID }}/artifacts -H "apiKey:${{ secrets.OMA_APP_TOKEN }}" - name: Store Google Play Store artifacts uses: actions/upload-artifact@v3 with: name: google-play-store path: | - app/build/outputs/apk/*/*.apk + app/build/outputs/apk/*/*/*.apk app/build/outputs/bundle/*/*.aab diff --git a/.github/workflows/app-distribution-daily.yml b/.github/workflows/app-distribution-daily.yml index a40eade75..21195f25d 100644 --- a/.github/workflows/app-distribution-daily.yml +++ b/.github/workflows/app-distribution-daily.yml @@ -18,7 +18,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Set up signing configuration uses: ./.github/actions/setup-signing diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml new file mode 100644 index 000000000..7f21a81f7 --- /dev/null +++ b/.github/workflows/jekyll-gh-pages.yml @@ -0,0 +1,61 @@ +# Sample workflow for building and deploying a Jekyll site to GitHub Pages +name: Deploy Jekyll with GitHub Pages dependencies preinstalled + +on: + # Runs on pushes targeting the default branch + push: + branches: [ "main" ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Setup Pages + uses: actions/configure-pages@v3 + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - name: Build with Jekyll + run: | + cd docs + bundle config set --local path 'vendor/bundle' + bundle install + bundle exec jekyll build + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + path: ./docs/_site + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 + diff --git a/DEVELOP.md b/DEVELOP.md index 153d89284..d97bdb69f 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -18,7 +18,7 @@ repositories { ```groovy dependencies { - implementation 'com.orange.ods.android:ods-lib:0.14.0' + implementation 'com.orange.ods.android:ods-lib:0.15.0' } ``` diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ff1c70991..be50e43a5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,23 +18,24 @@ plugins { id("com.android.application") id("com.google.gms.google-services") id("kotlin-android") - id("kotlin-kapt") id("kotlin-parcelize") id("com.google.firebase.appdistribution") id("com.google.firebase.crashlytics") id("firebase") id("dagger.hilt.android.plugin") + id("kotlin-kapt") // This must be the last statement in the plugins {} to avoid "options not recognized" warning } android { + namespace = "com.orange.ods.app" + compileSdk = Versions.compileSdk defaultConfig { - applicationId = "com.orange.ods.app" minSdk = Versions.minSdk targetSdk = Versions.targetSdk val versionCodeProperty = project.findTypedProperty("versionCode") - versionCode = versionCodeProperty?.toInt() ?: 5 + versionCode = versionCodeProperty?.toInt() ?: 6 versionName = version.toString() val versionNameSuffixProperty = project.findTypedProperty("versionNameSuffix") versionNameSuffix = versionNameSuffixProperty @@ -74,6 +75,20 @@ android { } } + val versionFlavorDimension = "version" + flavorDimensions.add(versionFlavorDimension) + productFlavors { + create("qualif") { + dimension = versionFlavorDimension + applicationId = "com.orange.ods.test.app" + } + + create("prod") { + dimension = versionFlavorDimension + applicationId = "com.orange.ods.app" + } + } + firebaseAppDistribution { releaseNotesFile = Firebase_gradle.AppDistribution.releaseNotesFilePath groups = project.findTypedProperty("appDistributionGroup") @@ -91,16 +106,17 @@ android { } buildFeatures { + buildConfig = true compose = true viewBinding = true dataBinding = true } composeOptions { - kotlinCompilerExtensionVersion = Versions.compose + kotlinCompilerExtensionVersion = Versions.composeCompiler } - packagingOptions { + packaging { with(resources.excludes) { add("/META-INF/{AL2.0,LGPL2.1}") } @@ -112,38 +128,31 @@ dependencies { implementation(project(":lib-xml")) implementation(project(":theme-innovation-cup")) - implementation(Dependencies.composeMaterial3) - implementation(Dependencies.coreKtx) - implementation(Dependencies.kotlinReflect) + implementation(Dependencies.accompanistFlowLayout) + implementation(Dependencies.accompanistSystemUiController) + implementation(Dependencies.activityCompose) implementation(Dependencies.appCompat) - implementation(Dependencies.material) + implementation(Dependencies.browser) + implementation(Dependencies.coil) + implementation(Dependencies.coilCompose) + implementation(platform(Dependencies.composeBom)) + implementation(Dependencies.composeMaterial3) implementation(Dependencies.composeUi) - implementation(Dependencies.lifecycleViewModelKtx) + implementation(Dependencies.composeUiTooling) implementation(Dependencies.composeUiToolingPreview) - implementation(Dependencies.lifecycleRuntimeKtx) - implementation(Dependencies.activityCompose) - implementation(Dependencies.navigationCompose) - implementation(Dependencies.accompanistSystemUiController) - implementation(Dependencies.accompanistPager) - implementation(Dependencies.accompanistPagerIndicators) - implementation(Dependencies.accompanistFlowLayout) + implementation(Dependencies.coreKtx) + implementation(Dependencies.dataStorePreferences) implementation(platform(Dependencies.firebaseBom)) implementation(Dependencies.firebaseCrashlytics) - implementation(Dependencies.webkit) - implementation(Dependencies.browser) implementation(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) - implementation(Dependencies.dataStorePreferences) - implementation(Dependencies.coil) - implementation(Dependencies.coilCompose) + implementation(Dependencies.kotlinReflect) + implementation(Dependencies.lifecycleRuntimeKtx) + implementation(Dependencies.lifecycleViewModelKtx) + implementation(Dependencies.material) + implementation(Dependencies.navigationCompose) implementation(Dependencies.timber) - - debugImplementation(Dependencies.composeUiTooling) -} - -// Allow references to generated code -kapt { - correctErrorTypes = true + implementation(Dependencies.webkit) } tasks.register("copyChangelog") { diff --git a/app/google-services.json b/app/google-services.json index d1d0cef61..dffac0317 100644 --- a/app/google-services.json +++ b/app/google-services.json @@ -62,6 +62,64 @@ ] } } + }, + { + "client_info": { + "mobilesdk_app_id": "1:212698857200:android:67d1403d02a72f4d5ecc35", + "android_client_info": { + "package_name": "com.orange.ods.test.app" + } + }, + "oauth_client": [ + { + "client_id": "212698857200-mvqaopuseqhqeaglk7jm0g8qg0dcvsab.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAIY6bMaglXBkcA72v_vja3yI6-7uaR-8U" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "212698857200-mvqaopuseqhqeaglk7jm0g8qg0dcvsab.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:212698857200:android:92978ae61c91c8b85ecc35", + "android_client_info": { + "package_name": "com.orange.ods.test.flutterapp" + } + }, + "oauth_client": [ + { + "client_id": "212698857200-mvqaopuseqhqeaglk7jm0g8qg0dcvsab.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAIY6bMaglXBkcA72v_vja3yI6-7uaR-8U" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "212698857200-mvqaopuseqhqeaglk7jm0g8qg0dcvsab.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } } ], "configuration_version": "1" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b3740a9c8..e2f1f71de 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,8 +9,7 @@ ~ * https://opensource.org/licenses/MIT. ~ */ --> - + , currentRoute: String, navigateToRoute: (String) -> Unit) { - OdsBottomNavigation { - items.forEach { item -> + OdsBottomNavigation( + items = items.map { item -> OdsBottomNavigationItem( - icon = { Icon(painter = painterResource(id = item.iconRes), contentDescription = null) }, + icon = OdsBottomNavigationItemIcon(painter = painterResource(id = item.iconRes), contentDescription = ""), label = stringResource(id = item.titleRes), selected = currentRoute == item.route, onClick = { navigateToRoute(item.route) } ) } - } + ) } fun NavGraphBuilder.addBottomNavigationGraph(navigateToElement: (String, Long?, NavBackStackEntry) -> Unit) { diff --git a/app/src/main/java/com/orange/ods/app/ui/MainScreen.kt b/app/src/main/java/com/orange/ods/app/ui/MainScreen.kt index 8fdc3ac52..c8ac64622 100644 --- a/app/src/main/java/com/orange/ods/app/ui/MainScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/MainScreen.kt @@ -13,6 +13,7 @@ package com.orange.ods.app.ui import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -36,7 +37,6 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.navigation -import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalCategories @@ -50,8 +50,8 @@ import com.orange.ods.app.ui.search.SearchScreen import com.orange.ods.app.ui.utilities.extension.isDarkModeEnabled import com.orange.ods.app.ui.utilities.extension.isOrange import com.orange.ods.compose.theme.OdsTheme +import com.orange.ods.extension.orElse import com.orange.ods.theme.OdsThemeConfigurationContract -import com.orange.ods.utilities.extension.orElse import com.orange.ods.xml.theme.OdsXml import com.orange.ods.xml.utilities.extension.xml @@ -183,7 +183,7 @@ private fun SystemBarsColorSideEffect() { } } -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) @Composable private fun MainTabs(mainTabsState: MainTabsState) { with(mainTabsState) { diff --git a/app/src/main/java/com/orange/ods/app/ui/MainState.kt b/app/src/main/java/com/orange/ods/app/ui/MainState.kt index b337bb476..c5d2ac900 100644 --- a/app/src/main/java/com/orange/ods/app/ui/MainState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/MainState.kt @@ -123,7 +123,7 @@ class MainState( * This is used to de-duplicate navigation events. */ private fun NavBackStackEntry.lifecycleIsResumed() = - this.lifecycle.currentState == Lifecycle.State.RESUMED + this.getLifecycle().currentState == Lifecycle.State.RESUMED private val NavGraph.startDestination: NavDestination? get() = findNode(startDestinationId) diff --git a/app/src/main/java/com/orange/ods/app/ui/MainTabsState.kt b/app/src/main/java/com/orange/ods/app/ui/MainTabsState.kt index 15864ad53..6c3962fd0 100644 --- a/app/src/main/java/com/orange/ods/app/ui/MainTabsState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/MainTabsState.kt @@ -10,14 +10,14 @@ package com.orange.ods.app.ui +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.pager.PagerState import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.snapshots.SnapshotStateList -import com.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.PagerState import com.orange.ods.app.ui.components.tabs.MainTabsCustomizationState import com.orange.ods.app.ui.utilities.NavigationItem import com.orange.ods.app.ui.utilities.rememberSaveableMutableStateListOf @@ -33,7 +33,7 @@ fun rememberMainTabsState( MainTabsState(tabs, tabIconType, tabTextEnabled, scrollableTabs) } -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) class MainTabsState( val tabs: SnapshotStateList, val tabIconType: MutableState, @@ -78,7 +78,7 @@ class MainTabsState( } } -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) data class TabsConfiguration( val scrollableTabs: Boolean, val tabs: List, diff --git a/app/src/main/java/com/orange/ods/app/ui/MainTopAppBar.kt b/app/src/main/java/com/orange/ods/app/ui/MainTopAppBar.kt index 72af9668b..1d8f01c5f 100644 --- a/app/src/main/java/com/orange/ods/app/ui/MainTopAppBar.kt +++ b/app/src/main/java/com/orange/ods/app/ui/MainTopAppBar.kt @@ -12,10 +12,8 @@ package com.orange.ods.app.ui import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Icon import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.ExperimentalMaterial3Api @@ -37,13 +35,14 @@ import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes import com.orange.ods.app.ui.components.utilities.clickOnElement import com.orange.ods.app.ui.utilities.extension.isDarkModeEnabled -import com.orange.ods.compose.component.appbar.top.OdsLargeTopAppBar -import com.orange.ods.compose.component.appbar.top.OdsTopAppBar +import com.orange.ods.compose.component.appbar.top.OdsLargeTopAppBarInternal import com.orange.ods.compose.component.appbar.top.OdsTopAppBarActionButton -import com.orange.ods.compose.component.appbar.top.OdsTopAppBarOverflowMenuBox +import com.orange.ods.compose.component.appbar.top.OdsTopAppBarInternal +import com.orange.ods.compose.component.appbar.top.OdsTopAppBarNavigationIcon +import com.orange.ods.compose.component.appbar.top.OdsTopAppBarOverflowMenuActionItem +import com.orange.ods.compose.component.content.OdsComponentContent import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsRadioButtonTrailing -import com.orange.ods.compose.component.menu.OdsDropdownMenuItem import com.orange.ods.compose.component.textfield.search.OdsSearchTextField import com.orange.ods.compose.text.OdsTextH6 import com.orange.ods.compose.theme.OdsTheme @@ -63,37 +62,34 @@ fun MainTopAppBar( val showSearchAction = topAppBarState.titleRes.value == R.string.navigation_item_search val title = stringResource(id = topAppBarState.titleRes.value) - val navigationIcon: (@Composable () -> Unit)? = if (shouldShowUpNavigationIcon && topAppBarState.isNavigationIconEnabled) { - { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = stringResource(id = R.string.top_app_bar_back_icon_desc) - ) - } - } else null + val navigationIcon = if (shouldShowUpNavigationIcon && topAppBarState.isNavigationIconEnabled) { + OdsTopAppBarNavigationIcon(Icons.Filled.ArrowBack, stringResource(id = R.string.top_app_bar_back_icon_desc), upPress) + } else { + null + } - val actions: @Composable RowScope.() -> Unit = { - if (showSearchAction) { - TopAppBarSearchAction(searchedText = topAppBarState.searchedText) - } else { - TopAppBarActions(topAppBarState, onSearchActionClick) { changeThemeDialogVisible = true } - } + val actions = if (showSearchAction) { + listOf(getTopAppBarSearchTextFieldAction(searchedText = topAppBarState.searchedText)) + } else { + getTopAppBarActions(topAppBarState, onSearchActionClick) { changeThemeDialogVisible = true } } + val overflowMenuActions = getTopAppBarOverflowMenuActions(topAppBarState) + if (topAppBarState.isLarge) { - OdsLargeTopAppBar( + OdsLargeTopAppBarInternal( title = title, navigationIcon = navigationIcon, - onNavigationIconClick = upPress, actions = actions, + overflowMenuActions = overflowMenuActions, scrollBehavior = if (topAppBarState.hasScrollBehavior) scrollBehavior else null ) } else { - OdsTopAppBar( + OdsTopAppBarInternal( title = title, navigationIcon = navigationIcon, - onNavigationIconClick = upPress, actions = actions, + overflowMenuActions = overflowMenuActions, elevated = false // elevation is managed in [MainScreen] cause of tabs ) } @@ -111,41 +107,50 @@ fun MainTopAppBar( } } - @Composable -private fun TopAppBarSearchAction(searchedText: MutableState) { - val focusRequester = remember { FocusRequester() } - OdsSearchTextField( - value = searchedText.value, - onValueChange = { value -> - searchedText.value = value - }, - placeholder = stringResource(id = R.string.search_text_field_hint), - modifier = Modifier - .fillMaxWidth() - .focusRequester(focusRequester) - ) - LaunchedEffect(Unit) { - focusRequester.requestFocus() +private fun getTopAppBarSearchTextFieldAction(searchedText: MutableState): OdsComponentContent { + return object : OdsComponentContent() { + + @Composable + override fun Content(modifier: Modifier) { + val focusRequester = remember { FocusRequester() } + OdsSearchTextField( + value = searchedText.value, + onValueChange = { value -> + searchedText.value = value + }, + placeholder = stringResource(id = R.string.search_text_field_hint), + modifier = Modifier + .fillMaxWidth() + .focusRequester(focusRequester) + ) + LaunchedEffect(Unit) { + focusRequester.requestFocus() + } + } } } @Composable -private fun TopAppBarActions(state: MainTopAppBarState, onSearchActionClick: () -> Unit, onChangeThemeActionClick: () -> Unit) { - state.actions.value.forEach { action -> +private fun getTopAppBarActions( + state: MainTopAppBarState, + onSearchActionClick: () -> Unit, + onChangeThemeActionClick: () -> Unit +): List { + return state.actions.value.mapNotNull { action -> when (action) { - TopAppBarConfiguration.Action.Search -> TopAppBarSearchActionButton(onClick = onSearchActionClick) - TopAppBarConfiguration.Action.Theme -> TopAppBarChangeThemeActionButton(onClick = onChangeThemeActionClick) - TopAppBarConfiguration.Action.Mode -> TopAppBarChangeModeActionButton() - TopAppBarConfiguration.Action.OverflowMenu -> TopAppBarOverflowMenuBox() - is TopAppBarConfiguration.Action.Custom -> TopAppBarCustomActionButton(action = action) + TopAppBarConfiguration.Action.Search -> getTopAppBarSearchAction(onClick = onSearchActionClick) + TopAppBarConfiguration.Action.Theme -> getTopAppBarChangeThemeAction(onClick = onChangeThemeActionClick) + TopAppBarConfiguration.Action.Mode -> getTopAppBarChangeModeAction() + TopAppBarConfiguration.Action.OverflowMenu -> null + is TopAppBarConfiguration.Action.Custom -> getTopAppBarCustomAction(action = action) } } } @Composable -private fun TopAppBarChangeThemeActionButton(onClick: () -> Unit) { - OdsTopAppBarActionButton( +private fun getTopAppBarChangeThemeAction(onClick: () -> Unit): OdsTopAppBarActionButton { + return OdsTopAppBarActionButton( onClick = onClick, painter = painterResource(id = R.drawable.ic_palette), contentDescription = stringResource(id = R.string.top_app_bar_action_change_mode_to_dark_desc) @@ -153,7 +158,7 @@ private fun TopAppBarChangeThemeActionButton(onClick: () -> Unit) { } @Composable -private fun TopAppBarChangeModeActionButton() { +private fun getTopAppBarChangeModeAction(): OdsTopAppBarActionButton { val configuration = LocalConfiguration.current val themeManager = LocalThemeManager.current @@ -161,7 +166,7 @@ private fun TopAppBarChangeModeActionButton() { val iconDesc = if (configuration.isDarkModeEnabled) R.string.top_app_bar_action_change_mode_to_light_desc else R.string.top_app_bar_action_change_mode_to_dark_desc - OdsTopAppBarActionButton( + return OdsTopAppBarActionButton( onClick = { themeManager.darkModeEnabled = !configuration.isDarkModeEnabled }, painter = painterResource(id = painterRes), contentDescription = stringResource(id = iconDesc) @@ -169,8 +174,8 @@ private fun TopAppBarChangeModeActionButton() { } @Composable -private fun TopAppBarSearchActionButton(onClick: () -> Unit) { - OdsTopAppBarActionButton( +private fun getTopAppBarSearchAction(onClick: () -> Unit): OdsTopAppBarActionButton { + return OdsTopAppBarActionButton( onClick = onClick, painter = painterResource(id = R.drawable.ic_search), contentDescription = stringResource(id = R.string.search_content_description) @@ -178,24 +183,24 @@ private fun TopAppBarSearchActionButton(onClick: () -> Unit) { } @Composable -private fun TopAppBarOverflowMenuBox() { - val context = LocalContext.current - OdsTopAppBarOverflowMenuBox( - overflowIconContentDescription = stringResource(id = R.string.component_app_bars_top_element_overflow_menu) - ) { - LocalRecipes.current.forEach { recipe -> - OdsDropdownMenuItem( +private fun getTopAppBarOverflowMenuActions(state: MainTopAppBarState): List { + return if (state.actions.value.contains(TopAppBarConfiguration.Action.OverflowMenu)) { + val context = LocalContext.current + LocalRecipes.current.map { recipe -> + OdsTopAppBarOverflowMenuActionItem( text = recipe.title, onClick = { clickOnElement(context, recipe.title) } ) } + } else { + emptyList() } } @Composable -private fun TopAppBarCustomActionButton(action: TopAppBarConfiguration.Action.Custom) { +private fun getTopAppBarCustomAction(action: TopAppBarConfiguration.Action.Custom): OdsTopAppBarActionButton { val context = LocalContext.current - OdsTopAppBarActionButton( + return OdsTopAppBarActionButton( onClick = { clickOnElement(context, action.name) }, painter = painterResource(id = action.iconResId), contentDescription = action.name @@ -211,8 +216,8 @@ private fun ChangeThemeDialog(themeManager: ThemeManager, dismissDialog: () -> U OdsTextH6( text = stringResource(R.string.top_app_bar_action_change_theme_desc), modifier = Modifier - .padding(top = dimensionResource(R.dimen.spacing_m), bottom = dimensionResource(id = R.dimen.spacing_s)) - .padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin)) + .padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_m), bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) + .padding(horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin)) ) themeManager.themeConfigurations.forEach { themeConfiguration -> OdsListItem( diff --git a/app/src/main/java/com/orange/ods/app/ui/about/AboutFileScreen.kt b/app/src/main/java/com/orange/ods/app/ui/about/AboutFileScreen.kt index 421f7736b..34eba1e21 100644 --- a/app/src/main/java/com/orange/ods/app/ui/about/AboutFileScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/about/AboutFileScreen.kt @@ -21,13 +21,12 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.viewinterop.AndroidView -import com.orange.ods.compose.theme.OdsTheme -import com.orange.ods.app.R import com.orange.ods.app.ui.LocalMainTopAppBarManager import com.orange.ods.app.ui.utilities.Markdown import com.orange.ods.app.ui.utilities.extension.injectLightDarkModeCss import com.orange.ods.app.ui.utilities.extension.isDarkModeEnabled import com.orange.ods.app.ui.utilities.launchUrl +import com.orange.ods.compose.theme.OdsTheme import java.io.BufferedReader import java.nio.charset.StandardCharsets @@ -42,8 +41,8 @@ fun AboutFileScreen(aboutItemId: Long) { val context = LocalContext.current val configuration = LocalConfiguration.current val colors = OdsTheme.colors - val horizontalPadding = dimensionResource(id = R.dimen.screen_horizontal_margin).value - val verticalPadding = dimensionResource(id = R.dimen.screen_vertical_margin).value + val horizontalPadding = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin).value + val verticalPadding = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin).value AndroidView( factory = { WebView(context).apply { diff --git a/app/src/main/java/com/orange/ods/app/ui/about/AboutScreen.kt b/app/src/main/java/com/orange/ods/app/ui/about/AboutScreen.kt index d732da98e..be1170a19 100644 --- a/app/src/main/java/com/orange/ods/app/ui/about/AboutScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/about/AboutScreen.kt @@ -35,8 +35,8 @@ import com.orange.ods.app.ui.utilities.extension.versionCode import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.text.OdsTextCaption import com.orange.ods.compose.text.OdsTextH4 -import com.orange.ods.utilities.extension.ifNotNull -import com.orange.ods.utilities.extension.orElse +import com.orange.ods.extension.ifNotNull +import com.orange.ods.extension.orElse @Composable fun AboutScreen(onAboutItemClick: (Long) -> Unit) { @@ -45,7 +45,7 @@ fun AboutScreen(onAboutItemClick: (Long) -> Unit) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(bottom = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { val context = LocalContext.current Image( @@ -55,22 +55,22 @@ fun AboutScreen(onAboutItemClick: (Long) -> Unit) { contentScale = ContentScale.Crop, contentDescription = null ) - Column(Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin))) { + Column(Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin))) { OdsTextH4( text = stringResource(id = R.string.about_app_name), - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_xl)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xl)) ) OdsTextCaption( text = getVersion(context), - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_xs)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)) ) OdsTextCaption( text = stringResource(id = R.string.about_description), - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_xs)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)) ) } - Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.spacing_m))) + Spacer(modifier = Modifier.height(dimensionResource(id = com.orange.ods.R.dimen.spacing_m))) for (aboutItem in aboutItems) { OdsListItem(text = stringResource(id = aboutItem.titleRes), modifier = Modifier.clickable { diff --git a/app/src/main/java/com/orange/ods/app/ui/components/Component.kt b/app/src/main/java/com/orange/ods/app/ui/components/Component.kt index e4d27a974..807eb32ed 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/Component.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/Component.kt @@ -23,10 +23,11 @@ import com.orange.ods.app.ui.components.buttons.icons.ComponentButtonsIcons import com.orange.ods.app.ui.components.cards.ComponentCard import com.orange.ods.app.ui.components.checkboxes.ComponentCheckboxes import com.orange.ods.app.ui.components.chips.Chip +import com.orange.ods.app.ui.components.chips.ChipFilter import com.orange.ods.app.ui.components.dialogs.ComponentDialog import com.orange.ods.app.ui.components.floatingactionbuttons.ComponentFloatingActionButton -import com.orange.ods.app.ui.components.imageitem.ComponentImageItem -import com.orange.ods.app.ui.components.lists.ComponentLists +import com.orange.ods.app.ui.components.imagetile.ComponentImageTile +import com.orange.ods.app.ui.components.listitem.ComponentListItem import com.orange.ods.app.ui.components.menus.ComponentMenu import com.orange.ods.app.ui.components.navigationdrawers.ComponentModalDrawers import com.orange.ods.app.ui.components.progress.ComponentProgress @@ -97,7 +98,8 @@ sealed class Component( Variant.ButtonsDefault, Variant.ButtonsOutlined, Variant.ButtonsText, - Variant.ButtonsFunctional + Variant.ButtonsFunctional, + Variant.ButtonsTextToggleGroup ), demoScreen = { variant, _ -> if (variant != null) ComponentButtons(variant = variant) } ) @@ -139,7 +141,12 @@ sealed class Component( R.drawable.il_chips_small, R.string.component_chips_description, listOf(Variant.ChipAction, Variant.ChipChoice, Variant.ChipInput, Variant.ChipFilter), - demoScreen = { variant, _ -> if (variant != null) Chip(variant = variant) } + demoScreen = { variant, _ -> + when { + variant == Variant.ChipFilter -> ChipFilter() + variant != null -> Chip(variant = variant) + } + } ) object Dialogs : Component( @@ -160,23 +167,22 @@ sealed class Component( demoScreen = { _, _ -> ComponentFloatingActionButton() } ) - object ImageItem : Component( - R.string.component_image_item, - R.drawable.il_image_item, + object ImageTile : Component( + R.string.component_image_tile, + R.drawable.il_image_tile, null, - R.string.component_image_item_description, - composableName = OdsComposable.OdsImageItem.name, - demoScreen = { _, _ -> ComponentImageItem() } + R.string.component_image_tile_description, + composableName = OdsComposable.OdsImageTile.name, + demoScreen = { _, _ -> ComponentImageTile() } ) - object Lists : Component( - R.string.component_lists, - R.drawable.il_lists, + object ListItem : Component( + R.string.component_list_item, + R.drawable.il_list_item, null, - R.string.component_lists_description, + R.string.component_list_item_description, composableName = OdsComposable.OdsListItem.name, - demoScreen = { _, _ -> ComponentLists() }, - imageAlignment = Alignment.BottomCenter + demoScreen = { _, _ -> ComponentListItem() } ) object Menus : Component( @@ -288,6 +294,7 @@ sealed class Variant( object ButtonsDefault : Variant(R.string.component_buttons_high_emphasis, "${OdsComposable.OdsButton.name} with ${OdsButtonStyle.Default.name}") object ButtonsOutlined : Variant(R.string.component_buttons_medium_emphasis, OdsComposable.OdsOutlinedButton.name) object ButtonsText : Variant(R.string.component_buttons_low_emphasis, OdsComposable.OdsTextButton.name) + object ButtonsTextToggleGroup : Variant(R.string.component_button_text_toggle_group, OdsComposable.OdsTextToggleButtonsRow.name) object ButtonsFunctional : Variant(R.string.component_buttons_functional, "${OdsComposable.OdsButton.name} with a functional style") object ButtonsIcon : Variant(R.string.component_buttons_icon, OdsComposable.OdsIconButton.name) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/ComponentDetailScreen.kt b/app/src/main/java/com/orange/ods/app/ui/components/ComponentDetailScreen.kt index e3d597023..7b6abd6a0 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/ComponentDetailScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/ComponentDetailScreen.kt @@ -40,7 +40,7 @@ fun ComponentDetailScreen( Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(bottom = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { DetailScreenHeader( imageRes = DrawableManager.getDrawableResIdForCurrentTheme(resId = component.imageRes), @@ -48,7 +48,7 @@ fun ComponentDetailScreen( descriptionRes = component.descriptionRes ) Column( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_m)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) ) { if (component.variants.isEmpty()) { ComponentDetailLinkItem( diff --git a/app/src/main/java/com/orange/ods/app/ui/components/ComponentsNavGraph.kt b/app/src/main/java/com/orange/ods/app/ui/components/ComponentsNavGraph.kt index 0202bfaa4..7197ee5d4 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/ComponentsNavGraph.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/ComponentsNavGraph.kt @@ -54,7 +54,7 @@ fun NavGraphBuilder.addComponentsGraph(navigateToElement: (String, Long?, NavBac if (variant != null && component != null) { LocalMainTopAppBarManager.current.updateTopAppBarTitle(variant.titleRes) LocalMainTopAppBarManager.current.setLargeTopAppBar(variant.largeTopAppBar) - component.demoScreen(variant = variant, upPress = upPress) + component.demoScreen(variant, upPress) } } @@ -70,7 +70,7 @@ fun NavGraphBuilder.addComponentsGraph(navigateToElement: (String, Long?, NavBac component?.let { LocalMainTopAppBarManager.current.updateTopAppBarTitle(component.titleRes) - component.demoScreen(variant = null, upPress = upPress) + component.demoScreen(null, upPress) } } diff --git a/app/src/main/java/com/orange/ods/app/ui/components/ComponentsScreen.kt b/app/src/main/java/com/orange/ods/app/ui/components/ComponentsScreen.kt index 873ffc9d1..019b92276 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/ComponentsScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/ComponentsScreen.kt @@ -27,11 +27,11 @@ 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 com.orange.ods.compose.component.card.OdsSmallCard import com.orange.ods.app.R import com.orange.ods.app.ui.LocalMainTopAppBarManager import com.orange.ods.app.ui.utilities.DrawableManager -import com.orange.ods.utilities.extension.orElse +import com.orange.ods.compose.component.card.OdsSmallCard +import com.orange.ods.extension.orElse @Composable fun ComponentsScreen(onComponentClick: (Long) -> Unit) { @@ -42,12 +42,12 @@ fun ComponentsScreen(onComponentClick: (Long) -> Unit) { modifier = Modifier .fillMaxSize() .verticalScroll(scrollState) - .padding(dimensionResource(id = R.dimen.spacing_m)), - verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)) + .padding(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + verticalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) ) { components.sortedBy { context.getString(it.titleRes) }.chunked(2).forEach { rowCards -> Row( - horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)), + horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), ) { ComponentCard(component = rowCards[0], onComponentClick) if (rowCards.size == 2) { 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 636f1a3e9..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 @@ -41,6 +41,8 @@ import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSh import com.orange.ods.app.ui.utilities.NavigationItem import com.orange.ods.app.ui.utilities.composable.* import com.orange.ods.compose.OdsComposable +import com.orange.ods.compose.component.appbar.top.OdsTopAppBarActionButton +import com.orange.ods.compose.component.appbar.top.OdsTopAppBarNavigationIcon import com.orange.ods.compose.component.chip.OdsChoiceChip import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow import com.orange.ods.compose.component.list.OdsListItem @@ -84,7 +86,7 @@ fun ComponentTopAppBar(variant: Variant) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)), + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)), horizontalAlignment = Alignment.CenterHorizontally ) { if (isLargeCollapsible) { @@ -92,11 +94,11 @@ fun ComponentTopAppBar(variant: Variant) { BlinkingChevronDown( modifier = Modifier .rotate(180f) - .padding(vertical = dimensionResource(id = R.dimen.spacing_s)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) ) } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), contentBackground = false ) { CodeBackgroundColumn { @@ -107,41 +109,29 @@ fun ComponentTopAppBar(variant: Variant) { title(context.getString(R.string.component_app_bars_top_regular)) if (isNavigationIconEnabled) { - composable(name = "navigationIcon") { - FunctionCallCode( - name = "Icon", - parameters = { - simple("imageVector", "") - contentDescription(context.getString(R.string.top_app_bar_back_icon_desc)) - } - ) + classInstance("navigationIcon", OdsTopAppBarNavigationIcon::class.java) { + simple("imageVector", "") + contentDescription(context.getString(R.string.top_app_bar_back_icon_desc)) } } - composable(name = "actions") { + list("actions") { repeat(actionCount.value) { - FunctionCallCode( - name = OdsComposable.OdsTopAppBarActionButton.name, - parameters = { - onClick() - painter() - contentDescription("icon description") - } - ) + classInstance(OdsTopAppBarActionButton::class.java) { + onClick() + painter() + contentDescription("icon description") + } } - if (isOverflowMenuEnabled) { - FunctionCallCode( - name = OdsComposable.OdsTopAppBarOverflowMenuBox.name, - parameters = { string("overflowIconContentDescription", "Open overflow menu") } - ) { - for (i in 1..2) { - FunctionCallCode( - name = OdsComposable.OdsDropdownMenuItem.name, - parameters = { - text("Menu $i") - onClick() - } - ) + } + + if (isOverflowMenuEnabled) { + list("overflowMenuActions") { + for (i in 1..2) { + // The classInstance method displays the original type of type aliases, that's why function is used instead + function("OdsTopAppBarOverflowMenuActionItem") { + text("Menu $i") + onClick() } } } @@ -155,18 +145,24 @@ fun ComponentTopAppBar(variant: Variant) { } if (isLargeCollapsible) { OdsTextBody2( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s), bottom = dimensionResource(id = R.dimen.spacing_xs)), + modifier = Modifier.padding( + top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s), + bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs) + ), text = stringResource(id = R.string.component_app_bars_top_large_code_collapsing) ) OdsTextCaption( - modifier = Modifier.padding(bottom = dimensionResource(id = R.dimen.spacing_xs)), + modifier = Modifier.padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)), text = stringResource(id = R.string.component_app_bars_top_large_code_collapsing_step_1) ) CodeBackgroundColumn { TechnicalText(text = "val topBarScrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState())") } OdsTextCaption( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s), bottom = dimensionResource(id = R.dimen.spacing_xs)), + modifier = Modifier.padding( + top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s), + bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs) + ), text = stringResource(id = R.string.component_app_bars_top_large_code_collapsing_step_2) ) CodeBackgroundColumn { @@ -177,7 +173,7 @@ fun ComponentTopAppBar(variant: Variant) { } if (isLargeCollapsible) { - BlinkingChevronDown(modifier = Modifier.padding(vertical = dimensionResource(id = R.dimen.spacing_s))) + BlinkingChevronDown(modifier = Modifier.padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s))) OdsTextBody2(text = stringResource(id = R.string.component_app_bars_top_large_scrolling_downward)) } } @@ -191,16 +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, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), - outlinedChips = true - ) { - 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 + value = scrollBehavior.value, + onValueChange = { value -> scrollBehavior.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_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), @@ -209,7 +209,7 @@ private fun CustomizationBottomSheetContent(customizationState: TopAppBarCustomi ) ) ComponentCountRow( - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), title = stringResource(id = R.string.component_app_bars_top_actions_count), count = actionCount, minusIconContentDescription = stringResource(id = R.string.component_app_bars_top_remove_action), @@ -227,19 +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 = R.dimen.spacing_m)) - .padding(bottom = dimensionResource(id = 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) - 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/banners/BannerCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/banners/BannerCustomizationState.kt index 8133a1310..f6c017cb5 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/banners/BannerCustomizationState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/banners/BannerCustomizationState.kt @@ -42,7 +42,7 @@ class BannerCustomizationState( val hasImage get() = imageChecked.value - val hasButton2 + val hasSecondButton get() = buttonsCount.value > 1 val hasTwoTextLines diff --git a/app/src/main/java/com/orange/ods/app/ui/components/banners/ComponentBanners.kt b/app/src/main/java/com/orange/ods/app/ui/components/banners/ComponentBanners.kt index e8e3a3c84..0f33b1c4c 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/banners/ComponentBanners.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/banners/ComponentBanners.kt @@ -12,7 +12,6 @@ package com.orange.ods.app.ui.components.banners import androidx.appcompat.content.res.AppCompatResources import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -31,7 +30,6 @@ import coil.request.ImageRequest import com.orange.ods.app.R import com.orange.ods.app.databinding.OdsBannerBinding import com.orange.ods.app.domain.recipes.LocalRecipes -import com.orange.ods.app.ui.LocalUiFramework import com.orange.ods.app.ui.UiFramework import com.orange.ods.app.ui.components.utilities.ComponentCountRow import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold @@ -39,11 +37,13 @@ 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.TechnicalText import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.banner.OdsBanner +import com.orange.ods.compose.component.banner.OdsBannerButton +import com.orange.ods.compose.component.banner.OdsBannerImage import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsSwitchTrailing +import com.orange.ods.extension.ifNotNull @OptIn(ExperimentalMaterialApi::class) @Composable @@ -61,7 +61,7 @@ fun ComponentBanners() { count = textLinesCount, minusIconContentDescription = stringResource(id = R.string.component_remove_action_button), plusIconContentDescription = stringResource(id = R.string.component_add_action_button), - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), minCount = BannerCustomizationState.MinTextCount, maxCount = BannerCustomizationState.MaxTextCount ) @@ -70,7 +70,7 @@ fun ComponentBanners() { count = buttonsCount, minusIconContentDescription = stringResource(id = R.string.component_banner_remove_action_button), plusIconContentDescription = stringResource(id = R.string.component_banner_add_action_button), - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), minCount = BannerCustomizationState.MinActionButtonCount, maxCount = BannerCustomizationState.MaxActionButtonCount ) @@ -86,35 +86,40 @@ fun ComponentBanners() { .verticalScroll(rememberScrollState()) ) { val message = if (hasTwoTextLines) recipe.description else recipe.title - val button1Text = stringResource(id = R.string.component_banner_dismiss) - val onButton1ClickText = stringResource(id = R.string.component_element_button1) - val onButton1Click = { clickOnElement(context, onButton1ClickText) } - val button2Text = if (hasButton2) stringResource(id = R.string.component_banner_detail) else null - val onButton2ClickText = stringResource(id = R.string.component_element_button2) - val onButton2Click = { clickOnElement(context, onButton2ClickText) } + val firstButtonText = stringResource(id = R.string.component_banner_dismiss) + val onFirstButtonClickText = stringResource(id = R.string.component_element_first_button) + val onFirstButtonClick = { clickOnElement(context, onFirstButtonClickText) } + val secondButtonText = if (hasSecondButton) stringResource(id = R.string.component_banner_detail) else null + val onSecondButtonClickText = stringResource(id = R.string.component_element_second_button) + val onSecondButtonClick = if (hasSecondButton) { + { clickOnElement(context, onSecondButtonClickText) } + } else null val placeholderResId = DrawableManager.getPlaceholderResId() val errorPlaceholderResId = DrawableManager.getPlaceholderResId(error = true) UiFramework( compose = { OdsBanner( message = message, - button1Text = button1Text, - button2Text = button2Text, - image = if (hasImage) rememberAsyncImagePainter( - model = recipe.imageUrl, - placeholder = painterResource(id = placeholderResId), - error = painterResource(id = errorPlaceholderResId) - ) else null, - onButton1Click = onButton1Click, - onButton2Click = onButton2Click, + firstButton = OdsBannerButton(firstButtonText, onFirstButtonClick), + image = if (hasImage) { + val painter = rememberAsyncImagePainter( + model = recipe.imageUrl, + placeholder = painterResource(id = placeholderResId), + error = painterResource(id = errorPlaceholderResId) + ) + OdsBannerImage(painter, "") + } else { + null + }, + secondButton = ifNotNull(secondButtonText, onSecondButtonClick) { text, onClick -> OdsBannerButton(text, onClick) } ) }, xml = { this.message = message - this.button1Text = button1Text - this.button2Text = button2Text - odsBanner.onButton1Click = onButton1Click - odsBanner.onButton2Click = onButton1Click + this.firstButtonText = firstButtonText + this.secondButtonText = secondButtonText + odsBanner.onFirstButtonClick = onFirstButtonClick + odsBanner.onSecondButtonClick = onFirstButtonClick if (hasImage) { odsBanner.image = AppCompatResources.getDrawable(context, placeholderResId) val request = ImageRequest.Builder(context) @@ -130,7 +135,7 @@ fun ComponentBanners() { ) CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), xmlAvailable = true ) { FunctionCallCode( @@ -138,13 +143,25 @@ fun ComponentBanners() { exhaustiveParameters = false, parameters = { string("message", if (hasTwoTextLines) recipe.description else recipe.title) - button1Text(context.getString(R.string.component_banner_dismiss)) - if (hasImage) image() - if (hasButton2) button2Text(context.getString(R.string.component_banner_detail)) + classInstance("firstButton", OdsBannerButton::class.java) { + text(context.getString(R.string.component_banner_dismiss)) + onClick() + } + if (hasImage) { + classInstance("image", OdsBannerImage::class.java) { + painter() + contentDescription("") + } + } + if (hasSecondButton) { + classInstance("secondButton", OdsBannerButton::class.java) { + text(context.getString(R.string.component_banner_detail)) + onClick() + } + } } ) } - } } } diff --git a/app/src/main/java/com/orange/ods/app/ui/components/bottomnavigation/ComponentBottomNavigation.kt b/app/src/main/java/com/orange/ods/app/ui/components/bottomnavigation/ComponentBottomNavigation.kt index 963bb55bf..361039399 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/bottomnavigation/ComponentBottomNavigation.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/bottomnavigation/ComponentBottomNavigation.kt @@ -10,14 +10,12 @@ package com.orange.ods.app.ui.components.bottomnavigation -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.Icon import androidx.compose.material.rememberBottomSheetScaffoldState import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf @@ -40,6 +38,7 @@ import com.orange.ods.app.ui.utilities.composable.FunctionCallCode import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigation import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigationItem +import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigationItemIcon private object ComponentBottomNavigation { const val MinNavigationItemCount = 3 @@ -58,7 +57,7 @@ fun ComponentBottomNavigation() { bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { ComponentCountRow( - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), title = stringResource(id = R.string.component_bottom_navigation_navigation_item_count), count = selectedNavigationItemCount, minusIconContentDescription = stringResource(id = R.string.component_bottom_navigation_remove_item), @@ -70,19 +69,17 @@ fun ComponentBottomNavigation() { Column( modifier = Modifier .fillMaxSize() - .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin)) .verticalScroll(rememberScrollState()) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { - OdsBottomNavigation { - navigationItems.take(selectedNavigationItemCount.value).forEach { navigationItem -> + OdsBottomNavigation( + items = navigationItems.take(selectedNavigationItemCount.value).map { navigationItem -> val label = stringResource(id = navigationItem.textResId) OdsBottomNavigationItem( - icon = { - Icon( - painter = painterResource(id = navigationItem.iconResId), - contentDescription = null - ) - }, + icon = OdsBottomNavigationItemIcon( + painter = painterResource(id = navigationItem.iconResId), + contentDescription = "" + ), label = label, selected = selectedNavigationItem.value.textResId == navigationItem.textResId, onClick = { @@ -91,24 +88,28 @@ fun ComponentBottomNavigation() { } ) } - } + ) CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) { - FunctionCallCode(name = OdsComposable.OdsBottomNavigation.name) { - navigationItems.take(2).forEach { item -> - FunctionCallCode( - name = OdsComposable.OdsBottomNavigationItem.name, - parameters = { - icon() - string("label", context.getString(item.textResId)) - selected(selectedNavigationItem.value.textResId == item.textResId) - onClick() + FunctionCallCode( + name = OdsComposable.OdsBottomNavigation.name, + parameters = { + list("items") { + navigationItems.take(selectedNavigationItemCount.value).forEach { item -> + classInstance(OdsBottomNavigationItem::class.java) { + classInstance("icon", OdsBottomNavigationItemIcon::class.java) { + painter() + contentDescription("") + } + string("label", context.getString(item.textResId)) + selected(selectedNavigationItem.value.textResId == item.textResId) + onClick() + } } - ) - } - } + } + }) } } } diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonCustomizationState.kt index 2c8efc05d..aca0e559e 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonCustomizationState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonCustomizationState.kt @@ -21,23 +21,31 @@ import com.orange.ods.compose.component.button.OdsTextButtonStyle @Composable fun rememberButtonCustomizationState( + toggleCount: MutableState = rememberSaveable { mutableStateOf(ButtonCustomizationState.MinToggleCount) }, buttonStyle: MutableState = rememberSaveable { mutableStateOf(OdsButtonStyle.Default) }, textButtonStyle: MutableState = rememberSaveable { mutableStateOf(OdsTextButtonStyle.Default) }, leadingIcon: MutableState = rememberSaveable { mutableStateOf(false) }, fullScreenWidth: MutableState = rememberSaveable { mutableStateOf(false) }, + sameItemsWeight: MutableState = rememberSaveable { mutableStateOf(false) }, enabled: MutableState = rememberSaveable { mutableStateOf(true) } ) = - remember(buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, enabled) { - ButtonCustomizationState(buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, enabled) + remember(buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, sameItemsWeight, enabled, toggleCount) { + ButtonCustomizationState(toggleCount, buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, sameItemsWeight, enabled) } class ButtonCustomizationState( + val toggleCount: MutableState, val buttonStyle: MutableState, val textButtonStyle: MutableState, val leadingIcon: MutableState, val fullScreenWidth: MutableState, + val sameItemsWeight: MutableState, val enabled: MutableState ) { + companion object { + const val MinToggleCount = 2 + const val MaxToggleCount = 3 + } val hasLeadingIcon get() = leadingIcon.value @@ -47,4 +55,7 @@ class ButtonCustomizationState( val hasFullScreenWidth get() = fullScreenWidth.value + + val hasSameItemsWeight + get() = sameItemsWeight.value } \ No newline at end of file diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsContained.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsContained.kt index e0c2276e5..31dff263c 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsContained.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsContained.kt @@ -34,9 +34,10 @@ import com.orange.ods.app.ui.utilities.composable.FunctionCallCode import com.orange.ods.app.ui.utilities.composable.Title import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.button.OdsButton +import com.orange.ods.compose.component.button.OdsButtonIcon import com.orange.ods.compose.component.button.OdsButtonStyle import com.orange.ods.compose.theme.OdsDisplaySurface -import com.orange.ods.utilities.extension.fullName +import com.orange.ods.extension.fullName @Composable fun ButtonsContained(customizationState: ButtonCustomizationState) { @@ -45,7 +46,7 @@ fun ButtonsContained(customizationState: ButtonCustomizationState) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { with(buttonStyle.value) { @@ -63,7 +64,7 @@ fun ButtonsContained(customizationState: ButtonCustomizationState) { fullScreenWidth = hasFullScreenWidth ) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) InvertedBackgroundColumn { ContainedButton( @@ -76,7 +77,7 @@ fun ButtonsContained(customizationState: ButtonCustomizationState) { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), xmlAvailable = true ) { FunctionCallCode( @@ -85,7 +86,11 @@ fun ButtonsContained(customizationState: ButtonCustomizationState) { parameters = { simple("style", buttonStyle.value.fullName) if (hasFullScreenWidth) fillMaxWidth() - if (hasLeadingIcon) icon() + if (hasLeadingIcon) { + classInstance("icon", OdsButtonIcon::class.java) { + painter() + } + } if (!isEnabled) enabled(false) } ) @@ -106,12 +111,17 @@ private fun ContainedButton( val text = stringResource(if (enabled) R.string.component_state_enabled else R.string.component_state_disabled) val iconId = R.drawable.ic_coffee - Box(modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin), vertical = dimensionResource(R.dimen.spacing_m))) { + Box( + modifier = Modifier.padding( + horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(com.orange.ods.R.dimen.spacing_m) + ) + ) { UiFramework( compose = { OdsButton( modifier = if (fullScreenWidth) Modifier.fillMaxWidth() else Modifier, - icon = if (leadingIcon) painterResource(id = iconId) else null, + icon = if (leadingIcon) OdsButtonIcon(painterResource(id = iconId)) else null, text = text, onClick = {}, enabled = enabled, diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsOutlined.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsOutlined.kt index 370f13845..8197bda6c 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsOutlined.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsOutlined.kt @@ -32,6 +32,7 @@ import com.orange.ods.app.ui.UiFramework import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode import com.orange.ods.compose.OdsComposable +import com.orange.ods.compose.component.button.OdsButtonIcon import com.orange.ods.compose.component.button.OdsOutlinedButton import com.orange.ods.compose.theme.OdsDisplaySurface @@ -41,19 +42,19 @@ fun ButtonsOutlined(customizationState: ButtonCustomizationState) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { OutlinedButton(leadingIcon = hasLeadingIcon, enabled = isEnabled, fullScreenWidth = hasFullScreenWidth) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) InvertedBackgroundColumn { OutlinedButton(leadingIcon = hasLeadingIcon, enabled = isEnabled, fullScreenWidth = hasFullScreenWidth, displaySurface = displaySurface) } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), xmlAvailable = true ) { FunctionCallCode( @@ -61,7 +62,11 @@ fun ButtonsOutlined(customizationState: ButtonCustomizationState) { exhaustiveParameters = false, parameters = { if (hasFullScreenWidth) fillMaxWidth() - if (hasLeadingIcon) icon() + if (hasLeadingIcon) { + classInstance("icon", OdsButtonIcon::class.java) { + painter() + } + } if (!isEnabled) enabled(false) }) } @@ -80,14 +85,19 @@ private fun OutlinedButton( val text = stringResource(if (enabled) R.string.component_state_enabled else R.string.component_state_disabled) val iconId = R.drawable.ic_coffee - Box(modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin), vertical = dimensionResource(R.dimen.spacing_m))) { + Box( + modifier = Modifier.padding( + horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(com.orange.ods.R.dimen.spacing_m) + ) + ) { UiFramework( compose = { OdsOutlinedButton( modifier = if (fullScreenWidth) Modifier.fillMaxWidth() else Modifier, text = text, onClick = {}, - icon = if (leadingIcon) painterResource(id = iconId) else null, + icon = if (leadingIcon) OdsButtonIcon(painterResource(id = iconId)) else null, enabled = enabled, displaySurface = displaySurface ) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsText.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsText.kt index 005ab4f37..1b9ab8f15 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsText.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsText.kt @@ -33,10 +33,11 @@ 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.Title import com.orange.ods.compose.OdsComposable +import com.orange.ods.compose.component.button.OdsButtonIcon import com.orange.ods.compose.component.button.OdsTextButton import com.orange.ods.compose.component.button.OdsTextButtonStyle import com.orange.ods.compose.theme.OdsDisplaySurface -import com.orange.ods.utilities.extension.fullName +import com.orange.ods.extension.fullName @Composable fun ButtonsText(customizationState: ButtonCustomizationState) { @@ -44,7 +45,7 @@ fun ButtonsText(customizationState: ButtonCustomizationState) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { Title( textRes = if (textButtonStyle.value == OdsTextButtonStyle.Default) R.string.component_button_style_default else R.string.component_button_style_primary, @@ -58,7 +59,7 @@ fun ButtonsText(customizationState: ButtonCustomizationState) { fullScreenWidth = hasFullScreenWidth ) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) InvertedBackgroundColumn { TextButton( @@ -71,7 +72,7 @@ fun ButtonsText(customizationState: ButtonCustomizationState) { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), xmlAvailable = true ) { FunctionCallCode( @@ -80,7 +81,11 @@ fun ButtonsText(customizationState: ButtonCustomizationState) { parameters = { simple("style", textButtonStyle.value.fullName) if (hasFullScreenWidth) fillMaxWidth() - if (hasLeadingIcon) icon() + if (hasLeadingIcon) { + classInstance("icon", OdsButtonIcon::class.java) { + painter() + } + } if (!isEnabled) enabled(false) } ) @@ -101,12 +106,17 @@ private fun TextButton( val text = stringResource(if (enabled) R.string.component_state_enabled else R.string.component_state_disabled) val iconId = R.drawable.ic_coffee - Box(modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin), vertical = dimensionResource(R.dimen.spacing_m))) { + Box( + modifier = Modifier.padding( + horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(com.orange.ods.R.dimen.spacing_m) + ) + ) { UiFramework( compose = { OdsTextButton( modifier = if (fullScreenWidth) Modifier.fillMaxWidth() else Modifier, - icon = if (leadingIcon) painterResource(id = iconId) else null, + icon = if (leadingIcon) OdsButtonIcon(painterResource(id = iconId)) else null, text = text, onClick = {}, enabled = enabled, diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsTextToggleGroup.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsTextToggleGroup.kt new file mode 100644 index 000000000..86d7fe558 --- /dev/null +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsTextToggleGroup.kt @@ -0,0 +1,122 @@ +/* + * + * 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.app.ui.components.buttons + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.dimensionResource +import com.orange.ods.app.domain.recipes.LocalRecipes +import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn +import com.orange.ods.app.ui.utilities.composable.FunctionCallCode +import com.orange.ods.compose.OdsComposable +import com.orange.ods.compose.annotation.ExperimentalOdsApi +import com.orange.ods.compose.component.button.OdsTextToggleButtonsRow +import com.orange.ods.compose.component.button.OdsTextToggleButtonsRowItem +import com.orange.ods.compose.theme.OdsDisplaySurface + +@Composable +fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { + val textToggleButtons = + LocalRecipes.current.first().ingredients.take(ButtonCustomizationState.MaxToggleCount).map { ingredient -> + OdsTextToggleButtonsRowItem(ingredient.food.name, customizationState.isEnabled) + } + + var selectedIndex by rememberSaveable { mutableStateOf(0) } + + with(customizationState) { + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) + ) { + ToggleButtonsRow( + textToggleButtons = textToggleButtons, + selectedIndex = selectedIndex, + onSelectedIndexChange = { index -> selectedIndex = index }, + toggleCount = toggleCount.value, + sameItemsWeight = hasSameItemsWeight, + ) + + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) + + InvertedBackgroundColumn { + ToggleButtonsRow( + textToggleButtons = textToggleButtons, + selectedIndex = selectedIndex, + onSelectedIndexChange = { index -> selectedIndex = index }, + toggleCount = toggleCount.value, + sameItemsWeight = hasSameItemsWeight, + displaySurface = displaySurface + ) + } + + CodeImplementationColumn( + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) + ) { + FunctionCallCode( + name = OdsComposable.OdsTextToggleButtonsRow.name, + exhaustiveParameters = false, + parameters = { + list("textToggleButtons") { + textToggleButtons.take(toggleCount.value).forEach { item -> + classInstance(OdsTextToggleButtonsRowItem::class.java) { + text(item.text) + enabled(customizationState.isEnabled) + } + } + } + stringRepresentation("selectedIndex", selectedIndex) + stringRepresentation("sameItemsWeight", hasSameItemsWeight) + } + ) + } + } + } +} + +@OptIn(ExperimentalOdsApi::class) +@Composable +private fun ToggleButtonsRow( + textToggleButtons: List, + selectedIndex: Int, + onSelectedIndexChange: (Int) -> Unit, + toggleCount: Int, + sameItemsWeight: Boolean, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default +) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_m)) + .padding(horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin)), + horizontalArrangement = Arrangement.Center + ) { + OdsTextToggleButtonsRow( + textToggleButtons = textToggleButtons.take(toggleCount), + selectedIndex = selectedIndex, + onSelectedIndexChange = onSelectedIndexChange, + sameItemsWeight = sameItemsWeight, + displaySurface = displaySurface + ) + } +} \ No newline at end of file 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 22abb3fd9..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 @@ -29,6 +29,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource 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.button.OdsButtonStyle @@ -58,35 +59,61 @@ fun ComponentButtons(variant: Variant) { ComponentCustomizationBottomSheetScaffold( bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { - if (variant == Variant.ButtonsFunctional) { - Subtitle(textRes = R.string.component_button_style_functional, horizontalPadding = true) - OdsChoiceChipsFlowRow( - selectedChip = buttonStyle, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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) + when (variant) { + Variant.ButtonsFunctional -> { + Subtitle(textRes = R.string.component_button_style_functional, horizontalPadding = true) + OdsChoiceChipsFlowRow( + 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) + ) + ) } - } else if (variant == Variant.ButtonsText) { - Subtitle(textRes = R.string.component_style, horizontalPadding = true) - OdsChoiceChipsFlowRow( - selectedChip = textButtonStyle, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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) + Variant.ButtonsText -> { + Subtitle(textRes = R.string.component_style, horizontalPadding = true) + OdsChoiceChipsFlowRow( + 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( + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), + title = stringResource(id = R.string.component_button_icon_toggle_count), + count = toggleCount, + minusIconContentDescription = stringResource(id = R.string.component_button_icon_toggle_remove), + plusIconContentDescription = stringResource(id = R.string.component_button_icon_toggle_add), + minCount = ButtonCustomizationState.MinToggleCount, + maxCount = ButtonCustomizationState.MaxToggleCount + ) + + OdsListItem( + text = stringResource(id = R.string.component_buttons_text_toggle_group_same_weight), + trailing = OdsSwitchTrailing(checked = sameItemsWeight) + ) + } + else -> {} } - OdsListItem( - text = stringResource(id = R.string.component_element_icon), - trailing = OdsSwitchTrailing(checked = leadingIcon) - ) - OdsListItem( - text = stringResource(id = R.string.component_button_full_screen_width), - trailing = OdsSwitchTrailing(checked = fullScreenWidth) - ) + + if (variant != Variant.ButtonsTextToggleGroup) { + OdsListItem( + text = stringResource(id = R.string.component_element_icon), + trailing = OdsSwitchTrailing(checked = leadingIcon) + ) + OdsListItem( + text = stringResource(id = R.string.component_button_full_screen_width), + trailing = OdsSwitchTrailing(checked = fullScreenWidth) + ) + } + OdsListItem( text = stringResource(id = R.string.component_state_enabled), trailing = OdsSwitchTrailing(checked = enabled) @@ -97,6 +124,7 @@ fun ComponentButtons(variant: Variant) { Variant.ButtonsPrimary, Variant.ButtonsDefault, Variant.ButtonsFunctional -> ButtonsContained(customizationState) Variant.ButtonsOutlined -> ButtonsOutlined(customizationState) Variant.ButtonsText -> ButtonsText(customizationState) + Variant.ButtonsTextToggleGroup -> ButtonsTextToggleButtonsRow(customizationState) else -> {} } } @@ -125,13 +153,13 @@ fun InvertedBackgroundColumn( modifier = Modifier .fillMaxWidth() .background(color = backgroundColor) - .padding(bottom = dimensionResource(R.dimen.spacing_m)), + .padding(bottom = dimensionResource(com.orange.ods.R.dimen.spacing_m)), horizontalAlignment = horizontalAlignment ) { OdsTextBody2( modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.spacing_m)) - .padding(top = dimensionResource(id = R.dimen.spacing_s)) + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) .fillMaxWidth() .align(Alignment.Start), text = stringResource(id = textRes), diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIcon.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIcon.kt index b2b120f52..ebbccc681 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIcon.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIcon.kt @@ -36,6 +36,7 @@ import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.button.OdsIconButton +import com.orange.ods.compose.component.button.OdsIconButtonIcon import com.orange.ods.compose.theme.OdsDisplaySurface @Composable @@ -45,7 +46,7 @@ fun ButtonsIcon(customizationState: ButtonIconCustomizationState) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { Row( modifier = Modifier.fillMaxWidth(), @@ -56,7 +57,7 @@ fun ButtonsIcon(customizationState: ButtonIconCustomizationState) { ) } - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) InvertedBackgroundColumn(horizontalAlignment = Alignment.CenterHorizontally) { IconButton( @@ -66,14 +67,17 @@ fun ButtonsIcon(customizationState: ButtonIconCustomizationState) { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), xmlAvailable = true ) { FunctionCallCode( name = OdsComposable.OdsIconButton.name, exhaustiveParameters = false, parameters = { - painter() + classInstance("icon", OdsIconButtonIcon::class.java) { + painter() + contentDescription("") + } if (!isEnabled) enabled(false) } ) @@ -92,13 +96,17 @@ private fun IconButton( val contentDescription = stringResource(id = R.string.component_button_icon_search_desc) val onClick = { clickOnElement(context, context.getString(R.string.component_button_icon)) } - Box(modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin), vertical = dimensionResource(R.dimen.spacing_m))) { + Box( + modifier = Modifier.padding( + horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(com.orange.ods.R.dimen.spacing_m) + ) + ) { UiFramework( compose = { OdsIconButton( onClick = onClick, - painter = painterResource(id = R.drawable.ic_search), - contentDescription = contentDescription, + icon = OdsIconButtonIcon(painterResource(id = R.drawable.ic_search), contentDescription), enabled = enabled, displaySurface = displaySurface ) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggle.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggle.kt index 774e262b0..be3045b9c 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggle.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggle.kt @@ -35,8 +35,8 @@ import com.orange.ods.app.ui.UiFramework import com.orange.ods.app.ui.components.buttons.InvertedBackgroundColumn 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.IconPainterValue import com.orange.ods.compose.OdsComposable +import com.orange.ods.compose.component.button.OdsIconButtonIcon import com.orange.ods.compose.component.button.OdsIconToggleButton import com.orange.ods.compose.theme.OdsDisplaySurface @@ -48,7 +48,7 @@ fun ButtonsIconToggle(customizationState: ButtonIconCustomizationState) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { val onCheckedChange: (Boolean) -> Unit = { checked -> buttonCheckedState.value = checked } @@ -63,7 +63,7 @@ fun ButtonsIconToggle(customizationState: ButtonIconCustomizationState) { ) } - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) InvertedBackgroundColumn(horizontalAlignment = Alignment.CenterHorizontally) { IconToggleButton( @@ -75,15 +75,21 @@ fun ButtonsIconToggle(customizationState: ButtonIconCustomizationState) { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), xmlAvailable = true ) { FunctionCallCode( name = OdsComposable.OdsIconToggleButton.name, exhaustiveParameters = false, parameters = { - painter() - simple("painterChecked", IconPainterValue) + classInstance("uncheckedIcon", OdsIconButtonIcon::class.java) { + painter() + contentDescription("") + } + classInstance("checkedIcon", OdsIconButtonIcon::class.java) { + painter() + contentDescription("") + } checked(buttonCheckedState.value) if (!isEnabled) enabled(false) } @@ -103,25 +109,31 @@ private fun IconToggleButton( val context = LocalContext.current val uncheckedIconResId = R.drawable.ic_heart_outlined val checkedIconResId = R.drawable.ic_heart - val iconContentDescription = stringResource(id = R.string.component_button_icon_toggle_favorite_icon_desc) + val uncheckedIconContentDescription = stringResource(id = R.string.component_button_icon_toggle_favorite_add_icon_desc) + val checkedIconContentDescription = stringResource(id = R.string.component_button_icon_toggle_favorite_remove_icon_desc) - Box(modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin), vertical = dimensionResource(R.dimen.spacing_m))) { + Box( + modifier = Modifier.padding( + horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(com.orange.ods.R.dimen.spacing_m) + ) + ) { UiFramework( compose = { OdsIconToggleButton( checked = checked, - uncheckedPainter = painterResource(id = uncheckedIconResId), - checkedPainter = painterResource(id = checkedIconResId), - iconContentDescription = iconContentDescription, + uncheckedIcon = OdsIconButtonIcon(painterResource(id = uncheckedIconResId), uncheckedIconContentDescription), + checkedIcon = OdsIconButtonIcon(painterResource(id = checkedIconResId), checkedIconContentDescription), onCheckedChange = onCheckedChange, enabled = enabled, displaySurface = displaySurface ) }, xml = { this.checked = checked - checkedIcon = AppCompatResources.getDrawable(context, checkedIconResId) uncheckedIcon = AppCompatResources.getDrawable(context, uncheckedIconResId) - iconDescription = iconContentDescription + checkedIcon = AppCompatResources.getDrawable(context, checkedIconResId) + uncheckedIconDescription = uncheckedIconContentDescription + checkedIconDescription = checkedIconContentDescription this.enabled = enabled this.displaySurface = displaySurface odsIconToggleButton.onCheckedChange = onCheckedChange diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggleGroup.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggleGroup.kt index b2f2ca8be..5238d1629 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggleGroup.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ButtonsIconToggleGroup.kt @@ -26,7 +26,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource -import com.orange.ods.app.R import com.orange.ods.app.databinding.OdsIconToggleButtonsGroupBinding import com.orange.ods.app.domain.recipes.LocalRecipes import com.orange.ods.app.ui.UiFramework @@ -35,14 +34,14 @@ import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.button.OdsIconToggleButtonsRow -import com.orange.ods.compose.component.button.OdsIconToggleButtonsRowItem +import com.orange.ods.compose.component.button.OdsIconToggleButtonsRowIcon import com.orange.ods.compose.theme.OdsDisplaySurface @Composable fun ButtonsIconToggleGroup(customizationState: ButtonIconCustomizationState) { - val iconToggleButtons = + val icons = LocalRecipes.current.distinctBy { it.iconResId }.filter { it.iconResId != null }.take(ButtonIconCustomizationState.MaxToggleCount).map { recipe -> - OdsIconToggleButtonsRowItem(painterResource(id = recipe.iconResId!!), recipe.title, customizationState.enabled.value) + OdsIconToggleButtonsRowIcon(painterResource(id = recipe.iconResId!!), recipe.title, customizationState.enabled.value) } var selectedIndex by rememberSaveable { mutableStateOf(0) } @@ -51,21 +50,21 @@ fun ButtonsIconToggleGroup(customizationState: ButtonIconCustomizationState) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { ToggleButtonsRow( - iconToggleButtons = iconToggleButtons, + icons = icons, selectedIndex = selectedIndex, onSelectedIndexChange = { index -> selectedIndex = index }, toggleCount = toggleCount.value ) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) InvertedBackgroundColumn { ToggleButtonsRow( - iconToggleButtons = iconToggleButtons, + icons = icons, selectedIndex = selectedIndex, onSelectedIndexChange = { index -> selectedIndex = index }, toggleCount = toggleCount.value, @@ -74,23 +73,23 @@ fun ButtonsIconToggleGroup(customizationState: ButtonIconCustomizationState) { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), xmlAvailable = true ) { FunctionCallCode( name = OdsComposable.OdsIconToggleButtonsRow.name, exhaustiveParameters = false, parameters = { - list("iconsToggleButtons") { + list("icons") { repeat(toggleCount.value) { - classInstance(OdsIconToggleButtonsRowItem::class.java) { + classInstance(OdsIconToggleButtonsRowIcon::class.java) { painter() - string("iconDescription", "icon description") + contentDescription("") if (!isEnabled) enabled(false) } } } - stringRepresentation("selectedButtonIndex", selectedIndex) + stringRepresentation("selectedIndex", selectedIndex) } ) } @@ -100,7 +99,7 @@ fun ButtonsIconToggleGroup(customizationState: ButtonIconCustomizationState) { @Composable private fun ToggleButtonsRow( - iconToggleButtons: List, + icons: List, selectedIndex: Int, onSelectedIndexChange: (Int) -> Unit, toggleCount: Int, @@ -109,21 +108,21 @@ private fun ToggleButtonsRow( Row( modifier = Modifier .fillMaxWidth() - .padding(top = dimensionResource(R.dimen.spacing_m)) - .padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin)), + .padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_m)) + .padding(horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin)), horizontalArrangement = Arrangement.Center ) { - val buttons = iconToggleButtons.take(toggleCount) + val displayedIcons = icons.take(toggleCount) UiFramework( compose = { OdsIconToggleButtonsRow( - iconToggleButtons = buttons, + icons = displayedIcons, selectedIndex = selectedIndex, onSelectedIndexChange = onSelectedIndexChange, displaySurface = displaySurface ) }, xml = { - this.odsIconToggleButtonsRow.iconToggleButtons = buttons + this.odsIconToggleButtonsRow.icons = displayedIcons this.selectedIndex = selectedIndex this.displaySurface = displaySurface this.odsIconToggleButtonsRow.onSelectedIndexChange = onSelectedIndexChange diff --git a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ComponentButtonsIcons.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ComponentButtonsIcons.kt index 0b44b9884..baf3e9b3a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ComponentButtonsIcons.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/icons/ComponentButtonsIcons.kt @@ -35,7 +35,7 @@ fun ComponentButtonsIcons(variant: Variant) { bottomSheetContent = { if (variant == Variant.ButtonsIconToggleGroup) { ComponentCountRow( - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), title = stringResource(id = R.string.component_button_icon_toggle_count), count = toggleCount, minusIconContentDescription = stringResource(id = R.string.component_button_icon_toggle_remove), diff --git a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardHorizontal.kt b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardHorizontal.kt index 0c40a9230..4112debd3 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardHorizontal.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardHorizontal.kt @@ -38,16 +38,16 @@ fun CardHorizontal(customizationState: CardCustomizationState) { val context = LocalContext.current val recipes = LocalRecipes.current val recipe = rememberSaveable { recipes.filter { it.description.isNotBlank() }.random() } - + with(customizationState) { Column( modifier = Modifier .fillMaxSize() - .padding(dimensionResource(id = R.dimen.spacing_m)) + .padding(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) .verticalScroll(state = rememberScrollState()), ) { - val button1Text = stringResource(id = R.string.component_element_button1) - val button2Text = stringResource(id = R.string.component_element_button2) + val button1Text = stringResource(id = R.string.component_element_first_button) + val button2Text = stringResource(id = R.string.component_element_second_button) val cardText = stringResource(id = R.string.component_card_element_card) OdsHorizontalCard( @@ -70,7 +70,7 @@ fun CardHorizontal(customizationState: CardCustomizationState) { dividerEnabled = hasDivider ) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) CodeImplementationColumn { FunctionCallCode( diff --git a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardSmall.kt b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardSmall.kt index f688b8d91..44129eb7b 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardSmall.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardSmall.kt @@ -46,13 +46,13 @@ fun CardSmall(customizationState: CardCustomizationState) { Column( modifier = Modifier .fillMaxSize() - .padding(dimensionResource(id = R.dimen.spacing_m)) + .padding(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) .verticalScroll(state = rememberScrollState()), ) { Row( modifier = Modifier .fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)), + horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), ) { val cardText = stringResource(id = R.string.component_card_element_card) @@ -72,7 +72,7 @@ fun CardSmall(customizationState: CardCustomizationState) { Box(modifier = Modifier.weight(0.5f)) } - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) CodeImplementationColumn { FunctionCallCode( diff --git a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalHeaderFirst.kt b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalHeaderFirst.kt index 8bb24d2f6..d2e0ac107 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalHeaderFirst.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalHeaderFirst.kt @@ -45,11 +45,11 @@ fun CardVerticalHeaderFirst(customizationState: CardCustomizationState) { Column( modifier = Modifier .fillMaxSize() - .padding(dimensionResource(id = R.dimen.spacing_m)) + .padding(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) .verticalScroll(state = rememberScrollState()), ) { - val button1Text = stringResource(id = R.string.component_element_button1) - val button2Text = stringResource(id = R.string.component_element_button2) + val button1Text = stringResource(id = R.string.component_element_first_button) + val button2Text = stringResource(id = R.string.component_element_second_button) val cardText = stringResource(id = R.string.component_card_element_card) val imagePainter = rememberAsyncImagePainter( model = ImageRequest.Builder(context) @@ -75,7 +75,7 @@ fun CardVerticalHeaderFirst(customizationState: CardCustomizationState) { onButton2Click = { clickOnElement(context, button2Text) } ) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) CodeImplementationColumn { FunctionCallCode( diff --git a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalImageFirst.kt b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalImageFirst.kt index 2910678f6..32a2f249f 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalImageFirst.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardVerticalImageFirst.kt @@ -43,11 +43,11 @@ fun CardVerticalImageFirst(customizationState: CardCustomizationState) { Column( modifier = Modifier .fillMaxSize() - .padding(dimensionResource(id = R.dimen.spacing_m)) + .padding(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) .verticalScroll(state = rememberScrollState()), ) { - val button1Text = stringResource(id = R.string.component_element_button1) - val button2Text = stringResource(id = R.string.component_element_button2) + val button1Text = stringResource(id = R.string.component_element_first_button) + val button2Text = stringResource(id = R.string.component_element_second_button) val cardText = stringResource(id = R.string.component_card_element_card) OdsVerticalImageFirstCard( @@ -68,7 +68,7 @@ fun CardVerticalImageFirst(customizationState: CardCustomizationState) { onButton2Click = { clickOnElement(context, button2Text) } ) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) CodeImplementationColumn { FunctionCallCode( 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 cd8665db1..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 @@ -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 @@ -49,13 +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 = 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) - } + 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), @@ -71,7 +72,7 @@ fun ComponentCard(variant: Variant) { count = actionButtonCount, minusIconContentDescription = stringResource(id = R.string.component_remove_action_button), plusIconContentDescription = stringResource(id = R.string.component_add_action_button), - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), minCount = CardCustomizationState.MinActionButtonCount, maxCount = CardCustomizationState.MaxActionButtonCount ) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/checkboxes/ComponentCheckboxes.kt b/app/src/main/java/com/orange/ods/app/ui/components/checkboxes/ComponentCheckboxes.kt index dde102461..c47efd402 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/checkboxes/ComponentCheckboxes.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/checkboxes/ComponentCheckboxes.kt @@ -50,7 +50,7 @@ fun ComponentCheckboxes() { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.spacing_s)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) ) { recipe.ingredients.take(3).forEachIndexed { index, ingredient -> OdsListItem( @@ -63,7 +63,7 @@ fun ComponentCheckboxes() { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) { FunctionCallCode( name = OdsComposable.OdsCheckbox.name, 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 66f5725c4..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 @@ -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 @@ -37,16 +36,16 @@ 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 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 @@ -60,14 +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 = 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) - 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() } @@ -91,10 +91,13 @@ fun ChipTypeDemo(chipType: ChipType, content: @Composable () -> Unit) { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin), vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding( + horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin) + ) ) { OdsTextBody2( - modifier = Modifier.padding(bottom = dimensionResource(id = R.dimen.spacing_s)), + modifier = Modifier.padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), text = stringResource(id = chipType.descriptionRes) ) content() @@ -104,55 +107,57 @@ 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) { - 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(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) CodeImplementationColumn { FunctionCallCode( name = OdsComposable.OdsChoiceChipsFlowRow.name, parameters = { - mutableState("selectedChip", choiceChipIndexSelected.value.toString()) - if (!outlinedChips) stringRepresentation("outlinedChips", outlinedChips) - } - ) { - 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() 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, + 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, @@ -161,7 +166,7 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { } else null ) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) CodeImplementationColumn { FunctionCallCode( @@ -169,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/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 9ddba3fc4..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 @@ -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( @@ -58,13 +55,14 @@ fun ChipFilter() { Subtitle(textRes = R.string.component_element_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = leadingElement, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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) - } + 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), @@ -75,33 +73,34 @@ fun ChipFilter() { }) { var selectedChipIndexes by rememberSaveable { mutableStateOf(emptySet()) } ChipTypeDemo(chipType = chipType.value) { - FlowRow(modifier = Modifier.fillMaxWidth(), mainAxisSpacing = dimensionResource(id = R.dimen.spacing_s)) { + FlowRow(modifier = Modifier.fillMaxWidth(), mainAxisSpacing = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) { recipe.ingredients.forEachIndexed { index, ingredient -> 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, ) } } - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) CodeImplementationColumn { FunctionCallCode( name = "FlowRow", - parameters = { simple("mainAxisSpacing", "dimensionResource(id = R.dimen.spacing_s))") } + parameters = { simple("mainAxisSpacing", "8.dp") } ) { recipe.ingredients.forEachIndexed { index, ingredient -> FunctionCallCode( @@ -109,9 +108,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/app/src/main/java/com/orange/ods/app/ui/components/dialogs/ComponentDialog.kt b/app/src/main/java/com/orange/ods/app/ui/components/dialogs/ComponentDialog.kt index 00d16006c..efdd0bc92 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/dialogs/ComponentDialog.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/dialogs/ComponentDialog.kt @@ -31,6 +31,7 @@ import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.dialog.OdsAlertDialog +import com.orange.ods.compose.component.dialog.OdsAlertDialogButton import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsSwitchTrailing @@ -68,19 +69,23 @@ fun ComponentDialog() { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) { FunctionCallCode( name = OdsComposable.OdsAlertDialog.name, exhaustiveParameters = false, parameters = { simple("text", "") - string("confirmButtonText", confirmButtonText) - lambda("onConfirmButtonClick") - if (customizationState.isTitleChecked) string("titleText", recipe.title) + classInstance("confirmButton", OdsAlertDialogButton::class.java) { + text(confirmButtonText) + onClick() + } + if (customizationState.isTitleChecked) string("title", recipe.title) if (customizationState.isDismissButtonChecked) { - string("dismissButtonText", dismissButtonText) - lambda("onDismissButtonClick") + classInstance("dismissButton", OdsAlertDialogButton::class.java) { + text(dismissButtonText) + onClick() + } } } ) @@ -88,18 +93,18 @@ fun ComponentDialog() { if (customizationState.shouldOpenDialog) { OdsAlertDialog( - titleText = if (customizationState.isTitleChecked) recipe.title else null, + title = if (customizationState.isTitleChecked) recipe.title else null, text = recipe.description, - confirmButtonText = confirmButtonText, - onConfirmButtonClick = { + confirmButton = OdsAlertDialogButton(confirmButtonText) { clickOnElement(context = context, clickedElement = confirmButtonText) closeDialogAction() }, - dismissButtonText = if (customizationState.isDismissButtonChecked) dismissButtonText else null, - onDismissButtonClick = { - clickOnElement(context = context, clickedElement = dismissButtonText) - closeDialogAction() - }, + dismissButton = if (customizationState.isDismissButtonChecked) { + OdsAlertDialogButton(dismissButtonText) { + clickOnElement(context = context, clickedElement = dismissButtonText) + closeDialogAction() + } + } else null, ) } } 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 18ecaeee1..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 @@ -34,6 +34,7 @@ import com.orange.ods.app.ui.utilities.composable.Subtitle import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.button.OdsExtendedFloatingActionButton import com.orange.ods.compose.component.button.OdsFloatingActionButton +import com.orange.ods.compose.component.button.OdsFloatingActionButtonIcon import com.orange.ods.compose.component.chip.OdsChoiceChip import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow import com.orange.ods.compose.component.list.OdsListItem @@ -54,8 +55,8 @@ fun ComponentFloatingActionButton() { .let { if (isFullScreenWidth) it .padding( - start = dimensionResource(id = R.dimen.spacing_m), - end = dimensionResource(id = R.dimen.spacing_m), + start = dimensionResource(id = com.orange.ods.R.dimen.spacing_m), + end = dimensionResource(id = com.orange.ods.R.dimen.spacing_m), bottom = 64.dp ) .fillMaxWidth() @@ -71,7 +72,7 @@ fun ComponentFloatingActionButton() { clickOnElement(context, context.getString(R.string.component_floating_action_button)) }, text = stringResource(id = R.string.component_floating_action_button_add), - icon = painterResource(id = R.drawable.ic_plus), + icon = OdsFloatingActionButtonIcon(painterResource(id = R.drawable.ic_plus), ""), modifier = modifier ) } else { @@ -80,8 +81,10 @@ fun ComponentFloatingActionButton() { clickOnElement(context, context.getString(R.string.component_floating_action_button)) }, mini = size.value == FabCustomizationState.Size.Mini, - icon = painterResource(id = R.drawable.ic_plus), - iconContentDescription = stringResource(id = R.string.component_floating_action_button_add), + icon = OdsFloatingActionButtonIcon( + painterResource(id = R.drawable.ic_plus), + stringResource(id = R.string.component_floating_action_button_add) + ), modifier = modifier ) } @@ -90,13 +93,17 @@ fun ComponentFloatingActionButton() { bottomSheetContent = { Subtitle(textRes = R.string.component_size, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = size, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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) - } + value = size.value, + onValueChange = { value -> size.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + 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) @@ -109,13 +116,16 @@ fun ComponentFloatingActionButton() { Column(modifier = Modifier.verticalScroll(rememberScrollState())) { val usedComponentName = if (hasText) OdsComposable.OdsExtendedFloatingActionButton.name else OdsComposable.OdsFloatingActionButton.name CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) { FunctionCallCode( name = usedComponentName, exhaustiveParameters = false, parameters = { - icon() + classInstance("icon", OdsFloatingActionButtonIcon::class.java) { + painter() + contentDescription("") + } if (this@with.size.value == FabCustomizationState.Size.Mini) stringRepresentation("mini", true) if (hasText) string("text", "Add") if (isFullScreenWidth) fillMaxWidth() diff --git a/app/src/main/java/com/orange/ods/app/ui/components/imageitem/ComponentImageItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/imageitem/ComponentImageItem.kt deleted file mode 100644 index 7ea36ef3e..000000000 --- a/app/src/main/java/com/orange/ods/app/ui/components/imageitem/ComponentImageItem.kt +++ /dev/null @@ -1,131 +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.app.ui.components.imageitem - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.rememberBottomSheetScaffoldState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import coil.compose.rememberAsyncImagePainter -import com.orange.ods.app.R -import com.orange.ods.app.domain.recipes.LocalRecipes -import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold -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.IconPainterValue -import com.orange.ods.app.ui.utilities.composable.Subtitle -import com.orange.ods.compose.OdsComposable -import com.orange.ods.compose.component.chip.OdsChoiceChip -import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow -import com.orange.ods.compose.component.imageitem.OdsImageItem -import com.orange.ods.compose.component.imageitem.OdsImageItemTitleType -import com.orange.ods.compose.component.list.OdsListItem -import com.orange.ods.compose.component.list.OdsSwitchTrailing - -@OptIn(ExperimentalMaterialApi::class) -@Composable -fun ComponentImageItem() { - val imageItemCustomizationState = rememberImageItemCustomizationState() - var iconChecked by rememberSaveable { mutableStateOf(false) } - val recipes = LocalRecipes.current - val recipe = rememberSaveable { recipes.random() } - - with(imageItemCustomizationState) { - if (type.value == OdsImageItemTitleType.None) { - iconDisplayed.value = false - } - if (!hasIcon) { - iconChecked = false - } - ComponentCustomizationBottomSheetScaffold( - bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), - bottomSheetContent = { - OdsChoiceChipsFlowRow( - selectedChip = type, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), - outlinedChips = true - ) { - Subtitle(textRes = R.string.component_element_type) - OdsChoiceChip(textRes = R.string.component_image_item_overlay_text, value = OdsImageItemTitleType.Overlay) - OdsChoiceChip(textRes = R.string.component_image_item_below_text, value = OdsImageItemTitleType.Below) - OdsChoiceChip(textRes = R.string.component_element_none, value = OdsImageItemTitleType.None) - } - OdsListItem( - text = stringResource(id = R.string.component_element_icon), - trailing = OdsSwitchTrailing(checked = iconDisplayed, enabled = hasText) - ) - }) { - Column( - modifier = Modifier - .fillMaxSize() - .padding( - top = dimensionResource(id = R.dimen.screen_horizontal_margin), - start = dimensionResource(id = R.dimen.screen_horizontal_margin) - ), - horizontalAlignment = Alignment.Start, - ) { - val imageSize = 200.dp - val height = when (type.value) { - OdsImageItemTitleType.Below -> imageSize + dimensionResource(id = R.dimen.image_item_title_height) - OdsImageItemTitleType.Overlay, - OdsImageItemTitleType.None -> imageSize - } - OdsImageItem( - image = rememberAsyncImagePainter( - model = recipe.imageUrl, - placeholder = painterResource(id = R.drawable.placeholder), - error = painterResource(id = R.drawable.placeholder) - ), - uncheckedIcon = if (hasIcon) painterResource(id = R.drawable.ic_heart_outlined) else null, - checkedIcon = if (hasIcon) painterResource(id = R.drawable.ic_heart) else null, - title = if (hasText) recipe.title else null, - modifier = Modifier - .width(imageSize) - .height(height), - iconChecked = iconChecked, - iconContentDescription = stringResource(id = R.string.component_button_icon_toggle_favorite_icon_desc), - onIconCheckedChange = { checked -> iconChecked = checked }, - displayTitle = if (isOverlay) OdsImageItemTitleType.Overlay else if (isBelow) OdsImageItemTitleType.Below else OdsImageItemTitleType.None, - ) - CodeImplementationColumn( - modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_m)) - ) { - FunctionCallCode( - name = OdsComposable.OdsImageItem.name, - exhaustiveParameters = false, - parameters = { - stringRepresentation("displayTitle", type.value) - if (hasText) title(recipe.title) - image() - checked(iconChecked) - lambda("onIconCheckedChange") - if (hasIcon) simple("checkedIcon", IconPainterValue) - if (hasIcon) simple("uncheckedIcon", IconPainterValue) - }) - } - } - } - } -} \ No newline at end of file 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 new file mode 100644 index 000000000..335b04d3e --- /dev/null +++ b/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ComponentImageTile.kt @@ -0,0 +1,173 @@ +/* + * + * 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.app.ui.components.imagetile + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.rememberBottomSheetScaffoldState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +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.res.stringResource +import androidx.compose.ui.unit.dp +import coil.compose.rememberAsyncImagePainter +import com.orange.ods.app.R +import com.orange.ods.app.domain.recipes.LocalRecipes +import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold +import com.orange.ods.app.ui.components.utilities.clickOnElement +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.Subtitle +import com.orange.ods.compose.OdsComposable +import com.orange.ods.compose.component.button.OdsIconButtonIcon +import com.orange.ods.compose.component.chip.OdsChoiceChip +import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow +import com.orange.ods.compose.component.imagetile.OdsImageTile +import com.orange.ods.compose.component.imagetile.OdsImageTileIconToggleButton +import com.orange.ods.compose.component.imagetile.OdsImageTileImage +import com.orange.ods.compose.component.imagetile.OdsImageTileLegendAreaDisplayType +import com.orange.ods.compose.component.list.OdsListItem +import com.orange.ods.compose.component.list.OdsSwitchTrailing + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun ComponentImageTile() { + val context = LocalContext.current + val imageTileCustomizationState = rememberImageTileCustomizationState() + var iconChecked by rememberSaveable { mutableStateOf(false) } + val recipes = LocalRecipes.current + val recipe = rememberSaveable { recipes.random() } + + with(imageTileCustomizationState) { + if (type.value == OdsImageTileLegendAreaDisplayType.None) { + iconDisplayed.value = false + } + if (!hasIcon) { + iconChecked = false + } + ComponentCustomizationBottomSheetScaffold( + bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), + bottomSheetContent = { + Subtitle(textRes = R.string.component_image_tile_legend_area_display_type, horizontalPadding = true) + OdsChoiceChipsFlowRow( + value = type.value, + onValueChange = { value -> type.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + 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) + ) + }) { + Column( + modifier = Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .padding( + top = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin), + start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin) + ), + horizontalAlignment = Alignment.Start, + ) { + val imageSize = 200.dp + val height = when (type.value) { + OdsImageTileLegendAreaDisplayType.Below -> imageSize + dimensionResource(id = com.orange.ods.R.dimen.image_tile_legend_area_height) + OdsImageTileLegendAreaDisplayType.Overlay, + OdsImageTileLegendAreaDisplayType.None -> imageSize + } + OdsImageTile( + modifier = Modifier + .width(imageSize) + .height(height), + onClick = { clickOnElement(context, context.getString(R.string.component_image_tile)) }, + image = OdsImageTileImage( + rememberAsyncImagePainter( + model = recipe.imageUrl, + placeholder = painterResource(id = R.drawable.placeholder), + error = painterResource(id = R.drawable.placeholder) + ), "" + ), + title = if (hasText) recipe.title else null, + legendAreaDisplayType = type.value, + icon = if (hasIcon) { + OdsImageTileIconToggleButton( + uncheckedIcon = OdsIconButtonIcon( + painterResource(id = R.drawable.ic_heart_outlined), + stringResource(id = R.string.component_button_icon_toggle_favorite_add_icon_desc) + ), + checkedIcon = OdsIconButtonIcon( + painterResource(id = R.drawable.ic_heart), + stringResource(id = R.string.component_button_icon_toggle_favorite_remove_icon_desc) + ), + checked = iconChecked, + onCheckedChange = { checked -> iconChecked = checked }, + ) + } else { + null + } + ) + CodeImplementationColumn( + modifier = Modifier.padding(end = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) + ) { + FunctionCallCode( + name = OdsComposable.OdsImageTile.name, + exhaustiveParameters = false, + parameters = { + stringRepresentation("legendAreaDisplayType", type.value) + if (hasText) title(recipe.title) + classInstance("image", OdsImageTileImage::class.java) { + painter() + contentDescription("") + } + if (hasIcon) { + classInstance("icon", OdsImageTileIconToggleButton::class.java) { + checked(iconChecked) + lambda("onCheckedChange") + classInstance("uncheckedIcon", OdsIconButtonIcon::class.java) { + painter() + contentDescription("") + } + classInstance("checkedIcon", OdsIconButtonIcon::class.java) { + painter() + contentDescription("") + } + } + } + }) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/orange/ods/app/ui/components/imageitem/ImageItemCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ImageTileCustomizationState.kt similarity index 52% rename from app/src/main/java/com/orange/ods/app/ui/components/imageitem/ImageItemCustomizationState.kt rename to app/src/main/java/com/orange/ods/app/ui/components/imagetile/ImageTileCustomizationState.kt index 782bb212c..cd19b7274 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/imageitem/ImageItemCustomizationState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/imagetile/ImageTileCustomizationState.kt @@ -8,38 +8,31 @@ * / */ -package com.orange.ods.app.ui.components.imageitem +package com.orange.ods.app.ui.components.imagetile import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable -import com.orange.ods.compose.component.imageitem.OdsImageItemTitleType +import com.orange.ods.compose.component.imagetile.OdsImageTileLegendAreaDisplayType @Composable -fun rememberImageItemCustomizationState( - type: MutableState = rememberSaveable { mutableStateOf(OdsImageItemTitleType.Overlay) }, +fun rememberImageTileCustomizationState( + type: MutableState = rememberSaveable { mutableStateOf(OdsImageTileLegendAreaDisplayType.Overlay) }, iconDisplayed: MutableState = rememberSaveable { mutableStateOf(false) } ) = remember(type, iconDisplayed) { - ImageItemCustomizationState(type, iconDisplayed) + ImageTileCustomizationState(type, iconDisplayed) } -class ImageItemCustomizationState( - val type: MutableState, +class ImageTileCustomizationState( + val type: MutableState, val iconDisplayed: MutableState ) { - - val isOverlay - get() = type.value == OdsImageItemTitleType.Overlay - - val isBelow - get() = type.value == OdsImageItemTitleType.Below - val hasIcon get() = iconDisplayed.value val hasText - get() = type.value != OdsImageItemTitleType.None + get() = type.value != OdsImageTileLegendAreaDisplayType.None } \ No newline at end of file diff --git a/app/src/main/java/com/orange/ods/app/ui/components/lists/ComponentLists.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt similarity index 56% rename from app/src/main/java/com/orange/ods/app/ui/components/lists/ComponentLists.kt rename to app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index a41976ae8..63d00aee7 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/lists/ComponentLists.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -8,13 +8,11 @@ * / */ -package com.orange.ods.app.ui.components.lists +package com.orange.ods.app.ui.components.listitem import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf @@ -37,7 +35,10 @@ import com.orange.ods.app.ui.components.utilities.ComponentCountRow import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold 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.Subtitle +import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.chip.OdsChoiceChip import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow import com.orange.ods.compose.component.list.OdsCaptionTrailing @@ -49,68 +50,62 @@ import com.orange.ods.compose.component.list.OdsListItemIconScope import com.orange.ods.compose.component.list.OdsListItemIconType import com.orange.ods.compose.component.list.OdsListItemTrailing import com.orange.ods.compose.component.list.OdsSwitchTrailing -import com.orange.ods.compose.component.list.divider import com.orange.ods.compose.component.list.iconType -import com.orange.ods.utilities.extension.orElse +import com.orange.ods.extension.orElse @OptIn(ExperimentalMaterialApi::class) @Composable -fun ComponentLists() { +fun ComponentListItem() { val listItemCustomizationState = rememberListItemCustomizationState() ComponentCustomizationBottomSheetScaffold( bottomSheetScaffoldState = listItemCustomizationState.bottomSheetScaffoldState, - bottomSheetContent = { ComponentListsBottomSheetContent(listItemCustomizationState) }, - content = { ComponentListsContent(listItemCustomizationState) } + bottomSheetContent = { ComponentListItemBottomSheetContent(listItemCustomizationState) }, + content = { ComponentListItemContent(listItemCustomizationState) } ) } @Composable -private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListItemCustomizationState) { +private fun ComponentListItemBottomSheetContent(listItemCustomizationState: ListItemCustomizationState) { ComponentCountRow( - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), title = stringResource(id = R.string.component_list_item_size), count = listItemCustomizationState.lineCount, minusIconContentDescription = stringResource(id = R.string.component_list_item_remove_line), plusIconContentDescription = stringResource(id = R.string.component_list_item_add_line), - minCount = ComponentListItem.MinLineCount, - maxCount = ComponentListItem.MaxLineCount + minCount = ListItemCustomizationState.MinLineCount, + maxCount = ListItemCustomizationState.MaxLineCount ) Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = listItemCustomizationState.selectedLeading, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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) - 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 = R.dimen.screen_horizontal_margin)), - outlinedChips = true - ) { - 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) } - } - - OdsListItem( - text = stringResource(id = R.string.component_element_divider), - trailing = OdsSwitchTrailing(checked = listItemCustomizationState.dividerEnabled) ) } @Composable -private fun ComponentListsContent(listItemCustomizationState: ListItemCustomizationState) { - val recipes = LocalRecipes.current.filter { it.description.isNotBlank() } +private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomizationState) { + val recipe = LocalRecipes.current.first { it.description.isNotBlank() } with(listItemCustomizationState) { - Column(modifier = Modifier.verticalScroll(rememberScrollState())) { + Column { if (!trailings.contains(selectedTrailing.value)) { resetTrailing() } @@ -119,33 +114,63 @@ private fun ComponentListsContent(listItemCustomizationState: ListItemCustomizat .let { modifier -> iconType?.let { modifier.iconType(it) }.orElse { modifier } } - .let { if (dividerEnabled.value) it.divider() else it } val singleLineSecondaryText = lineCount.value == 2 - recipes.forEach { recipe -> - val text = recipe.title - val secondaryText = listItemCustomizationState.getSecondaryText(recipe) - val icon: @Composable (OdsListItemIconScope.() -> Unit)? = - listItemCustomizationState.getIconPainter(recipe)?.let { { OdsListItemIcon(painter = it) } } - trailing?.let { listItemTrailing -> - OdsListItem( - modifier = modifier, - text = text, - secondaryText = secondaryText, - singleLineSecondaryText = singleLineSecondaryText, - icon = icon, - trailing = listItemTrailing - ) - }.orElse { - val context = LocalContext.current - OdsListItem( - modifier = modifier.clickable { clickOnElement(context = context, context.getString(R.string.component_list_item)) }, - text = text, - secondaryText = secondaryText, - singleLineSecondaryText = singleLineSecondaryText, - icon = icon - ) - } + val text = recipe.title + val secondaryText = if (lineCount.value > 1) recipe.description else null + val icon: @Composable (OdsListItemIconScope.() -> Unit)? = + listItemCustomizationState.getIconPainter(recipe)?.let { { OdsListItemIcon(painter = it) } } + trailing?.let { listItemTrailing -> + OdsListItem( + modifier = modifier, + text = text, + secondaryText = secondaryText, + singleLineSecondaryText = singleLineSecondaryText, + icon = icon, + trailing = listItemTrailing + ) + }.orElse { + val context = LocalContext.current + OdsListItem( + modifier = modifier.clickable { clickOnElement(context = context, context.getString(R.string.component_list_item)) }, + text = text, + secondaryText = secondaryText, + singleLineSecondaryText = singleLineSecondaryText, + icon = icon + ) + } + + CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin))) { + FunctionCallCode( + name = OdsComposable.OdsListItem.name, + parameters = { + string("text", text) + if (secondaryText != null) { + string("secondaryText", secondaryText) + if (!singleLineSecondaryText) stringRepresentation("singleLineSecondaryText", false) + } + if (selectedLeading.value != ListItemCustomizationState.Leading.None) { + simple("modifier", "Modifier.iconType($iconType)") + simple("icon", "{ OdsListItemIcon() }") + } + if (selectedTrailing.value != ListItemCustomizationState.Trailing.None) { + val clazz: Class<*>? = when (selectedTrailing.value) { + ListItemCustomizationState.Trailing.Checkbox -> OdsCheckboxTrailing::class.java + ListItemCustomizationState.Trailing.Switch -> OdsSwitchTrailing::class.java + ListItemCustomizationState.Trailing.Icon -> OdsIconTrailing::class.java + ListItemCustomizationState.Trailing.Caption -> OdsCaptionTrailing::class.java + else -> null + } + + val trailingParamName = "trailing" + clazz?.let { + classInstance(trailingParamName, it) {} + }.orElse { + simple(trailingParamName, "") + } + } + } + ) } } } @@ -160,14 +185,6 @@ private val ListItemCustomizationState.Trailing.textResId: Int ListItemCustomizationState.Trailing.Caption -> R.string.component_list_trailing_caption } -private fun ListItemCustomizationState.getSecondaryText(recipe: Recipe): String? { - return when (lineCount.value) { - 2 -> recipe.subtitle - 3 -> recipe.description - else -> null - } -} - private val ListItemCustomizationState.iconType: OdsListItemIconType? get() = when (selectedLeading.value) { ListItemCustomizationState.Leading.None -> null @@ -185,8 +202,8 @@ private fun ListItemCustomizationState.getIconPainter(recipe: Recipe): Painter? ListItemCustomizationState.Leading.CircularImage, ListItemCustomizationState.Leading.SquareImage, ListItemCustomizationState.Leading.WideImage -> { - val wideImageSizeWidthPx = with(LocalDensity.current) { dimensionResource(id = R.dimen.list_wide_image_width).toPx() } - val wideImageSizeHeightPx = with(LocalDensity.current) { dimensionResource(id = R.dimen.list_wide_image_height).toPx() } + val wideImageSizeWidthPx = with(LocalDensity.current) { dimensionResource(id = com.orange.ods.R.dimen.list_wide_image_width).toPx() } + val wideImageSizeHeightPx = with(LocalDensity.current) { dimensionResource(id = com.orange.ods.R.dimen.list_wide_image_height).toPx() } rememberAsyncImagePainter( model = ImageRequest.Builder(LocalContext.current) .data(recipe.imageUrl) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/lists/ListItemCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ListItemCustomizationState.kt similarity index 80% rename from app/src/main/java/com/orange/ods/app/ui/components/lists/ListItemCustomizationState.kt rename to app/src/main/java/com/orange/ods/app/ui/components/listitem/ListItemCustomizationState.kt index b930ef445..58996563b 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/lists/ListItemCustomizationState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ListItemCustomizationState.kt @@ -8,7 +8,7 @@ * / */ -package com.orange.ods.app.ui.components.lists +package com.orange.ods.app.ui.components.listitem import androidx.compose.material.BottomSheetScaffoldState import androidx.compose.material.ExperimentalMaterialApi @@ -19,22 +19,15 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable -object ComponentListItem { - const val DefaultLineCount = 2 - const val MinLineCount = 1 - const val MaxLineCount = 3 -} - @OptIn(ExperimentalMaterialApi::class) @Composable fun rememberListItemCustomizationState( bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(), - lineCount: MutableState = rememberSaveable { mutableStateOf(ComponentListItem.DefaultLineCount) }, + lineCount: MutableState = rememberSaveable { mutableStateOf(ListItemCustomizationState.DefaultLineCount) }, selectedLeading: MutableState = rememberSaveable { mutableStateOf(ListItemCustomizationState.Leading.None) }, selectedTrailing: MutableState = rememberSaveable { mutableStateOf(ListItemCustomizationState.Trailing.None) }, - dividerEnabled: MutableState = rememberSaveable { mutableStateOf(false) } ) = remember(lineCount) { - ListItemCustomizationState(bottomSheetScaffoldState, lineCount, selectedLeading, selectedTrailing, dividerEnabled) + ListItemCustomizationState(bottomSheetScaffoldState, lineCount, selectedLeading, selectedTrailing) } @OptIn(ExperimentalMaterialApi::class) @@ -43,8 +36,12 @@ class ListItemCustomizationState( val lineCount: MutableState, val selectedLeading: MutableState, val selectedTrailing: MutableState, - val dividerEnabled: MutableState ) { + companion object { + const val DefaultLineCount = 2 + const val MinLineCount = 1 + const val MaxLineCount = 3 + } enum class Leading { None, Icon, CircularImage, SquareImage, WideImage @@ -55,7 +52,7 @@ class ListItemCustomizationState( } val trailings: List - get() = if (lineCount.value < ComponentListItem.MaxLineCount) { + get() = if (lineCount.value < MaxLineCount) { listOf(Trailing.None, Trailing.Checkbox, Trailing.Switch, Trailing.Icon) } else { listOf(Trailing.None, Trailing.Caption) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuDropdown.kt b/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuDropdown.kt index 936b83b5e..daea4424d 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuDropdown.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuDropdown.kt @@ -37,7 +37,6 @@ import com.orange.ods.app.ui.components.utilities.clickOnElement import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode import com.orange.ods.compose.OdsComposable -import com.orange.ods.compose.component.divider.OdsDivider import com.orange.ods.compose.component.list.OdsIconTrailing import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsSwitchTrailing @@ -71,17 +70,22 @@ fun MenuDropdown() { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin), bottom = dimensionResource(id = R.dimen.spacing_s)) + .padding( + top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin), + bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s) + ) ) { OdsTextBody1( modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), text = stringResource(id = R.string.component_menu_dropdown_description) ) - Box(modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s))) { + val dividerIndex = 1 + + Box(modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s))) { OdsListItem( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s)), + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), text = recipe.title, secondaryText = recipe.subtitle, trailing = OdsIconTrailing( @@ -90,22 +94,26 @@ fun MenuDropdown() { contentDescription = stringResource(id = R.string.component_menu_show_ingredients), ) ) - OdsDropdownMenu(expanded = menuExpanded, onDismissRequest = { menuExpanded = false }, offset = DpOffset(x = (-100).dp, y = (-10).dp)) { - recipes.take(MenuDropdownCustomizationState.MenuItemCount).forEachIndexed { index, recipe -> + + val items = recipes.take(MenuDropdownCustomizationState.MenuItemCount) + .mapIndexed { index, recipe -> OdsDropdownMenuItem( text = recipe.title, icon = if (hasIcons && recipe.iconResId != null) painterResource(id = recipe.iconResId) else null, + divider = hasDividerExample && index == dividerIndex, onClick = { clickOnElement(context, recipe.title) } ) - if (hasDividerExample && index == 2) { - OdsDivider() - } } - } + OdsDropdownMenu( + items = items, + expanded = menuExpanded, + onDismissRequest = { menuExpanded = false }, + offset = DpOffset(x = (-100).dp, y = (-10).dp) + ) } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) { FunctionCallCode( name = OdsComposable.OdsDropdownMenu.name, @@ -113,22 +121,18 @@ fun MenuDropdown() { parameters = { stringRepresentation("expanded", menuExpanded) lambda("onDismissRequest") - } - ) { - recipes.take(2).forEachIndexed { index, recipe -> - FunctionCallCode( - name = OdsComposable.OdsDropdownMenuItem.name, - parameters = { - string("text", recipe.title) - onClick() - if (hasIcons && recipe.iconResId != null) icon() + list("items") { + recipes.take(2).forEachIndexed { index, recipe -> + classInstance(OdsDropdownMenuItem::class.java) { + string("text", recipe.title) + if (hasIcons && recipe.iconResId != null) icon() + if (hasDividerExample && index == dividerIndex) stringRepresentation("divider", true) + onClick() + } } - ) - if (hasDividerExample && index == 0) { - FunctionCallCode(name = OdsComposable.OdsDivider.name) } } - } + ) } } } diff --git a/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuExposedDropdown.kt b/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuExposedDropdown.kt index 0692d4e33..cc3446bf8 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuExposedDropdown.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuExposedDropdown.kt @@ -77,14 +77,17 @@ fun MenuExposedDropdown() { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin), bottom = dimensionResource(id = R.dimen.spacing_s)) - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + .padding( + top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin), + bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s) + ) + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), ) { val label = stringResource(id = R.string.data_recipe) OdsExposedDropdownMenu( modifier = Modifier .fillMaxWidth() - .padding(top = dimensionResource(id = R.dimen.spacing_s)), + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), label = label, items = items, selectedItem = selectedItem, 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 1dc95e09d..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,19 +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, - outlinedChips = true, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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( @@ -142,28 +149,26 @@ fun ComponentModalDrawers() { enabled = isContentExampleChecked ), ) + Subtitle(textRes = R.string.component_modal_drawer_list_example, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = content, - outlinedChips = true, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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( @@ -172,7 +177,7 @@ fun ComponentModalDrawers() { onButtonClick = { scope.launch { drawerState.open() } } ) - CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin))) { + CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin))) { FunctionCallCode( name = OdsComposable.OdsModalDrawer.name, exhaustiveParameters = false, 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 bbb0055e0..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,22 +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, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), - outlinedChips = true - ) { - 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) - } + value = type.value, + onValueChange = { value -> type.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + 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) @@ -83,7 +85,7 @@ fun ProgressCircular() { progress = if (type.value == ProgressCustomizationState.Type.Determinate) determinateProgressAnimation else null, label = if (hasLabel) text else null, modifier = Modifier - .padding(top = dimensionResource(id = R.dimen.spacing_m)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) .align(alignment = Alignment.CenterHorizontally) ) if (type.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 e01ce17f1..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 @@ -41,6 +41,7 @@ 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.component.progressindicator.OdsLinearProgressIndicator +import com.orange.ods.compose.component.progressindicator.OdsLinearProgressIndicatorIcon private const val DeterminateProgressTargetValue = 0.9f private const val DeterminateProgressAnimDuration = 5000 @@ -61,15 +62,16 @@ fun ProgressLinear() { ComponentCustomizationBottomSheetScaffold( bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { + Subtitle(textRes = R.string.component_element_type, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = type, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), - outlinedChips = true - ) { - 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) - } + value = type.value, + onValueChange = { value -> type.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + 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) @@ -96,9 +98,9 @@ fun ProgressLinear() { progress = if (type.value == ProgressCustomizationState.Type.Determinate) determinateProgressAnimation else null, label = if (hasLabel) text else null, showCurrentValue = hasCurrentValue, - icon = if (hasIcon) painterResource(id = R.drawable.ic_arrow_down) else null, + icon = if (hasIcon) OdsLinearProgressIndicatorIcon(painterResource(id = R.drawable.ic_arrow_down), "") else null, modifier = Modifier - .padding(top = dimensionResource(id = R.dimen.spacing_m)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) .fillMaxWidth() ) if (type.value == ProgressCustomizationState.Type.Determinate) { @@ -107,14 +109,19 @@ fun ProgressLinear() { } } - CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin))) { + CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin))) { FunctionCallCode( name = OdsComposable.OdsLinearProgressIndicator.name, exhaustiveParameters = false, parameters = { if (type.value == ProgressCustomizationState.Type.Determinate) stringRepresentation("progress", determinateProgressValue) if (hasLabel) string("label", text) - if (hasIcon) icon() + if (hasIcon) { + classInstance("icon", OdsLinearProgressIndicatorIcon::class.java) { + painter() + contentDescription("") + } + } if (hasCurrentValue) stringRepresentation("showCurrentValue", hasCurrentValue) } ) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/radiobuttons/ComponentRadioButtons.kt b/app/src/main/java/com/orange/ods/app/ui/components/radiobuttons/ComponentRadioButtons.kt index 14e064704..467c88bb9 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/radiobuttons/ComponentRadioButtons.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/radiobuttons/ComponentRadioButtons.kt @@ -49,7 +49,7 @@ fun ComponentRadioButtons() { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.spacing_s)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) ) { val recipes = LocalRecipes.current.take(3) val selectedRadio = rememberSaveable { mutableStateOf(recipes.firstOrNull()?.title) } @@ -66,7 +66,7 @@ fun ComponentRadioButtons() { } } - CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin))) { + CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin))) { FunctionCallCode( name = OdsComposable.OdsRadioButton.name, exhaustiveParameters = false, 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 f2774b4d0..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 @@ -67,23 +67,23 @@ fun ComponentSheetsBottom() { Column(modifier = Modifier.verticalScroll(rememberScrollState())) { Column( modifier = Modifier - .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin)) - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) { OdsTextBody1(text = stringResource(id = R.string.component_sheet_bottom_customize)) OdsTextSubtitle1( text = stringResource(id = R.string.component_element_content), - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) ) - OdsChoiceChipsFlowRow( - selectedChip = content, - outlinedChips = true, - modifier = Modifier.padding(top = dimensionResource(id = 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/sliders/ComponentSliders.kt b/app/src/main/java/com/orange/ods/app/ui/components/sliders/ComponentSliders.kt index cea94f53b..9fc2f5d6f 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/sliders/ComponentSliders.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/sliders/ComponentSliders.kt @@ -64,7 +64,7 @@ fun ComponentSliders() { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(horizontal = dimensionResource(id = R.dimen.spacing_m)) + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) ) { val technicalText = if (shouldDisplayValue) OdsComposable.OdsSliderLockups.name else OdsComposable.OdsSlider.name val steps = if (isStepped) 9 else 0 @@ -79,7 +79,7 @@ fun ComponentSliders() { Title(textRes = getTitleRes(isStepped, hasSideIcons, shouldDisplayValue)) TechnicalText(text = technicalText) - Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_m))) + Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_m))) val componentName: String if (shouldDisplayValue) { diff --git a/app/src/main/java/com/orange/ods/app/ui/components/snackbars/ComponentSnackbars.kt b/app/src/main/java/com/orange/ods/app/ui/components/snackbars/ComponentSnackbars.kt index d996a9640..338e0411a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/snackbars/ComponentSnackbars.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/snackbars/ComponentSnackbars.kt @@ -91,11 +91,11 @@ fun ComponentSnackbars() { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), contentBackground = false ) { OdsTextBody2( - modifier = Modifier.padding(bottom = dimensionResource(id = R.dimen.spacing_xs)), + modifier = Modifier.padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)), text = stringResource(id = R.string.component_snackbar_code_first_step) ) CodeBackgroundColumn { @@ -115,7 +115,10 @@ fun ComponentSnackbars() { } OdsTextBody2( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s), bottom = dimensionResource(id = R.dimen.spacing_xs)), + modifier = Modifier.padding( + top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s), + bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs) + ), text = stringResource(id = R.string.component_snackbar_code_second_step) ) CodeBackgroundColumn { diff --git a/app/src/main/java/com/orange/ods/app/ui/components/switches/ComponentSwitches.kt b/app/src/main/java/com/orange/ods/app/ui/components/switches/ComponentSwitches.kt index deb86203e..992a3c53d 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/switches/ComponentSwitches.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/switches/ComponentSwitches.kt @@ -49,7 +49,7 @@ fun ComponentSwitches() { Column( modifier = Modifier .verticalScroll(rememberScrollState()) - .padding(vertical = dimensionResource(id = R.dimen.spacing_s)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) ) { val recipes = LocalRecipes.current.take(3) recipes.forEach { recipe -> @@ -64,7 +64,7 @@ fun ComponentSwitches() { } CodeImplementationColumn( - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) { FunctionCallCode( name = OdsComposable.OdsSwitch.name, 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 b317fd7a8..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 @@ -11,10 +11,12 @@ package com.orange.ods.app.ui.components.tabs import androidx.activity.compose.BackHandler +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf @@ -23,8 +25,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource -import com.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.HorizontalPager import com.orange.ods.app.R import com.orange.ods.app.ui.LocalMainTopAppBarManager import com.orange.ods.app.ui.TabsConfiguration @@ -43,7 +43,7 @@ private const val MaxFixedTabCount = 3 private const val MinScrollableTabCount = 4 private const val MaxScrollableTabCount = 6 -@OptIn(ExperimentalMaterialApi::class, ExperimentalPagerApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) @Composable fun ComponentTabs(variant: Variant, upPress: () -> Unit) { val scrollableTabs: Boolean @@ -79,34 +79,32 @@ 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 = R.dimen.screen_horizontal_margin)), - outlinedChips = true - ) { - 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) ) ComponentCountRow( - modifier = Modifier.padding(start = dimensionResource(id = R.dimen.screen_horizontal_margin)), + modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), title = stringResource(id = R.string.component_tabs_count), count = tabsCustomizationState.tabsCount, minusIconContentDescription = stringResource(id = R.string.component_tabs_remove_tab), @@ -116,7 +114,7 @@ fun ComponentTabs(variant: Variant, upPress: () -> Unit) { ) }) { - HorizontalPager(state = tabsCustomizationState.pagerState, count = tabsCustomizationState.tabs.size) { page -> + HorizontalPager(state = tabsCustomizationState.pagerState, pageCount = tabsCustomizationState.tabs.size) { page -> val textResId = tabsCustomizationState.tabs[page].textResId TabsPagerContentScreen(stringResource(id = textResId)) } diff --git a/app/src/main/java/com/orange/ods/app/ui/components/tabs/FixedTabRow.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/FixedTabRow.kt index d03eb94f1..86874d313 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/tabs/FixedTabRow.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/tabs/FixedTabRow.kt @@ -10,13 +10,13 @@ package com.orange.ods.app.ui.components.tabs +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.pager.PagerState import androidx.compose.runtime.Composable -import com.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.PagerState -import com.orange.ods.compose.component.tab.OdsTabRow import com.orange.ods.app.ui.utilities.NavigationItem +import com.orange.ods.compose.component.tab.OdsTabRow -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) @Composable fun FixedTabRow(tabs: List, pagerState: PagerState, tabIconType: MainTabsCustomizationState.TabIconType, tabTextEnabled: Boolean) { OdsTabRow(selectedTabIndex = pagerState.currentPage) { 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 7fcf1cb7e..3ee3fa48c 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 @@ -10,6 +10,9 @@ package com.orange.ods.app.ui.components.tabs +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.pager.PagerState +import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material.BottomSheetScaffoldState import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.rememberBottomSheetScaffoldState @@ -18,12 +21,9 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable -import com.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.PagerState -import com.google.accompanist.pager.rememberPagerState import com.orange.ods.app.ui.utilities.NavigationItem -@OptIn(ExperimentalMaterialApi::class, ExperimentalPagerApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) @Composable fun rememberMainTabsCustomizationState( bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(), @@ -36,7 +36,7 @@ fun rememberMainTabsCustomizationState( MainTabsCustomizationState(bottomSheetScaffoldState, pagerState, tabsCount, selectedTabIconType, tabTextEnabled) } -@OptIn(ExperimentalMaterialApi::class, ExperimentalPagerApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) class MainTabsCustomizationState( val bottomSheetScaffoldState: BottomSheetScaffoldState, val pagerState: PagerState, diff --git a/app/src/main/java/com/orange/ods/app/ui/components/tabs/ScrollableTabRow.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/ScrollableTabRow.kt index 1406cd965..c0385e94f 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/tabs/ScrollableTabRow.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/tabs/ScrollableTabRow.kt @@ -10,13 +10,13 @@ package com.orange.ods.app.ui.components.tabs +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.pager.PagerState import androidx.compose.runtime.Composable -import com.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.PagerState import com.orange.ods.compose.component.tab.OdsScrollableTabRow import com.orange.ods.app.ui.utilities.NavigationItem -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) @Composable fun ScrollableTabRow(tabs: List, pagerState: PagerState, tabIconType: MainTabsCustomizationState.TabIconType, tabTextEnabled: Boolean) { OdsScrollableTabRow(selectedTabIndex = pagerState.currentPage) { diff --git a/app/src/main/java/com/orange/ods/app/ui/components/tabs/Tabs.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/Tabs.kt index 9499c5f2c..fe559a2d1 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/tabs/Tabs.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/tabs/Tabs.kt @@ -10,18 +10,18 @@ package com.orange.ods.app.ui.components.tabs +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.pager.PagerState import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import com.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.PagerState +import com.orange.ods.app.ui.utilities.NavigationItem import com.orange.ods.compose.component.tab.OdsLeadingIconTab import com.orange.ods.compose.component.tab.OdsTab -import com.orange.ods.app.ui.utilities.NavigationItem import kotlinx.coroutines.launch -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) @Composable fun Tabs(tabs: List, pagerState: PagerState, tabIconType: MainTabsCustomizationState.TabIconType, tabTextEnabled: Boolean) { val scope = rememberCoroutineScope() 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 e8ad01f8d..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 @@ -11,8 +11,11 @@ package com.orange.ods.app.ui.components.textfields import androidx.annotation.StringRes +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi @@ -27,22 +30,18 @@ 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.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.HorizontalPager -import com.google.accompanist.pager.rememberPagerState +import com.orange.ods.app.R +import com.orange.ods.app.ui.components.Variant +import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold +import com.orange.ods.app.ui.utilities.composable.Subtitle 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.compose.component.tab.OdsTab import com.orange.ods.compose.component.tab.OdsTabRow -import com.orange.ods.app.R -import com.orange.ods.app.ui.components.Variant -import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold -import com.orange.ods.app.ui.utilities.composable.Subtitle -import com.orange.ods.utilities.composable.Keyboard -import com.orange.ods.utilities.composable.keyboardAsState +import com.orange.ods.compose.utilities.composable.Keyboard +import com.orange.ods.compose.utilities.composable.keyboardAsState import kotlinx.coroutines.launch @OptIn(ExperimentalMaterialApi::class) @@ -63,8 +62,8 @@ fun ComponentTextField(variant: Variant) { modifier = Modifier .verticalScroll(rememberScrollState()) .padding( - horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin), - vertical = dimensionResource(id = R.dimen.screen_vertical_margin) + horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin) ) ) { when (variant) { @@ -76,7 +75,7 @@ fun ComponentTextField(variant: Variant) { } } -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) @Composable private fun TextFieldTextCustomization(textFieldCustomizationState: TextFieldCustomizationState) { val pagerState = rememberPagerState() @@ -102,7 +101,7 @@ private fun TextFieldTextCustomization(textFieldCustomizationState: TextFieldCus ) } } - HorizontalPager(state = pagerState, count = tabs.size) { page -> + HorizontalPager(state = pagerState, pageCount = tabs.size) { page -> Column { tabs[page].Content(textFieldCustomizationState) } @@ -131,34 +130,45 @@ private fun ComponentCustomizationContent(textFieldCustomizationState: TextField Subtitle(textRes = R.string.component_text_field_input_type, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = textFieldCustomizationState.inputType, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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) - // 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 + value = textFieldCustomizationState.inputType.value, + onValueChange = { value -> textFieldCustomizationState.inputType.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + 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, - modifier = Modifier.padding(horizontal = dimensionResource(id = 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) - OdsChoiceChip(textRes = R.string.component_element_text, value = TextFieldCustomizationState.TrailingElement.Text) - } - + value = textFieldCustomizationState.trailingElement.value, + onValueChange = { value -> textFieldCustomizationState.trailingElement.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 = 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) @@ -169,15 +179,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 = R.dimen.spacing_m)), - outlinedChips = true - ) { - 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), @@ -186,34 +194,41 @@ private fun KeyboardCustomizationContent(textFieldCustomizationState: TextFieldC Subtitle(textRes = R.string.component_text_field_keyboard_action, horizontalPadding = true) OdsChoiceChipsFlowRow( - selectedChip = textFieldCustomizationState.softKeyboardAction, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), - outlinedChips = true - ) { - TextFieldCustomizationState.SoftKeyboardAction.values().forEach { softKeyboardAction -> + value = textFieldCustomizationState.softKeyboardAction.value, + onValueChange = { value -> textFieldCustomizationState.softKeyboardAction.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + 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, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), - outlinedChips = true - ) { - 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) - } + value = displayType.value, + onValueChange = { value -> displayType.value = value }, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + 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, + 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/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextField.kt b/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextField.kt index 26d18316e..380fe32b7 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextField.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextField.kt @@ -39,7 +39,7 @@ fun TextField(customizationState: TextFieldCustomizationState) { val modifier = Modifier .fillMaxWidth() - .padding(top = dimensionResource(id = R.dimen.spacing_s)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) with(customizationState) { val leadingIcon = if (hasLeadingIcon) painterResource(id = R.drawable.ic_heart) else null @@ -66,7 +66,7 @@ fun TextField(customizationState: TextFieldCustomizationState) { placeholder = placeholder, trailing = if (hasTrailingIcon) { OdsIconTrailing( - painter = painterResource(id = R.drawable.ic_eye), + painter = painterResource(id = com.orange.ods.R.drawable.ic_eye), onClick = { clickOnElement(context = context, trailingIconName) }) } else { OdsTextTrailing(text = "units") diff --git a/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextFieldPassword.kt b/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextFieldPassword.kt index 1f918e039..0ef898059 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextFieldPassword.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/textfields/TextFieldPassword.kt @@ -32,7 +32,7 @@ fun TextFieldPassword(customizationState: TextFieldCustomizationState) { OdsPasswordTextField( modifier = Modifier .fillMaxWidth() - .padding(top = dimensionResource(id = R.dimen.spacing_s)), + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), enabled = isEnabled, isError = isError, errorMessage = if (isError) errorMessage else null, diff --git a/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentCountRow.kt b/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentCountRow.kt index 4fdfc57df..24e7e6587 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentCountRow.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentCountRow.kt @@ -21,9 +21,10 @@ import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.semantics +import com.orange.ods.app.R import com.orange.ods.compose.component.button.OdsIconButton +import com.orange.ods.compose.component.button.OdsIconButtonIcon import com.orange.ods.compose.text.OdsTextSubtitle1 -import com.orange.ods.app.R @Composable fun ComponentCountRow( @@ -43,8 +44,7 @@ fun ComponentCountRow( OdsTextSubtitle1(modifier = Modifier.weight(1f), text = title) OdsIconButton( onClick = { count.value-- }, - painter = painterResource(id = R.drawable.ic_remove), - contentDescription = minusIconContentDescription, + icon = OdsIconButtonIcon(painterResource(id = R.drawable.ic_remove), minusIconContentDescription), enabled = count.value > minCount ) @@ -54,8 +54,7 @@ fun ComponentCountRow( }) OdsIconButton( onClick = { count.value++ }, - painter = painterResource(id = R.drawable.ic_add), - contentDescription = plusIconContentDescription, + icon = OdsIconButtonIcon(painterResource(id = R.drawable.ic_add), plusIconContentDescription), enabled = count.value < maxCount ) } diff --git a/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentLaunchContentColumn.kt b/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentLaunchContentColumn.kt index 5d49758d4..4610b2143 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentLaunchContentColumn.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/utilities/ComponentLaunchContentColumn.kt @@ -14,8 +14,6 @@ import androidx.annotation.StringRes import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource @@ -23,22 +21,26 @@ import androidx.compose.ui.res.stringResource import com.orange.ods.compose.component.button.OdsButton import com.orange.ods.compose.component.button.OdsButtonStyle import com.orange.ods.compose.text.OdsTextBody1 -import com.orange.ods.app.R @Composable fun ComponentLaunchContentColumn(@StringRes textRes: Int, @StringRes buttonLabelRes: Int, onButtonClick: () -> Unit) { - Column(modifier = Modifier.padding(top = dimensionResource(id = R.dimen.screen_vertical_margin), bottom = dimensionResource(id = R.dimen.spacing_s))) { + Column( + modifier = Modifier.padding( + top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin), + bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s) + ) + ) { OdsTextBody1( modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)), + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), text = stringResource(id = textRes) ) OdsButton( modifier = Modifier .fillMaxWidth() - .padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin)) - .padding(top = dimensionResource(R.dimen.spacing_m)), + .padding(horizontal = dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin)) + .padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_m)), text = stringResource(id = buttonLabelRes), style = OdsButtonStyle.Primary, onClick = onButtonClick diff --git a/app/src/main/java/com/orange/ods/app/ui/guidelines/GuidelinesScreen.kt b/app/src/main/java/com/orange/ods/app/ui/guidelines/GuidelinesScreen.kt index fc8d3894d..66b9096e9 100644 --- a/app/src/main/java/com/orange/ods/app/ui/guidelines/GuidelinesScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/guidelines/GuidelinesScreen.kt @@ -35,8 +35,8 @@ fun GuidelinesScreen(onGuidelineClick: (String) -> Unit) { modifier = Modifier .fillMaxSize() .verticalScroll(scrollState) - .padding(dimensionResource(id = R.dimen.spacing_m)), - verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)) + .padding(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), + verticalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) ) { Guideline.values().forEach { guideline -> OdsVerticalImageFirstCard( diff --git a/app/src/main/java/com/orange/ods/app/ui/guidelines/color/GuidelineColorScreen.kt b/app/src/main/java/com/orange/ods/app/ui/guidelines/color/GuidelineColorScreen.kt index a7485caf5..507171b53 100644 --- a/app/src/main/java/com/orange/ods/app/ui/guidelines/color/GuidelineColorScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/guidelines/color/GuidelineColorScreen.kt @@ -80,20 +80,20 @@ fun GuidelineColorScreen() { if (guidelineColors.isEmpty()) { OdsTextBody1( modifier = Modifier.padding( - horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin), - vertical = dimensionResource(id = R.dimen.screen_vertical_margin) + horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin) ), text = stringResource(id = R.string.guideline_colour_no_colours_defined) ) } else { LazyColumn( contentPadding = PaddingValues( - start = dimensionResource(id = R.dimen.spacing_m), - end = dimensionResource(id = R.dimen.spacing_m), - top = dimensionResource(id = R.dimen.screen_vertical_margin), - bottom = dimensionResource(id = R.dimen.screen_vertical_margin) + start = dimensionResource(id = com.orange.ods.R.dimen.spacing_m), + end = dimensionResource(id = com.orange.ods.R.dimen.spacing_m), + top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin), + bottom = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin) ), - verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)), + verticalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), ) { if (coreColors.isNotEmpty()) { item { @@ -101,7 +101,7 @@ fun GuidelineColorScreen() { } items(coreColors.chunked(2)) { rowColors -> Row( - horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)), + horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), ) { BigColorItem(color = rowColors[0]) BigColorItem(color = rowColors[1]) @@ -115,7 +115,7 @@ fun GuidelineColorScreen() { } items(functionalColors.chunked(2)) { rowColors -> Row( - horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)), + horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), ) { BigColorItem(color = rowColors[0]) BigColorItem(color = rowColors[1]) @@ -129,7 +129,7 @@ fun GuidelineColorScreen() { } items(supportingColors.chunked(3)) { rowColors -> Row( - horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)), + horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), ) { SmallColorItem(color = rowColors[0]) SmallColorItem(color = rowColors[1]) @@ -164,7 +164,7 @@ private fun RowScope.SmallColorItem(color: GuidelineColor) { ) OdsTextH6( text = color.getName(), - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_xs)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)) ) OdsTextCaption(text = colorValue.toHexString()) } @@ -201,11 +201,11 @@ private fun RowScope.BigColorItem(color: GuidelineColor) { ) OdsTextH6( text = color.getName(), - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_xs)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)) ) OdsTextBody1(text = color.callable.name) OdsTextCaption( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_xs)), + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)), text = colorValue.toHexString() ) OdsTextCaption( @@ -236,24 +236,27 @@ fun DialogColor(color: GuidelineColor, openDialog: MutableState) { modifier = Modifier .background(color = OdsTheme.colors.background) .fillMaxWidth() - .padding(horizontal = dimensionResource(id = R.dimen.spacing_m), vertical = dimensionResource(id = R.dimen.spacing_s)) + .padding( + horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m), + vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s) + ) ) { OdsTextH5(text = color.getName()) OdsTextBody1( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_xs)), + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)), text = color.callable.name ) OdsTextBody1( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s)), + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), text = colorValue.toHexString() ) OdsTextBody1( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s)), + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), text = colorValue.toRgbString() ) color.xmlResource?.let { xmlResource -> OdsTextBody1( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s)), + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), text = stringResource( id = R.string.guideline_colour_xml, context.getStringName(xmlResource) @@ -261,7 +264,7 @@ fun DialogColor(color: GuidelineColor, openDialog: MutableState) { ) } OdsButton( - modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s)), + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), text = stringResource(id = R.string.guideline_colour_copy_to_clipboard_button_title), onClick = { copyColorToClipboard(context, colorValue, clipboardManager) }) } diff --git a/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacing.kt b/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacing.kt index b2d9b5c29..a2967989a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacing.kt +++ b/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacing.kt @@ -13,17 +13,16 @@ package com.orange.ods.app.ui.guidelines.spacing import androidx.annotation.DimenRes import androidx.compose.runtime.Composable import androidx.compose.ui.res.dimensionResource -import com.orange.ods.app.R enum class Spacing(val tokenName: String, @DimenRes val dimenRes: Int) { - None("spacing - none", R.dimen.spacing_none), - ExtraSmall("spacing - xs", R.dimen.spacing_xs), - Small("spacing - s", R.dimen.spacing_s), - Medium("spacing - m", R.dimen.spacing_m), - Large("spacing - l", R.dimen.spacing_l), - ExtraLarge("spacing - xl", R.dimen.spacing_xl), - ExtraExtraLarge("spacing - 2xl", R.dimen.spacing_2xl); + None("spacing - none", com.orange.ods.R.dimen.spacing_none), + ExtraSmall("spacing - xs", com.orange.ods.R.dimen.spacing_xs), + Small("spacing - s", com.orange.ods.R.dimen.spacing_s), + Medium("spacing - m", com.orange.ods.R.dimen.spacing_m), + Large("spacing - l", com.orange.ods.R.dimen.spacing_l), + ExtraLarge("spacing - xl", com.orange.ods.R.dimen.spacing_xl), + ExtraExtraLarge("spacing - 2xl", com.orange.ods.R.dimen.spacing_2xl); @Composable fun getDp() = dimensionResource(id = dimenRes) diff --git a/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacingScreen.kt b/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacingScreen.kt index 466088373..87dfc3000 100644 --- a/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacingScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/guidelines/spacing/GuidelineSpacingScreen.kt @@ -46,7 +46,7 @@ private val ratioFormatter = DecimalFormat("0.#", DecimalFormatSymbols(Locale.EN fun GuidelineSpacingScreen() { LocalMainTopAppBarManager.current.updateTopAppBarTitle(R.string.guideline_spacing) - LazyColumn(contentPadding = PaddingValues(bottom = dimensionResource(id = R.dimen.spacing_m))) { + LazyColumn(contentPadding = PaddingValues(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_m))) { item { DetailScreenHeader( imageRes = DrawableManager.getDrawableResIdForCurrentTheme(resId = R.drawable.il_spacing), @@ -57,13 +57,14 @@ fun GuidelineSpacingScreen() { item { OdsTextSubtitle1( modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) - .padding(vertical = dimensionResource(id = R.dimen.spacing_m)), + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) + .padding(vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), text = stringResource(id = R.string.guideline_spacing_subtitle) ) } items(Spacing.values()) { spacing -> - val dividerStartIndent = dimensionResource(id = R.dimen.guideline_spacing_image_width) + dimensionResource(id = R.dimen.spacing_m).times(2) + val dividerStartIndent = + dimensionResource(id = R.dimen.guideline_spacing_image_width) + dimensionResource(id = com.orange.ods.R.dimen.spacing_m).times(2) val dp = spacing.getDp() val ratio = spacing.getRatio() OdsListItem( diff --git a/app/src/main/java/com/orange/ods/app/ui/guidelines/typography/GuidelineTypographyScreen.kt b/app/src/main/java/com/orange/ods/app/ui/guidelines/typography/GuidelineTypographyScreen.kt index c34db7d8a..7e2666144 100644 --- a/app/src/main/java/com/orange/ods/app/ui/guidelines/typography/GuidelineTypographyScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/guidelines/typography/GuidelineTypographyScreen.kt @@ -46,8 +46,8 @@ fun GuidelineTypographyScreen() { val guidelineTypography = LocalOdsGuideline.current.guidelineTypography LazyColumn( - contentPadding = PaddingValues(bottom = dimensionResource(id = R.dimen.screen_vertical_margin)), - verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)) + contentPadding = PaddingValues(bottom = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)), + verticalArrangement = Arrangement.spacedBy(dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) ) { item { DetailScreenHeader( @@ -59,8 +59,8 @@ fun GuidelineTypographyScreen() { item { OdsTextBody1( modifier = Modifier.padding( - horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin), - vertical = dimensionResource(id = R.dimen.screen_vertical_margin) + horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin), + vertical = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin) ), text = stringResource(id = R.string.guideline_typography_no_typography_defined) ) @@ -71,8 +71,8 @@ fun GuidelineTypographyScreen() { if (index < guidelineTypography.lastIndex) { OdsDivider( modifier = Modifier - .padding(top = dimensionResource(id = R.dimen.spacing_m)) - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) ) } } @@ -85,7 +85,7 @@ private fun TextStyleRow(guidelineTextStyle: GuidelineTextStyle) { val context = LocalContext.current val textColor = OdsTheme.colors.onBackground Column(modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) .semantics(mergeDescendants = true) {}) { Text( text = guidelineTextStyle.name, diff --git a/app/src/main/java/com/orange/ods/app/ui/search/SearchScreen.kt b/app/src/main/java/com/orange/ods/app/ui/search/SearchScreen.kt index 0f89e9829..a9d463c38 100644 --- a/app/src/main/java/com/orange/ods/app/ui/search/SearchScreen.kt +++ b/app/src/main/java/com/orange/ods/app/ui/search/SearchScreen.kt @@ -12,19 +12,27 @@ package com.orange.ods.app.ui.search import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.LiveRegionMode +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.liveRegion +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.unit.dp import com.orange.ods.app.R import com.orange.ods.app.ui.LocalOdsGuideline import com.orange.ods.app.ui.MainDestinations @@ -39,9 +47,9 @@ import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsListItemIcon import com.orange.ods.compose.component.list.OdsListItemIconType import com.orange.ods.compose.component.list.iconType +import com.orange.ods.extension.orElse import com.orange.ods.theme.guideline.GuidelineColor import com.orange.ods.theme.guideline.toHexString -import com.orange.ods.utilities.extension.orElse @Composable fun SearchScreen( @@ -132,6 +140,25 @@ fun SearchScreen( modifier = Modifier .fillMaxWidth() ) { + item { + // The aim of this item is to vocalize the number of search results + // This should be done on LazyColumn with liveRegion and contentDescription, but doing so vocalizes the entire content of the column + // Thus we add the text below in order to vocalize the number of search results only + // The text is not empty with a 1dp height otherwise it is not vocalized, and alpha is set to 0 to make it invisible when navigating with TalkBack + Text(" ", modifier = Modifier + .height(1.dp) + .alpha(0f) + .semantics { + liveRegion = LiveRegionMode.Polite + contentDescription = with(context.resources) { + if (searchResults.isNotEmpty()) { + getQuantityString(R.plurals.search_result_count_content_description, searchResults.count(), searchResults.count()) + } else { + getString(R.string.search_no_result_content_description) + } + } + }) + } items(searchResults) { item -> val openDialog = remember { mutableStateOf(false) } val guidelineColor = filteredGuidelineColors.firstOrNull { guidelineColor -> diff --git a/app/src/main/java/com/orange/ods/app/ui/utilities/DrawableManager.kt b/app/src/main/java/com/orange/ods/app/ui/utilities/DrawableManager.kt index f01350458..65efd2f1a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/utilities/DrawableManager.kt +++ b/app/src/main/java/com/orange/ods/app/ui/utilities/DrawableManager.kt @@ -16,7 +16,7 @@ import androidx.compose.runtime.Composable import com.orange.ods.app.R import com.orange.ods.app.ui.LocalThemeManager import com.orange.ods.app.ui.utilities.extension.isOrange -import com.orange.ods.utilities.extension.orElse +import com.orange.ods.extension.orElse object DrawableManager { @@ -41,7 +41,8 @@ object DrawableManager { R.drawable.il_chips_small_generic to R.drawable.il_chips_small, R.drawable.il_dialogs_generic to R.drawable.il_dialogs, R.drawable.il_fab_generic to R.drawable.il_fab, - R.drawable.il_image_item_generic to R.drawable.il_image_item, + R.drawable.il_image_tile_generic to R.drawable.il_image_tile, + R.drawable.il_list_item_generic to R.drawable.il_list_item, R.drawable.il_lists_generic to R.drawable.il_lists, R.drawable.il_menus_generic to R.drawable.il_menus, R.drawable.il_navigation_drawers_generic to R.drawable.il_navigation_drawers, diff --git a/app/src/main/java/com/orange/ods/app/ui/utilities/composable/CodeImplementation.kt b/app/src/main/java/com/orange/ods/app/ui/utilities/composable/CodeImplementation.kt index 120fd4c1c..e4d101d0a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/utilities/composable/CodeImplementation.kt +++ b/app/src/main/java/com/orange/ods/app/ui/utilities/composable/CodeImplementation.kt @@ -31,7 +31,7 @@ import com.orange.ods.app.ui.UiFramework import com.orange.ods.compose.component.menu.OdsExposedDropdownMenu import com.orange.ods.compose.component.menu.OdsExposedDropdownMenuItem import com.orange.ods.compose.theme.OdsTheme -import com.orange.ods.utilities.extension.orElse +import com.orange.ods.extension.orElse const val IconPainterValue = "" const val ImagePainterValue = "" @@ -74,21 +74,21 @@ private open class FunctionParameter(name: String, val value: Function) : CodePa private class ClassInstanceParameter(name: String, value: ClassInstance) : FunctionParameter(name, with(value) { Function(clazz.simpleName, parameters) }) -private class ListParameter(name: String, val value: List) : CodeParameter(name) { +private class ListParameter(name: String, val value: List) : CodeParameter(name) { override val code get() = @Composable { TechnicalText(text = "$name = listOf(") IndentCodeColumn { value.forEach { item -> - FunctionCallCode(name = item.clazz.simpleName, parameters = item.parameters, trailingComma = true, exhaustiveParameters = true) + FunctionCallCode(name = item.name, parameters = item.parameters, trailingComma = true, exhaustiveParameters = true) } } TechnicalText(text = "),") } } -data class ClassInstance(val clazz: Class<*>, val parameters: ParametersBuilder.() -> Unit = {}) -data class Function(val name: String, val parameters: ParametersBuilder.() -> Unit = {}) +class ClassInstance(val clazz: Class<*>, parameters: ParametersBuilder.() -> Unit = {}) : Function(clazz.simpleName, parameters) +open class Function(val name: String, val parameters: ParametersBuilder.() -> Unit = {}) private sealed class PredefinedParameter { object Icon : SimpleParameter("icon", IconPainterValue) @@ -137,7 +137,7 @@ fun CodeImplementationColumn( Column( modifier = modifier.padding( - vertical = dimensionResource(id = R.dimen.spacing_s) + vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s) ) ) { UiFrameworkChoice(xmlAvailable) @@ -152,7 +152,7 @@ fun CodeImplementationColumn( TechnicalText( modifier = Modifier .fillMaxWidth() - .padding(dimensionResource(id = R.dimen.spacing_xs)), + .padding(dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)), text = stringResource(id = R.string.soon_available) ) } @@ -189,7 +189,7 @@ fun CodeBackgroundColumn(content: @Composable () -> Unit) { Column( modifier = Modifier .background(OdsTheme.colors.onSurface.copy(alpha = 0.12f)) - .padding(horizontal = dimensionResource(id = R.dimen.spacing_s), vertical = dimensionResource(id = R.dimen.spacing_s)) + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_s), vertical = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)) .semantics(mergeDescendants = true) {}) { content() } @@ -197,7 +197,7 @@ fun CodeBackgroundColumn(content: @Composable () -> Unit) { @Composable fun IndentCodeColumn(content: @Composable () -> Unit) { - Column(modifier = Modifier.padding(start = dimensionResource(id = R.dimen.spacing_s))) { + Column(modifier = Modifier.padding(start = dimensionResource(id = com.orange.ods.R.dimen.spacing_s))) { content() } } @@ -260,11 +260,13 @@ annotation class CodeImplementationDslMarker @CodeImplementationDslMarker class ListParameterValueBuilder { - private val classInstances = mutableListOf() + private val functions = mutableListOf() - fun classInstance(clazz: Class<*>, parameters: ParametersBuilder.() -> Unit = {}) = apply { classInstances.add(ClassInstance(clazz, parameters)) } + fun classInstance(clazz: Class<*>, parameters: ParametersBuilder.() -> Unit = {}) = apply { functions.add(ClassInstance(clazz, parameters)) } - fun build() = classInstances.toList() + fun function(functionName: String, parameters: ParametersBuilder.() -> Unit = {}) = apply { functions.add(Function(functionName, parameters)) } + + fun build() = functions.toList() } @CodeImplementationDslMarker diff --git a/app/src/main/java/com/orange/ods/app/ui/utilities/composable/DetailScreenHeader.kt b/app/src/main/java/com/orange/ods/app/ui/utilities/composable/DetailScreenHeader.kt index 45e18ac2e..1ff36e321 100644 --- a/app/src/main/java/com/orange/ods/app/ui/utilities/composable/DetailScreenHeader.kt +++ b/app/src/main/java/com/orange/ods/app/ui/utilities/composable/DetailScreenHeader.kt @@ -26,9 +26,8 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import com.orange.ods.compose.text.OdsTextBody1 -import com.orange.ods.app.R import com.orange.ods.app.ui.components.Component +import com.orange.ods.compose.text.OdsTextBody1 @Composable fun DetailScreenHeader( @@ -48,7 +47,7 @@ fun DetailScreenHeader( ) DetailScreenDescription( modifier = Modifier.padding( - horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin) + horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin) ), descriptionRes = descriptionRes ) @@ -62,7 +61,7 @@ private fun DetailScreenDescription( OdsTextBody1( text = stringResource(descriptionRes), modifier = modifier.padding( - top = dimensionResource(id = R.dimen.spacing_m) + top = dimensionResource(id = com.orange.ods.R.dimen.spacing_m) ) ) } \ No newline at end of file diff --git a/app/src/main/java/com/orange/ods/app/ui/utilities/composable/Texts.kt b/app/src/main/java/com/orange/ods/app/ui/utilities/composable/Texts.kt index ff82b2b95..9f3b66658 100644 --- a/app/src/main/java/com/orange/ods/app/ui/utilities/composable/Texts.kt +++ b/app/src/main/java/com/orange/ods/app/ui/utilities/composable/Texts.kt @@ -37,8 +37,8 @@ fun Title(@StringRes textRes: Int, modifier: Modifier = Modifier, horizontalPadd text = stringResource(textRes), modifier = modifier .fillMaxWidth() - .padding(top = if (topPadding) dimensionResource(R.dimen.spacing_xl) else 0.dp) - .padding(horizontal = if (horizontalPadding) dimensionResource(R.dimen.screen_horizontal_margin) else 0.dp) + .padding(top = if (topPadding) dimensionResource(com.orange.ods.R.dimen.spacing_xl) else 0.dp) + .padding(horizontal = if (horizontalPadding) dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin) else 0.dp) ) } @@ -54,8 +54,8 @@ fun Subtitle(@StringRes textRes: Int, displaySurface: OdsDisplaySurface = OdsDis modifier = Modifier .fillMaxWidth() .background(backgroundColor) - .padding(top = dimensionResource(id = R.dimen.spacing_m)) - .padding(horizontal = if (horizontalPadding) dimensionResource(R.dimen.screen_horizontal_margin) else 0.dp), + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) + .padding(horizontal = if (horizontalPadding) dimensionResource(com.orange.ods.R.dimen.screen_horizontal_margin) else 0.dp), displaySurface = displaySurface ) } diff --git a/app/src/main/res/drawable-hdpi/il_image_item.png b/app/src/main/res/drawable-hdpi/il_image_tile.png similarity index 100% rename from app/src/main/res/drawable-hdpi/il_image_item.png rename to app/src/main/res/drawable-hdpi/il_image_tile.png diff --git a/app/src/main/res/drawable-hdpi/il_image_item_generic.png b/app/src/main/res/drawable-hdpi/il_image_tile_generic.png similarity index 100% rename from app/src/main/res/drawable-hdpi/il_image_item_generic.png rename to app/src/main/res/drawable-hdpi/il_image_tile_generic.png diff --git a/app/src/main/res/drawable-mdpi/il_image_item.png b/app/src/main/res/drawable-mdpi/il_image_tile.png similarity index 100% rename from app/src/main/res/drawable-mdpi/il_image_item.png rename to app/src/main/res/drawable-mdpi/il_image_tile.png diff --git a/app/src/main/res/drawable-mdpi/il_image_item_generic.png b/app/src/main/res/drawable-mdpi/il_image_tile_generic.png similarity index 100% rename from app/src/main/res/drawable-mdpi/il_image_item_generic.png rename to app/src/main/res/drawable-mdpi/il_image_tile_generic.png diff --git a/app/src/main/res/drawable-xhdpi/il_image_item.png b/app/src/main/res/drawable-xhdpi/il_image_tile.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/il_image_item.png rename to app/src/main/res/drawable-xhdpi/il_image_tile.png diff --git a/app/src/main/res/drawable-xhdpi/il_image_item_generic.png b/app/src/main/res/drawable-xhdpi/il_image_tile_generic.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/il_image_item_generic.png rename to app/src/main/res/drawable-xhdpi/il_image_tile_generic.png diff --git a/app/src/main/res/drawable-xxhdpi/il_image_item.png b/app/src/main/res/drawable-xxhdpi/il_image_tile.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/il_image_item.png rename to app/src/main/res/drawable-xxhdpi/il_image_tile.png diff --git a/app/src/main/res/drawable-xxhdpi/il_image_item_generic.png b/app/src/main/res/drawable-xxhdpi/il_image_tile_generic.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/il_image_item_generic.png rename to app/src/main/res/drawable-xxhdpi/il_image_tile_generic.png diff --git a/app/src/main/res/drawable-xxxhdpi/il_image_item.png b/app/src/main/res/drawable-xxxhdpi/il_image_tile.png similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/il_image_item.png rename to app/src/main/res/drawable-xxxhdpi/il_image_tile.png diff --git a/app/src/main/res/drawable-xxxhdpi/il_image_item_generic.png b/app/src/main/res/drawable-xxxhdpi/il_image_tile_generic.png similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/il_image_item_generic.png rename to app/src/main/res/drawable-xxxhdpi/il_image_tile_generic.png diff --git a/app/src/main/res/drawable/il_list_item.xml b/app/src/main/res/drawable/il_list_item.xml new file mode 100644 index 000000000..e51d46726 --- /dev/null +++ b/app/src/main/res/drawable/il_list_item.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/il_list_item_generic.xml b/app/src/main/res/drawable/il_list_item_generic.xml new file mode 100644 index 000000000..e51d46726 --- /dev/null +++ b/app/src/main/res/drawable/il_list_item_generic.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/app/src/main/res/layout/ods_banner.xml b/app/src/main/res/layout/ods_banner.xml index d1ae230a7..8d9eb2d5d 100644 --- a/app/src/main/res/layout/ods_banner.xml +++ b/app/src/main/res/layout/ods_banner.xml @@ -20,11 +20,11 @@ type="String" /> @@ -52,8 +52,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:message="Message displayed in the banner" - app:button1Text="Button 1" - app:button2Text="Button 2" + app:firstButtonText="First button" + app:secondButtonText="Second button" app:imageContentDescription="Content description of the image" /> diff --git a/app/src/main/res/layout/ods_icon_toogle_button.xml b/app/src/main/res/layout/ods_icon_toogle_button.xml index 0b800fe3a..92202af4d 100644 --- a/app/src/main/res/layout/ods_icon_toogle_button.xml +++ b/app/src/main/res/layout/ods_icon_toogle_button.xml @@ -25,7 +25,11 @@ type="android.graphics.drawable.Drawable" /> + + @@ -63,7 +68,8 @@ app:uncheckedIcon="@drawable/ic_add" app:checkedIcon="@drawable/ic_add" app:checked="true" - app:iconContentDescription="Button" + app:uncheckedIconContentDescription="@{uncheckedIconDescription}" + app:checkedIconContentDescription="@{checkedIconDescription}" app:displaySurface="standard" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 844b9f14d..911ed8786 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -76,8 +76,8 @@ Label Caption Thumbnail - Button 1 - Button 2 + First button + Second button Text Avatar Icon @@ -146,6 +146,7 @@ Medium emphasis buttons Low emphasis buttons Functional buttons + Same items weight Full screen width Primary @@ -153,6 +154,7 @@ Functional Positive Negative + Toggle text button group Buttons: Icons @@ -163,7 +165,8 @@ Search Toggle icon button Toggle icon button group - Add to favorites + Add to favorites + Remove from favorites Toggle count Remove toggle Add toggle @@ -218,14 +221,35 @@ Mini Full screen width - - Image Item - An Image Item contains primary information which is usually an image. It can also contain secondary information such as a title or an action. - Image item sizes - Small image - Large image - Overlay - Below + + Image tile + An image tile contains primary information which is usually an image. It can also contain secondary information such as a title or an action. + Image tile sizes + Small image + Large image + Legend area display type + Overlay + Below + + + List item + A list item is the individual element of data entries like text, icons or images that is used to create a list. + List item size + Add line + Remove line + Leading - Before the list text + None + Icon + Circle + Square + Wide + Trailing - After the list text + None + Checkbox + Switch + Icon + Caption + Information Menus @@ -285,27 +309,6 @@ Circular Downloading … - - Lists - A list is a continuous vertical group of data entries like text, icons or images. - List item - List item size - Add line - Remove line - Leading - Before the list text - None - Icon - Circle - Square - Wide - Trailing - After the list text - None - Checkbox - Switch - Icon - Caption - Information - Sheets: bottom Bottom sheets are surfaces anchored to the bottom of the screen that present users supplemental content. @@ -392,5 +395,10 @@ Search Search icon + + There is %1$d result + There are %1$d results + + There are no results \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/prod/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from app/src/main/res/drawable/ic_launcher_foreground.xml rename to app/src/prod/res/drawable/ic_launcher_foreground.xml diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/prod/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to app/src/prod/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/prod/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to app/src/prod/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/prod/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/mipmap-hdpi/ic_launcher.png rename to app/src/prod/res/mipmap-hdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/prod/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from app/src/main/res/mipmap-hdpi/ic_launcher_round.png rename to app/src/prod/res/mipmap-hdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/prod/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/mipmap-mdpi/ic_launcher.png rename to app/src/prod/res/mipmap-mdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/prod/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from app/src/main/res/mipmap-mdpi/ic_launcher_round.png rename to app/src/prod/res/mipmap-mdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/prod/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to app/src/prod/res/mipmap-xhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/prod/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from app/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename to app/src/prod/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/prod/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to app/src/prod/res/mipmap-xxhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/prod/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename to app/src/prod/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/prod/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to app/src/prod/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/prod/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename to app/src/prod/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/prod/res/values/ic_launcher_background.xml similarity index 100% rename from app/src/main/res/values/ic_launcher_background.xml rename to app/src/prod/res/values/ic_launcher_background.xml diff --git a/app/src/qualif/res/drawable-hdpi/ic_launcher_foreground.png b/app/src/qualif/res/drawable-hdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..1218b395a Binary files /dev/null and b/app/src/qualif/res/drawable-hdpi/ic_launcher_foreground.png differ diff --git a/app/src/qualif/res/drawable-xhdpi/ic_launcher_foreground.png b/app/src/qualif/res/drawable-xhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..2b36dc43f Binary files /dev/null and b/app/src/qualif/res/drawable-xhdpi/ic_launcher_foreground.png differ diff --git a/app/src/qualif/res/drawable-xxhdpi/ic_launcher_foreground.png b/app/src/qualif/res/drawable-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..6d96e7383 Binary files /dev/null and b/app/src/qualif/res/drawable-xxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/qualif/res/drawable-xxxhdpi/ic_launcher_foreground.png b/app/src/qualif/res/drawable-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..ece2731b0 Binary files /dev/null and b/app/src/qualif/res/drawable-xxxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/qualif/res/mipmap-hdpi/ic_launcher.png b/app/src/qualif/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..d5c7b9b85 Binary files /dev/null and b/app/src/qualif/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/qualif/res/mipmap-hdpi/ic_launcher_round.png b/app/src/qualif/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 000000000..bf5d3fc98 Binary files /dev/null and b/app/src/qualif/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/qualif/res/mipmap-xhdpi/ic_launcher.png b/app/src/qualif/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..f79fa611a Binary files /dev/null and b/app/src/qualif/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/qualif/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/qualif/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 000000000..9c3ce0fc0 Binary files /dev/null and b/app/src/qualif/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/qualif/res/mipmap-xxhdpi/ic_launcher.png b/app/src/qualif/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..7616ebc4c Binary files /dev/null and b/app/src/qualif/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/qualif/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/qualif/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..f4380dc3b Binary files /dev/null and b/app/src/qualif/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/qualif/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/qualif/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..a4d6fb622 Binary files /dev/null and b/app/src/qualif/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/qualif/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/qualif/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..5131084cc Binary files /dev/null and b/app/src/qualif/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b1a25a7df..ebb1c4248 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -19,14 +19,16 @@ repositories { } java { - // Use Java 8 instead of Java 11 - // See https://github.com/gradle/gradle/issues/18935 - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +kotlin { + jvmToolchain(11) } dependencies { - implementation("com.android.tools.build:gradle:7.3.1") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10") // https://issuetracker.google.com/issues/176079157#comment14 + implementation("com.android.tools.build:gradle:8.1.0") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0") // https://issuetracker.google.com/issues/176079157#comment14 implementation("com.squareup:javapoet:1.13.0") // https://github.com/google/dagger/issues/3282 } diff --git a/buildSrc/src/main/kotlin/com/orange/ods/gradle/Dependencies.kt b/buildSrc/src/main/kotlin/com/orange/ods/gradle/Dependencies.kt index 7f528ced6..771133430 100644 --- a/buildSrc/src/main/kotlin/com/orange/ods/gradle/Dependencies.kt +++ b/buildSrc/src/main/kotlin/com/orange/ods/gradle/Dependencies.kt @@ -23,11 +23,12 @@ object Dependencies { const val browser = "androidx.browser:browser:${Versions.browser}" const val coil = "io.coil-kt:coil:${Versions.coil}" const val coilCompose = "io.coil-kt:coil-compose:${Versions.coil}" - const val composeMaterial = "androidx.compose.material:material:${Versions.compose}" - const val composeMaterial3 = "androidx.compose.material3:material3:${Versions.composeMaterial3}" - const val composeUi = "androidx.compose.ui:ui:${Versions.compose}" - const val composeUiTooling = "androidx.compose.ui:ui-tooling:${Versions.compose}" - const val composeUiToolingPreview = "androidx.compose.ui:ui-tooling-preview:${Versions.compose}" + const val composeBom = "androidx.compose:compose-bom:${Versions.composeBom}" + const val composeMaterial = "androidx.compose.material:material" + const val composeMaterial3 = "androidx.compose.material3:material3" + const val composeUi = "androidx.compose.ui:ui" + const val composeUiTooling = "androidx.compose.ui:ui-tooling" + const val composeUiToolingPreview = "androidx.compose.ui:ui-tooling-preview" const val constraintLayoutCompose = "androidx.constraintlayout:constraintlayout-compose:${Versions.constraintLayoutCompose}" const val coreKtx = "androidx.core:core-ktx:${Versions.core}" const val customViewPoolingContainer = "androidx.customview:customview-poolingcontainer:${Versions.customViewPoolingContainer}" @@ -45,7 +46,6 @@ object Dependencies { const val kotlinGradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}" const val kotlinPoet = "com.squareup:kotlinpoet:${Versions.kotlinPoet}" const val kotlinPoetKsp = "com.squareup:kotlinpoet-ksp:${Versions.kotlinPoet}" - const val kotlinStdlibJdk8 = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Versions.kotlin}" const val ksp = "com.google.devtools.ksp:symbol-processing-api:${Versions.ksp}" const val lifecycleRuntimeKtx = "androidx.lifecycle:lifecycle-runtime-ktx:${Versions.lifecycle}" const val lifecycleViewModelKtx = "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.lifecycle}" diff --git a/buildSrc/src/main/kotlin/com/orange/ods/gradle/MavenCentralPublishPluginExtension.kt b/buildSrc/src/main/kotlin/com/orange/ods/gradle/MavenCentralPublishPluginExtension.kt index 42fa127af..bd2413c54 100644 --- a/buildSrc/src/main/kotlin/com/orange/ods/gradle/MavenCentralPublishPluginExtension.kt +++ b/buildSrc/src/main/kotlin/com/orange/ods/gradle/MavenCentralPublishPluginExtension.kt @@ -13,7 +13,8 @@ package com.orange.ods.gradle abstract class MavenCentralPublishPluginExtension { companion object { - const val Name = "mavenCentralPublish" + const val NAME = "mavenCentralPublish" + const val VARIANT = "prodRelease" } var artifactId: String? = null diff --git a/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt b/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt index 497dc0aeb..ad21858f2 100644 --- a/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt +++ b/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt @@ -18,11 +18,11 @@ object Versions { const val accompanist = "0.28.0" const val activity = "1.6.1" - const val androidGradlePlugin = "7.3.1" + const val androidGradlePlugin = "8.1.0" const val appCompat = "1.5.1" const val browser = "1.4.0" - const val compose = "1.3.1" //TODO: When upgrading, see TODO in OdsOutlinedTextField.kt - const val composeMaterial3 = "1.0.1" + const val composeBom = "2023.06.01" + const val composeCompiler = "1.5.1" const val coil = "2.2.2" const val constraintLayoutCompose = "1.0.1" const val core = "1.9.0" @@ -32,11 +32,11 @@ object Versions { const val firebaseBom = "31.1.1" const val firebaseCrashlyticsGradlePlugin = "2.9.2" const val googleServicesGradlePlugin = "4.3.14" - const val hilt = "2.44" + const val hilt = "2.47" const val jUnit = "4.13.2" - const val kotlin = "1.7.10" + const val kotlin = "1.9.0" const val kotlinPoet = "1.12.0" - const val ksp = "$kotlin-1.0.6" + const val ksp = "$kotlin-1.0.13" const val lifecycle = "2.5.1" const val material = "1.7.0" const val navigation = "2.5.3" diff --git a/buildSrc/src/main/kotlin/firebase.gradle.kts b/buildSrc/src/main/kotlin/firebase.gradle.kts index 8d3f94623..bea69167d 100644 --- a/buildSrc/src/main/kotlin/firebase.gradle.kts +++ b/buildSrc/src/main/kotlin/firebase.gradle.kts @@ -30,7 +30,7 @@ internal val Project.appDistributionVariants: List * An array containing tasks to execute for Firebase App Distribution deployment */ internal val appDistributionTasks: List - get() = appDistributionVariants.map { tasks["appDistributionUpload${it.capitalize()}"] } + get() = appDistributionVariants.map { variant -> tasks["appDistributionUpload${variant.replaceFirstChar { it.uppercaseChar() }}"] } /** * The git tag prefix for Firebase App Distribution uploads @@ -44,7 +44,7 @@ internal val Project.gitTagPrefix: String tasks.register("appDistributionUpload") { dependsOn( // Assemble and generate release notes first - *appDistributionVariants.map { tasks["assemble${it.capitalize()}"] }.toTypedArray(), + *appDistributionVariants.map { variant -> tasks["assemble${variant.replaceFirstChar { it.uppercaseChar() }}"] }.toTypedArray(), tasks["generateAppDistributionReleaseNotes"] ) diff --git a/buildSrc/src/main/kotlin/library.gradle.kts b/buildSrc/src/main/kotlin/library.gradle.kts new file mode 100644 index 000000000..fb1b6c91b --- /dev/null +++ b/buildSrc/src/main/kotlin/library.gradle.kts @@ -0,0 +1,52 @@ +/* + * + * 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. + * / + */ + +import com.orange.ods.gradle.MavenCentralPublishPluginExtension +import com.orange.ods.gradle.Versions + +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") + id("maven-central-publish") +} + +android { + compileSdk = Versions.compileSdk + + defaultConfig { + minSdk = Versions.minSdk + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFile("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), file("proguard-rules.pro")) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = "11" + allWarningsAsErrors = true + } + + publishing { + singleVariant(MavenCentralPublishPluginExtension.VARIANT) { + withSourcesJar() + withJavadocJar() + } + } +} diff --git a/buildSrc/src/main/kotlin/maven-central-publish.gradle.kts b/buildSrc/src/main/kotlin/maven-central-publish.gradle.kts index e0b3d16b4..d033d1526 100644 --- a/buildSrc/src/main/kotlin/maven-central-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/maven-central-publish.gradle.kts @@ -18,23 +18,22 @@ plugins { } val pluginExtension: MavenCentralPublishPluginExtension? - get() = extensions.findByName(MavenCentralPublishPluginExtension.Name) as? MavenCentralPublishPluginExtension? + get() = extensions.findByName(MavenCentralPublishPluginExtension.NAME) as? MavenCentralPublishPluginExtension? apply { if (pluginExtension == null) { - extensions.create(MavenCentralPublishPluginExtension.Name) + extensions.create(MavenCentralPublishPluginExtension.NAME) } } afterEvaluate { publishing { publications { - create("release") { + create(MavenCentralPublishPluginExtension.VARIANT) { from(components["release"]) groupId = "com.orange.ods.android" artifactId = pluginExtension?.artifactId ?: "ods-${project.name}" this.version = version - artifact(tasks["sourcesJar"]) pom { name.set(artifactId) @@ -87,11 +86,6 @@ afterEvaluate { "GNUPG_SIGNING_PASSWORD" ) useInMemoryPgpKeys(signingKeyId, signingSecretKey, signingPassword) - sign(publishing.publications["release"]) + sign(publishing.publications[MavenCentralPublishPluginExtension.VARIANT]) } } - -tasks.register("sourcesJar") { - archiveClassifier.set("sources") - from(android.sourceSets.getByName("main").java.srcDirs) -} diff --git a/changelog.md b/changelog.md index ea01ea21c..da285f31c 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,37 @@ All notable changes done in ODS library will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.15.0](https://github.com/Orange-OpenSource/ods-android/compare/0.14.0...0.15.0) - 2023-09-12 + +### Added + +- \[App\] Add list item component ([#555](https://github.com/Orange-OpenSource/ods-android/issues/555)) +- \[App\] Add toggle text buttons group component ([#530](https://github.com/Orange-OpenSource/ods-android/issues/530)) +- \[Lib\] Add `OdsTextToggleButtonsRow` component ([#530](https://github.com/Orange-OpenSource/ods-android/issues/530)) + +### Changed + +- \[All\] Use Compose BOM and update Kotlin and Gradle versions ([#578](https://github.com/Orange-OpenSource/ods-android/issues/578)) +- \[Lib\] Replace composable parameter of `OdsDropdownMenu` with a list of `OdsDropdownMenuItem` ([#572](https://github.com/Orange-OpenSource/ods-android/issues/572)) +- \[Lib\] Update `OdsTopAppBar` and `OdsLargeTopAppBar` APIs ([#572](https://github.com/Orange-OpenSource/ods-android/issues/572)) +- \[Lib\] Update `OdsBottomNavigation` API ([#588](https://github.com/Orange-OpenSource/ods-android/issues/588)) +- \[Lib\] Update `OdsBanner` API ([#592](https://github.com/Orange-OpenSource/ods-android/issues/592)) +- \[Lib\] Update `OdsButton`, `OdsOutlinedButton`and `OdsTextButton` APIs ([#596](https://github.com/Orange-OpenSource/ods-android/issues/596)) +- \[Lib\] Update `OdsIconButton`, `OdsIconToggleButton`and `OdsIconToggleButtonsRow` APIs ([#599](https://github.com/Orange-OpenSource/ods-android/issues/599)) +- \[Lib\] Update `OdsAlertDialog` API ([#605](https://github.com/Orange-OpenSource/ods-android/issues/605)) +- \[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 + +- \[App\] Screen displayed on filter chip variant click was not the good one ([#580](https://github.com/Orange-OpenSource/ods-android/issues/580)) +- \[App\] Fix a bug where `OdsListItem` text color did not update when switching between light and dark modes in text field demo ([#578](https://github.com/Orange-OpenSource/ods-android/issues/578)) +- \[App\] The number of search results is now vocalized ([#506](https://github.com/Orange-OpenSource/ods-android/issues/506)) +- \[Lib\] Vocalize exposed dropdown menu content as a group ([#560](https://github.com/Orange-OpenSource/ods-android/issues/560)) +- \[Lib\] Fix `OdsTextField` content color in dark mode ([#621](https://github.com/Orange-OpenSource/ods-android/issues/621)) + ## [0.14.0](https://github.com/Orange-OpenSource/ods-android/compare/0.13.0...0.14.0) - 2023-07-12 ### Added @@ -27,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - \[Lib\] Fix a bug where `enabled` property of `OdsIconToggleButtonsRowItem` has no effect ([#329](https://github.com/Orange-OpenSource/ods-android/issues/329)) +- \[Lib\] Vocalize icon toggle button state change in `OdsIconToggleButtonsRow` component ([#567](https://github.com/Orange-OpenSource/ods-android/issues/567)) ## [0.13.0](https://github.com/Orange-OpenSource/ods-android/compare/0.12.0...0.13.0) - 2023-06-01 diff --git a/composable-processor/build.gradle.kts b/composable-processor/build.gradle.kts index 1a742e9f2..b62279963 100644 --- a/composable-processor/build.gradle.kts +++ b/composable-processor/build.gradle.kts @@ -12,7 +12,7 @@ import com.orange.ods.gradle.Dependencies plugins { kotlin("jvm") - id("com.google.devtools.ksp") version "1.7.10-1.0.6" + id("com.google.devtools.ksp") version "1.9.0-1.0.13" } sourceSets.main { diff --git a/docs/0.15.0/404.html b/docs/0.15.0/404.html new file mode 100644 index 000000000..dd331eb8e --- /dev/null +++ b/docs/0.15.0/404.html @@ -0,0 +1,26 @@ +--- +permalink: /404.html +layout: default +--- + + + +
+

404

+ +

Page not found :(

+

The requested page could not be found.

+
\ No newline at end of file diff --git a/docs/0.15.0/components/AppBarsBottom.md b/docs/0.15.0/components/AppBarsBottom.md new file mode 100644 index 000000000..c78807e84 --- /dev/null +++ b/docs/0.15.0/components/AppBarsBottom.md @@ -0,0 +1,167 @@ +--- +layout: detail +title: "App bars: bottom" +description: A bottom app bar displays navigation and key actions at the bottom of mobile screens. +--- + +--- + +**Page Summary** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) +* [Component specific tokens](#component-specific-tokens) + +--- + +## Specifications references + +- [Design System Manager - App bars](https://system.design.orange.com/0c1af118d/p/23e0e6-app-bars/b/620966) +- [Material Design - App bars: bottom](https://material.io/components/app-bars-bottom) +- *Technical documentation soon available* + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/) + +Android's bottom app bar component APIs provide support for the navigation icon, +action items, overflow menu and more for informing the user as to what each +action performs. While optional, their use is strongly encouraged. + +**Content descriptions** + +When using icons for navigation icons, action items and other elements of bottom +app bars, you should set a content description on them so that screen readers +like TalkBack are able to announce their purpose or action, if any. + +For an overall content description of the bottom app bar, set an +`android:contentDescription` or use the `setContentDescription` method on the +`BottomAppBar`. + +For the navigation icon, this can be achieved via the +`app:navigationContentDescription` attribute or +`setNavigationContentDescription` method. + +For action items and items within the overflow menu, the content description +needs to be set in the menu: + +```xml + + + + +``` + +## Implementation + +Bottom app bars provide access to a bottom navigation drawer and up to four +actions, including the floating action button. + +> **Jetpack Compose implementation** + +*Not available yet* + +> **XML implementation** + +API and source code: + +* `CoordinatorLayout`: [Class definition](https://developer.android.com/reference/androidx/coordinatorlayout/widget/CoordinatorLayout) +* `BottomAppBar`: [Class definition](https://developer.android.com/reference/com/google/android/material/bottomappbar/BottomAppBar), [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/bottomappbar/BottomAppBar.java) +* `FloatingActionButton`: [Class definition](https://developer.android.com/reference/com/google/android/material/floatingactionbutton/FloatingActionButton), [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/floatingactionbutton/FloatingActionButton.java) + +In the layout: + +```xml + + + + + + + + + + + + + + +``` + +In `menu/bottom_app_bar.xml`: + +```xml + + + + + + + +``` + +In menu/navigation icon drawables: + +```xml + + +``` + +In code: + +```kotlin +bottomAppBar.setNavigationOnClickListener { + // Handle navigation icon press +} + +bottomAppBar.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.search -> { + // Handle search icon press + true + } + R.id.more -> { + // Handle more item (inside overflow menu) press + true + } + else -> false + } +} +``` + +## Component specific tokens + +_Soon available_ diff --git a/docs/0.15.0/components/AppBarsBottom_docs.md b/docs/0.15.0/components/AppBarsBottom_docs.md new file mode 100644 index 000000000..4566c033f --- /dev/null +++ b/docs/0.15.0/components/AppBarsBottom_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: AppBarsBottom.md +--- \ No newline at end of file diff --git a/docs/0.15.0/components/AppBarsTop.md b/docs/0.15.0/components/AppBarsTop.md new file mode 100644 index 000000000..b51fb0d83 --- /dev/null +++ b/docs/0.15.0/components/AppBarsTop.md @@ -0,0 +1,323 @@ +--- +layout: detail +title: "App bars: top" +description: Top app bars display information and actions relating to the current screen. +--- + +--- + +**Page Summary** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Regular top app bar](#regular-top-app-bar) + * [Large top app bar](#large-top-app-bar) +* [Extras](#extras) + * [Overflow menu](#overflow-menu) +* [Component specific tokens](#component-specific-tokens) + +--- + +## Specifications references + +- [Design System Manager - App bars](https://system.design.orange.com/0c1af118d/p/23e0e6-app-bars/b/620966) +- [Material Design - App bars: top](https://material.io/components/app-bars-top/) +- Technical documentation soon available + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/) + +Android's top app bar component APIs provide support for the navigation icon, +action items, overflow menu and more for informing the user as to what each +action performs. While optional, their use is strongly encouraged. + +**Content descriptions** + +When using icons for navigation icons, action items and other elements of top +app bars, you should set a content description on them so that screen readers +like TalkBack are able to announce their purpose or action, if any. + +For an overall content description of the top app bar, set an +`android:contentDescription` or use the `setContentDescription` method on the +`MaterialToolbar`. + +For the navigation icon, this can be achieved via the +`app:navigationContentDescription` attribute or +`setNavigationContentDescription` method. + +For action items and items within the overflow menu, the content description +needs to be set in the menu: + +```xml + + + + + +``` + +For images within top app bars, set an `android:contentDescription` +or use the `setContentDescription` method on the `ImageView`. + +## Variants + +### Regular top app bar + +> **Jetpack Compose implementation** + +Add `OdsTopAppBar` composable to your Scaffold topBar: + +```kotlin +OdsTopAppBar( + title = "Title", + navigationIcon = OdsTopAppBarNavigationIcon( + painter = painterResource(id = R.drawable.ic_back), + contentDescription = "content description", + onClick = { /* Do something */ } + ), + actions = listOf( + OdsTopAppBarActionButton( + painter = painterResource(id = R.drawable.ic_share), + contentDescription = "content description", + onClick = { } + ), + // ... + ), + overflowMenuActions = listOf( + OdsTopAppBarOverflowMenuActionItem( + text = "Text", + onClick = { } + ), + // ... + ) +) +``` + +Note: By default, the `OdsTopAppBar` is elevated but you can set `elevated` parameter to `false` if you don't want any shadow below it (for example if you want to display tabs below). + +> **XML implementation** + +API and source code: + +* `CoordinatorLayout`: [Class definition](https://developer.android.com/reference/androidx/coordinatorlayout/widget/CoordinatorLayout) +* `AppBarLayout`: [Class definition](https://developer.android.com/reference/com/google/android/material/appbar/AppBarLayout), [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/appbar/AppBarLayout.java) +* `MaterialToolbar`: [Class definition](https://developer.android.com/reference/com/google/android/material/appbar/MaterialToolbar), [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/appbar/MaterialToolbar.java) +* `CollapsingToolbarLayout`: [Class definition](https://developer.android.com/reference/com/google/android/material/appbar/CollapsingToolbarLayout), [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/appbar/CollapsingToolbarLayout.java) + +In the layout: + +```xml + + + + + + + + + + + + + + + + + +``` + +In `@menu/top_app_bar.xml`: + +```xml + + + + + + + + + + +``` + +In menu/navigation icons: + +```xml + + +``` + +In code: + +```kotlin +topAppBar.setNavigationOnClickListener { + // Handle navigation icon press +} + +topAppBar.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.favorite -> { + // Handle favorite icon press + true + } + R.id.search -> { + // Handle search icon press + true + } + R.id.more -> { + // Handle more item (inside overflow menu) press + true + } + else -> false + } +} +``` + +_**Applying scrolling behavior to the top app bar**_ + +The following example shows the top app bar positioned at the same elevation as +content. Upon scroll, it increases elevation and lets content scroll behind it. + +In the layout: + +```xml + + + + + + + + + + +``` + +_**Raised top app bar**_ + +If you need to have a top app bar with some elevation you can set the `@style/Widget.Orange.Toolbar.Raised` + +```xml + + + + + + + + + + +``` + +### Large top app bar + +> **Jetpack Compose implementation** + +First, you have to add this line in your application `build.gradle.kts` file cause this component relies on Compose Material 3 implementation: + +```kotlin +implementation("androidx.compose.material3:material3:") +``` + +Then you can add `OdsLargeTopAppBar` composable to your Scaffold topBar: + +```kotlin +OdsLargeTopAppBar( + title = "Title", + navigationIcon = OdsTopAppBarNavigationIcon( + painter = painterResource(id = R.drawable.ic_back), + contentDescription = "content description", + onClick = { /* Do something */ } + ), + actions = listOf( + OdsTopAppBarActionButton( + painter = painterResource(id = R.drawable.ic_share), + contentDescription = "content description", + onClick = { } + ), + // ... + ), + overflowMenuActions = listOf( + OdsTopAppBarOverflowMenuActionItem( + text = "Text", + onClick = { } + ), + // ... + ) + scrollBehavior = null // See below to attach a scroll behavior and make the top app bar collapsible +) +``` + +If you want a collapsible large top app bar, you can follow these steps: + +1 - Define the scroll behavior to use: + +```kotlin +val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()) +``` + +2 - Provide this `scrollBehavior` to the `OdsLargeTopAppBar` and as a modifier of your Scaffold in order to listen to the scroll event + +```kotlin +Scaffold( + modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), + topBar = { + OdsLargeTopAppBar( + //... + scrollBehavior = scrollBehavior, + ) + }, + //... +) { + // Scaffold content +} +``` + +## Extras + +### Overflow menu + +![Overflow menu light](images/app_bar_top_overflow_menu_light.png) +![Overflow menu dark](images/app_bar_top_overflow_menu_dark.png) + +You can easily add an overflow menu to your top app bar by using the `OdsTopAppBarOverflowMenuBox` composable as follow: + +```kotlin +OdsTopAppBarOverflowMenuBox(overflowIconContentDescription = "more actions") { + OdsDropdownMenuItem( + text = "account", + onClick = { + // Do something + } + ) + OdsDropdownMenuItem( + text = "settings", + onClick = { + // Do something + } + ) +} +``` + +## Component specific tokens + +_Soon available_ diff --git a/docs/0.15.0/components/AppBarsTop_docs.md b/docs/0.15.0/components/AppBarsTop_docs.md new file mode 100644 index 000000000..1afad632b --- /dev/null +++ b/docs/0.15.0/components/AppBarsTop_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: AppBarsTop.md +--- \ No newline at end of file diff --git a/docs/0.15.0/components/Banners.md b/docs/0.15.0/components/Banners.md new file mode 100644 index 000000000..5311c240a --- /dev/null +++ b/docs/0.15.0/components/Banners.md @@ -0,0 +1,66 @@ +--- +layout: detail +title: Banners +description: Banners displays an important message which requires an action to be dismissed. +--- + +A banner displays an important, succinct message, and provides actions for users to address (or dismiss the banner). +It requires a user action to be dismissed. + +Banners should be displayed at the top of the screen, below a top app bar. They’re persistent and nonmodal, allowing the user to either ignore them or interact with them at any time. +Only one banner should be shown at a time + +--- + +**Page Summary** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Implementation](#implementation) +* [Component specific tokens](#component-specific-tokens) + +--- + +## Specifications references + +- [Design System Manager - Banners](https://system.design.orange.com/0c1af118d/p/19a040-banners/b/497b77) +- [Material Design - Banners](https://m2.material.io/components/banners) +- Technical documentation soon available + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/) + +Users should be able to use the left phone buttons to interact with the banner. +The user should be able to hear the current state of the banner at all times. +Recommendation is available at the Orange Accessibility site + +## Implementation + +![Banner light](images/banner_light.png) + +![Banner dark](images/banner_dark.png) + +> **Jetpack Compose implementation** + +You can use the `OdsBanner` composable like this: + +```kotlin +OdsBanner( + message = "Message displayed in the banner.", + button1Text = "Dismiss", + button2Text = "Detail", // Optional + image = painterResource(id = R.drawable.placeholder), // Optional + imageContentDescription = "", // Optional + onButton1Click = { + // Do something + }, + onButton2Click = { + // Do something + }, // Optional +) +``` + +## Component specific tokens + +_Soon available_ \ No newline at end of file diff --git a/docs/0.15.0/components/Banners_docs.md b/docs/0.15.0/components/Banners_docs.md new file mode 100644 index 000000000..78ed1c027 --- /dev/null +++ b/docs/0.15.0/components/Banners_docs.md @@ -0,0 +1,4 @@ +--- +layout: main +content_page: Banners.md +--- \ No newline at end of file diff --git a/docs/0.15.0/components/Buttons.md b/docs/0.15.0/components/Buttons.md new file mode 100644 index 000000000..269a6776a --- /dev/null +++ b/docs/0.15.0/components/Buttons.md @@ -0,0 +1,346 @@ +--- +layout: detail +title: Buttons +description: Buttons allow users to take actions, and make choices, with a single tap. +--- + +--- + +**Page Summary** + +* [Specifications references](#specifications-references) +* [Accessibility](#accessibility) +* [Variants](#variants) + * [Text button](#text-button) + * [Outlined button](#outlined-button) + * [Contained button](#contained-button) + * [Text toggle buttons group](#text-toggle-buttons-group) + * [Icon button](#icon-button) + * [Icon toggle button](#icon-toggle-button) + * [Icon toggle buttons group](#icon-toggle-buttons-group) +* [Component specific tokens](#component-specific-tokens) + +--- + +## Specifications references + +- [Design System Manager - Buttons](https://system.design.orange.com/0c1af118d/p/06a393-buttons/b/530521) +- [Material Design - Buttons](https://material.io/components/buttons/) +- Technical documentation soon available + +## Accessibility + +Please follow [accessibility criteria for development](https://a11y-guidelines.orange.com/en/mobile/android/development/) + +Buttons support content labeling for accessibility and are readable by most screen readers, such as +TalkBack. Text rendered in buttons is automatically provided to accessibility services. Additional +content labels are usually unnecessary. + +## Variants + +### Text button + +Text buttons are typically used for less-pronounced actions, including those located in dialogs and +cards. In cards, text buttons help maintain an emphasis on card content. + +![TextButton](images/button_text_light.png) ![TextButton dark](images/button_text_dark.png) + +> **Jetpack Compose implementation** + +Use the `OdsTextButton` composable: + +```kotlin +OdsTextButton( + text = "Text button", + onClick = {}, + enabled = true, + icon = OdsButtonIcon(painterResource(R.drawable.ic_coffee)), // Optional, line can be removed if you don't need any icon + style = OdsTextButtonStyle.Primary +) +``` + +> **XML implementation** + +To create a Text Button using Orange theme you will need to apply +style `@style/Widget.Orange.Button.Text` on your `Button` layout + +In the layout: + +```xml + +