From b807dcb60312f0a2825991359f3c95064cb84b3c Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 13 Jul 2023 11:29:07 +0200 Subject: [PATCH 001/132] [#575] Add Maven Central publish plugin to lib-xml module --- lib-xml/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib-xml/build.gradle.kts b/lib-xml/build.gradle.kts index db6c95801..2bd7ecb87 100644 --- a/lib-xml/build.gradle.kts +++ b/lib-xml/build.gradle.kts @@ -15,6 +15,7 @@ plugins { id("com.android.library") id("kotlin-android") id("kotlin-kapt") + id("maven-central-publish") } android { From 281e2d2726501458ee939ae4b1ffb5948d8e0705 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 13 Jul 2023 11:56:44 +0200 Subject: [PATCH 002/132] [#575] Fix release documentation --- release/RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/RELEASE.md b/release/RELEASE.md index 458bf0b51..0a026a3f6 100644 --- a/release/RELEASE.md +++ b/release/RELEASE.md @@ -117,7 +117,7 @@ This file lists all the steps to follow when releasing a new version of ODS Andr - Progress through the various submission steps. -- When step is `Store submissions`, select `Closed beta with Google Groups`, set `Email addresses` to `odsapp@googlegroups.com` and click `Go to store submission`. +- When step is `Store submissions`, select `Closed beta with Google Groups`, set `Email addresses` to `odsapp@googlegroups.com` and click `Go for store submission`. ![OMA Portal store submission](images/google_play_store_release_02.png)

From 11066e5e18fde0cb0a8ba19821a4a9ec61e2d0a9 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 13 Jul 2023 11:58:28 +0200 Subject: [PATCH 003/132] [#575] Use the new Maven publishing DSL --- lib-xml/build.gradle.kts | 7 +++++++ lib/build.gradle.kts | 7 +++++++ theme-contract/build.gradle.kts | 7 +++++++ theme-innovation-cup/build.gradle.kts | 7 +++++++ theme-orange/build.gradle.kts | 7 +++++++ 5 files changed, 35 insertions(+) diff --git a/lib-xml/build.gradle.kts b/lib-xml/build.gradle.kts index 2bd7ecb87..68c4c45b1 100644 --- a/lib-xml/build.gradle.kts +++ b/lib-xml/build.gradle.kts @@ -54,6 +54,13 @@ android { composeOptions { kotlinCompilerExtensionVersion = Versions.compose } + + publishing { + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } + } } dependencies { diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 8d5946c6c..19da5cde2 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -68,6 +68,13 @@ android { sourceSets.configureEach { java.srcDir("$buildDir/generated/ksp/$name/kotlin/") } + + publishing { + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } + } } dependencies { diff --git a/theme-contract/build.gradle.kts b/theme-contract/build.gradle.kts index b1ee84df8..c7f076513 100644 --- a/theme-contract/build.gradle.kts +++ b/theme-contract/build.gradle.kts @@ -49,6 +49,13 @@ android { composeOptions { kotlinCompilerExtensionVersion = Versions.compose } + + publishing { + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } + } } dependencies { diff --git a/theme-innovation-cup/build.gradle.kts b/theme-innovation-cup/build.gradle.kts index 14064b313..936fc757c 100644 --- a/theme-innovation-cup/build.gradle.kts +++ b/theme-innovation-cup/build.gradle.kts @@ -45,6 +45,13 @@ android { jvmTarget = "11" allWarningsAsErrors = true } + + publishing { + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } + } } dependencies { diff --git a/theme-orange/build.gradle.kts b/theme-orange/build.gradle.kts index 655a5220d..49502144a 100644 --- a/theme-orange/build.gradle.kts +++ b/theme-orange/build.gradle.kts @@ -56,6 +56,13 @@ android { composeOptions { kotlinCompilerExtensionVersion = Versions.compose } + + publishing { + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } + } } dependencies { From 1cbda2eb6f2805fd4c92cea5433f2fa7f710a42e Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 13 Jul 2023 15:52:39 +0200 Subject: [PATCH 004/132] [#575] Refactor build.gradle files --- app/build.gradle.kts | 42 ++++++------- .../MavenCentralPublishPluginExtension.kt | 3 +- buildSrc/src/main/kotlin/library.gradle.kts | 53 ++++++++++++++++ .../kotlin/maven-central-publish.gradle.kts | 16 ++--- lib-xml/build.gradle.kts | 39 +----------- lib/build.gradle.kts | 51 ++-------------- theme-contract/build.gradle.kts | 38 +----------- theme-innovation-cup/build.gradle.kts | 46 +------------- theme-orange/build.gradle.kts | 60 +------------------ 9 files changed, 90 insertions(+), 258 deletions(-) create mode 100644 buildSrc/src/main/kotlin/library.gradle.kts diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ff1c70991..b93dd94a7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -112,38 +112,32 @@ dependencies { implementation(project(":lib-xml")) implementation(project(":theme-innovation-cup")) - implementation(Dependencies.composeMaterial3) - implementation(Dependencies.coreKtx) - implementation(Dependencies.kotlinReflect) + implementation(Dependencies.accompanistFlowLayout) + implementation(Dependencies.accompanistPager) + implementation(Dependencies.accompanistPagerIndicators) + implementation(Dependencies.accompanistSystemUiController) + implementation(Dependencies.activityCompose) implementation(Dependencies.appCompat) - implementation(Dependencies.material) + implementation(Dependencies.browser) + implementation(Dependencies.coil) + implementation(Dependencies.coilCompose) + 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/buildSrc/src/main/kotlin/com/orange/ods/gradle/MavenCentralPublishPluginExtension.kt b/buildSrc/src/main/kotlin/com/orange/ods/gradle/MavenCentralPublishPluginExtension.kt index 42fa127af..d798f1c44 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 RELEASE_COMPONENT_NAME = "release" } var artifactId: String? = null diff --git a/buildSrc/src/main/kotlin/library.gradle.kts b/buildSrc/src/main/kotlin/library.gradle.kts new file mode 100644 index 000000000..44e62dc7d --- /dev/null +++ b/buildSrc/src/main/kotlin/library.gradle.kts @@ -0,0 +1,53 @@ +/* + * + * 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 +import gradle.kotlin.dsl.accessors._ecf15b363eddec123ebdbce713433fa8.android + +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.RELEASE_COMPONENT_NAME) { + 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..fdf45facb 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") { - from(components["release"]) + create(MavenCentralPublishPluginExtension.RELEASE_COMPONENT_NAME) { + from(components[MavenCentralPublishPluginExtension.RELEASE_COMPONENT_NAME]) 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.RELEASE_COMPONENT_NAME]) } } - -tasks.register("sourcesJar") { - archiveClassifier.set("sources") - from(android.sourceSets.getByName("main").java.srcDirs) -} diff --git a/lib-xml/build.gradle.kts b/lib-xml/build.gradle.kts index 68c4c45b1..c0ddbe4ba 100644 --- a/lib-xml/build.gradle.kts +++ b/lib-xml/build.gradle.kts @@ -12,39 +12,11 @@ import com.orange.ods.gradle.Dependencies import com.orange.ods.gradle.Versions plugins { - id("com.android.library") - id("kotlin-android") + id("library") id("kotlin-kapt") - 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 - freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn" - } - buildFeatures { compose = true viewBinding = true @@ -54,22 +26,15 @@ android { composeOptions { kotlinCompilerExtensionVersion = Versions.compose } - - publishing { - singleVariant("release") { - withSourcesJar() - withJavadocJar() - } - } } dependencies { implementation(project(":lib")) implementation(Dependencies.accompanistDrawablePainter) + implementation(Dependencies.appCompat) implementation(Dependencies.composeMaterial) implementation(Dependencies.composeUi) - implementation(Dependencies.kotlinStdlibJdk8) testImplementation(Dependencies.jUnit) androidTestImplementation(Dependencies.testExtJUnit) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 19da5cde2..8ee79887e 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -13,10 +13,8 @@ import com.orange.ods.gradle.Versions plugins { id("com.google.devtools.ksp") version "1.7.10-1.0.6" - id("com.android.library") - id("kotlin-android") + id("library") id("github") - id("maven-central-publish") id("kotlin-parcelize") } @@ -28,33 +26,8 @@ plugins { val previewThemeConfigurationClass = "com.orange.ods.theme.orange.OrangeThemeConfiguration" android { - compileSdk = Versions.compileSdk - defaultConfig { - minSdk = Versions.minSdk - buildConfigField("com.orange.ods.theme.OdsThemeConfigurationContract", "PREVIEW_THEME_CONFIGURATION", "new $previewThemeConfigurationClass()") - - 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 - freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn" } buildFeatures { @@ -68,39 +41,27 @@ android { sourceSets.configureEach { java.srcDir("$buildDir/generated/ksp/$name/kotlin/") } - - publishing { - singleVariant("release") { - withSourcesJar() - withJavadocJar() - } - } } dependencies { + compileOnly(project(":composable-processor")) + ksp(project(":composable-processor")) api(project(":theme-contract")) api(project(":theme-orange")) - api(Dependencies.composeMaterial) - - implementation(Dependencies.composeMaterial3) - - implementation(Dependencies.kotlinStdlibJdk8) - implementation(Dependencies.kotlinReflect) - compileOnly(project(":composable-processor")) implementation(Dependencies.accompanistFlowLayout) implementation(Dependencies.appCompat) + api(Dependencies.composeMaterial) + implementation(Dependencies.composeMaterial3) implementation(Dependencies.composeUi) implementation(Dependencies.composeUiTooling) implementation(Dependencies.composeUiToolingPreview) + implementation(Dependencies.constraintLayoutCompose) implementation(Dependencies.coreKtx) implementation(Dependencies.customViewPoolingContainer) // This dependency is needed otherwise the compose preview does not work properly implementation(Dependencies.kotlinReflect) implementation(Dependencies.lifecycleRuntimeKtx) - implementation(Dependencies.constraintLayoutCompose) testImplementation(Dependencies.jUnit) androidTestImplementation(Dependencies.testExtJUnit) - - ksp(project(":composable-processor")) } diff --git a/theme-contract/build.gradle.kts b/theme-contract/build.gradle.kts index c7f076513..8d9b838d1 100644 --- a/theme-contract/build.gradle.kts +++ b/theme-contract/build.gradle.kts @@ -11,37 +11,10 @@ import com.orange.ods.gradle.Versions plugins { - id("com.android.library") - id("org.jetbrains.kotlin.android") - id("maven-central-publish") + id("library") } android { - compileSdk = Versions.compileSdk - - defaultConfig { - minSdk = Versions.minSdk - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - kotlinOptions { - jvmTarget = "11" - allWarningsAsErrors = true - } - buildFeatures { compose = true } @@ -49,18 +22,9 @@ android { composeOptions { kotlinCompilerExtensionVersion = Versions.compose } - - publishing { - singleVariant("release") { - withSourcesJar() - withJavadocJar() - } - } } dependencies { - implementation(com.orange.ods.gradle.Dependencies.coreKtx) - implementation(com.orange.ods.gradle.Dependencies.appCompat) implementation(com.orange.ods.gradle.Dependencies.material) implementation(com.orange.ods.gradle.Dependencies.composeMaterial) implementation(com.orange.ods.gradle.Dependencies.kotlinReflect) diff --git a/theme-innovation-cup/build.gradle.kts b/theme-innovation-cup/build.gradle.kts index 936fc757c..1bcbbd69b 100644 --- a/theme-innovation-cup/build.gradle.kts +++ b/theme-innovation-cup/build.gradle.kts @@ -9,62 +9,18 @@ */ import com.orange.ods.gradle.Dependencies -import com.orange.ods.gradle.Versions plugins { - id("com.android.library") - id("org.jetbrains.kotlin.android") + id("library") id("kotlin-kapt") id("dagger.hilt.android.plugin") id("kotlin-parcelize") - id("maven-central-publish") -} - -android { - compileSdk = Versions.compileSdk - - defaultConfig { - minSdk = Versions.minSdk - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - kotlinOptions { - jvmTarget = "11" - allWarningsAsErrors = true - } - - publishing { - singleVariant("release") { - withSourcesJar() - withJavadocJar() - } - } } dependencies { implementation(project(":theme-contract")) - implementation(Dependencies.coreKtx) - implementation(Dependencies.appCompat) implementation(Dependencies.composeMaterial) implementation(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) } - -// Allow references to generated code -kapt { - correctErrorTypes = true -} \ No newline at end of file diff --git a/theme-orange/build.gradle.kts b/theme-orange/build.gradle.kts index 49502144a..e4dbf78e5 100644 --- a/theme-orange/build.gradle.kts +++ b/theme-orange/build.gradle.kts @@ -9,74 +9,18 @@ */ import com.orange.ods.gradle.Dependencies -import com.orange.ods.gradle.Versions plugins { - id("com.android.library") - id("org.jetbrains.kotlin.android") + id("library") id("kotlin-kapt") id("dagger.hilt.android.plugin") id("kotlin-parcelize") - id("maven-central-publish") -} - -android { - compileSdk = Versions.compileSdk - - defaultConfig { - minSdk = Versions.minSdk - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - kotlinOptions { - jvmTarget = "11" - allWarningsAsErrors = true - } - - buildFeatures { - compose = true - } - - composeOptions { - kotlinCompilerExtensionVersion = Versions.compose - } - - publishing { - singleVariant("release") { - withSourcesJar() - withJavadocJar() - } - } } dependencies { implementation(project(":theme-contract")) - - api(Dependencies.material) - implementation(Dependencies.coreKtx) - implementation(Dependencies.appCompat) + implementation(Dependencies.composeMaterial) implementation(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) } - -// Allow references to generated code -kapt { - correctErrorTypes = true -} \ No newline at end of file From 1b669920a29aaf35d06e88c248dbe84397a0d09a Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 13 Jul 2023 16:02:00 +0200 Subject: [PATCH 005/132] [#575] Namepaces are now set in build.gradle files instead of manifests --- app/build.gradle.kts | 2 ++ app/src/main/AndroidManifest.xml | 3 +-- lib-xml/build.gradle.kts | 2 ++ lib-xml/src/main/AndroidManifest.xml | 2 +- lib/build.gradle.kts | 2 ++ lib/src/main/AndroidManifest.xml | 2 +- theme-contract/build.gradle.kts | 2 ++ theme-contract/src/main/AndroidManifest.xml | 2 +- theme-innovation-cup/build.gradle.kts | 4 ++++ theme-innovation-cup/src/main/AndroidManifest.xml | 2 +- theme-orange/build.gradle.kts | 6 +++++- theme-orange/src/main/AndroidManifest.xml | 2 +- 12 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b93dd94a7..3480495e6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -27,6 +27,8 @@ plugins { } android { + namespace = "com.orange.ods.app" + compileSdk = Versions.compileSdk defaultConfig { 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. ~ */ --> - + - + diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 8ee79887e..f58a92215 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -26,6 +26,8 @@ plugins { val previewThemeConfigurationClass = "com.orange.ods.theme.orange.OrangeThemeConfiguration" android { + namespace = "com.orange.ods" + defaultConfig { buildConfigField("com.orange.ods.theme.OdsThemeConfigurationContract", "PREVIEW_THEME_CONFIGURATION", "new $previewThemeConfigurationClass()") } diff --git a/lib/src/main/AndroidManifest.xml b/lib/src/main/AndroidManifest.xml index 4e5064dd0..ef70ea53e 100644 --- a/lib/src/main/AndroidManifest.xml +++ b/lib/src/main/AndroidManifest.xml @@ -10,5 +10,5 @@ ~ */ --> - + diff --git a/theme-contract/build.gradle.kts b/theme-contract/build.gradle.kts index 8d9b838d1..61cf88e0d 100644 --- a/theme-contract/build.gradle.kts +++ b/theme-contract/build.gradle.kts @@ -15,6 +15,8 @@ plugins { } android { + namespace = "com.orange.ods.theme" + buildFeatures { compose = true } diff --git a/theme-contract/src/main/AndroidManifest.xml b/theme-contract/src/main/AndroidManifest.xml index cac20f4fc..5658abe27 100644 --- a/theme-contract/src/main/AndroidManifest.xml +++ b/theme-contract/src/main/AndroidManifest.xml @@ -8,4 +8,4 @@ ~ */ --> - + diff --git a/theme-innovation-cup/build.gradle.kts b/theme-innovation-cup/build.gradle.kts index 1bcbbd69b..67dc0ab93 100644 --- a/theme-innovation-cup/build.gradle.kts +++ b/theme-innovation-cup/build.gradle.kts @@ -17,6 +17,10 @@ plugins { id("kotlin-parcelize") } +android { + namespace = "com.orange.ods.theme.innovationcup" +} + dependencies { implementation(project(":theme-contract")) diff --git a/theme-innovation-cup/src/main/AndroidManifest.xml b/theme-innovation-cup/src/main/AndroidManifest.xml index 39891492b..a17d4ed99 100644 --- a/theme-innovation-cup/src/main/AndroidManifest.xml +++ b/theme-innovation-cup/src/main/AndroidManifest.xml @@ -8,4 +8,4 @@ ~ */ --> - \ No newline at end of file + \ No newline at end of file diff --git a/theme-orange/build.gradle.kts b/theme-orange/build.gradle.kts index e4dbf78e5..b2056cd26 100644 --- a/theme-orange/build.gradle.kts +++ b/theme-orange/build.gradle.kts @@ -17,9 +17,13 @@ plugins { id("kotlin-parcelize") } +android { + namespace = "com.orange.ods.theme.orange" +} + dependencies { implementation(project(":theme-contract")) - + implementation(Dependencies.composeMaterial) implementation(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) diff --git a/theme-orange/src/main/AndroidManifest.xml b/theme-orange/src/main/AndroidManifest.xml index 4ec29d469..a17d4ed99 100644 --- a/theme-orange/src/main/AndroidManifest.xml +++ b/theme-orange/src/main/AndroidManifest.xml @@ -8,4 +8,4 @@ ~ */ --> - \ No newline at end of file + \ No newline at end of file From 700069d8ed679fe31cbf80671da365f75283e176 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Tue, 18 Jul 2023 14:40:15 +0200 Subject: [PATCH 006/132] [#580] Display ChipFilter screen on filter chip variant click --- .../java/com/orange/ods/app/ui/components/Component.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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..39573a034 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,6 +23,7 @@ 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 @@ -139,7 +140,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( From 1f3c6c9141fc9490761b4abee73ce6b5ea6a9ecb Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Tue, 18 Jul 2023 14:40:27 +0200 Subject: [PATCH 007/132] [#580] Update changelog --- changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.md b/changelog.md index ea01ea21c..d237c32bb 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,12 @@ 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). +## [Unreleased](https://github.com/Orange-OpenSource/ods-android/compare/0.14.0...develop) + +### Fixed + +- [\App\] Screen displayed on filter chip variant click was not the good one ([#580](https://github.com/Orange-OpenSource/ods-android/issues/580)) + ## [0.14.0](https://github.com/Orange-OpenSource/ods-android/compare/0.13.0...0.14.0) - 2023-07-12 ### Added From 411d997f924a13e1b168092c5238d9017c7b5545 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 18 Jul 2023 11:12:19 +0200 Subject: [PATCH 008/132] [#572] Add OdsIcon component for internal usage --- .../component/appbar/top/OdsTopAppBar.kt | 2 +- .../compose/component/button/OdsIconButton.kt | 108 ++++++++++++++++-- .../ods/compose/component/icon/OdsIcon.kt | 55 +++++++++ .../textfield/search/OdsSearchTextField.kt | 2 +- 4 files changed, 158 insertions(+), 9 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt diff --git a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt index b4f1273b8..f7e71d167 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt @@ -110,7 +110,7 @@ fun OdsTopAppBarActionButton( ) { OdsIconButton( onClick = onClick, - painter = painter, + graphicsObject = painter, contentDescription = contentDescription, modifier = modifier, enabled = enabled, diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconButton.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconButton.kt index 0bcb27b8e..9d81ddf72 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconButton.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconButton.kt @@ -18,14 +18,16 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.painterResource import com.orange.ods.compose.component.OdsComposable +import com.orange.ods.compose.component.icon.OdsIcon import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.theme.OdsDisplaySurface import com.orange.ods.compose.theme.OdsTheme -import com.orange.ods.utilities.extension.enable /** * OdsIconButton is a clickable icon, used to represent actions. An OdsIconButton has an overall minimum @@ -36,9 +38,9 @@ import com.orange.ods.utilities.extension.enable * This component is typically used inside an App Bar for the navigation icon / actions. * * @param onClick the lambda to be invoked when this icon is pressed - * @param painter the painter to be drawn inside the IconButton + * @param painter the painter to be drawn inside the OdsIconButton * @param contentDescription the content description associated to this OdsIconButton. - * @param modifier optional [Modifier] for this IconButton + * @param modifier optional [Modifier] for this OdsIconButton * @param enabled whether or not this OdsIconButton will handle input events and appear enabled for * semantics purposes, true by default * @param displaySurface optional allow to force the button display on a dark or light @@ -53,13 +55,106 @@ fun OdsIconButton( modifier: Modifier = Modifier, enabled: Boolean = true, displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default +) { + OdsIconButton( + onClick = onClick, + graphicsObject = painter as Any, + contentDescription = contentDescription, + modifier = modifier, + enabled = enabled, + displaySurface = displaySurface + ) +} + +/** + * OdsIconButton is a clickable icon, used to represent actions. An OdsIconButton has an overall minimum + * touch target size of 48 x 48dp, to meet accessibility guidelines. It contains an [Icon] centered + * inside the OdsIconButton. + * If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. + * + * This component is typically used inside an App Bar for the navigation icon / actions. + * + * @param onClick the lambda to be invoked when this icon is pressed + * @param imageVector [ImageVector] to draw inside this OdsIconButton + * @param contentDescription the content description associated to this OdsIconButton. + * @param modifier optional [Modifier] for this OdsIconButton + * @param enabled whether or not this OdsIconButton will handle input events and appear enabled for + * semantics purposes, true by default + * @param displaySurface optional allow to force the button display on a dark or light + * surface. By default the appearance applied is based on the system night mode value. + */ +@Composable +@OdsComposable +fun OdsIconButton( + onClick: () -> Unit, + imageVector: ImageVector, + contentDescription: String, + modifier: Modifier = Modifier, + enabled: Boolean = true, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default +) { + OdsIconButton( + onClick = onClick, + graphicsObject = imageVector as Any, + contentDescription = contentDescription, + modifier = modifier, + enabled = enabled, + displaySurface = displaySurface + ) +} + +/** + * OdsIconButton is a clickable icon, used to represent actions. An OdsIconButton has an overall minimum + * touch target size of 48 x 48dp, to meet accessibility guidelines. It contains an [Icon] centered + * inside the OdsIconButton. + * If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. + * + * This component is typically used inside an App Bar for the navigation icon / actions. + * + * @param onClick the lambda to be invoked when this icon is pressed + * @param bitmap [ImageBitmap] to draw inside this OdsIconButton + * @param contentDescription the content description associated to this OdsIconButton. + * @param modifier optional [Modifier] for this OdsIconButton + * @param enabled whether or not this OdsIconButton will handle input events and appear enabled for + * semantics purposes, true by default + * @param displaySurface optional allow to force the button display on a dark or light + * surface. By default the appearance applied is based on the system night mode value. + */ +@Composable +@OdsComposable +fun OdsIconButton( + onClick: () -> Unit, + bitmap: ImageBitmap, + contentDescription: String, + modifier: Modifier = Modifier, + enabled: Boolean = true, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default +) { + OdsIconButton( + onClick = onClick, + graphicsObject = bitmap as Any, + contentDescription = contentDescription, + modifier = modifier, + enabled = enabled, + displaySurface = displaySurface + ) +} + +@Composable +internal fun OdsIconButton( + onClick: () -> Unit, + graphicsObject: Any, + contentDescription: String, + modifier: Modifier = Modifier, + enabled: Boolean = true, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default ) { CompositionLocalProvider( LocalRippleTheme provides displaySurface.rippleTheme ) { OdsIconButton( onClick = onClick, - painter = painter, + graphicsObject = graphicsObject, contentDescription = contentDescription, modifier = modifier.background(color = iconButtonBackgroundColor(displaySurface = displaySurface)), enabled = enabled, @@ -71,18 +166,17 @@ fun OdsIconButton( @Composable internal fun OdsIconButton( onClick: () -> Unit, - painter: Painter, + graphicsObject: Any, contentDescription: String, tint: Color, modifier: Modifier = Modifier, enabled: Boolean = true, ) { IconButton(onClick = onClick, modifier = modifier, enabled = enabled) { - Icon(painter = painter, contentDescription = contentDescription, tint = tint.enable(enabled = enabled)) + OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint, enabled = enabled) } } - @Composable private fun iconButtonBackgroundColor(displaySurface: OdsDisplaySurface) = when (displaySurface) { diff --git a/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt b/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt new file mode 100644 index 000000000..bd99f8b96 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt @@ -0,0 +1,55 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.icon + +import androidx.compose.material.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import com.orange.ods.compose.theme.OdsDisplaySurface +import com.orange.ods.utilities.extension.enable + +@Composable +internal fun OdsIcon( + graphicsObject: Any, + contentDescription: String, + tint: Color, + modifier: Modifier = Modifier, + enabled: Boolean = true, +) { + val iconTint = tint.enable(enabled = enabled) + when (graphicsObject) { + is Painter -> Icon(painter = graphicsObject, contentDescription = contentDescription, modifier = modifier, tint = iconTint) + is ImageVector -> Icon(imageVector = graphicsObject, contentDescription = contentDescription, modifier = modifier, tint = iconTint) + is ImageBitmap -> Icon(bitmap = graphicsObject, contentDescription = contentDescription, modifier = modifier, tint = iconTint) + else -> {} + } +} + +@Composable +internal fun OdsIcon( + graphicsObject: Any, + contentDescription: String, + modifier: Modifier = Modifier, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default, + enabled: Boolean = true +) { + OdsIcon( + graphicsObject = graphicsObject, + contentDescription = contentDescription, + tint = displaySurface.themeColors.onSurface, + modifier = modifier, + enabled = enabled + ) +} diff --git a/lib/src/main/java/com/orange/ods/compose/component/textfield/search/OdsSearchTextField.kt b/lib/src/main/java/com/orange/ods/compose/component/textfield/search/OdsSearchTextField.kt index feea28f67..f45a36e68 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/textfield/search/OdsSearchTextField.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/textfield/search/OdsSearchTextField.kt @@ -70,7 +70,7 @@ fun OdsSearchTextField( trailingIcon = { OdsIconButton( onClick = { onValueChange(TextFieldValue("")) }, - painter = rememberVectorPainter(image = Icons.Default.Close), + graphicsObject = rememberVectorPainter(image = Icons.Default.Close), contentDescription = stringResource(id = R.string.search_clear), tint = OdsTheme.colors.component.topAppBar.barContent ) From 4c4e199686bfd2dd54853a6cf4cab260cb8e7385 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 18 Jul 2023 15:57:29 +0200 Subject: [PATCH 009/132] [#572] Replace composable parameter of OdsDropdownMenu with a list of OdsDropdownMenuItem --- .../app/ui/components/menus/MenuDropdown.kt | 41 ++--- changelog.md | 4 + .../component/content/OdsComponentContent.kt | 31 ++++ .../component/content/OdsComponentIcon.kt | 73 ++++++++ .../compose/component/menu/OdsDropdownMenu.kt | 159 ++++++++++++------ .../component/menu/OdsExposedDropdownMenu.kt | 14 +- 6 files changed, 243 insertions(+), 79 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt create mode 100644 lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt 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..e813243c4 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 @@ -79,6 +78,8 @@ fun MenuDropdown() { text = stringResource(id = R.string.component_menu_dropdown_description) ) + val dividerIndex = 1 + Box(modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s))) { OdsListItem( modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s)), @@ -90,18 +91,22 @@ 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( @@ -113,22 +118,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/changelog.md b/changelog.md index d237c32bb..406d4640c 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/Orange-OpenSource/ods-android/compare/0.14.0...develop) +### Changed + +- \[Lib\] Replace composable parameter of `OdsDropdownMenu` with a list of `OdsDropdownMenuItem` ([#572](https://github.com/Orange-OpenSource/ods-android/issues/572)) + ### Fixed - [\App\] Screen displayed on filter chip variant click was not the good one ([#580](https://github.com/Orange-OpenSource/ods-android/issues/580)) diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt new file mode 100644 index 000000000..601be5c55 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt @@ -0,0 +1,31 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.content + +import androidx.compose.runtime.Composable + +/** + * The content of a component. + * + * Subclasses of [OdsComponentContent] should be used instead of composable methods when passing parameters to components. + * This prevents using generic composable methods that can encapsulate any kind of views and thus helps developers to follow UI guidelines more easily. + * This also allows to group parameters that are related to the same content inside a component. + * For instance it is possible to create an `Icon` subclass to replace both `icon: @Composable () -> Unit` and `onIconClick: () -> Unit` parameters with a single `icon: Icon` parameter. + */ +abstract class OdsComponentContent { + + /** + * The Jetpack Compose UI for this component content. + * Subclasses must implement this method to provide content. + */ + @Composable + internal abstract fun Content() +} diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt new file mode 100644 index 000000000..2622ddd76 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt @@ -0,0 +1,73 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.content + +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import com.orange.ods.compose.component.button.OdsIconButton +import com.orange.ods.compose.component.icon.OdsIcon +import com.orange.ods.utilities.extension.orElse + +/** + * An icon in a component. + */ +abstract class OdsComponentIcon protected constructor( + protected val graphicsObject: Any, + protected val contentDescription: String, + protected val enabled: Boolean = true, + protected open var onClick: (() -> Unit)? = null +) : OdsComponentContent() { + + protected open val tint: Color? + @Composable + get() = null + + protected constructor( + painter: Painter, + contentDescription: String, + enabled: Boolean = true, + onClick: (() -> Unit)? = null + ) : this(painter as Any, contentDescription, enabled, onClick) + + protected constructor( + imageVector: ImageVector, + contentDescription: String, + enabled: Boolean = true, + onClick: (() -> Unit)? = null + ) : this(imageVector as Any, contentDescription, enabled, onClick) + + protected constructor( + bitmap: ImageBitmap, + contentDescription: String, + enabled: Boolean = true, + onClick: (() -> Unit)? = null + ) : this(bitmap as Any, contentDescription, enabled, onClick) + + @Composable + override fun Content() { + onClick?.let { onClick -> + tint?.let { tint -> + OdsIconButton(onClick = onClick, graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint, enabled = enabled) + }.orElse { + OdsIconButton(onClick = onClick, graphicsObject = graphicsObject, contentDescription = contentDescription, enabled = enabled) + } + }.orElse { + tint?.let { tint -> + OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint) + }.orElse { + OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription) + } + } + } +} diff --git a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt index 059495a2d..b08eed69e 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt @@ -10,17 +10,16 @@ package com.orange.ods.compose.component.menu -import androidx.annotation.DrawableRes +import android.graphics.Bitmap import androidx.compose.foundation.background -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.padding import androidx.compose.material.DropdownMenu import androidx.compose.material.DropdownMenuItem -import androidx.compose.material.Icon import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.DpOffset @@ -28,6 +27,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.PopupProperties import com.orange.ods.R import com.orange.ods.compose.component.OdsComposable +import com.orange.ods.compose.component.content.OdsComponentContent +import com.orange.ods.compose.component.divider.OdsDivider +import com.orange.ods.compose.component.icon.OdsIcon import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.theme.OdsTheme @@ -37,23 +39,23 @@ import com.orange.ods.compose.theme.OdsTheme * * @see androidx.compose.material.DropdownMenu * + * @param items The items of the dropdown menu * @param expanded Whether the menu is currently open and visible to the user * @param onDismissRequest Called when the user requests to dismiss the menu, such as by * tapping outside the menu's bounds * @param modifier The modifier to be applied to the menu * @param offset [DpOffset] to be added to the position of the menu * @param properties [PopupProperties] for further customization of the popup's behavior - * @param content The content of the dropdown menu */ @OdsComposable @Composable fun OdsDropdownMenu( + items: List, expanded: Boolean, onDismissRequest: () -> Unit, modifier: Modifier = Modifier, offset: DpOffset = DpOffset(0.dp, 0.dp), - properties: PopupProperties = PopupProperties(focusable = true), - content: @Composable ColumnScope.() -> Unit + properties: PopupProperties = PopupProperties(focusable = true) ) { DropdownMenu( expanded = expanded, @@ -61,40 +63,109 @@ fun OdsDropdownMenu( modifier = modifier.background(OdsTheme.colors.surface), offset = offset, properties = properties, - content = content + content = { items.forEach { it.Content() } } ) } /** * @see androidx.compose.material.DropdownMenuItem * - * @param text The text of the menu item - * @param onClick Called when the menu item was clicked - * @param icon Optional icon to display in the menu item - * @param enabled Controls the enabled state of the menu item - when `false`, the menu item - * will not be clickable and [onClick] will not be invoked + * An item displayed in a [OdsDropdownMenu]. + * + * @property text The text of the menu item + * @property icon Optional icon to display in the menu item + * @property enabled Controls the enabled state of the menu item - when `false`, the menu item + * @property divider Whether or not a divider is displayed at the bottom of the menu item + * @property onClick Called when the menu item was clicked */ -@Composable -@OdsComposable -fun ColumnScope.OdsDropdownMenuItem( - text: String, - onClick: () -> Unit, - icon: Painter? = null, - enabled: Boolean = true -) { - DropdownMenuItem( - onClick = onClick, - enabled = enabled - ) { - icon?.let { - Icon( - modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_m)), - painter = icon, - contentDescription = null, - tint = OdsTheme.colors.onSurface - ) +class OdsDropdownMenuItem private constructor( + val text: String, + val icon: Any?, + val enabled: Boolean, + val divider: Boolean, + val onClick: () -> Unit +) : OdsComponentContent() { + + /** + * Creates an instance of [OdsDropdownMenuItem]. + * + * @param text The text of the menu item + * @param enabled Controls the enabled state of the menu item - when `false`, the menu item + * @param divider Whether or not a divider is displayed at the bottom of the menu item + * @param onClick Called when the menu item was clicked + */ + constructor( + text: String, + enabled: Boolean = true, + divider: Boolean = false, + onClick: () -> Unit + ) : this(text, null as Any?, enabled, divider, onClick) + + /** + * Creates an instance of [OdsDropdownMenuItem]. + * + * @param text The text of the menu item + * @param icon Optional icon to display in the menu item + * @param enabled Controls the enabled state of the menu item - when `false`, the menu item + * @param divider Whether or not a divider is displayed at the bottom of the menu item + * @param onClick Called when the menu item was clicked + */ + constructor( + text: String, + icon: Painter? = null, + enabled: Boolean = true, + divider: Boolean = false, + onClick: () -> Unit + ) : this(text, icon as Any?, enabled, divider, onClick) + + /** + * Creates an instance of [OdsDropdownMenuItem]. + * + * @param text The text of the menu item + * @param icon Optional icon to display in the menu item + * @param enabled Controls the enabled state of the menu item - when `false`, the menu item + * @param divider Whether or not a divider is displayed at the bottom of the menu item + * @param onClick Called when the menu item was clicked + */ + constructor( + text: String, + icon: ImageVector? = null, + enabled: Boolean = true, + divider: Boolean = false, + onClick: () -> Unit + ) : this(text, icon as Any?, enabled, divider, onClick) + + /** + * Creates an instance of [OdsDropdownMenuItem]. + * + * @param text The text of the menu item + * @param icon Optional icon to display in the menu item + * @param enabled Controls the enabled state of the menu item - when `false`, the menu item + * @param divider Whether or not a divider is displayed at the bottom of the menu item + * @param onClick Called when the menu item was clicked + */ + constructor( + text: String, + icon: Bitmap? = null, + enabled: Boolean = true, + divider: Boolean = false, + onClick: () -> Unit + ) : this(text, icon as Any?, enabled, divider, onClick) + + @Composable + override fun Content() { + DropdownMenuItem(onClick = onClick, enabled = enabled) { + icon?.let { + OdsIcon( + graphicsObject = icon, + contentDescription = "", + tint = OdsTheme.colors.onSurface, + modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_m)), + ) + } + Text(text = text, style = OdsTheme.typography.body1, color = OdsTheme.colors.onSurface) } - Text(text = text, style = OdsTheme.typography.body1, color = OdsTheme.colors.onSurface) + if (divider) OdsDivider() } } @@ -104,25 +175,11 @@ fun ColumnScope.OdsDropdownMenuItem( @UiModePreviews.Default @Composable private fun PreviewOdsDropdownMenu() = Preview { - data class Item(@DrawableRes val iconResId: Int, val text: String) - val items = listOf( - Item(android.R.drawable.ic_dialog_email, "First menu item"), - Item(android.R.drawable.ic_dialog_map, "Second menu item"), - Item(android.R.drawable.ic_dialog_dialer, "Third menu item"), - Item(android.R.drawable.ic_dialog_info, "Fourth menu item") + OdsDropdownMenuItem("First menu item", painterResource(id = android.R.drawable.ic_dialog_email)) {}, + OdsDropdownMenuItem("Second menu item", painterResource(id = android.R.drawable.ic_dialog_map), divider = true) {}, + OdsDropdownMenuItem("Third menu item", painterResource(id = android.R.drawable.ic_dialog_dialer)) {}, + OdsDropdownMenuItem("Fourth menu item", painterResource(id = android.R.drawable.ic_dialog_info)) {} ) - - OdsDropdownMenu( - expanded = true, - onDismissRequest = { }, - ) { - items.forEach { item -> - OdsDropdownMenuItem( - text = item.text, - icon = painterResource(id = item.iconResId), - onClick = { } - ) - } - } + OdsDropdownMenu(items = items, expanded = true, onDismissRequest = {}) } diff --git a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt index 2fd1cb6a2..dd2072686 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt @@ -69,16 +69,14 @@ fun OdsExposedDropdownMenu( enabled = enabled ) OdsDropdownMenu( - modifier = Modifier.exposedDropdownSize(), expanded = if (enabled) expanded else false, onDismissRequest = { expanded = false }, - content = { - items.forEach { item -> - OdsDropdownMenuItem(text = item.label, icon = item.iconResId?.let { painterResource(id = it) }, onClick = { - selectedItem.value = item - expanded = false - onItemSelectionChange(item) - }) + modifier = Modifier.exposedDropdownSize(), + items = items.map { item -> + OdsDropdownMenuItem(text = item.label, icon = item.iconResId?.let { painterResource(id = it) }) { + selectedItem.value = item + expanded = false + onItemSelectionChange(item) } } ) From c1fe7ab3bb1f0ac40c603d28428309017e55619a Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Wed, 12 Jul 2023 16:12:35 +0200 Subject: [PATCH 010/132] [#572] Update OdsTopAppBar API --- .../com/orange/ods/app/ui/MainTopAppBar.kt | 127 +++++++-------- .../appbars/top/ComponentTopAppBar.kt | 50 +++--- .../composable/CodeImplementation.kt | 16 +- changelog.md | 1 + .../component/appbar/top/OdsLargeTopAppBar.kt | 78 +++++----- .../component/appbar/top/OdsTopAppBar.kt | 145 +++++------------- .../appbar/top/OdsTopAppBarsCommon.kt | 139 +++++++++++++++++ .../component/content/OdsComponentContent.kt | 3 +- lib/src/main/res/values/strings.xml | 4 +- 9 files changed, 319 insertions(+), 244 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt 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..5dc4bd3d7 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() { + 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 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..dbf282dd2 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 @@ -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() } } } 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..27f314dbc 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 @@ -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) @@ -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/changelog.md b/changelog.md index 406d4640c..c4235f848 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - \[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)) ### Fixed diff --git a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt index 35db77889..ff55e0348 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt @@ -10,13 +10,10 @@ package com.orange.ods.compose.component.appbar.top -import androidx.compose.foundation.layout.RowScope 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 -import androidx.compose.material3.IconButton import androidx.compose.material3.LargeTopAppBar import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults @@ -34,7 +31,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import com.orange.ods.R import com.orange.ods.compose.component.OdsComposable -import com.orange.ods.compose.component.menu.OdsDropdownMenuItem +import com.orange.ods.compose.component.content.OdsComponentContent import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews @@ -46,9 +43,31 @@ import com.orange.ods.compose.theme.OdsTheme fun OdsLargeTopAppBar( title: String, modifier: Modifier = Modifier, - navigationIcon: @Composable (() -> Unit)? = null, - onNavigationIconClick: (() -> Unit)? = null, - actions: @Composable RowScope.() -> Unit = {}, + navigationIcon: OdsTopAppBarNavigationIcon? = null, + actions: List = emptyList(), + overflowMenuActions: List = emptyList(), + scrollBehavior: TopAppBarScrollBehavior? = null +) { + OdsLargeTopAppBarInternal( + title = title, + modifier = modifier, + navigationIcon = navigationIcon, + actions = actions, + overflowMenuActions = overflowMenuActions, + scrollBehavior = scrollBehavior + ) +} + +// TODO: Remove this method once OdsSearchTopAppBar is developed +@OptIn(ExperimentalMaterial3Api::class) +@Composable +@OdsComposable +fun OdsLargeTopAppBarInternal( + title: String, + modifier: Modifier = Modifier, + navigationIcon: OdsTopAppBarNavigationIcon? = null, + actions: List = emptyList(), + overflowMenuActions: List = emptyList(), scrollBehavior: TopAppBarScrollBehavior? = null ) { val contentColor = OdsTheme.colors.component.topAppBar.barContent @@ -100,18 +119,11 @@ fun OdsLargeTopAppBar( ) }, modifier = modifier, - navigationIcon = { - if (navigationIcon != null) { - if (onNavigationIconClick != null) { - IconButton(onClick = onNavigationIconClick) { - navigationIcon() - } - } else { - navigationIcon() - } - } + navigationIcon = { navigationIcon?.Content() }, + actions = { + actions.forEach { it.Content() } + if (overflowMenuActions.isNotEmpty()) OdsTopAppBarOverflowMenu(items = overflowMenuActions) }, - actions = actions, colors = TopAppBarDefaults.largeTopAppBarColors( containerColor = OdsTheme.colors.component.topAppBar.barBackground, navigationIconContentColor = contentColor, @@ -127,28 +139,22 @@ fun OdsLargeTopAppBar( @Composable private fun PreviewOdsLargeTopAppBar(@PreviewParameter(OdsLargeTopAppBarPreviewParameterProvider::class) parameter: OdsLargeTopAppBarPreviewParameter) = Preview { + val actions = listOf(OdsTopAppBarActionButton(painterResource(id = android.R.drawable.ic_dialog_info), "Info") {}) + val overflowMenuActions = listOf( + OdsTopAppBarOverflowMenuActionItem("Settings") { }, + OdsTopAppBarOverflowMenuActionItem("Account") { } + ) OdsLargeTopAppBar( title = parameter.title, navigationIcon = parameter.navigationIcon, - actions = { - OdsTopAppBarActionButton( - onClick = {}, - painter = painterResource(id = android.R.drawable.ic_dialog_info), - contentDescription = "Info" - ) - OdsTopAppBarOverflowMenuBox( - overflowIconContentDescription = "More options" - ) { - OdsDropdownMenuItem(text = "Settings", onClick = { }) - OdsDropdownMenuItem(text = "Account", onClick = { }) - } - } + actions = actions, + overflowMenuActions = overflowMenuActions ) } internal data class OdsLargeTopAppBarPreviewParameter( val title: String, - val navigationIcon: @Composable () -> Unit + val navigationIcon: OdsTopAppBarNavigationIcon? ) private class OdsLargeTopAppBarPreviewParameterProvider : @@ -156,15 +162,11 @@ private class OdsLargeTopAppBarPreviewParameterProvider : private val previewParameterValues: List get() { - val navigationIcon = @Composable { - IconButton(onClick = {}) { - Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null) - } - } + val navigationIcon = OdsTopAppBarNavigationIcon(Icons.Filled.ArrowBack, "") {} return listOf( OdsLargeTopAppBarPreviewParameter("One line title", navigationIcon), OdsLargeTopAppBarPreviewParameter("Two lines title is allowed in large top app bar", navigationIcon), OdsLargeTopAppBarPreviewParameter("The title will be truncated if it is too long to fit in the large top app bar like this one", navigationIcon), - OdsLargeTopAppBarPreviewParameter("One line title", { }) + OdsLargeTopAppBarPreviewParameter("One line title", null) ) } \ No newline at end of file diff --git a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt index f7e71d167..794bc0eb6 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt @@ -10,32 +10,18 @@ package com.orange.ods.compose.component.appbar.top -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.RowScope import androidx.compose.material.AppBarDefaults -import androidx.compose.material.Icon -import androidx.compose.material.IconButton import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.MoreVert import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.orange.ods.compose.component.OdsComposable -import com.orange.ods.compose.component.button.OdsIconButton -import com.orange.ods.compose.component.menu.OdsDropdownMenu -import com.orange.ods.compose.component.menu.OdsDropdownMenuItem +import com.orange.ods.compose.component.content.OdsComponentContent import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.theme.OdsTheme @@ -50,124 +36,71 @@ import com.orange.ods.compose.theme.OdsTheme * centering the title, use the other TopAppBar overload for a generic TopAppBar with no * restriction on content. * - * @param modifier The [Modifier] to be applied to this TopAppBar * @param title The title to be displayed in the center of the TopAppBar - * @param navigationIcon Optional navigation icon displayed at the start of the TopAppBar. This should be an [Icon]. - * @param onNavigationIconClick Optional action executed on the navigation icon click. - * @param actions The actions displayed at the end of the TopAppBar. This should be [OdsTopAppBarActionButton]s. + * @param modifier The [Modifier] to be applied to this TopAppBar + * @param navigationIcon Optional navigation icon displayed at the start of the TopAppBar. + * @param actions The actions displayed at the end of the TopAppBar. * The default layout here is a [Row], so icons inside will be placed horizontally. + * @param overflowMenuActions The actions displayed in the overflow menu. * @param elevated True to set an elevation to the top app bar (shadow displayed), false otherwise. */ @Composable @OdsComposable fun OdsTopAppBar( + title: String, modifier: Modifier = Modifier, - title: String? = null, - navigationIcon: @Composable (() -> Unit)? = null, - onNavigationIconClick: (() -> Unit)? = null, - actions: @Composable RowScope.() -> Unit = {}, + navigationIcon: OdsTopAppBarNavigationIcon? = null, + actions: List = emptyList(), + overflowMenuActions: List = emptyList(), elevated: Boolean = true ) { - TopAppBar( - title = { title?.let { Text(text = title, style = OdsTheme.typography.h6) } }, + OdsTopAppBarInternal( + title = title, modifier = modifier, - navigationIcon = navigationIcon?.let { navIcon -> - { - if (onNavigationIconClick != null) { - IconButton(onClick = onNavigationIconClick) { - navIcon() - } - } else { - navIcon() - } - } - }, + navigationIcon = navigationIcon, actions = actions, - backgroundColor = OdsTheme.colors.component.topAppBar.barBackground, - contentColor = OdsTheme.colors.component.topAppBar.barContent, - elevation = if (elevated) AppBarDefaults.TopAppBarElevation else 0.dp + overflowMenuActions = overflowMenuActions, + elevated = elevated ) } -/** - * Action icon button displayed in an [OdsTopAppBar]. - * - * @param onClick Will be called when the user clicks on the action icon button. - * @param painter Painter of the icon. - * @param contentDescription The content description associated to this OdsTopAppBarActionButton. - * @param modifier The [Modifier] to be applied to this OdsTopAppBarActionButton. - * @param enabled whether or not this OdsTopAppBarActionButton will handle input events and appear enabled for - * semantics purposes, true by default. - */ +// TODO: Remove this method once OdsSearchTopAppBar is developed @Composable @OdsComposable -fun OdsTopAppBarActionButton( - onClick: () -> Unit, - painter: Painter, - contentDescription: String, +fun OdsTopAppBarInternal( + title: String, modifier: Modifier = Modifier, - enabled: Boolean = true + navigationIcon: OdsTopAppBarNavigationIcon? = null, + actions: List = emptyList(), + overflowMenuActions: List = emptyList(), + elevated: Boolean = true ) { - OdsIconButton( - onClick = onClick, - graphicsObject = painter, - contentDescription = contentDescription, + TopAppBar( + title = { Text(text = title, style = OdsTheme.typography.h6) }, modifier = modifier, - enabled = enabled, - tint = OdsTheme.colors.component.topAppBar.barContent + navigationIcon = navigationIcon?.let { { it.Content() } }, + actions = { + actions.forEach { it.Content() } + if (overflowMenuActions.isNotEmpty()) OdsTopAppBarOverflowMenu(items = overflowMenuActions) + }, + backgroundColor = OdsTheme.colors.component.topAppBar.barBackground, + contentColor = OdsTheme.colors.component.topAppBar.barContent, + elevation = if (elevated) AppBarDefaults.TopAppBarElevation else 0.dp ) } -/** - * Overflow menu displayed in an [OdsTopAppBar]. It displays the overflow icon (3 vertical dots) and the menu appearing on click. - * - * @param overflowIconContentDescription The content description of the overflow icon. - * @param content The content of the overflow dropdown menu - */ -@Composable -@OdsComposable -fun OdsTopAppBarOverflowMenuBox( - overflowIconContentDescription: String, - content: @Composable ColumnScope.() -> Unit -) { - var showMenu by remember { mutableStateOf(false) } - - Box { - OdsTopAppBarActionButton( - onClick = { showMenu = !showMenu }, - painter = rememberVectorPainter(image = Icons.Filled.MoreVert), - contentDescription = overflowIconContentDescription - ) - OdsDropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false }, - content = content - ) - } -} - @UiModePreviews.Default @Composable private fun PreviewOdsTopAppBar() = Preview { + val actions = listOf(OdsTopAppBarActionButton(painterResource(id = android.R.drawable.ic_dialog_info), "Info") {}) + val overflowMenuItems = listOf( + OdsTopAppBarOverflowMenuActionItem("Settings") {}, + OdsTopAppBarOverflowMenuActionItem("Account") {} + ) OdsTopAppBar( title = "Title", - navigationIcon = { - IconButton(onClick = {}) { - Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null) - } - }, - actions = { - OdsTopAppBarActionButton( - onClick = {}, - painter = painterResource(id = android.R.drawable.ic_dialog_info), - contentDescription = "Info" - ) - OdsTopAppBarOverflowMenuBox( - overflowIconContentDescription = "More options" - ) { - OdsDropdownMenuItem(text = "Settings", onClick = { }) - OdsDropdownMenuItem(text = "Account", onClick = { }) - } - } + navigationIcon = OdsTopAppBarNavigationIcon(Icons.Filled.ArrowBack, "") {}, + actions = actions, + overflowMenuActions = overflowMenuItems ) } diff --git a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt new file mode 100644 index 000000000..bfd608a3b --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt @@ -0,0 +1,139 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.appbar.top + +import androidx.compose.foundation.layout.Box +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +import com.orange.ods.R +import com.orange.ods.compose.component.OdsComposable +import com.orange.ods.compose.component.content.OdsComponentIcon +import com.orange.ods.compose.component.menu.OdsDropdownMenu +import com.orange.ods.compose.component.menu.OdsDropdownMenuItem +import com.orange.ods.compose.theme.OdsTheme + +@Composable +internal fun OdsTopAppBarOverflowMenu(items: List) { + Box { + var showMenu by remember { mutableStateOf(false) } + val contentDescription = stringResource(id = R.string.top_app_bar_overflow_menu_content_description) + val dropdownMenuAction = OdsTopAppBarActionButton(Icons.Filled.MoreVert, contentDescription, true) { showMenu = !showMenu } + dropdownMenuAction.Content() + OdsDropdownMenu( + items = items, + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) + } +} + +/** + * A navigation icon in an [OdsTopAppBar]. + */ +class OdsTopAppBarNavigationIcon : OdsComponentIcon { + + /** + * Creates an instance of [OdsTopAppBarNavigationIcon]. + * + * @param painter Painter of the icon. + * @param contentDescription The content description associated to this [OdsTopAppBarNavigationIcon]. + * @param onClick Will be called when the user clicks on the action icon button. + */ + constructor(painter: Painter, contentDescription: String, onClick: () -> Unit) : super(painter as Any, contentDescription, onClick = onClick) + + /** + * Creates an instance of [OdsTopAppBarNavigationIcon]. + * + * @param imageVector Image vector of the icon. + * @param contentDescription The content description associated to this [OdsTopAppBarNavigationIcon]. + * @param onClick Will be called when the user clicks on the action icon button. + */ + constructor(imageVector: ImageVector, contentDescription: String, onClick: () -> Unit) : super(imageVector as Any, contentDescription, onClick = onClick) + + /** + * Creates an instance of [OdsTopAppBarNavigationIcon]. + * + * @param bitmap Image bitmap of the icon. + * @param contentDescription The content description associated to this [OdsTopAppBarNavigationIcon]. + * @param onClick Will be called when the user clicks on the action icon button. + */ + constructor(bitmap: ImageBitmap, contentDescription: String, onClick: () -> Unit) : super(bitmap as Any, contentDescription, onClick = onClick) +} + +/** + * An action button displayed in an [OdsTopAppBar]. + */ +open class OdsTopAppBarActionButton : OdsComponentIcon { + + /** + * Creates an instance of [OdsTopAppBarActionButton]. + * + * @param painter Painter of the icon. + * @param contentDescription The content description associated to this [OdsTopAppBarActionButton]. + * @param enabled whether or not this [OdsTopAppBarActionButton] will handle input events and appear enabled for + * semantics purposes, true by default. + * @param onClick Will be called when the user clicks on the action icon button. + */ + constructor( + painter: Painter, + contentDescription: String, + enabled: Boolean = true, + onClick: () -> Unit + ) : super(painter as Any, contentDescription, enabled, onClick) + + /** + * Creates an instance of [OdsTopAppBarActionButton]. + * + * @param imageVector Image vector of the icon. + * @param contentDescription The content description associated to this [OdsTopAppBarActionButton]. + * @param enabled whether or not this [OdsTopAppBarActionButton] will handle input events and appear enabled for + * semantics purposes, true by default. + * @param onClick Will be called when the user clicks on the action icon button. + */ + constructor( + imageVector: ImageVector, + contentDescription: String, + enabled: Boolean = true, + onClick: () -> Unit + ) : super(imageVector as Any, contentDescription, enabled, onClick) + + /** + * Creates an instance of [OdsTopAppBarActionButton]. + * + * @param bitmap Image bitmap of the icon. + * @param contentDescription The content description associated to this [OdsTopAppBarActionButton]. + * @param enabled whether or not this [OdsTopAppBarActionButton] will handle input events and appear enabled for + * semantics purposes, true by default. + * @param onClick Will be called when the user clicks on the action icon button. + */ + constructor( + bitmap: ImageBitmap, + contentDescription: String, + enabled: Boolean = true, + onClick: () -> Unit + ) : super(bitmap as Any, contentDescription, enabled, onClick) + + override val tint: Color? + @Composable + get() = OdsTheme.colors.component.topAppBar.barContent +} + +typealias OdsTopAppBarOverflowMenuActionItem = OdsDropdownMenuItem diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt index 601be5c55..3c1643f1d 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt @@ -26,6 +26,7 @@ abstract class OdsComponentContent { * The Jetpack Compose UI for this component content. * Subclasses must implement this method to provide content. */ + // TODO: Set this method internal once OdsSearchTopAppBar is developed @Composable - internal abstract fun Content() + abstract fun Content() } diff --git a/lib/src/main/res/values/strings.xml b/lib/src/main/res/values/strings.xml index 5207eda10..05bf689a1 100644 --- a/lib/src/main/res/values/strings.xml +++ b/lib/src/main/res/values/strings.xml @@ -15,7 +15,9 @@ Show password Hide password + More options + %s%% - + Clear search \ No newline at end of file From c2510595a011afadaa91972330d8ac4bcae72a64 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Wed, 19 Jul 2023 18:31:57 +0200 Subject: [PATCH 011/132] [#572] Remove empty file --- .../password/OdsPasswordTextFieldsCommon.kt | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 lib/src/main/java/com/orange/ods/compose/component/textfield/password/OdsPasswordTextFieldsCommon.kt diff --git a/lib/src/main/java/com/orange/ods/compose/component/textfield/password/OdsPasswordTextFieldsCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/textfield/password/OdsPasswordTextFieldsCommon.kt deleted file mode 100644 index 7c96f199c..000000000 --- a/lib/src/main/java/com/orange/ods/compose/component/textfield/password/OdsPasswordTextFieldsCommon.kt +++ /dev/null @@ -1,12 +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.compose.component.textfield.password - From f28ea378a09ba576d3ee1b43c7a67697331a9789 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Fri, 21 Jul 2023 11:05:58 +0200 Subject: [PATCH 012/132] [#572] Review: Several OdsComponentIcon properties are now private --- .../ods/compose/component/content/OdsComponentIcon.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt index 2622ddd76..faad1684e 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt @@ -23,10 +23,10 @@ import com.orange.ods.utilities.extension.orElse * An icon in a component. */ abstract class OdsComponentIcon protected constructor( - protected val graphicsObject: Any, - protected val contentDescription: String, - protected val enabled: Boolean = true, - protected open var onClick: (() -> Unit)? = null + private val graphicsObject: Any, + private val contentDescription: String, + private val enabled: Boolean = true, + private val onClick: (() -> Unit)? = null ) : OdsComponentContent() { protected open val tint: Color? From 643079eb092c45af9f709a9de619e0c809cdbb07 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Fri, 21 Jul 2023 11:38:33 +0200 Subject: [PATCH 013/132] [#572] Review: Total number of actions in top app bars is now limited to 3 --- .../component/appbar/top/OdsLargeTopAppBar.kt | 5 +--- .../component/appbar/top/OdsTopAppBar.kt | 5 +--- .../appbar/top/OdsTopAppBarsCommon.kt | 29 +++++++++++-------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt index ff55e0348..4b4026db2 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsLargeTopAppBar.kt @@ -120,10 +120,7 @@ fun OdsLargeTopAppBarInternal( }, modifier = modifier, navigationIcon = { navigationIcon?.Content() }, - actions = { - actions.forEach { it.Content() } - if (overflowMenuActions.isNotEmpty()) OdsTopAppBarOverflowMenu(items = overflowMenuActions) - }, + actions = { OdsTopAppBarActions(actions = actions, overflowMenuActions = overflowMenuActions) }, colors = TopAppBarDefaults.largeTopAppBarColors( containerColor = OdsTheme.colors.component.topAppBar.barBackground, navigationIconContentColor = contentColor, diff --git a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt index 794bc0eb6..a94340d28 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBar.kt @@ -79,10 +79,7 @@ fun OdsTopAppBarInternal( title = { Text(text = title, style = OdsTheme.typography.h6) }, modifier = modifier, navigationIcon = navigationIcon?.let { { it.Content() } }, - actions = { - actions.forEach { it.Content() } - if (overflowMenuActions.isNotEmpty()) OdsTopAppBarOverflowMenu(items = overflowMenuActions) - }, + actions = { OdsTopAppBarActions(actions = actions, overflowMenuActions = overflowMenuActions) }, backgroundColor = OdsTheme.colors.component.topAppBar.barBackground, contentColor = OdsTheme.colors.component.topAppBar.barContent, elevation = if (elevated) AppBarDefaults.TopAppBarElevation else 0.dp diff --git a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt index bfd608a3b..5049cce64 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/appbar/top/OdsTopAppBarsCommon.kt @@ -24,24 +24,29 @@ import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import com.orange.ods.R -import com.orange.ods.compose.component.OdsComposable +import com.orange.ods.compose.component.content.OdsComponentContent import com.orange.ods.compose.component.content.OdsComponentIcon import com.orange.ods.compose.component.menu.OdsDropdownMenu import com.orange.ods.compose.component.menu.OdsDropdownMenuItem import com.orange.ods.compose.theme.OdsTheme @Composable -internal fun OdsTopAppBarOverflowMenu(items: List) { - Box { - var showMenu by remember { mutableStateOf(false) } - val contentDescription = stringResource(id = R.string.top_app_bar_overflow_menu_content_description) - val dropdownMenuAction = OdsTopAppBarActionButton(Icons.Filled.MoreVert, contentDescription, true) { showMenu = !showMenu } - dropdownMenuAction.Content() - OdsDropdownMenu( - items = items, - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) +internal fun OdsTopAppBarActions(actions: List, overflowMenuActions: List) { + val maxTotalActionCount = 3 + val maxActionCount = if (overflowMenuActions.isNotEmpty()) maxTotalActionCount - 1 else maxTotalActionCount + actions.take(maxActionCount).forEach { it.Content() } + if (overflowMenuActions.isNotEmpty()) { + Box { + var showMenu by remember { mutableStateOf(false) } + val contentDescription = stringResource(id = R.string.top_app_bar_overflow_menu_content_description) + val dropdownMenuAction = OdsTopAppBarActionButton(Icons.Filled.MoreVert, contentDescription, true) { showMenu = !showMenu } + dropdownMenuAction.Content() + OdsDropdownMenu( + items = overflowMenuActions, + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) + } } } From 3f28e7bfade3688832736fc7d06ffdeafda84bf4 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Fri, 21 Jul 2023 12:02:26 +0200 Subject: [PATCH 014/132] [#572] Review: Update documentation --- docs/components/AppBarsTop.md | 74 ++++++++++++++++++----------------- docs/components/Menus.md | 35 +++++++++-------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/docs/components/AppBarsTop.md b/docs/components/AppBarsTop.md index a1918cc4e..b51fb0d83 100644 --- a/docs/components/AppBarsTop.md +++ b/docs/components/AppBarsTop.md @@ -71,25 +71,27 @@ Add `OdsTopAppBar` composable to your Scaffold topBar: ```kotlin OdsTopAppBar( - title = { - Text(text = "Title") - }, - navigationIcon = { - Icon( - painter = painterResource(id = R.drawable.ic_back), - contentDescription = "content description" - ) - }, - onNavigationIconClick = { - // Do something - }, - actions = { + title = "Title", + navigationIcon = OdsTopAppBarNavigationIcon( + painter = painterResource(id = R.drawable.ic_back), + contentDescription = "content description", + onClick = { /* Do something */ } + ), + actions = listOf( OdsTopAppBarActionButton( - onClick = { }, painter = painterResource(id = R.drawable.ic_share), - contentDescription = "content description" - ) // Each action should be an `OdsTopAppBarActionButton`. They are displayed in a `Row`, so icons inside will be placed horizontally. - } + contentDescription = "content description", + onClick = { } + ), + // ... + ), + overflowMenuActions = listOf( + OdsTopAppBarOverflowMenuActionItem( + text = "Text", + onClick = { } + ), + // ... + ) ) ``` @@ -159,7 +161,7 @@ In menu/navigation icons: ```xml - + ``` In code: @@ -240,25 +242,27 @@ Then you can add `OdsLargeTopAppBar` composable to your Scaffold topBar: ```kotlin OdsLargeTopAppBar( - title = { - Text(text = "Title") - }, - navigationIcon = { - Icon( - painter = painterResource(id = R.drawable.ic_back), - contentDescription = "content description" - ) - }, - onNavigationIconClick = { - // Do something - }, - actions = { + title = "Title", + navigationIcon = OdsTopAppBarNavigationIcon( + painter = painterResource(id = R.drawable.ic_back), + contentDescription = "content description", + onClick = { /* Do something */ } + ), + actions = listOf( OdsTopAppBarActionButton( - onClick = { }, painter = painterResource(id = R.drawable.ic_share), - contentDescription = "content description" - ) // Each action should be an `OdsTopAppBarActionButton`. They are displayed in a `Row`, so icons inside will be placed horizontally. - }, + 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 ) ``` diff --git a/docs/components/Menus.md b/docs/components/Menus.md index ec5c65dcd..40b633717 100644 --- a/docs/components/Menus.md +++ b/docs/components/Menus.md @@ -45,24 +45,25 @@ var menuExpanded by remember { mutableStateOf(false) } OdsDropdownMenu( expanded = menuExpanded, onDismissRequest = { menuExpanded = false }, - offset = DpOffset(x = (-100).dp, y = (-10).dp) -) { - OdsDropdownMenuItem( - text = "Summer salad", - icon = painterResource(id = R.drawable.ic_salad), - onClick = { - // Do something - } + offset = DpOffset(x = (-100).dp, y = (-10).dp), + items = listOf( + OdsDropdownMenuItem( + text = "Summer salad", + icon = painterResource(id = R.drawable.ic_salad), + divider = true, // Allow to add a divider between the 2 items + onClick = { + // Do something + } + ), + OdsDropdownMenuItem( + text = "Brocoli soup", + icon = painterResource(id = R.drawable.ic_soup), + onClick = { + // Do something + } + ) ) - OdsDivider() // Allow to add a divider between the 2 items - OdsDropdownMenuItem( - text = "Brocoli soup", - icon = painterResource(id = R.drawable.ic_soup), - onClick = { - // Do something - } - ) -} +) ``` > **XML implementation** From b471bdbc602c17b60d1ac7c762d1923059c01055 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 3 Aug 2023 11:09:39 +0200 Subject: [PATCH 015/132] [#544] Add workflow to deploy Jekyll site with GitHub Pages --- .github/workflows/jekyll-gh-pages.yml | 61 +++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/jekyll-gh-pages.yml 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 + From 8f08448d0d9ed10e218e9cfdc0c39ee6910eca40 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Wed, 2 Aug 2023 14:53:10 +0200 Subject: [PATCH 016/132] [#588] Update OdsBottomNavigation API --- .../orange/ods/app/ui/MainBottomNavigation.kt | 10 +- .../ComponentBottomNavigation.kt | 47 +++---- changelog.md | 1 + docs/components/NavigationBottom.md | 29 ++-- .../bottomnavigation/OdsBottomNavigation.kt | 128 +++++++++++------- .../component/content/OdsComponentIcon.kt | 14 +- .../content/OdsComponentScopeContent.kt | 30 ++++ .../ods/compose/component/icon/OdsIcon.kt | 20 +-- .../compose/component/icon/OdsIconDefaults.kt | 22 +++ 9 files changed, 181 insertions(+), 120 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentScopeContent.kt create mode 100644 lib/src/main/java/com/orange/ods/compose/component/icon/OdsIconDefaults.kt diff --git a/app/src/main/java/com/orange/ods/app/ui/MainBottomNavigation.kt b/app/src/main/java/com/orange/ods/app/ui/MainBottomNavigation.kt index ba1ba062a..24fa5fc52 100644 --- a/app/src/main/java/com/orange/ods/app/ui/MainBottomNavigation.kt +++ b/app/src/main/java/com/orange/ods/app/ui/MainBottomNavigation.kt @@ -12,7 +12,6 @@ package com.orange.ods.app.ui import androidx.annotation.DrawableRes import androidx.annotation.StringRes -import androidx.compose.material.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource @@ -31,19 +30,20 @@ import com.orange.ods.app.ui.modules.ModulesScreen import com.orange.ods.app.ui.utilities.launchUrl import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigation import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigationItem +import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigationItemIcon @Composable fun MainBottomNavigation(items: Array, 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/components/bottomnavigation/ComponentBottomNavigation.kt b/app/src/main/java/com/orange/ods/app/ui/components/bottomnavigation/ComponentBottomNavigation.kt index 963bb55bf..5d9ccf9a3 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 @@ -73,16 +72,14 @@ fun ComponentBottomNavigation() { .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin)) .verticalScroll(rememberScrollState()) ) { - 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)) ) { - 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(2).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/changelog.md b/changelog.md index c4235f848..6b420fc07 100644 --- a/changelog.md +++ b/changelog.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - \[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)) ### Fixed diff --git a/docs/components/NavigationBottom.md b/docs/components/NavigationBottom.md index 846eb9a47..86e891b20 100644 --- a/docs/components/NavigationBottom.md +++ b/docs/components/NavigationBottom.md @@ -61,29 +61,30 @@ Here is an example: ```kotlin private data class NavigationItem(@StringRes val titleResId: Int, @DrawableRes val iconResId: Int) - val navigationItems = listOf( - NavigationItem(R.string.component_bottom_navigation_coffee, R.drawable.ic_coffee), - NavigationItem(R.string.component_bottom_navigation_cooking_pot, R.drawable.ic_cooking_pot), - NavigationItem(R.string.component_bottom_navigation_ice_cream, R.drawable.ic_ice_cream), - NavigationItem(R.string.component_bottom_navigation_restaurant, R.drawable.ic_restaurant), - NavigationItem(R.string.component_bottom_navigation_favorites, R.drawable.ic_heart) + val items = listOf( + R.string.component_bottom_navigation_coffee to R.drawable.ic_coffee, + R.string.component_bottom_navigation_cooking_pot to R.drawable.ic_cooking_pot, + R.string.component_bottom_navigation_ice_cream to R.drawable.ic_ice_cream, + R.string.component_bottom_navigation_restaurant to R.drawable.ic_restaurant, + R.string.component_bottom_navigation_favorites to R.drawable.ic_heart ) - val selectedItem = remember { mutableStateOf(navigationItems[0]) } + var selectedItemIndex by remember { mutableStateOf(0) } - OdsBottomNavigation { - for (item in navigationItems) { + OdsBottomNavigation( + items = items.mapIndexed { index, item -> OdsBottomNavigationItem( - icon = { Icon(painter = painterResource(id = item.iconResId), contentDescription = null) }, // contentDescription is null cause TalkBack already read the item's title - label = stringResource(id = item.titleResId), - selected = selectedItem.value.titleResId == item.titleResId, + icon = OdsBottomNavigationItemIcon(painter = painterResource(id = item.first), contentDescription = ""), // contentDescription is empty cause TalkBack already read the item's title + label = stringResource(id = item.second), + selected = selectedItemIndex == index, onClick = { - selectedItem.value = item + selectedItemIndex = index // Do what you want with a piece of code } ) } - } + ) + ) ``` > **XML implementation** diff --git a/lib/src/main/java/com/orange/ods/compose/component/bottomnavigation/OdsBottomNavigation.kt b/lib/src/main/java/com/orange/ods/compose/component/bottomnavigation/OdsBottomNavigation.kt index 4bccaee56..f5d3cfe93 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/bottomnavigation/OdsBottomNavigation.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/bottomnavigation/OdsBottomNavigation.kt @@ -10,11 +10,9 @@ package com.orange.ods.compose.component.bottomnavigation -import androidx.annotation.DrawableRes import androidx.compose.foundation.layout.RowScope import androidx.compose.material.BottomNavigation import androidx.compose.material.BottomNavigationItem -import androidx.compose.material.Icon import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -22,9 +20,14 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import com.orange.ods.compose.component.OdsComposable +import com.orange.ods.compose.component.content.OdsComponentIcon +import com.orange.ods.compose.component.content.OdsComponentScopeContent import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.theme.OdsTheme @@ -41,21 +44,21 @@ import com.orange.ods.compose.theme.OdsTheme * OdsBottomNavigation component. * * @param modifier optional [Modifier] for this OdsBottomNavigation - * @param content destinations inside this OdsBottomNavigation, this should contain multiple + * @param items destinations inside this OdsBottomNavigation, this contain multiple * [OdsBottomNavigationItem]s */ @Composable @OdsComposable fun OdsBottomNavigation( modifier: Modifier = Modifier, - content: @Composable RowScope.() -> Unit + items: List ) { BottomNavigation( modifier = modifier, // Need to define backgroundColor cause in Compose default backgroundColor is primarySurface backgroundColor = OdsTheme.colors.component.bottomNavigation.barBackground, contentColor = OdsTheme.colors.component.bottomNavigation.barContent, - content = content + content = { items.forEach { with(it) { Content() } } } ) } @@ -76,68 +79,95 @@ fun OdsBottomNavigation( * * @param selected whether this item is selected * @param onClick the callback to be invoked when this item is selected - * @param icon icon for this item, typically this will be an [Icon] - * @param modifier optional [Modifier] for this item + * @param icon icon for this item * @param enabled controls the enabled state of this item. When `false`, this item will not * be clickable and will appear disabled to accessibility services. * @param label optional text label for this item * @param alwaysShowLabel whether to always show the label for this item. If false, the label will * only be shown when this item is selected. */ -@Composable -@OdsComposable -fun RowScope.OdsBottomNavigationItem( - selected: Boolean, - onClick: () -> Unit, - icon: @Composable () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - label: String?, - alwaysShowLabel: Boolean = true -) { - BottomNavigationItem( - selected = selected, - onClick = onClick, - icon = icon, - modifier = modifier, - enabled = enabled, - label = label?.let { - { - Text( - text = label, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = OdsTheme.typography.caption - ) - } - }, - alwaysShowLabel = alwaysShowLabel, - selectedContentColor = OdsTheme.colors.component.bottomNavigation.itemSelected, - unselectedContentColor = OdsTheme.colors.component.bottomNavigation.itemUnselected - ) +class OdsBottomNavigationItem( + val selected: Boolean, + val onClick: () -> Unit, + val icon: OdsBottomNavigationItemIcon, + val enabled: Boolean = true, + val label: String? = null, + val alwaysShowLabel: Boolean = true +) : OdsComponentScopeContent() { + + @Composable + override fun RowScope.Content() { + BottomNavigationItem( + selected = selected, + onClick = onClick, + icon = { icon.Content() }, + enabled = enabled, + label = label?.let { + { + Text( + text = label, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = OdsTheme.typography.caption + ) + } + }, + alwaysShowLabel = alwaysShowLabel, + selectedContentColor = OdsTheme.colors.component.bottomNavigation.itemSelected, + unselectedContentColor = OdsTheme.colors.component.bottomNavigation.itemUnselected + ) + } +} + +/** + * An icon in an [OdsBottomNavigationItem]. + */ +class OdsBottomNavigationItemIcon : OdsComponentIcon { + + /** + * Creates an instance of [OdsBottomNavigationItemIcon]. + * + * @param painter Painter of the icon. + * @param contentDescription The content description associated to this [OdsBottomNavigationItemIcon]. + */ + constructor(painter: Painter, contentDescription: String) : super(painter as Any, contentDescription) + + /** + * Creates an instance of [OdsBottomNavigationItemIcon]. + * + * @param imageVector Image vector of the icon. + * @param contentDescription The content description associated to this [OdsBottomNavigationItemIcon]. + */ + constructor(imageVector: ImageVector, contentDescription: String) : super(imageVector as Any, contentDescription) + + /** + * Creates an instance of [OdsBottomNavigationItemIcon]. + * + * @param bitmap Image bitmap of the icon. + * @param contentDescription The content description associated to this [OdsBottomNavigationItemIcon]. + */ + constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap as Any, contentDescription) } @UiModePreviews.Default @Composable private fun PreviewOdsBottomNavigation() = Preview { - data class Item(@DrawableRes val iconResId: Int, val label: String) - val items = listOf( - Item(android.R.drawable.ic_dialog_email, "First item"), - Item(android.R.drawable.ic_dialog_map, "Second item"), - Item(android.R.drawable.ic_dialog_dialer, "Third item"), - Item(android.R.drawable.ic_dialog_info, "Fourth item") + android.R.drawable.ic_dialog_email to "First item", + android.R.drawable.ic_dialog_map to "Second item", + android.R.drawable.ic_dialog_dialer to "Third item", + android.R.drawable.ic_dialog_info to "Fourth item" ) var selectedItemIndex by remember { mutableStateOf(0) } - OdsBottomNavigation { - items.forEachIndexed { index, item -> + OdsBottomNavigation( + items = items.mapIndexed { index, item -> OdsBottomNavigationItem( - icon = { Icon(painter = painterResource(id = item.iconResId), contentDescription = null) }, - label = item.label, + icon = OdsBottomNavigationItemIcon(painter = painterResource(id = item.first), contentDescription = ""), + label = item.second, selected = selectedItemIndex == index, onClick = { selectedItemIndex = index } ) } - } + ) } diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt index faad1684e..b6099a701 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import com.orange.ods.compose.component.button.OdsIconButton import com.orange.ods.compose.component.icon.OdsIcon +import com.orange.ods.compose.component.icon.OdsIconDefaults import com.orange.ods.utilities.extension.orElse /** @@ -56,18 +57,11 @@ abstract class OdsComponentIcon protected constructor( @Composable override fun Content() { + val tint = tint.orElse { OdsIconDefaults.tint() } onClick?.let { onClick -> - tint?.let { tint -> - OdsIconButton(onClick = onClick, graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint, enabled = enabled) - }.orElse { - OdsIconButton(onClick = onClick, graphicsObject = graphicsObject, contentDescription = contentDescription, enabled = enabled) - } + OdsIconButton(onClick = onClick, graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint, enabled = enabled) }.orElse { - tint?.let { tint -> - OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint) - }.orElse { - OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription) - } + OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint) } } } diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentScopeContent.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentScopeContent.kt new file mode 100644 index 000000000..1cbe429b8 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentScopeContent.kt @@ -0,0 +1,30 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.content + +import androidx.compose.runtime.Composable + +/** + * The content in the scope of a component. + * + * This class is an equivalent to [OdsComponentContent] where the `Content` method is called against a specific scope (for instance a [androidx.compose.foundation.layout.RowScope]). + * + * @param T The type of the scope. + */ +abstract class OdsComponentScopeContent { + + /** + * The Jetpack Compose UI for this component content. + * Subclasses must implement this method to provide content. + */ + @Composable + internal abstract fun T.Content() +} diff --git a/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt b/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt index bd99f8b96..1a340cc5f 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIcon.kt @@ -17,15 +17,14 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector -import com.orange.ods.compose.theme.OdsDisplaySurface import com.orange.ods.utilities.extension.enable @Composable internal fun OdsIcon( graphicsObject: Any, contentDescription: String, - tint: Color, modifier: Modifier = Modifier, + tint: Color = OdsIconDefaults.tint(), enabled: Boolean = true, ) { val iconTint = tint.enable(enabled = enabled) @@ -36,20 +35,3 @@ internal fun OdsIcon( else -> {} } } - -@Composable -internal fun OdsIcon( - graphicsObject: Any, - contentDescription: String, - modifier: Modifier = Modifier, - displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default, - enabled: Boolean = true -) { - OdsIcon( - graphicsObject = graphicsObject, - contentDescription = contentDescription, - tint = displaySurface.themeColors.onSurface, - modifier = modifier, - enabled = enabled - ) -} diff --git a/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIconDefaults.kt b/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIconDefaults.kt new file mode 100644 index 000000000..d2499455d --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/icon/OdsIconDefaults.kt @@ -0,0 +1,22 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.icon + +import androidx.compose.material.LocalContentAlpha +import androidx.compose.material.LocalContentColor +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +internal object OdsIconDefaults { + + @Composable + fun tint(): Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current) +} From 71250cd8a7a4782defaf030f5db8c587c367b7f2 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Mon, 7 Aug 2023 13:32:24 +0200 Subject: [PATCH 017/132] [#588] Review: Show all bottom navigation items in code implementation --- .../ui/components/bottomnavigation/ComponentBottomNavigation.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5d9ccf9a3..387af0607 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 @@ -97,7 +97,7 @@ fun ComponentBottomNavigation() { name = OdsComposable.OdsBottomNavigation.name, parameters = { list("items") { - navigationItems.take(2).forEach { item -> + navigationItems.take(selectedNavigationItemCount.value).forEach { item -> classInstance(OdsBottomNavigationItem::class.java) { classInstance("icon", OdsBottomNavigationItemIcon::class.java) { painter() From 04e54d3df7e018aef4af47852f921d2991d78024 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Mon, 7 Aug 2023 13:32:46 +0200 Subject: [PATCH 018/132] [#588] Fix padding in bottom navigation demo --- .../ui/components/bottomnavigation/ComponentBottomNavigation.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 387af0607..adb5bb206 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 @@ -69,8 +69,8 @@ fun ComponentBottomNavigation() { Column( modifier = Modifier .fillMaxSize() - .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin)) .verticalScroll(rememberScrollState()) + .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin)) ) { OdsBottomNavigation( items = navigationItems.take(selectedNavigationItemCount.value).map { navigationItem -> From 585bd46be1af3415b13021959faccc71367a2dec Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Fri, 4 Aug 2023 11:47:15 +0200 Subject: [PATCH 019/132] [#578] Use Compose BOM and update Kotlin version to 1.9.0 --- app/build.gradle.kts | 7 +++---- .../java/com/orange/ods/app/ui/MainScreen.kt | 4 ++-- .../java/com/orange/ods/app/ui/MainState.kt | 2 +- .../com/orange/ods/app/ui/MainTabsState.kt | 8 ++++---- .../app/ui/components/ComponentsNavGraph.kt | 4 ++-- .../app/ui/components/tabs/ComponentTabs.kt | 8 ++++---- .../ods/app/ui/components/tabs/FixedTabRow.kt | 8 ++++---- .../tabs/MainTabsCustomizationState.kt | 10 +++++----- .../app/ui/components/tabs/ScrollableTabRow.kt | 6 +++--- .../orange/ods/app/ui/components/tabs/Tabs.kt | 8 ++++---- .../textfields/ComponentTextField.kt | 18 +++++++++--------- buildSrc/build.gradle.kts | 2 +- .../com/orange/ods/gradle/Dependencies.kt | 12 ++++++------ .../kotlin/com/orange/ods/gradle/Versions.kt | 10 +++++----- changelog.md | 2 ++ composable-processor/build.gradle.kts | 2 +- lib-xml/build.gradle.kts | 5 +++-- lib/build.gradle.kts | 5 +++-- .../textfield/OdsOutlinedTextField.kt | 8 +------- theme-contract/build.gradle.kts | 12 +++++++----- theme-innovation-cup/build.gradle.kts | 1 + theme-orange/build.gradle.kts | 1 + 22 files changed, 72 insertions(+), 71 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3480495e6..03c327bcd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -28,7 +28,7 @@ plugins { android { namespace = "com.orange.ods.app" - + compileSdk = Versions.compileSdk defaultConfig { @@ -99,7 +99,7 @@ android { } composeOptions { - kotlinCompilerExtensionVersion = Versions.compose + kotlinCompilerExtensionVersion = Versions.composeCompiler } packagingOptions { @@ -115,14 +115,13 @@ dependencies { implementation(project(":theme-innovation-cup")) implementation(Dependencies.accompanistFlowLayout) - implementation(Dependencies.accompanistPager) - implementation(Dependencies.accompanistPagerIndicators) implementation(Dependencies.accompanistSystemUiController) implementation(Dependencies.activityCompose) implementation(Dependencies.appCompat) implementation(Dependencies.browser) implementation(Dependencies.coil) implementation(Dependencies.coilCompose) + implementation(platform(Dependencies.composeBom)) implementation(Dependencies.composeMaterial3) implementation(Dependencies.composeUi) implementation(Dependencies.composeUiTooling) 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..787d4d7f6 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 @@ -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/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/tabs/ComponentTabs.kt b/app/src/main/java/com/orange/ods/app/ui/components/tabs/ComponentTabs.kt index b317fd7a8..15655447a 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 @@ -116,7 +116,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..e5cceb2e0 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 @@ -28,19 +31,16 @@ 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 kotlinx.coroutines.launch @@ -76,7 +76,7 @@ fun ComponentTextField(variant: Variant) { } } -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalFoundationApi::class) @Composable private fun TextFieldTextCustomization(textFieldCustomizationState: TextFieldCustomizationState) { val pagerState = rememberPagerState() @@ -102,7 +102,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) } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b1a25a7df..fe2adbb3c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -27,6 +27,6 @@ java { 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("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/Versions.kt b/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt index 497dc0aeb..80e9fdb57 100644 --- a/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt +++ b/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt @@ -21,8 +21,8 @@ object Versions { const val androidGradlePlugin = "7.3.1" 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/changelog.md b/changelog.md index 6b420fc07..3fb252c54 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- [\All\] Use Compose BOM and update Kotlin version to 1.9.0 ([#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)) @@ -16,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### 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)) ## [0.14.0](https://github.com/Orange-OpenSource/ods-android/compare/0.13.0...0.14.0) - 2023-07-12 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/lib-xml/build.gradle.kts b/lib-xml/build.gradle.kts index acb13b8c1..460f2e3c5 100644 --- a/lib-xml/build.gradle.kts +++ b/lib-xml/build.gradle.kts @@ -18,7 +18,7 @@ plugins { android { namespace = "com.orange.ods.xml" - + buildFeatures { compose = true viewBinding = true @@ -26,7 +26,7 @@ android { } composeOptions { - kotlinCompilerExtensionVersion = Versions.compose + kotlinCompilerExtensionVersion = Versions.composeCompiler } } @@ -35,6 +35,7 @@ dependencies { implementation(Dependencies.accompanistDrawablePainter) implementation(Dependencies.appCompat) + implementation(platform(Dependencies.composeBom)) implementation(Dependencies.composeMaterial) implementation(Dependencies.composeUi) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index f58a92215..2ee629f6f 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -12,7 +12,7 @@ import com.orange.ods.gradle.Dependencies import com.orange.ods.gradle.Versions plugins { - id("com.google.devtools.ksp") version "1.7.10-1.0.6" + id("com.google.devtools.ksp") version "1.9.0-1.0.13" id("library") id("github") id("kotlin-parcelize") @@ -37,7 +37,7 @@ android { } composeOptions { - kotlinCompilerExtensionVersion = Versions.compose + kotlinCompilerExtensionVersion = Versions.composeCompiler } sourceSets.configureEach { @@ -53,6 +53,7 @@ dependencies { implementation(Dependencies.accompanistFlowLayout) implementation(Dependencies.appCompat) + implementation(platform(Dependencies.composeBom)) api(Dependencies.composeMaterial) implementation(Dependencies.composeMaterial3) implementation(Dependencies.composeUi) diff --git a/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsOutlinedTextField.kt b/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsOutlinedTextField.kt index 03f7a4738..16644f186 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsOutlinedTextField.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsOutlinedTextField.kt @@ -24,14 +24,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.tooling.preview.PreviewParameter import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.theme.OdsTheme -import com.orange.ods.utilities.extension.orElse @Composable internal fun OdsOutlinedTextField( @@ -63,10 +60,7 @@ internal fun OdsOutlinedTextField( onValueChange(newValue) } }, - modifier = modifier.semantics { - contentDescription = - label.orElse { "Text field" } //TODO: Remove it when switching to Compose 1.4.0 which is supposed to fix the problem of OutlinedTextField TalkBack focus: https://issuetracker.google.com/issues/251162419 - }, + modifier = modifier, enabled = enabled, readOnly = readOnly, textStyle = OdsTheme.typography.subtitle1, diff --git a/theme-contract/build.gradle.kts b/theme-contract/build.gradle.kts index 61cf88e0d..7aa66c846 100644 --- a/theme-contract/build.gradle.kts +++ b/theme-contract/build.gradle.kts @@ -8,6 +8,7 @@ * / */ +import com.orange.ods.gradle.Dependencies import com.orange.ods.gradle.Versions plugins { @@ -16,18 +17,19 @@ plugins { android { namespace = "com.orange.ods.theme" - + buildFeatures { compose = true } composeOptions { - kotlinCompilerExtensionVersion = Versions.compose + kotlinCompilerExtensionVersion = Versions.composeCompiler } } dependencies { - implementation(com.orange.ods.gradle.Dependencies.material) - implementation(com.orange.ods.gradle.Dependencies.composeMaterial) - implementation(com.orange.ods.gradle.Dependencies.kotlinReflect) + implementation(platform(Dependencies.composeBom)) + implementation(Dependencies.composeMaterial) + implementation(Dependencies.kotlinReflect) + implementation(Dependencies.material) } \ No newline at end of file diff --git a/theme-innovation-cup/build.gradle.kts b/theme-innovation-cup/build.gradle.kts index 67dc0ab93..c606cce5c 100644 --- a/theme-innovation-cup/build.gradle.kts +++ b/theme-innovation-cup/build.gradle.kts @@ -24,6 +24,7 @@ android { dependencies { implementation(project(":theme-contract")) + implementation(platform(Dependencies.composeBom)) implementation(Dependencies.composeMaterial) implementation(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) diff --git a/theme-orange/build.gradle.kts b/theme-orange/build.gradle.kts index b2056cd26..77cdda941 100644 --- a/theme-orange/build.gradle.kts +++ b/theme-orange/build.gradle.kts @@ -24,6 +24,7 @@ android { dependencies { implementation(project(":theme-contract")) + implementation(platform(Dependencies.composeBom)) implementation(Dependencies.composeMaterial) implementation(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) From e130d81b9a754a14bf231af6eb1718021bb7232b Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Fri, 4 Aug 2023 15:23:56 +0200 Subject: [PATCH 020/132] [#578] Update Gradle to version 8.1 --- app/build.gradle.kts | 1 + .../com/orange/ods/app/ui/MainTopAppBar.kt | 4 +- .../ods/app/ui/about/AboutFileScreen.kt | 7 ++-- .../orange/ods/app/ui/about/AboutScreen.kt | 12 +++--- .../ui/components/ComponentDetailScreen.kt | 4 +- .../ods/app/ui/components/ComponentsScreen.kt | 8 ++-- .../appbars/top/ComponentTopAppBar.kt | 28 ++++++++----- .../ui/components/banners/ComponentBanners.kt | 6 +-- .../ComponentBottomNavigation.kt | 6 +-- .../ui/components/buttons/ButtonsContained.kt | 13 ++++-- .../ui/components/buttons/ButtonsOutlined.kt | 13 ++++-- .../app/ui/components/buttons/ButtonsText.kt | 13 ++++-- .../ui/components/buttons/ComponentButtons.kt | 10 ++--- .../components/buttons/icons/ButtonsIcon.kt | 13 ++++-- .../buttons/icons/ButtonsIconToggle.kt | 13 ++++-- .../buttons/icons/ButtonsIconToggleGroup.kt | 11 +++-- .../buttons/icons/ComponentButtonsIcons.kt | 2 +- .../app/ui/components/cards/CardHorizontal.kt | 4 +- .../ods/app/ui/components/cards/CardSmall.kt | 6 +-- .../cards/CardVerticalHeaderFirst.kt | 4 +- .../cards/CardVerticalImageFirst.kt | 4 +- .../app/ui/components/cards/ComponentCard.kt | 4 +- .../checkboxes/ComponentCheckboxes.kt | 4 +- .../ods/app/ui/components/chips/Chip.kt | 13 +++--- .../ods/app/ui/components/chips/ChipFilter.kt | 8 ++-- .../ui/components/dialogs/ComponentDialog.kt | 2 +- .../ComponentFloatingActionButton.kt | 8 ++-- .../imageitem/ComponentImageItem.kt | 10 ++--- .../app/ui/components/lists/ComponentLists.kt | 10 ++--- .../app/ui/components/menus/MenuDropdown.kt | 13 +++--- .../components/menus/MenuExposedDropdown.kt | 9 ++-- .../ComponentModalDrawers.kt | 6 +-- .../components/progress/ProgressCircular.kt | 4 +- .../ui/components/progress/ProgressLinear.kt | 6 +-- .../radiobuttons/ComponentRadioButtons.kt | 4 +- .../sheets/ComponentSheetsBottom.kt | 8 ++-- .../ui/components/sliders/ComponentSliders.kt | 4 +- .../snackbars/ComponentSnackbars.kt | 9 ++-- .../components/switches/ComponentSwitches.kt | 4 +- .../app/ui/components/tabs/ComponentTabs.kt | 4 +- .../textfields/ComponentTextField.kt | 14 +++---- .../app/ui/components/textfields/TextField.kt | 4 +- .../textfields/TextFieldPassword.kt | 2 +- .../utilities/ComponentLaunchContentColumn.kt | 16 ++++---- .../ods/app/ui/guidelines/GuidelinesScreen.kt | 4 +- .../guidelines/color/GuidelineColorScreen.kt | 41 ++++++++++--------- .../ui/guidelines/spacing/GuidelineSpacing.kt | 15 ++++--- .../spacing/GuidelineSpacingScreen.kt | 9 ++-- .../typography/GuidelineTypographyScreen.kt | 14 +++---- .../composable/CodeImplementation.kt | 8 ++-- .../composable/DetailScreenHeader.kt | 7 ++-- .../ods/app/ui/utilities/composable/Texts.kt | 8 ++-- buildSrc/build.gradle.kts | 12 +++--- .../kotlin/com/orange/ods/gradle/Versions.kt | 2 +- buildSrc/src/main/kotlin/library.gradle.kts | 1 - changelog.md | 2 +- docs/components/Chips.md | 2 +- docs/components/Snackbars.md | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- lib/build.gradle.kts | 1 + .../ods/theme/guideline/OdsGuideline.kt | 27 ++++++------ theme-orange/build.gradle.kts | 1 + .../orange/guideline/OrangeGuidelineColors.kt | 8 ++-- 63 files changed, 282 insertions(+), 234 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 03c327bcd..e808840a1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -93,6 +93,7 @@ android { } buildFeatures { + buildConfig = true compose = true viewBinding = true dataBinding = true 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 5dc4bd3d7..ce627b0f4 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 @@ -216,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..31aaf6a03 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 @@ -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/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/ComponentsScreen.kt b/app/src/main/java/com/orange/ods/app/ui/components/ComponentsScreen.kt index 873ffc9d1..e0b9cbc42 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,10 +27,10 @@ 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.compose.component.card.OdsSmallCard import com.orange.ods.utilities.extension.orElse @Composable @@ -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 dbf282dd2..824632300 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 @@ -86,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) { @@ -94,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 { @@ -145,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 { @@ -167,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)) } } @@ -182,7 +188,7 @@ private fun CustomizationBottomSheetContent(customizationState: TopAppBarCustomi 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)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_app_bars_top_large_scroll_behavior_none, value = TopAppBarCustomizationState.ScrollBehavior.None) @@ -199,7 +205,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), @@ -219,8 +225,8 @@ private fun CustomizationBottomSheetContent(customizationState: TopAppBarCustomi OdsChoiceChipsFlowRow( selectedChip = title, modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.spacing_m)) - .padding(bottom = dimensionResource(id = R.dimen.spacing_s)), + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) + .padding(bottom = dimensionResource(id = com.orange.ods.R.dimen.spacing_s)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_app_bars_top_large_title_one_line, value = TopAppBarCustomizationState.Title.Short) 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..f209e18fb 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 @@ -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 ) @@ -130,7 +130,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( 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 adb5bb206..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 @@ -57,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,7 +70,7 @@ fun ComponentBottomNavigation() { modifier = Modifier .fillMaxSize() .verticalScroll(rememberScrollState()) - .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)) ) { OdsBottomNavigation( items = navigationItems.take(selectedNavigationItemCount.value).map { navigationItem -> @@ -91,7 +91,7 @@ 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, 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..5cf3bf2fe 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 @@ -45,7 +45,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 +63,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 +76,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( @@ -106,7 +106,12 @@ 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( 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..f53f929f3 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 @@ -41,19 +41,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( @@ -80,7 +80,12 @@ 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( 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..af60e59f1 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 @@ -44,7 +44,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 +58,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 +71,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( @@ -101,7 +101,12 @@ 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( 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..40d230670 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 @@ -62,7 +62,7 @@ fun ComponentButtons(variant: Variant) { Subtitle(textRes = R.string.component_button_style_functional, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = buttonStyle, - 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)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_button_style_functional_positive, value = OdsButtonStyle.FunctionalPositive) @@ -72,7 +72,7 @@ fun ComponentButtons(variant: Variant) { Subtitle(textRes = R.string.component_style, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = textButtonStyle, - 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)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_button_style_primary, value = OdsTextButtonStyle.Primary) @@ -125,13 +125,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..b37c67633 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 @@ -45,7 +45,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 +56,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,7 +66,7 @@ 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( @@ -92,7 +92,12 @@ 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( 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..98c66411a 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 @@ -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,7 +75,7 @@ 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( @@ -105,7 +105,12 @@ private fun IconToggleButton( val checkedIconResId = R.drawable.ic_heart val iconContentDescription = stringResource(id = R.string.component_button_icon_toggle_favorite_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( 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..ba3a5e217 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 @@ -51,7 +50,7 @@ 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( @@ -61,7 +60,7 @@ fun ButtonsIconToggleGroup(customizationState: ButtonIconCustomizationState) { 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( @@ -74,7 +73,7 @@ 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( @@ -109,8 +108,8 @@ 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) 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..eb8940682 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 @@ -43,7 +43,7 @@ fun CardHorizontal(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) @@ -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..38fe6e7b7 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,7 +45,7 @@ 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) @@ -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..7e6f5b921 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,7 +43,7 @@ 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) @@ -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..763e5c812 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 @@ -50,7 +50,7 @@ fun ComponentCard(variant: Variant) { 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)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_card_horizontal_image_position_start, value = OdsHorizontalCardImagePosition.Start) @@ -71,7 +71,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..21377c57b 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 @@ -61,7 +61,7 @@ fun Chip(variant: Variant) { Subtitle(textRes = R.string.component_element_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = leadingElement, - 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)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_element_none, value = LeadingElement.None) @@ -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() @@ -120,7 +123,7 @@ private fun Chip(chipCustomizationState: ChipCustomizationState) { } } - 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( @@ -161,7 +164,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( 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..53ce9a3f1 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 @@ -59,7 +59,7 @@ 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)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_element_none, value = ChipCustomizationState.LeadingElement.None) @@ -75,7 +75,7 @@ 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, @@ -96,12 +96,12 @@ fun ChipFilter() { } } - 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", "dimensionResource(id = com.orange.ods.R.dimen.spacing_s))") } ) { recipe.ingredients.forEachIndexed { index, ingredient -> FunctionCallCode( 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..e101d007b 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 @@ -68,7 +68,7 @@ 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, 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..1e9a7306a 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 @@ -54,8 +54,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() @@ -91,7 +91,7 @@ fun ComponentFloatingActionButton() { Subtitle(textRes = R.string.component_size, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = size, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_floating_action_button_size_default, value = FabCustomizationState.Size.Default) @@ -109,7 +109,7 @@ 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, 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 index 7ea36ef3e..d10c4dceb 100644 --- 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 @@ -64,7 +64,7 @@ fun ComponentImageItem() { bottomSheetContent = { OdsChoiceChipsFlowRow( selectedChip = type, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { Subtitle(textRes = R.string.component_element_type) @@ -81,14 +81,14 @@ fun ComponentImageItem() { modifier = Modifier .fillMaxSize() .padding( - top = dimensionResource(id = R.dimen.screen_horizontal_margin), - start = dimensionResource(id = R.dimen.screen_horizontal_margin) + 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) { - OdsImageItemTitleType.Below -> imageSize + dimensionResource(id = R.dimen.image_item_title_height) + OdsImageItemTitleType.Below -> imageSize + dimensionResource(id = com.orange.ods.R.dimen.image_item_title_height) OdsImageItemTitleType.Overlay, OdsImageItemTitleType.None -> imageSize } @@ -110,7 +110,7 @@ fun ComponentImageItem() { displayTitle = if (isOverlay) OdsImageItemTitleType.Overlay else if (isBelow) OdsImageItemTitleType.Below else OdsImageItemTitleType.None, ) CodeImplementationColumn( - modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_m)) + modifier = Modifier.padding(end = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) ) { FunctionCallCode( name = OdsComposable.OdsImageItem.name, 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/lists/ComponentLists.kt index a41976ae8..99429445d 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/lists/ComponentLists.kt @@ -67,7 +67,7 @@ fun ComponentLists() { @Composable private fun ComponentListsBottomSheetContent(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), @@ -79,7 +79,7 @@ private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListIte Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = listItemCustomizationState.selectedLeading, - 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)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_list_leading_none, value = ListItemCustomizationState.Leading.None) @@ -92,7 +92,7 @@ private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListIte Subtitle(textRes = R.string.component_list_trailing, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = listItemCustomizationState.selectedTrailing, - 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)), outlinedChips = true ) { listItemCustomizationState.trailings.forEach { trailing -> @@ -185,8 +185,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/menus/MenuDropdown.kt b/app/src/main/java/com/orange/ods/app/ui/components/menus/MenuDropdown.kt index e813243c4..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 @@ -70,19 +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) ) val dividerIndex = 1 - Box(modifier = Modifier.padding(top = dimensionResource(id = R.dimen.spacing_s))) { + 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( @@ -110,7 +113,7 @@ fun MenuDropdown() { } 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, 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..806105800 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 @@ -118,7 +118,7 @@ fun ComponentModalDrawers() { OdsChoiceChipsFlowRow( selectedChip = header, outlinedChips = true, - 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)), ) { Subtitle(textRes = R.string.component_modal_drawer_header_image) OdsChoiceChip(textRes = R.string.component_element_avatar, value = ComponentNavigationDrawersContentState.HeaderImage.Avatar) @@ -145,7 +145,7 @@ fun ComponentModalDrawers() { OdsChoiceChipsFlowRow( selectedChip = content, outlinedChips = true, - 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)), ) { Subtitle(textRes = R.string.component_modal_drawer_list_example) OdsChoiceChip( @@ -172,7 +172,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..d8d641484 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 @@ -61,7 +61,7 @@ fun ProgressCircular() { bottomSheetContent = { OdsChoiceChipsFlowRow( selectedChip = type, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { Subtitle(textRes = R.string.component_element_type) @@ -83,7 +83,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..bf989a486 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 @@ -63,7 +63,7 @@ fun ProgressLinear() { bottomSheetContent = { OdsChoiceChipsFlowRow( selectedChip = type, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { Subtitle(textRes = R.string.component_element_type) @@ -98,7 +98,7 @@ fun ProgressLinear() { showCurrentValue = hasCurrentValue, icon = if (hasIcon) 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,7 +107,7 @@ 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, 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..81670c8e0 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,19 +67,19 @@ 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)) + modifier = Modifier.padding(top = dimensionResource(id = com.orange.ods.R.dimen.spacing_xs)) ) { OdsChoiceChip(textRes = R.string.component_element_empty, value = SheetsBottomCustomizationState.Content.Empty) OdsChoiceChip(textRes = R.string.component_element_example, value = SheetsBottomCustomizationState.Content.Example) 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 15655447a..e1bc85c04 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 @@ -80,7 +80,7 @@ fun ComponentTabs(variant: Variant, upPress: () -> Unit) { Subtitle(textRes = R.string.component_element_icon, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = tabsCustomizationState.tabIconType, - 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)), outlinedChips = true ) { OdsChoiceChip( @@ -106,7 +106,7 @@ fun ComponentTabs(variant: Variant, upPress: () -> Unit) { ) 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), 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 e5cceb2e0..e193cfca7 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 @@ -63,8 +63,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) { @@ -132,7 +132,7 @@ 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)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_text_field_input_type_single_line, value = TextFieldCustomizationState.InputType.SingleLine) @@ -151,7 +151,7 @@ private fun ComponentCustomizationContent(textFieldCustomizationState: TextField Subtitle(textRes = R.string.component_element_trailing, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = textFieldCustomizationState.trailingElement, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_element_none, value = TextFieldCustomizationState.TrailingElement.None) @@ -171,7 +171,7 @@ private fun KeyboardCustomizationContent(textFieldCustomizationState: TextFieldC OdsChoiceChipsFlowRow( selectedChip = textFieldCustomizationState.softKeyboardType, modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.spacing_m)), + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { TextFieldCustomizationState.SoftKeyboardType.values().forEach { softKeyboardType -> @@ -187,7 +187,7 @@ 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)), + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)), outlinedChips = true ) { TextFieldCustomizationState.SoftKeyboardAction.values().forEach { softKeyboardAction -> @@ -202,7 +202,7 @@ private fun DisplayTypeCustomization(displayType: MutableState 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/utilities/composable/CodeImplementation.kt b/app/src/main/java/com/orange/ods/app/ui/utilities/composable/CodeImplementation.kt index 27f314dbc..62be7bb0a 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 @@ -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() } } 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/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fe2adbb3c..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("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/Versions.kt b/buildSrc/src/main/kotlin/com/orange/ods/gradle/Versions.kt index 80e9fdb57..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,7 +18,7 @@ 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 composeBom = "2023.06.01" diff --git a/buildSrc/src/main/kotlin/library.gradle.kts b/buildSrc/src/main/kotlin/library.gradle.kts index 44e62dc7d..460844f93 100644 --- a/buildSrc/src/main/kotlin/library.gradle.kts +++ b/buildSrc/src/main/kotlin/library.gradle.kts @@ -10,7 +10,6 @@ import com.orange.ods.gradle.MavenCentralPublishPluginExtension import com.orange.ods.gradle.Versions -import gradle.kotlin.dsl.accessors._ecf15b363eddec123ebdbce713433fa8.android plugins { id("com.android.library") diff --git a/changelog.md b/changelog.md index 3fb252c54..e31460161 100644 --- a/changelog.md +++ b/changelog.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- [\All\] Use Compose BOM and update Kotlin version to 1.9.0 ([#578](https://github.com/Orange-OpenSource/ods-android/issues/578)) +- [\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)) diff --git a/docs/components/Chips.md b/docs/components/Chips.md index ecf617a9c..1200e4ed2 100644 --- a/docs/components/Chips.md +++ b/docs/components/Chips.md @@ -245,7 +245,7 @@ Use `OdsChoiceChipsFlowRow` composable: ```kotlin OdsChoiceChipsFlowRow( selectedChip = iconTypeState, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing_m)) + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.spacing_m)) ) { SelectableChip(textRes = R.string.component_icon_leading, value = IconType.Leading) SelectableChip(textRes = R.string.component_icon_top, value = IconType.Top) diff --git a/docs/components/Snackbars.md b/docs/components/Snackbars.md index 559d01606..3cc7679e4 100644 --- a/docs/components/Snackbars.md +++ b/docs/components/Snackbars.md @@ -69,8 +69,8 @@ Scaffold( }) { OdsButton( modifier = Modifier - .padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) - .padding(top = dimensionResource(id = R.dimen.screen_vertical_margin)), + .padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)) + .padding(top = dimensionResource(id = com.orange.ods.R.dimen.screen_vertical_margin)), text = "Show snackbar", onClick = { coroutineScope.launch { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0a829c871..20f5a5e48 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -7,7 +7,7 @@ # #Fri May 13 10:10:34 CEST 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 2ee629f6f..1dcd2e0f1 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -33,6 +33,7 @@ android { } buildFeatures { + buildConfig = true compose = true } diff --git a/theme-contract/src/main/java/com/orange/ods/theme/guideline/OdsGuideline.kt b/theme-contract/src/main/java/com/orange/ods/theme/guideline/OdsGuideline.kt index 7b9b6d4b1..587be3be8 100644 --- a/theme-contract/src/main/java/com/orange/ods/theme/guideline/OdsGuideline.kt +++ b/theme-contract/src/main/java/com/orange/ods/theme/guideline/OdsGuideline.kt @@ -11,7 +11,6 @@ package com.orange.ods.theme.guideline import androidx.compose.material.Typography -import com.orange.ods.theme.R /** * This class defines what will be displayed in the ODS application guideline part. @@ -36,19 +35,19 @@ open class OdsGuideline(private val typography: Typography) { return properties.mapNotNull { property -> val (name, xmlResource) = when (property) { - ::h1 -> "Headline 1" to R.attr.textAppearanceHeadline1 - ::h2 -> "Headline 2" to R.attr.textAppearanceHeadline2 - ::h3 -> "Headline 3" to R.attr.textAppearanceHeadline3 - ::h4 -> "Headline 4" to R.attr.textAppearanceHeadline4 - ::h5 -> "Headline 5" to R.attr.textAppearanceHeadline5 - ::h6 -> "Headline 6" to R.attr.textAppearanceHeadline6 - ::subtitle1 -> "Subtitle1" to R.attr.textAppearanceSubtitle1 - ::subtitle2 -> "Subtitle2" to R.attr.textAppearanceSubtitle2 - ::body1 -> "Body1" to R.attr.textAppearanceBody1 - ::body2 -> "Body2" to R.attr.textAppearanceBody2 - ::button -> "BUTTON" to R.attr.textAppearanceButton - ::caption -> "Caption" to R.attr.textAppearanceCaption - ::overline -> "Overline" to R.attr.textAppearanceOverline + ::h1 -> "Headline 1" to com.google.android.material.R.attr.textAppearanceHeadline1 + ::h2 -> "Headline 2" to com.google.android.material.R.attr.textAppearanceHeadline2 + ::h3 -> "Headline 3" to com.google.android.material.R.attr.textAppearanceHeadline3 + ::h4 -> "Headline 4" to com.google.android.material.R.attr.textAppearanceHeadline4 + ::h5 -> "Headline 5" to com.google.android.material.R.attr.textAppearanceHeadline5 + ::h6 -> "Headline 6" to com.google.android.material.R.attr.textAppearanceHeadline6 + ::subtitle1 -> "Subtitle1" to com.google.android.material.R.attr.textAppearanceSubtitle1 + ::subtitle2 -> "Subtitle2" to com.google.android.material.R.attr.textAppearanceSubtitle2 + ::body1 -> "Body1" to com.google.android.material.R.attr.textAppearanceBody1 + ::body2 -> "Body2" to com.google.android.material.R.attr.textAppearanceBody2 + ::button -> "BUTTON" to com.google.android.material.R.attr.textAppearanceButton + ::caption -> "Caption" to com.google.android.material.R.attr.textAppearanceCaption + ::overline -> "Overline" to com.google.android.material.R.attr.textAppearanceOverline else -> null to null } if (name != null && xmlResource != null) { diff --git a/theme-orange/build.gradle.kts b/theme-orange/build.gradle.kts index 77cdda941..c2463232c 100644 --- a/theme-orange/build.gradle.kts +++ b/theme-orange/build.gradle.kts @@ -28,4 +28,5 @@ dependencies { implementation(Dependencies.composeMaterial) implementation(Dependencies.hiltAndroid) kapt(Dependencies.hiltCompiler) + implementation(Dependencies.material) } diff --git a/theme-orange/src/main/java/com/orange/ods/theme/orange/guideline/OrangeGuidelineColors.kt b/theme-orange/src/main/java/com/orange/ods/theme/orange/guideline/OrangeGuidelineColors.kt index bfaae7115..6b1cbec7e 100644 --- a/theme-orange/src/main/java/com/orange/ods/theme/orange/guideline/OrangeGuidelineColors.kt +++ b/theme-orange/src/main/java/com/orange/ods/theme/orange/guideline/OrangeGuidelineColors.kt @@ -33,13 +33,13 @@ import com.orange.ods.theme.orange.Yellow200 import com.orange.ods.theme.orange.Yellow300 val OrangeGuidelineColors = listOf( - GuidelineColor(OdsColors::primary, GuidelineColorType.Core, "Orange 100", "Orange 200", R.attr.colorPrimary), - GuidelineColor(OdsColors::background, GuidelineColorType.Core, "White 100", "Black 900", R.attr.backgroundColor), - GuidelineColor(OdsColors::surface, GuidelineColorType.Core, "White 100", "Secondary Background", R.attr.colorSurface), + GuidelineColor(OdsColors::primary, GuidelineColorType.Core, "Orange 100", "Orange 200", com.google.android.material.R.attr.colorPrimary), + GuidelineColor(OdsColors::background, GuidelineColorType.Core, "White 100", "Black 900", com.google.android.material.R.attr.backgroundColor), + GuidelineColor(OdsColors::surface, GuidelineColorType.Core, "White 100", "Secondary Background", com.google.android.material.R.attr.colorSurface), GuidelineColor(::ObsGrey700, GuidelineColorType.Core, "OBS Grey 700", xmlResource = R.color.core_obsgrey_700), GuidelineColor(OdsFunctionalColors::positive, GuidelineColorType.Functional, "Positive 200", "Positive 100", R.attr.functionalPositive), - GuidelineColor(OdsColors::error, GuidelineColorType.Functional, "Negative 200", "Negative 100", R.attr.colorError), + GuidelineColor(OdsColors::error, GuidelineColorType.Functional, "Negative 200", "Negative 100", com.google.android.material.R.attr.colorError), GuidelineColor(OdsFunctionalColors::info, GuidelineColorType.Functional, "Info 200", "Info 100", R.attr.functionalInfo), GuidelineColor(OdsFunctionalColors::alert, GuidelineColorType.Functional, "Alert 200", "Alert 100", R.attr.functionalAlert), From 4fd8098df758d66f467d20410762808cc4556c80 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Fri, 4 Aug 2023 15:58:16 +0200 Subject: [PATCH 021/132] [#578] Fix GitHub Actions error --- .github/workflows/android-build.yml | 8 ++++---- .github/workflows/app-distribution-daily.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 6b7a4b6bb..41372706b 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 @@ -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,7 +163,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Publish release to Google Play Store run: | 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 From b0d03907442a624287ffde2490ac6a5fd83bdf3f Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 7 Aug 2023 14:43:58 +0200 Subject: [PATCH 022/132] [#578] Replace capitalize deprecated function by replaceFirstChar --- buildSrc/src/main/kotlin/firebase.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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"] ) From 61d475fcb9621790d154b93b7df769cf0e8e621f Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 7 Aug 2023 14:44:28 +0200 Subject: [PATCH 023/132] [#578] Use packaging instead of packagingOptions which is deprecated --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e808840a1..83a3b16b7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -103,7 +103,7 @@ android { kotlinCompilerExtensionVersion = Versions.composeCompiler } - packagingOptions { + packaging { with(resources.excludes) { add("/META-INF/{AL2.0,LGPL2.1}") } From 4d225a3d63d180ff09b9938cf0b401265286f965 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 6 Jul 2023 17:32:31 +0200 Subject: [PATCH 024/132] [#567] Vocalize icon toggle buttons state --- .../button/OdsIconToggleButtonsRow.kt | 11 +++++++++-- .../ods/compose/component/chip/OdsChip.kt | 8 ++------ .../component/chip/OdsChoiceChipsFlowRow.kt | 3 ++- .../utilities/AccessibilityComposables.kt | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/utilities/AccessibilityComposables.kt diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt index 0c88a152d..d16875f4d 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt @@ -32,11 +32,14 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.unit.dp import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.utilities.DisabledInteractionSource import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews +import com.orange.ods.compose.component.utilities.selectionStateDescription import com.orange.ods.compose.theme.OdsDisplaySurface import com.orange.ods.utilities.extension.enable @@ -108,12 +111,13 @@ private fun IconToggleButtonsRowItem( ) { val iconTint = buttonToggleIconColor(displaySurface, selected, iconToggleButton.enabled) val backgroundAlpha = if (selected && iconToggleButton.enabled) 0.12f else 0f + val iconToggleButtonStateDescription = selectionStateDescription(selected = selected) Icon( modifier = Modifier .background( color = buttonToggleBackgroundColor(displaySurface) - .copy(alpha = if (iconToggleButton.enabled) animateFloatAsState(backgroundAlpha).value else backgroundAlpha) + .copy(alpha = if (iconToggleButton.enabled) animateFloatAsState(backgroundAlpha, label = "").value else backgroundAlpha) ) .padding(12.dp) .run { @@ -122,10 +126,13 @@ private fun IconToggleButtonsRowItem( } else { this } + } + .semantics { + stateDescription = iconToggleButtonStateDescription }, painter = iconToggleButton.icon, contentDescription = iconToggleButton.iconDescription, - tint = if (iconToggleButton.enabled) animateColorAsState(iconTint).value else iconTint + tint = if (iconToggleButton.enabled) animateColorAsState(iconTint, label = "").value else iconTint ) } diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt index 7c964f8b6..23759c2a9 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChip.kt @@ -28,7 +28,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.tooling.preview.PreviewParameter @@ -40,6 +39,7 @@ import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.OdsImageCircleShape import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews +import com.orange.ods.compose.component.utilities.selectionStateDescription import com.orange.ods.compose.theme.OdsTheme import com.orange.ods.utilities.extension.enable import com.orange.ods.utilities.extension.noRippleClickable @@ -80,7 +80,7 @@ fun OdsChip( leadingContentDescription: String? = null, onCancel: (() -> Unit)? = null ) { - val chipStateDescription = odsChipStateDescription(selected) + val chipStateDescription = selectionStateDescription(selected) Chip( onClick = onClick, @@ -136,10 +136,6 @@ fun OdsChip( } } -@Composable -internal fun odsChipStateDescription(selected: Boolean) = - if (selected) stringResource(id = R.string.state_selected) else stringResource(id = R.string.state_not_selected) - @OptIn(ExperimentalMaterialApi::class) @Composable private fun odsChipColors(outlined: Boolean, selected: Boolean): ChipColors { diff --git a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt index 9b569fdcf..ad1ac5264 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/chip/OdsChoiceChipsFlowRow.kt @@ -29,6 +29,7 @@ import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews +import com.orange.ods.compose.component.utilities.selectionStateDescription /** * Displays a full width [FlowRow] containing customized choice chips [OdsChoiceChipsFlowRowScope.OdsChoiceChip]. @@ -67,7 +68,7 @@ fun OdsChoiceChipsFlowRow( @OdsComposable fun OdsChoiceChipsFlowRowScope.OdsChoiceChip(text: String, value: T, modifier: Modifier = Modifier, enabled: Boolean = true) { val selected = selectedChip.value == value - val chipStateDescription = odsChipStateDescription(selected = selected) + val chipStateDescription = selectionStateDescription(selected = selected) OdsChip( text = text, modifier = modifier.semantics { diff --git a/lib/src/main/java/com/orange/ods/compose/component/utilities/AccessibilityComposables.kt b/lib/src/main/java/com/orange/ods/compose/component/utilities/AccessibilityComposables.kt new file mode 100644 index 000000000..063af82a4 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/utilities/AccessibilityComposables.kt @@ -0,0 +1,19 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.utilities + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import com.orange.ods.R + +@Composable +internal fun selectionStateDescription(selected: Boolean) = + if (selected) stringResource(id = R.string.state_selected) else stringResource(id = R.string.state_not_selected) \ No newline at end of file From 81f28974c02276778050293be6f0bb80a6b23c10 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 6 Jul 2023 17:40:39 +0200 Subject: [PATCH 025/132] [#567] Update changelog --- changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.md b/changelog.md index e31460161..40537e8d5 100644 --- a/changelog.md +++ b/changelog.md @@ -42,6 +42,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - \[Lib\] Fix a bug where `enabled` property of `OdsIconToggleButtonsRowItem` has no effect ([#329](https://github.com/Orange-OpenSource/ods-android/issues/329)) +### Fixed + +- \[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 ### Added From e59658cf7f7b676d2db7479c93961b79b946c4be Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 7 Aug 2023 15:49:34 +0200 Subject: [PATCH 026/132] [#567] Review: Rename files --- .../utilities/{AccessibilityComposables.kt => Accessibility.kt} | 0 .../compose/component/utilities/{ImageComposables.kt => Image.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename lib/src/main/java/com/orange/ods/compose/component/utilities/{AccessibilityComposables.kt => Accessibility.kt} (100%) rename lib/src/main/java/com/orange/ods/compose/component/utilities/{ImageComposables.kt => Image.kt} (100%) diff --git a/lib/src/main/java/com/orange/ods/compose/component/utilities/AccessibilityComposables.kt b/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt similarity index 100% rename from lib/src/main/java/com/orange/ods/compose/component/utilities/AccessibilityComposables.kt rename to lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt diff --git a/lib/src/main/java/com/orange/ods/compose/component/utilities/ImageComposables.kt b/lib/src/main/java/com/orange/ods/compose/component/utilities/Image.kt similarity index 100% rename from lib/src/main/java/com/orange/ods/compose/component/utilities/ImageComposables.kt rename to lib/src/main/java/com/orange/ods/compose/component/utilities/Image.kt From dd484c96434ba0fdc9369b81fe9138791930d6eb Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 7 Aug 2023 15:50:19 +0200 Subject: [PATCH 027/132] [#567] Add missing kdoc for utilities --- .../orange/ods/compose/component/utilities/Accessibility.kt | 5 +++++ .../compose/component/utilities/DisabledInteractionSource.kt | 3 +++ 2 files changed, 8 insertions(+) diff --git a/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt b/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt index 063af82a4..42d0baf2f 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt @@ -14,6 +14,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import com.orange.ods.R +/** + * Returns the selection state ready for vocalization according to the [selected] provided value. + * + * @param selected Set it to true if the element is selected, false otherwise. + */ @Composable internal fun selectionStateDescription(selected: Boolean) = if (selected) stringResource(id = R.string.state_selected) else stringResource(id = R.string.state_not_selected) \ No newline at end of file diff --git a/lib/src/main/java/com/orange/ods/compose/component/utilities/DisabledInteractionSource.kt b/lib/src/main/java/com/orange/ods/compose/component/utilities/DisabledInteractionSource.kt index 008ebadf1..e9643780e 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/utilities/DisabledInteractionSource.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/utilities/DisabledInteractionSource.kt @@ -15,6 +15,9 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow +/** + * Prevent ripple effect on element click. + */ class DisabledInteractionSource : MutableInteractionSource { override val interactions: Flow = emptyFlow() override suspend fun emit(interaction: Interaction) {} From 7d876d921c414e71a5818fd8892f31320db542d8 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 7 Aug 2023 15:50:40 +0200 Subject: [PATCH 028/132] [#567] Remove useless annotation --- .../ods/compose/component/textfield/OdsTextFieldsCommon.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsTextFieldsCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsTextFieldsCommon.kt index 54bd98b9c..55a3df33a 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsTextFieldsCommon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/textfield/OdsTextFieldsCommon.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding -import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.Text @@ -83,7 +82,6 @@ internal fun OdsTextFieldIcon(painter: Painter, contentDescription: String?, onC } } -@OptIn(ExperimentalMaterialApi::class) internal fun getTrailing(trailing: OdsTextFieldTrailing, value: String, enabled: Boolean = true): @Composable (() -> Unit) { return when (trailing) { is OdsTextTrailing -> { From c0fb62af9d937e8f1e269a109a402e466d9bffde Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Mon, 7 Aug 2023 16:20:26 +0200 Subject: [PATCH 029/132] [#506] The number of search results is now vocalized --- .../orange/ods/app/ui/search/SearchScreen.kt | 27 +++++++++++++++++++ app/src/main/res/values/strings.xml | 5 ++++ changelog.md | 7 ++--- 3 files changed, 36 insertions(+), 3 deletions(-) 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..33d157b8b 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 @@ -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/res/values/strings.xml b/app/src/main/res/values/strings.xml index 844b9f14d..9762f0262 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -392,5 +392,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/changelog.md b/changelog.md index 40537e8d5..0388c45ac 100644 --- a/changelog.md +++ b/changelog.md @@ -9,15 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- [\All\] Use Compose BOM and update Kotlin and Gradle versions ([#578](https://github.com/Orange-OpenSource/ods-android/issues/578)) +- \[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)) ### 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\] 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)) ## [0.14.0](https://github.com/Orange-OpenSource/ods-android/compare/0.13.0...0.14.0) - 2023-07-12 From 623cef212987bc67471345bae4b92873ce3ff70c Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Tue, 18 Jul 2023 20:24:22 +0200 Subject: [PATCH 030/132] [#555] add list item --- .../orange/ods/app/ui/components/Component.kt | 11 + .../components/listitem/ComponentListItem.kt | 236 ++++++++++++++++++ app/src/main/res/drawable/il_list_item.xml | 34 +++ 3 files changed, 281 insertions(+) create mode 100644 app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt create mode 100644 app/src/main/res/drawable/il_list_item.xml 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 39573a034..49fb3434c 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 @@ -27,6 +27,7 @@ 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.listitem.ComponentListItem import com.orange.ods.app.ui.components.lists.ComponentLists import com.orange.ods.app.ui.components.menus.ComponentMenu import com.orange.ods.app.ui.components.navigationdrawers.ComponentModalDrawers @@ -175,6 +176,16 @@ sealed class Component( demoScreen = { _, _ -> ComponentImageItem() } ) + object ListItem : Component( + R.string.component_list_item, + R.drawable.il_list_item, + null, + R.string.component_lists_description, + composableName = OdsComposable.OdsListItem.name, + demoScreen = { _, _ -> ComponentListItem() }, + imageAlignment = Alignment.BottomCenter + ) + object Lists : Component( R.string.component_lists, R.drawable.il_lists, diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt new file mode 100644 index 000000000..f65ed20ac --- /dev/null +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -0,0 +1,236 @@ +/* + * + * 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.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 +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import coil.compose.rememberAsyncImagePainter +import coil.request.ImageRequest +import coil.size.Scale +import coil.size.Size +import com.orange.ods.app.R +import com.orange.ods.app.domain.recipes.LocalRecipes +import com.orange.ods.app.domain.recipes.Recipe +import com.orange.ods.app.ui.components.lists.ListItemCustomizationState +import com.orange.ods.app.ui.components.lists.rememberListItemCustomizationState +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 +import com.orange.ods.compose.component.list.OdsCheckboxTrailing +import com.orange.ods.compose.component.list.OdsIconTrailing +import com.orange.ods.compose.component.list.OdsListItem +import com.orange.ods.compose.component.list.OdsListItemIcon +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.iconType +import com.orange.ods.utilities.extension.orElse + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun ComponentListItem() { + val listItemCustomizationState = rememberListItemCustomizationState() + ComponentCustomizationBottomSheetScaffold( + bottomSheetScaffoldState = listItemCustomizationState.bottomSheetScaffoldState, + bottomSheetContent = { ComponentListsBottomSheetContent(listItemCustomizationState) }, + content = { ComponentListsContent(listItemCustomizationState) } + ) +} + +@Composable +private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListItemCustomizationState) { + ComponentCountRow( + modifier = Modifier.padding(start = dimensionResource(id = 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 = com.orange.ods.app.ui.components.lists.ComponentListItem.MinLineCount, + maxCount = com.orange.ods.app.ui.components.lists.ComponentListItem.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) + } + + 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) + } + } + +} + +@Composable +private fun ComponentListsContent(listItemCustomizationState: ListItemCustomizationState) { + val recipes = LocalRecipes.current.filter { it.description.isNotBlank() } + with(listItemCustomizationState) { + Column(modifier = Modifier.verticalScroll(rememberScrollState())) { + if (!trailings.contains(selectedTrailing.value)) { + resetTrailing() + } + + val modifier = Modifier + .let { modifier -> + iconType?.let { modifier.iconType(it) }.orElse { modifier } + } + val singleLineSecondaryText = lineCount.value == 2 + + val text = recipes.first().title + val secondaryText = listItemCustomizationState.getSecondaryText(recipes.first()) + val icon: @Composable (OdsListItemIconScope.() -> Unit)? = + listItemCustomizationState.getIconPainter(recipes.first())?.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 = R.dimen.screen_horizontal_margin))) { + FunctionCallCode( + name = OdsComposable.OdsListItem.name, + parameters = { + string("text", text) + if (singleLineSecondaryText) secondaryText?.let { string("secondaryText", it) } + icon() + } + ) + } + } + } +} + +private val ListItemCustomizationState.Trailing.textResId: Int + get() = when (this) { + ListItemCustomizationState.Trailing.None -> R.string.component_list_trailing_none + ListItemCustomizationState.Trailing.Checkbox -> R.string.component_list_trailing_checkbox + ListItemCustomizationState.Trailing.Switch -> R.string.component_list_trailing_switch + ListItemCustomizationState.Trailing.Icon -> R.string.component_list_trailing_icon + 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 + ListItemCustomizationState.Leading.Icon -> OdsListItemIconType.Icon + ListItemCustomizationState.Leading.CircularImage -> OdsListItemIconType.CircularImage + ListItemCustomizationState.Leading.SquareImage -> OdsListItemIconType.SquareImage + ListItemCustomizationState.Leading.WideImage -> OdsListItemIconType.WideImage + } + +@Composable +private fun ListItemCustomizationState.getIconPainter(recipe: Recipe): Painter? { + return when (selectedLeading.value) { + ListItemCustomizationState.Leading.None -> null + ListItemCustomizationState.Leading.Icon -> recipe.iconResId?.let { painterResource(id = it) } + 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() } + rememberAsyncImagePainter( + model = ImageRequest.Builder(LocalContext.current) + .data(recipe.imageUrl) + .scale(Scale.FILL) + .size(Size(wideImageSizeWidthPx.toInt(), wideImageSizeHeightPx.toInt())) + .build(), + placeholder = painterResource(id = DrawableManager.getPlaceholderSmallResId()), + error = painterResource(id = DrawableManager.getPlaceholderSmallResId(error = true)) + ) + } + } +} + +private val ListItemCustomizationState.trailing: OdsListItemTrailing? + @Composable + get() = when (selectedTrailing.value) { + ListItemCustomizationState.Trailing.None -> null + ListItemCustomizationState.Trailing.Checkbox -> { + val checked = remember { mutableStateOf(true) } + OdsCheckboxTrailing(checked = checked) + } + ListItemCustomizationState.Trailing.Switch -> { + val checked = remember { mutableStateOf(true) } + OdsSwitchTrailing(checked = checked) + } + ListItemCustomizationState.Trailing.Icon -> { + val context = LocalContext.current + val iconText = stringResource(id = R.string.component_element_icon) + OdsIconTrailing( + modifier = Modifier.clickable { + clickOnElement(context, iconText) + }, + painter = painterResource(id = R.drawable.ic_info), + contentDescription = stringResource(id = R.string.component_list_information) + ) + } + ListItemCustomizationState.Trailing.Caption -> { + OdsCaptionTrailing(text = stringResource(id = R.string.component_element_caption)) + } + } 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 @@ + + + + + + + + From 23e9098bc29ca23d1c5b3aec4f217ca7e84c5b27 Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Mon, 24 Jul 2023 11:51:26 +0200 Subject: [PATCH 031/132] [#555] add list item description --- app/src/main/java/com/orange/ods/app/ui/components/Component.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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 49fb3434c..14ecdf02c 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 @@ -180,7 +180,7 @@ sealed class 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 = { _, _ -> ComponentListItem() }, imageAlignment = Alignment.BottomCenter diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9762f0262..196f54265 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -289,6 +289,7 @@ Lists A list is a continuous vertical group of data entries like text, icons or images. 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 From 6afabe76ff6d72fee60e6d31933207194a08ce4f Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Fri, 4 Aug 2023 10:49:38 +0200 Subject: [PATCH 032/132] [#555] Review : Update list item definition --- .../main/java/com/orange/ods/app/ui/components/Component.kt | 5 ++--- .../drawable/{il_list_item.xml => il_list_item_generic.xml} | 0 2 files changed, 2 insertions(+), 3 deletions(-) rename app/src/main/res/drawable/{il_list_item.xml => il_list_item_generic.xml} (100%) 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 14ecdf02c..38f95d2d2 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 @@ -178,12 +178,11 @@ sealed class Component( object ListItem : Component( R.string.component_list_item, - R.drawable.il_list_item, + R.drawable.il_list_item_generic, null, R.string.component_list_item_description, composableName = OdsComposable.OdsListItem.name, - demoScreen = { _, _ -> ComponentListItem() }, - imageAlignment = Alignment.BottomCenter + demoScreen = { _, _ -> ComponentListItem() } ) object Lists : Component( diff --git a/app/src/main/res/drawable/il_list_item.xml b/app/src/main/res/drawable/il_list_item_generic.xml similarity index 100% rename from app/src/main/res/drawable/il_list_item.xml rename to app/src/main/res/drawable/il_list_item_generic.xml From 138086c28928d960814790807c65b63a6f64fdc6 Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Fri, 4 Aug 2023 14:02:22 +0200 Subject: [PATCH 033/132] [#555] Review : Update component listItem --- .../components/listitem/ComponentListItem.kt | 31 ++++++++++--------- .../app/ui/components/lists/ComponentLists.kt | 6 ++-- .../lists/ListItemCustomizationState.kt | 16 +++++----- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index f65ed20ac..bb0be14f3 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -13,8 +13,6 @@ 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 @@ -34,6 +32,8 @@ import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes import com.orange.ods.app.domain.recipes.Recipe import com.orange.ods.app.ui.components.lists.ListItemCustomizationState +import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MaxLineCount +import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MinLineCount import com.orange.ods.app.ui.components.lists.rememberListItemCustomizationState import com.orange.ods.app.ui.components.utilities.ComponentCountRow import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold @@ -63,21 +63,21 @@ 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)), 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 = com.orange.ods.app.ui.components.lists.ComponentListItem.MinLineCount, - maxCount = com.orange.ods.app.ui.components.lists.ComponentListItem.MaxLineCount + minCount = MinLineCount, + maxCount = MaxLineCount ) Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) @@ -107,10 +107,10 @@ private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListIte } @Composable -private fun ComponentListsContent(listItemCustomizationState: ListItemCustomizationState) { - val recipes = LocalRecipes.current.filter { it.description.isNotBlank() } +private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomizationState) { + val recipes = LocalRecipes.current.filter { it.description.isNotBlank() }.first() with(listItemCustomizationState) { - Column(modifier = Modifier.verticalScroll(rememberScrollState())) { + Column { if (!trailings.contains(selectedTrailing.value)) { resetTrailing() } @@ -121,10 +121,10 @@ private fun ComponentListsContent(listItemCustomizationState: ListItemCustomizat } val singleLineSecondaryText = lineCount.value == 2 - val text = recipes.first().title - val secondaryText = listItemCustomizationState.getSecondaryText(recipes.first()) + val text = recipes.title + val secondaryText = listItemCustomizationState.getSecondaryText(recipes) val icon: @Composable (OdsListItemIconScope.() -> Unit)? = - listItemCustomizationState.getIconPainter(recipes.first())?.let { { OdsListItemIcon(painter = it) } } + listItemCustomizationState.getIconPainter(recipes)?.let { { OdsListItemIcon(painter = it) } } trailing?.let { listItemTrailing -> OdsListItem( modifier = modifier, @@ -149,7 +149,10 @@ private fun ComponentListsContent(listItemCustomizationState: ListItemCustomizat name = OdsComposable.OdsListItem.name, parameters = { string("text", text) - if (singleLineSecondaryText) secondaryText?.let { string("secondaryText", it) } + if (secondaryText != null) { + string("secondaryText", secondaryText) + if (!singleLineSecondaryText) stringRepresentation("singleLineSecondaryText", false) + } icon() } ) 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/lists/ComponentLists.kt index 99429445d..bbc5e2782 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/lists/ComponentLists.kt @@ -33,6 +33,8 @@ import coil.size.Size import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes import com.orange.ods.app.domain.recipes.Recipe +import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MaxLineCount +import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MinLineCount 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 @@ -72,8 +74,8 @@ private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListIte 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 = MinLineCount, + maxCount = MaxLineCount ) Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) 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/lists/ListItemCustomizationState.kt index b930ef445..5a35e76b8 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/lists/ListItemCustomizationState.kt @@ -18,18 +18,13 @@ import androidx.compose.runtime.MutableState 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 -} +import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.DefaultLineCount @OptIn(ExperimentalMaterialApi::class) @Composable fun rememberListItemCustomizationState( bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(), - lineCount: MutableState = rememberSaveable { mutableStateOf(ComponentListItem.DefaultLineCount) }, + lineCount: MutableState = rememberSaveable { mutableStateOf(DefaultLineCount) }, selectedLeading: MutableState = rememberSaveable { mutableStateOf(ListItemCustomizationState.Leading.None) }, selectedTrailing: MutableState = rememberSaveable { mutableStateOf(ListItemCustomizationState.Trailing.None) }, dividerEnabled: MutableState = rememberSaveable { mutableStateOf(false) } @@ -45,6 +40,11 @@ class ListItemCustomizationState( 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 +55,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) From 4f14bedaa3aa218eb74356b27f477efc8752b093 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 8 Aug 2023 16:26:29 +0200 Subject: [PATCH 034/132] [#555] Reference il_list_item in DrawableManager --- .../orange/ods/app/ui/components/Component.kt | 2 +- .../ods/app/ui/utilities/DrawableManager.kt | 1 + app/src/main/res/drawable/il_list_item.xml | 34 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/drawable/il_list_item.xml 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 38f95d2d2..513e7e522 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 @@ -178,7 +178,7 @@ sealed class Component( object ListItem : Component( R.string.component_list_item, - R.drawable.il_list_item_generic, + R.drawable.il_list_item, null, R.string.component_list_item_description, composableName = OdsComposable.OdsListItem.name, 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..6f6e81678 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 @@ -42,6 +42,7 @@ object DrawableManager { 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_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/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 @@ + + + + + + + + From 1041720aefe9b1c8564f57f3ef60be34c1b66c29 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 8 Aug 2023 16:33:33 +0200 Subject: [PATCH 035/132] [#555] Review: Minor modifications --- .../ui/components/listitem/ComponentListItem.kt | 14 ++++++-------- .../ods/app/ui/components/lists/ComponentLists.kt | 6 ++---- .../components/lists/ListItemCustomizationState.kt | 3 +-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index bb0be14f3..bb4056be8 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -32,8 +32,6 @@ import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes import com.orange.ods.app.domain.recipes.Recipe import com.orange.ods.app.ui.components.lists.ListItemCustomizationState -import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MaxLineCount -import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MinLineCount import com.orange.ods.app.ui.components.lists.rememberListItemCustomizationState import com.orange.ods.app.ui.components.utilities.ComponentCountRow import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold @@ -76,8 +74,8 @@ private fun ComponentListItemBottomSheetContent(listItemCustomizationState: List count = listItemCustomizationState.lineCount, minusIconContentDescription = stringResource(id = R.string.component_list_item_remove_line), plusIconContentDescription = stringResource(id = R.string.component_list_item_add_line), - minCount = MinLineCount, - maxCount = MaxLineCount + minCount = ListItemCustomizationState.MinLineCount, + maxCount = ListItemCustomizationState.MaxLineCount ) Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) @@ -108,7 +106,7 @@ private fun ComponentListItemBottomSheetContent(listItemCustomizationState: List @Composable private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomizationState) { - val recipes = LocalRecipes.current.filter { it.description.isNotBlank() }.first() + val recipe = LocalRecipes.current.first { it.description.isNotBlank() } with(listItemCustomizationState) { Column { if (!trailings.contains(selectedTrailing.value)) { @@ -121,10 +119,10 @@ private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomi } val singleLineSecondaryText = lineCount.value == 2 - val text = recipes.title - val secondaryText = listItemCustomizationState.getSecondaryText(recipes) + val text = recipe.title + val secondaryText = listItemCustomizationState.getSecondaryText(recipe) val icon: @Composable (OdsListItemIconScope.() -> Unit)? = - listItemCustomizationState.getIconPainter(recipes)?.let { { OdsListItemIcon(painter = it) } } + listItemCustomizationState.getIconPainter(recipe)?.let { { OdsListItemIcon(painter = it) } } trailing?.let { listItemTrailing -> OdsListItem( modifier = modifier, 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/lists/ComponentLists.kt index bbc5e2782..66b0470eb 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/lists/ComponentLists.kt @@ -33,8 +33,6 @@ import coil.size.Size import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes import com.orange.ods.app.domain.recipes.Recipe -import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MaxLineCount -import com.orange.ods.app.ui.components.lists.ListItemCustomizationState.Companion.MinLineCount 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 @@ -74,8 +72,8 @@ private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListIte count = listItemCustomizationState.lineCount, minusIconContentDescription = stringResource(id = R.string.component_list_item_remove_line), plusIconContentDescription = stringResource(id = R.string.component_list_item_add_line), - minCount = MinLineCount, - maxCount = MaxLineCount + minCount = ListItemCustomizationState.MinLineCount, + maxCount = ListItemCustomizationState.MaxLineCount ) Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) 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/lists/ListItemCustomizationState.kt index 5a35e76b8..c01a2f369 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/lists/ListItemCustomizationState.kt @@ -18,13 +18,12 @@ 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.app.ui.components.lists.ListItemCustomizationState.Companion.DefaultLineCount @OptIn(ExperimentalMaterialApi::class) @Composable fun rememberListItemCustomizationState( bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(), - lineCount: MutableState = rememberSaveable { mutableStateOf(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) } From e81ace1784f74a8573cc37dcf58ba72f9f50b583 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 8 Aug 2023 16:40:28 +0200 Subject: [PATCH 036/132] [#555] Update changelog --- changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.md b/changelog.md index 0388c45ac..43904b92d 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/Orange-OpenSource/ods-android/compare/0.14.0...develop) +### Added + +- \[App\] Add list item component ([#555](https://github.com/Orange-OpenSource/ods-android/issues/555)) + ### Changed - \[All\] Use Compose BOM and update Kotlin and Gradle versions ([#578](https://github.com/Orange-OpenSource/ods-android/issues/578)) From ab55a4c2c04e6369afc9e0759bbebcfae081c4ec Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 8 Aug 2023 16:44:39 +0200 Subject: [PATCH 037/132] [#555] Fix build error following dependencies update --- .../app/ui/components/listitem/ComponentListItem.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index bb4056be8..d4ab07a8f 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -69,7 +69,7 @@ fun ComponentListItem() { @Composable 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), @@ -81,7 +81,7 @@ private fun ComponentListItemBottomSheetContent(listItemCustomizationState: List Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = listItemCustomizationState.selectedLeading, - 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)), outlinedChips = true ) { OdsChoiceChip(textRes = R.string.component_list_leading_none, value = ListItemCustomizationState.Leading.None) @@ -94,7 +94,7 @@ private fun ComponentListItemBottomSheetContent(listItemCustomizationState: List Subtitle(textRes = R.string.component_list_trailing, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = listItemCustomizationState.selectedTrailing, - 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)), outlinedChips = true ) { listItemCustomizationState.trailings.forEach { trailing -> @@ -142,7 +142,7 @@ private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomi icon = icon ) } - 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.OdsListItem.name, parameters = { @@ -193,8 +193,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) From 5d44d99b863c3c82b26412ca60d6a2f4aa88433f Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 10 Aug 2023 11:03:51 +0200 Subject: [PATCH 038/132] [#555] Remove list component --- .../orange/ods/app/ui/components/Component.kt | 11 - .../components/listitem/ComponentListItem.kt | 2 - .../ListItemCustomizationState.kt | 2 +- .../app/ui/components/lists/ComponentLists.kt | 229 ------------------ app/src/main/res/values/strings.xml | 42 ++-- 5 files changed, 21 insertions(+), 265 deletions(-) rename app/src/main/java/com/orange/ods/app/ui/components/{lists => listitem}/ListItemCustomizationState.kt (97%) delete mode 100644 app/src/main/java/com/orange/ods/app/ui/components/lists/ComponentLists.kt 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 513e7e522..540bea13e 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 @@ -28,7 +28,6 @@ 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.listitem.ComponentListItem -import com.orange.ods.app.ui.components.lists.ComponentLists 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 @@ -185,16 +184,6 @@ sealed class Component( demoScreen = { _, _ -> ComponentListItem() } ) - object Lists : Component( - R.string.component_lists, - R.drawable.il_lists, - null, - R.string.component_lists_description, - composableName = OdsComposable.OdsListItem.name, - demoScreen = { _, _ -> ComponentLists() }, - imageAlignment = Alignment.BottomCenter - ) - object Menus : Component( R.string.component_menus, R.drawable.il_menus, diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index d4ab07a8f..75484fee0 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -31,8 +31,6 @@ import coil.size.Size import com.orange.ods.app.R import com.orange.ods.app.domain.recipes.LocalRecipes import com.orange.ods.app.domain.recipes.Recipe -import com.orange.ods.app.ui.components.lists.ListItemCustomizationState -import com.orange.ods.app.ui.components.lists.rememberListItemCustomizationState 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 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 97% 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 c01a2f369..3a1378bc9 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 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/lists/ComponentLists.kt deleted file mode 100644 index 66b0470eb..000000000 --- a/app/src/main/java/com/orange/ods/app/ui/components/lists/ComponentLists.kt +++ /dev/null @@ -1,229 +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.lists - -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 -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import coil.compose.rememberAsyncImagePainter -import coil.request.ImageRequest -import coil.size.Scale -import coil.size.Size -import com.orange.ods.app.R -import com.orange.ods.app.domain.recipes.LocalRecipes -import com.orange.ods.app.domain.recipes.Recipe -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.Subtitle -import com.orange.ods.compose.component.chip.OdsChoiceChip -import com.orange.ods.compose.component.chip.OdsChoiceChipsFlowRow -import com.orange.ods.compose.component.list.OdsCaptionTrailing -import com.orange.ods.compose.component.list.OdsCheckboxTrailing -import com.orange.ods.compose.component.list.OdsIconTrailing -import com.orange.ods.compose.component.list.OdsListItem -import com.orange.ods.compose.component.list.OdsListItemIcon -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 - -@OptIn(ExperimentalMaterialApi::class) -@Composable -fun ComponentLists() { - val listItemCustomizationState = rememberListItemCustomizationState() - ComponentCustomizationBottomSheetScaffold( - bottomSheetScaffoldState = listItemCustomizationState.bottomSheetScaffoldState, - bottomSheetContent = { ComponentListsBottomSheetContent(listItemCustomizationState) }, - content = { ComponentListsContent(listItemCustomizationState) } - ) -} - -@Composable -private fun ComponentListsBottomSheetContent(listItemCustomizationState: ListItemCustomizationState) { - ComponentCountRow( - 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 = ListItemCustomizationState.MinLineCount, - maxCount = ListItemCustomizationState.MaxLineCount - ) - - Subtitle(textRes = R.string.component_list_leading, horizontalPadding = true) - OdsChoiceChipsFlowRow( - selectedChip = listItemCustomizationState.selectedLeading, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - 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) - } - - Subtitle(textRes = R.string.component_list_trailing, horizontalPadding = true) - OdsChoiceChipsFlowRow( - selectedChip = listItemCustomizationState.selectedTrailing, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true - ) { - listItemCustomizationState.trailings.forEach { trailing -> - OdsChoiceChip(textRes = 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() } - with(listItemCustomizationState) { - Column(modifier = Modifier.verticalScroll(rememberScrollState())) { - if (!trailings.contains(selectedTrailing.value)) { - resetTrailing() - } - - val modifier = Modifier - .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 - ) - } - } - } - } -} - -private val ListItemCustomizationState.Trailing.textResId: Int - get() = when (this) { - ListItemCustomizationState.Trailing.None -> R.string.component_list_trailing_none - ListItemCustomizationState.Trailing.Checkbox -> R.string.component_list_trailing_checkbox - ListItemCustomizationState.Trailing.Switch -> R.string.component_list_trailing_switch - ListItemCustomizationState.Trailing.Icon -> R.string.component_list_trailing_icon - 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 - ListItemCustomizationState.Leading.Icon -> OdsListItemIconType.Icon - ListItemCustomizationState.Leading.CircularImage -> OdsListItemIconType.CircularImage - ListItemCustomizationState.Leading.SquareImage -> OdsListItemIconType.SquareImage - ListItemCustomizationState.Leading.WideImage -> OdsListItemIconType.WideImage - } - -@Composable -private fun ListItemCustomizationState.getIconPainter(recipe: Recipe): Painter? { - return when (selectedLeading.value) { - ListItemCustomizationState.Leading.None -> null - ListItemCustomizationState.Leading.Icon -> recipe.iconResId?.let { painterResource(id = it) } - ListItemCustomizationState.Leading.CircularImage, - ListItemCustomizationState.Leading.SquareImage, - ListItemCustomizationState.Leading.WideImage -> { - 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) - .scale(Scale.FILL) - .size(Size(wideImageSizeWidthPx.toInt(), wideImageSizeHeightPx.toInt())) - .build(), - placeholder = painterResource(id = DrawableManager.getPlaceholderSmallResId()), - error = painterResource(id = DrawableManager.getPlaceholderSmallResId(error = true)) - ) - } - } -} - -private val ListItemCustomizationState.trailing: OdsListItemTrailing? - @Composable - get() = when (selectedTrailing.value) { - ListItemCustomizationState.Trailing.None -> null - ListItemCustomizationState.Trailing.Checkbox -> { - val checked = remember { mutableStateOf(true) } - OdsCheckboxTrailing(checked = checked) - } - ListItemCustomizationState.Trailing.Switch -> { - val checked = remember { mutableStateOf(true) } - OdsSwitchTrailing(checked = checked) - } - ListItemCustomizationState.Trailing.Icon -> { - val context = LocalContext.current - val iconText = stringResource(id = R.string.component_element_icon) - OdsIconTrailing( - modifier = Modifier.clickable { - clickOnElement(context, iconText) - }, - painter = painterResource(id = R.drawable.ic_info), - contentDescription = stringResource(id = R.string.component_list_information) - ) - } - ListItemCustomizationState.Trailing.Caption -> { - OdsCaptionTrailing(text = stringResource(id = R.string.component_element_caption)) - } - } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 196f54265..2ae08fe9a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -227,6 +227,26 @@ 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 Menus appear from a button, action, or other control. It contains at least 2 items that can affect the app, the view or elements within the view. @@ -285,28 +305,6 @@ Circular Downloading … - - Lists - A list is a continuous vertical group of data entries like text, icons or images. - 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 - Sheets: bottom Bottom sheets are surfaces anchored to the bottom of the screen that present users supplemental content. From 084545c67b14142327e9c06212e87881a12daf4b Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 10 Aug 2023 11:15:15 +0200 Subject: [PATCH 039/132] [#555] Remove useless divider in list item customization --- .../app/ui/components/listitem/ListItemCustomizationState.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ListItemCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ListItemCustomizationState.kt index 3a1378bc9..58996563b 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ListItemCustomizationState.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ListItemCustomizationState.kt @@ -26,9 +26,8 @@ fun rememberListItemCustomizationState( 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) @@ -37,7 +36,6 @@ class ListItemCustomizationState( val lineCount: MutableState, val selectedLeading: MutableState, val selectedTrailing: MutableState, - val dividerEnabled: MutableState ) { companion object { const val DefaultLineCount = 2 From a780280732fbbedc411ac97efd074221c98cb689 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Thu, 10 Aug 2023 12:19:30 +0200 Subject: [PATCH 040/132] [#555] Update code implementation on customization change --- .../components/listitem/ComponentListItem.kt | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt index 75484fee0..d85067b46 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/listitem/ComponentListItem.kt @@ -118,7 +118,7 @@ private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomi val singleLineSecondaryText = lineCount.value == 2 val text = recipe.title - val secondaryText = listItemCustomizationState.getSecondaryText(recipe) + 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 -> @@ -140,6 +140,7 @@ private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomi icon = icon ) } + CodeImplementationColumn(modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin))) { FunctionCallCode( name = OdsComposable.OdsListItem.name, @@ -149,7 +150,26 @@ private fun ComponentListItemContent(listItemCustomizationState: ListItemCustomi string("secondaryText", secondaryText) if (!singleLineSecondaryText) stringRepresentation("singleLineSecondaryText", false) } - icon() + 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, "") + } + } } ) } @@ -166,14 +186,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 From 0dc017fd4d9a2cc30d680c9ca85a10055f7b02cd Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 7 Aug 2023 16:51:07 +0200 Subject: [PATCH 041/132] [#560] Group elements in a same vocalization --- .../compose/component/menu/OdsExposedDropdownMenu.kt | 12 +++++++++++- .../ods/compose/component/utilities/Accessibility.kt | 11 ++++++++++- lib/src/main/res/values/strings.xml | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt index dd2072686..08708229c 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsExposedDropdownMenu.kt @@ -18,6 +18,10 @@ import androidx.compose.material.ExposedDropdownMenuBox import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.tooling.preview.PreviewParameter import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.textfield.OdsExposedDropdownMenuTrailing @@ -25,6 +29,7 @@ import com.orange.ods.compose.component.textfield.OdsTextField import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews +import com.orange.ods.compose.component.utilities.enabledStateDescription import kotlinx.parcelize.Parcelize /** @@ -50,9 +55,14 @@ fun OdsExposedDropdownMenu( enabled: Boolean = true ) { var expanded by remember { mutableStateOf(false) } + val menuBoxStateDescription = enabledStateDescription(enabled = enabled) + val menuBoxAction = if (enabled) stringResource(id = com.orange.ods.R.string.dropdown_menu_action) else "" ExposedDropdownMenuBox( - modifier = modifier, + modifier = modifier.clearAndSetSemantics { + contentDescription = "$label, ${selectedItem.value.label}, $menuBoxAction" + stateDescription = menuBoxStateDescription + }, expanded = expanded, onExpandedChange = { expanded = !expanded diff --git a/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt b/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt index 42d0baf2f..a7bfcdafb 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/utilities/Accessibility.kt @@ -21,4 +21,13 @@ import com.orange.ods.R */ @Composable internal fun selectionStateDescription(selected: Boolean) = - if (selected) stringResource(id = R.string.state_selected) else stringResource(id = R.string.state_not_selected) \ No newline at end of file + if (selected) stringResource(id = R.string.state_selected) else stringResource(id = R.string.state_not_selected) + +/** + * Returns the enabled/disabled state ready for vocalization according to the [enabled] provided value. + * + * @param enabled Set it to true if the element is enabled, false otherwise. + */ +@Composable +internal fun enabledStateDescription(enabled: Boolean) = + if (!enabled) stringResource(id = R.string.state_disabled) else "" \ No newline at end of file diff --git a/lib/src/main/res/values/strings.xml b/lib/src/main/res/values/strings.xml index 05bf689a1..4c252f403 100644 --- a/lib/src/main/res/values/strings.xml +++ b/lib/src/main/res/values/strings.xml @@ -9,9 +9,12 @@ --> + Disabled Selected Not selected + Double click to change selection + Show password Hide password From 62576dc90bf5a2244cbb6177e7860fa55d91ceec Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Mon, 7 Aug 2023 16:51:38 +0200 Subject: [PATCH 042/132] [#560] Update changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 43904b92d..5cf7a2100 100644 --- a/changelog.md +++ b/changelog.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - \[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)) ## [0.14.0](https://github.com/Orange-OpenSource/ods-android/compare/0.13.0...0.14.0) - 2023-07-12 From ca457fc60471040d48788bffe20bc6a512996b0b Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 10 Aug 2023 18:02:23 +0200 Subject: [PATCH 043/132] [#560] Review: Fix typo in changelog --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 5cf7a2100..2442f41a3 100644 --- a/changelog.md +++ b/changelog.md @@ -23,7 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - \[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\] Vocalize exposed dropdown menu content as a group ([#560](https://github.com/Orange-OpenSource/ods-android/issues/560)) ## [0.14.0](https://github.com/Orange-OpenSource/ods-android/compare/0.13.0...0.14.0) - 2023-07-12 From 4a3d53271392d43f1bf7eb86055cb951f2543031 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Mon, 7 Aug 2023 11:59:08 +0200 Subject: [PATCH 044/132] [#592] Update OdsBanner API --- .../com/orange/ods/app/ui/MainTopAppBar.kt | 2 +- .../banners/BannerCustomizationState.kt | 2 +- .../ui/components/banners/ComponentBanners.kt | 69 +++++---- .../app/ui/components/cards/CardHorizontal.kt | 6 +- .../cards/CardVerticalHeaderFirst.kt | 4 +- .../cards/CardVerticalImageFirst.kt | 4 +- app/src/main/res/layout/ods_banner.xml | 12 +- app/src/main/res/values/strings.xml | 4 +- changelog.md | 1 + .../ods/xml/component/banner/OdsBanner.kt | 29 ++-- lib-xml/src/main/res/values/attrs.xml | 4 +- .../ods/compose/component/banner/OdsBanner.kt | 134 ++++++++++-------- .../component/content/OdsComponentContent.kt | 13 +- .../component/content/OdsComponentIcon.kt | 14 +- .../component/content/OdsComponentImage.kt | 57 ++++++++ .../compose/component/menu/OdsDropdownMenu.kt | 2 +- 16 files changed, 237 insertions(+), 120 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentImage.kt 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 ce627b0f4..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 @@ -112,7 +112,7 @@ private fun getTopAppBarSearchTextFieldAction(searchedText: MutableState 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 f209e18fb..e0a2454ac 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.utilities.extension.ifNotNull @OptIn(ExperimentalMaterialApi::class) @Composable @@ -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) @@ -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/cards/CardHorizontal.kt b/app/src/main/java/com/orange/ods/app/ui/components/cards/CardHorizontal.kt index eb8940682..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,7 +38,7 @@ 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 @@ -46,8 +46,8 @@ fun CardHorizontal(customizationState: CardCustomizationState) { .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( 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 38fe6e7b7..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 @@ -48,8 +48,8 @@ fun CardVerticalHeaderFirst(customizationState: CardCustomizationState) { .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) 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 7e6f5b921..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 @@ -46,8 +46,8 @@ fun CardVerticalImageFirst(customizationState: CardCustomizationState) { .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( 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/values/strings.xml b/app/src/main/res/values/strings.xml index 2ae08fe9a..4105ab2e2 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 diff --git a/changelog.md b/changelog.md index 2442f41a3..5f1dc030a 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - \[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)) ### Fixed diff --git a/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt b/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt index 56d914b08..6d42b1da3 100644 --- a/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt +++ b/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt @@ -21,6 +21,9 @@ import androidx.compose.runtime.setValue import androidx.core.content.withStyledAttributes import com.google.accompanist.drawablepainter.rememberDrawablePainter 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.utilities.extension.ifNotNull import com.orange.ods.xml.R import com.orange.ods.xml.component.OdsAbstractComposeView import com.orange.ods.xml.utilities.extension.getResourceIdOrNull @@ -28,20 +31,20 @@ import com.orange.ods.xml.utilities.extension.getResourceIdOrNull class OdsBanner @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : OdsAbstractComposeView(context, attrs) { var message by mutableStateOf("") - var button1Text by mutableStateOf("") - var onButton1Click by mutableStateOf({}) + var firstButtonText by mutableStateOf("") + var onFirstButtonClick by mutableStateOf({}) var image by mutableStateOf(null) var imageContentDescription by mutableStateOf(null) - var button2Text by mutableStateOf(null) - var onButton2Click by mutableStateOf<(() -> Unit)?>(null) + var secondButtonText by mutableStateOf(null) + var onSecondButtonClick by mutableStateOf<(() -> Unit)?>(null) init { context.withStyledAttributes(attrs, R.styleable.OdsBanner) { message = getString(R.styleable.OdsBanner_message).orEmpty() - button1Text = getString(R.styleable.OdsBanner_button1Text).orEmpty() + firstButtonText = getString(R.styleable.OdsBanner_firstButtonText).orEmpty() image = getResourceIdOrNull(R.styleable.OdsBanner_image)?.let { AppCompatResources.getDrawable(context, it) } imageContentDescription = getString(R.styleable.OdsBanner_imageContentDescription) - button2Text = getString(R.styleable.OdsBanner_button2Text) + secondButtonText = getString(R.styleable.OdsBanner_secondButtonText) } } @@ -49,12 +52,14 @@ class OdsBanner @JvmOverloads constructor(context: Context, attrs: AttributeSet? override fun OdsContent() { OdsBanner( message = message, - button1Text = button1Text, - onButton1Click = onButton1Click, - image = image?.let { rememberDrawablePainter(drawable = it) }, - imageContentDescription = imageContentDescription, - button2Text = button2Text, - onButton2Click = onButton2Click + firstButton = OdsBannerButton(firstButtonText, onFirstButtonClick), + image = ifNotNull(image, imageContentDescription) { image, contentDescription -> + val painter = rememberDrawablePainter(drawable = image) + OdsBannerImage(painter, contentDescription) + }, + secondButton = ifNotNull(secondButtonText, onSecondButtonClick) { text, onClick -> + OdsBannerButton(text, onClick) + } ) } } diff --git a/lib-xml/src/main/res/values/attrs.xml b/lib-xml/src/main/res/values/attrs.xml index 15f860f63..a6b7c1bbc 100644 --- a/lib-xml/src/main/res/values/attrs.xml +++ b/lib-xml/src/main/res/values/attrs.xml @@ -20,10 +20,10 @@ - + - + diff --git a/lib/src/main/java/com/orange/ods/compose/component/banner/OdsBanner.kt b/lib/src/main/java/com/orange/ods/compose/component/banner/OdsBanner.kt index 09f394a62..6bee4f218 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/banner/OdsBanner.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/banner/OdsBanner.kt @@ -10,7 +10,6 @@ package com.orange.ods.compose.component.banner -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -23,7 +22,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource @@ -34,6 +35,8 @@ import com.orange.ods.R import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.button.OdsTextButton import com.orange.ods.compose.component.button.OdsTextButtonStyle +import com.orange.ods.compose.component.content.OdsComponentContent +import com.orange.ods.compose.component.content.OdsComponentImage import com.orange.ods.compose.component.divider.OdsDivider import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.Preview @@ -45,27 +48,21 @@ import com.orange.ods.compose.theme.OdsTheme * * * @param message text displayed in the banner. - * @param button1Text principal button in the banner, it displays an [OdsTextButton] with the given [button1Text] as an action of the banner. - * @param onButton1Click executed on button1 click. + * @param firstButton principal button in the banner. * @param modifier modifiers for the Banner layout. * @param image image display in the banner. - * @param imageContentDescription Optional image content description. - * @param button2Text Optional text of the second button in the banner. If not present, button will not be shown. If present, [onButton2Click] need to be handle. - * @param onButton2Click Optional handler for the button2 click. + * @param secondButton Optional second button in the banner. */ @Composable @OdsComposable fun OdsBanner( message: String, - button1Text: String, - onButton1Click: () -> Unit, + firstButton: OdsBannerButton, modifier: Modifier = Modifier, - image: Painter? = null, - imageContentDescription: String? = null, - button2Text: String? = null, - onButton2Click: (() -> Unit)? = null + image: OdsBannerImage? = null, + secondButton: OdsBannerButton? = null ) { - val isSingleLineBanner = image == null && button2Text == null + val isSingleLineBanner = image == null && secondButton == null Column( modifier = modifier .fillMaxWidth() @@ -81,17 +78,12 @@ fun OdsBanner( ) .padding(horizontal = dimensionResource(id = R.dimen.spacing_m)) ) { - image?.let { - Image( - painter = image, - contentDescription = imageContentDescription, - contentScale = ContentScale.Crop, // crop the image if it's not a square - modifier = Modifier - .padding(end = dimensionResource(id = R.dimen.spacing_m)) - .size(40.dp) - .clip(CircleShape), - ) - } + image?.Content( + modifier = Modifier + .padding(end = dimensionResource(id = R.dimen.spacing_m)) + .size(40.dp) + .clip(CircleShape) + ) Row(verticalAlignment = Alignment.CenterVertically) { Text( modifier = Modifier.weight(1f), @@ -102,13 +94,7 @@ fun OdsBanner( overflow = TextOverflow.Ellipsis ) if (isSingleLineBanner) { - OdsTextButton( - modifier = Modifier - .padding(start = dimensionResource(id = R.dimen.spacing_s)), - style = OdsTextButtonStyle.Primary, - text = button1Text, - onClick = onButton1Click - ) + firstButton.Content(modifier = Modifier.padding(start = dimensionResource(id = R.dimen.spacing_s))) } } } @@ -118,26 +104,59 @@ fun OdsBanner( .padding(bottom = dimensionResource(id = R.dimen.spacing_s)) .align(Alignment.End) ) { - OdsTextButton( - modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_s)), - style = OdsTextButtonStyle.Primary, - text = button1Text, - onClick = onButton1Click - ) - button2Text?.let { - OdsTextButton( - modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_s)), - style = OdsTextButtonStyle.Primary, - text = button2Text, - onClick = { onButton2Click?.invoke() } - ) - } + firstButton.Content(modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_s))) + secondButton?.Content(modifier = Modifier.padding(end = dimensionResource(id = R.dimen.spacing_s))) } } OdsDivider() } } +/** + * A button in an [OdsBanner]. + * + * @constructor Creates an instance of [OdsBannerButton]. + * @param text Text of the button. + * @param onClick Will be called when the user clicks the button. + */ +class OdsBannerButton(private val text: String, private val onClick: () -> Unit) : OdsComponentContent() { + + @Composable + override fun Content(modifier: Modifier) { + OdsTextButton(text = text, onClick = onClick, modifier = modifier, style = OdsTextButtonStyle.Primary) + } +} + +/** + * An image in an [OdsBanner]. + */ +class OdsBannerImage : OdsComponentImage { + + /** + * Creates an instance of [OdsBannerImage]. + * + * @param painter The painter to draw. + * @param contentDescription The content description associated to this [OdsBannerImage]. + */ + constructor(painter: Painter, contentDescription: String) : super(painter as Any, contentDescription, ContentScale.Crop) + + /** + * Creates an instance of [OdsBannerImage]. + * + * @param imageVector The image vector to draw. + * @param contentDescription The content description associated to this [OdsBannerImage]. + */ + constructor(imageVector: ImageVector, contentDescription: String) : super(imageVector as Any, contentDescription, ContentScale.Crop) + + /** + * Creates an instance of [OdsBannerImage]. + * + * @param bitmap The image bitmap to draw. + * @param contentDescription The content description associated to this [OdsBannerImage]. + */ + constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap as Any, contentDescription, ContentScale.Crop) +} + @UiModePreviews.Default @Composable private fun PreviewOdsBanner(@PreviewParameter(OdsBannerPreviewParameterProvider::class) parameter: OdsBannerPreviewParameter) = @@ -145,18 +164,17 @@ private fun PreviewOdsBanner(@PreviewParameter(OdsBannerPreviewParameterProvider with(parameter) { OdsBanner( message = message, - button1Text = button1Text, - onButton1Click = {}, - button2Text = button2Text, - image = imageRes?.let { painterResource(id = it) }, + firstButton = OdsBannerButton(firstButtonText) {}, + image = imageRes?.let { OdsBannerImage(painterResource(id = it), "") }, + secondButton = secondButtonText?.let { OdsBannerButton(it) {} }, ) } } private data class OdsBannerPreviewParameter( val message: String, - val button1Text: String, - val button2Text: String? = null, + val firstButtonText: String, + val secondButtonText: String? = null, val imageRes: Int? = null ) @@ -168,14 +186,14 @@ private val previewParameterValues: List val imageRes = R.drawable.placeholder val shortMessage = "Two lines text string with two actions." val longMessage = "Two lines text string with two actions. One to two lines is preferable on mobile and tablet." - val button1Text = "ACTION" - val button2Text = "ACTION" + val firstButtonText = "ACTION" + val secondButtonText = "ACTION" return listOf( - OdsBannerPreviewParameter(longMessage, button1Text, button2Text, imageRes), - OdsBannerPreviewParameter(shortMessage, button1Text), - OdsBannerPreviewParameter(longMessage, button1Text, button2Text), - OdsBannerPreviewParameter(longMessage, button1Text), - OdsBannerPreviewParameter(shortMessage, button1Text, imageRes = imageRes) + OdsBannerPreviewParameter(longMessage, firstButtonText, secondButtonText, imageRes), + OdsBannerPreviewParameter(shortMessage, firstButtonText), + OdsBannerPreviewParameter(longMessage, firstButtonText, secondButtonText), + OdsBannerPreviewParameter(longMessage, firstButtonText), + OdsBannerPreviewParameter(shortMessage, firstButtonText, imageRes = imageRes) ) } \ No newline at end of file diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt index 3c1643f1d..1c04ed80f 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentContent.kt @@ -11,6 +11,7 @@ package com.orange.ods.compose.component.content import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier /** * The content of a component. @@ -22,11 +23,21 @@ import androidx.compose.runtime.Composable */ abstract class OdsComponentContent { + /** + * The Jetpack Compose UI for this component content. + * + * Calls `Content(Modifier)` with the default `Modifier`. + */ + @Composable + fun Content() = Content(modifier = Modifier) + /** * The Jetpack Compose UI for this component content. * Subclasses must implement this method to provide content. + * + * @param modifier the Modifier for this content. */ // TODO: Set this method internal once OdsSearchTopAppBar is developed @Composable - abstract fun Content() + abstract fun Content(modifier: Modifier) } diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt index b6099a701..87107ab3a 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentIcon.kt @@ -11,6 +11,7 @@ package com.orange.ods.compose.component.content import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter @@ -56,12 +57,19 @@ abstract class OdsComponentIcon protected constructor( ) : this(bitmap as Any, contentDescription, enabled, onClick) @Composable - override fun Content() { + override fun Content(modifier: Modifier) { val tint = tint.orElse { OdsIconDefaults.tint() } onClick?.let { onClick -> - OdsIconButton(onClick = onClick, graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint, enabled = enabled) + OdsIconButton( + onClick = onClick, + graphicsObject = graphicsObject, + contentDescription = contentDescription, + tint = tint, + modifier = modifier, + enabled = enabled + ) }.orElse { - OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription, tint = tint) + OdsIcon(graphicsObject = graphicsObject, contentDescription = contentDescription, modifier = modifier, tint = tint) } } } diff --git a/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentImage.kt b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentImage.kt new file mode 100644 index 000000000..9afc1bfc7 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/content/OdsComponentImage.kt @@ -0,0 +1,57 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.content + +import androidx.compose.foundation.Image +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.layout.ContentScale + +/** + * An image in a component. + */ +abstract class OdsComponentImage( + private val graphicsObject: Any, + private val contentDescription: String, + private val contentScale: ContentScale = ContentScale.Fit +) : OdsComponentContent() { + + protected constructor( + painter: Painter, + contentDescription: String, + contentScale: ContentScale = ContentScale.Fit + ) : this(painter as Any, contentDescription, contentScale) + + protected constructor( + imageVector: ImageVector, + contentDescription: String, + contentScale: ContentScale = ContentScale.Fit + ) : this(imageVector as Any, contentDescription, contentScale) + + protected constructor( + bitmap: ImageBitmap, + contentDescription: String, + contentScale: ContentScale = ContentScale.Fit + ) : this(bitmap as Any, contentDescription, contentScale) + + @Composable + override fun Content(modifier: Modifier) { + when (graphicsObject) { + is Painter -> Image(painter = graphicsObject, contentDescription = contentDescription, modifier = modifier, contentScale = contentScale) + is ImageVector -> Image(imageVector = graphicsObject, contentDescription = contentDescription, modifier = modifier, contentScale = contentScale) + is ImageBitmap -> Image(bitmap = graphicsObject, contentDescription = contentDescription, modifier = modifier, contentScale = contentScale) + else -> {} + } + } +} diff --git a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt index b08eed69e..bc3153347 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/menu/OdsDropdownMenu.kt @@ -153,7 +153,7 @@ class OdsDropdownMenuItem private constructor( ) : this(text, icon as Any?, enabled, divider, onClick) @Composable - override fun Content() { + override fun Content(modifier: Modifier) { DropdownMenuItem(onClick = onClick, enabled = enabled) { icon?.let { OdsIcon( From 09060e395c979a0b8b0de5c82f2ca86ffb57fe69 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Thu, 10 Aug 2023 18:11:07 +0200 Subject: [PATCH 045/132] [#592] Review: Fix a bug where OdsBanner image was not displayed in demo app when selecting XML framework --- .../java/com/orange/ods/xml/component/banner/OdsBanner.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt b/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt index 6d42b1da3..af76addb5 100644 --- a/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt +++ b/lib-xml/src/main/java/com/orange/ods/xml/component/banner/OdsBanner.kt @@ -53,9 +53,9 @@ class OdsBanner @JvmOverloads constructor(context: Context, attrs: AttributeSet? OdsBanner( message = message, firstButton = OdsBannerButton(firstButtonText, onFirstButtonClick), - image = ifNotNull(image, imageContentDescription) { image, contentDescription -> + image = image?.let { image -> val painter = rememberDrawablePainter(drawable = image) - OdsBannerImage(painter, contentDescription) + OdsBannerImage(painter, imageContentDescription.orEmpty()) }, secondButton = ifNotNull(secondButtonText, onSecondButtonClick) { text, onClick -> OdsBannerButton(text, onClick) From 3a2a0f2d5f47c69e8780284156c4829a72dc3b69 Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Thu, 22 Jun 2023 18:25:03 +0200 Subject: [PATCH 046/132] [#530] Add component ButtonsTextToggleGroup --- .../orange/ods/app/ui/components/Component.kt | 2 + .../buttons/ButtonCustomizationState.kt | 1 - .../buttons/ButtonsTextToggleGroup.kt | 118 ++++++++++++++ .../ui/components/buttons/ComponentButtons.kt | 79 ++++++---- app/src/main/res/values/strings.xml | 3 +- changelog.md | 5 +- .../button/OdsTextToggleButtonsRow.kt | 145 ++++++++++++++++++ 7 files changed, 317 insertions(+), 36 deletions(-) create mode 100644 app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsTextToggleGroup.kt create mode 100644 lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt 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 540bea13e..727b6a5a0 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 @@ -98,6 +98,7 @@ sealed class Component( Variant.ButtonsDefault, Variant.ButtonsOutlined, Variant.ButtonsText, + Variant.ButtonsTextToggleGroup, Variant.ButtonsFunctional ), demoScreen = { variant, _ -> if (variant != null) ComponentButtons(variant = variant) } @@ -293,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/buttons/ButtonCustomizationState.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonCustomizationState.kt index 2c8efc05d..5c878795b 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 @@ -38,7 +38,6 @@ class ButtonCustomizationState( val fullScreenWidth: MutableState, val enabled: MutableState ) { - val hasLeadingIcon get() = leadingIcon.value 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..b172533ae --- /dev/null +++ b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsTextToggleGroup.kt @@ -0,0 +1,118 @@ +/* + * + * 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.R +import com.orange.ods.app.domain.recipes.LocalCategories +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.OdsIconToggleButtonsRowItem +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 maxToggleCount = 2 + val textToggleButtons = + LocalCategories.current.distinctBy { it.name }.filter { it.name != "" }.take(maxToggleCount).map { category -> + OdsTextToggleButtonsRowItem(category.name, customizationState.isEnabled) + } + + var selectedIndex by rememberSaveable { mutableStateOf(0) } + + with(customizationState) { + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) + ) { + ToggleButtonsRow( + iconToggleButtons = textToggleButtons, + selectedIndex = selectedIndex, + onSelectedIndexChange = { index -> selectedIndex = index }, + toggleCount = maxToggleCount + ) + + Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) + + InvertedBackgroundColumn { + ToggleButtonsRow( + iconToggleButtons = textToggleButtons, + selectedIndex = selectedIndex, + onSelectedIndexChange = { index -> selectedIndex = index }, + toggleCount = maxToggleCount, + displaySurface = displaySurface + ) + } + + CodeImplementationColumn( + modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) + ) { + FunctionCallCode( + name = OdsComposable.OdsIconToggleButtonsRow.name, + exhaustiveParameters = false, + parameters = { + list("iconsToggleButtons") { + repeat(maxToggleCount) { + classInstance(OdsIconToggleButtonsRowItem::class.java) { + painter() + string("iconDescription", "icon description") + } + } + } + stringRepresentation("selectedButtonIndex", selectedIndex) + } + ) + } + } + } +} + +@Composable +private fun ToggleButtonsRow( + iconToggleButtons: List, + selectedIndex: Int, + onSelectedIndexChange: (Int) -> Unit, + toggleCount: Int, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default +) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = dimensionResource(R.dimen.spacing_m)) + .padding(horizontal = dimensionResource(R.dimen.screen_horizontal_margin)), + horizontalArrangement = Arrangement.Center + ) { + OdsTextToggleButtonsRow( + textToggleButtons = iconToggleButtons.take(toggleCount), + selectedIndex = selectedIndex, + onSelectedIndexChange = onSelectedIndexChange, + 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 40d230670..7767bd99e 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 @@ -58,45 +58,62 @@ 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 = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true - ) { - OdsChoiceChip(textRes = R.string.component_button_style_functional_positive, value = OdsButtonStyle.FunctionalPositive) - OdsChoiceChip(textRes = R.string.component_button_style_functional_negative, value = OdsButtonStyle.FunctionalNegative) - } - } else if (variant == Variant.ButtonsText) { - Subtitle(textRes = R.string.component_style, horizontalPadding = true) - OdsChoiceChipsFlowRow( - selectedChip = textButtonStyle, - modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), - outlinedChips = true - ) { - OdsChoiceChip(textRes = R.string.component_button_style_primary, value = OdsTextButtonStyle.Primary) - OdsChoiceChip(textRes = R.string.component_button_style_default, value = OdsTextButtonStyle.Default) + if (variant == Variant.ButtonsTextToggleGroup) { + /*ComponentCountRow( + modifier = Modifier.padding(start = dimensionResource(id = 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 = ButtonIconCustomizationState.MinToggleCount, + maxCount = ButtonIconCustomizationState.MaxToggleCount + )*/ + OdsListItem( + text = stringResource(id = R.string.component_state_enabled), + trailing = OdsSwitchTrailing(checked = enabled) + ) + } else { + if (variant == Variant.ButtonsFunctional) { + Subtitle(textRes = R.string.component_button_style_functional, horizontalPadding = true) + OdsChoiceChipsFlowRow( + selectedChip = buttonStyle, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), + 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) + } + } else if (variant == Variant.ButtonsText) { + Subtitle(textRes = R.string.component_style, horizontalPadding = true) + OdsChoiceChipsFlowRow( + selectedChip = textButtonStyle, + modifier = Modifier.padding(horizontal = dimensionResource(id = com.orange.ods.R.dimen.screen_horizontal_margin)), + outlinedChips = true + ) { + OdsChoiceChip(textRes = R.string.component_button_style_primary, value = OdsTextButtonStyle.Primary) + OdsChoiceChip(textRes = R.string.component_button_style_default, value = OdsTextButtonStyle.Default) + } } + 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) + ) } - 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) - ) }) { when (variant) { Variant.ButtonsPrimary, Variant.ButtonsDefault, Variant.ButtonsFunctional -> ButtonsContained(customizationState) Variant.ButtonsOutlined -> ButtonsOutlined(customizationState) Variant.ButtonsText -> ButtonsText(customizationState) + Variant.ButtonsTextToggleGroup -> ButtonsTextToggleButtonsRow(customizationState) else -> {} } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4105ab2e2..079b3357d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,7 +8,7 @@ ~ */ --> - + Orange Design System Code implementation @@ -163,6 +163,7 @@ Search Toggle icon button Toggle icon button group + Toggle text buttons group Add to favorites Toggle count Remove toggle diff --git a/changelog.md b/changelog.md index 5f1dc030a..ec6154239 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - \[App\] Add list item component ([#555](https://github.com/Orange-OpenSource/ods-android/issues/555)) +- \[App\] Add component buttons Text Toggle Group([#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 @@ -48,9 +50,6 @@ 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)) - -### Fixed - - \[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/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt new file mode 100644 index 000000000..b4345b56d --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt @@ -0,0 +1,145 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.button + +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.selection.selectableGroup +import androidx.compose.material.Divider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.orange.ods.compose.component.OdsComposable +import com.orange.ods.compose.component.utilities.Preview +import com.orange.ods.compose.component.utilities.UiModePreviews +import com.orange.ods.compose.theme.OdsDisplaySurface +import com.orange.ods.compose.theme.OdsTheme + +/** + * ODS Buttons. + * + * A group of toggle buttons. Only one option in a group of toggle buttons can be selected and active at a time. + * Selecting one option deselects any other. + * + * @param textToggleButtons Contains the [OdsTextToggleButtonsRowItem] to display in the toggle group + * @param selectedIndex The [textToggleButtons] list index of the selected button. + * @param onSelectedIndexChange Callback to be invoked when the selection change. + * @param modifier optional [Modifier] for this OdsTextToggleButtonsRow + * @param displaySurface optional allow to force the group display on a dark or light + * surface. By default the appearance applied is based on the system night mode value. + */ +@Composable +@OdsComposable +fun OdsTextToggleButtonsRow( + textToggleButtons: List, + selectedIndex: Int, + onSelectedIndexChange: (Int) -> Unit, + modifier: Modifier = Modifier, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default +) { + Row( + modifier = modifier + .height(IntrinsicSize.Min) + .selectableGroup() + .border( + width = 1.dp, + color = buttonToggleBorderColor(displaySurface) + ) + ) { + textToggleButtons.forEachIndexed { index, textToggleButton -> + TextToggleButtonsRowItem( + index = index, + textToggleButton = textToggleButton, + selected = selectedIndex == index, + displaySurface = displaySurface + ) { clickedButtonIndex -> + onSelectedIndexChange(clickedButtonIndex) + } + if (index < textToggleButtons.size) { + Divider( + modifier = Modifier + .fillMaxHeight() + .width(1.dp), + color = buttonToggleBorderColor(displaySurface) + ) + } + } + } +} + +data class OdsTextToggleButtonsRowItem( + val text: String, + val enabled: Boolean = true +) + +@Composable +private fun TextToggleButtonsRowItem( + index: Int, + textToggleButton: OdsTextToggleButtonsRowItem, + selected: Boolean, + displaySurface: OdsDisplaySurface, + onClick: (Int) -> Unit +) { + val backgroundAlpha by animateFloatAsState(if (selected) 0.12f else 0f) + + OdsTextButton( + modifier = Modifier + .background(color = buttonToggleBackgroundColor(displaySurface).copy(alpha = backgroundAlpha)), + text = textToggleButton.text, + enabled = textToggleButton.enabled, + displaySurface = displaySurface, + style = if (selected) OdsTextButtonStyle.Primary else OdsTextButtonStyle.Default, + onClick = { onClick(index) } + ) +} + +@Composable +private fun buttonToggleBackgroundColor(displaySurface: OdsDisplaySurface) = + when (displaySurface) { + OdsDisplaySurface.Default -> OdsTheme.colors.primary + OdsDisplaySurface.Dark -> OdsTheme.darkThemeColors.primary + OdsDisplaySurface.Light -> OdsTheme.lightThemeColors.primary + } + +@Composable +private fun buttonToggleBorderColor(displaySurface: OdsDisplaySurface) = + when (displaySurface) { + OdsDisplaySurface.Default -> OdsTheme.colors.onSurface + OdsDisplaySurface.Dark -> OdsTheme.darkThemeColors.onSurface + OdsDisplaySurface.Light -> OdsTheme.lightThemeColors.onSurface + }.copy(alpha = 0.12f) + + +@UiModePreviews.Default +@Composable +private fun PreviewOdsTextToggleButtonsGroupRow() = Preview { + val textToggleButtons = listOf( + OdsTextToggleButtonsRowItem("XML", true), + OdsTextToggleButtonsRowItem("COMPOSE", true), + ) + var selectedIndex by remember { mutableStateOf(0) } + + OdsTextToggleButtonsRow( + textToggleButtons = textToggleButtons, + selectedIndex = selectedIndex, + onSelectedIndexChange = { index -> selectedIndex = index } + ) +} From dc9e714d2173a689583a21d6e795d1111db3a3f1 Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Wed, 28 Jun 2023 16:58:57 +0200 Subject: [PATCH 047/132] [#530] Add OdsTextToggleButton --- .../orange/ods/app/ui/components/Component.kt | 4 +-- .../buttons/ButtonCustomizationState.kt | 11 +++++-- .../buttons/ButtonsTextToggleGroup.kt | 32 +++++++++---------- .../ui/components/buttons/ComponentButtons.kt | 9 +++--- app/src/main/res/values/strings.xml | 4 +-- .../compose/component/button/OdsTextButton.kt | 12 +++++-- .../button/OdsTextToggleButtonsRow.kt | 30 ++++++++++------- 7 files changed, 61 insertions(+), 41 deletions(-) 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 727b6a5a0..4bdf41965 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 @@ -98,8 +98,8 @@ sealed class Component( Variant.ButtonsDefault, Variant.ButtonsOutlined, Variant.ButtonsText, - Variant.ButtonsTextToggleGroup, - Variant.ButtonsFunctional + Variant.ButtonsFunctional, + Variant.ButtonsTextToggleGroup ), demoScreen = { variant, _ -> if (variant != null) ComponentButtons(variant = variant) } ) 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 5c878795b..6231e0591 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,30 @@ 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) }, enabled: MutableState = rememberSaveable { mutableStateOf(true) } ) = - remember(buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, enabled) { - ButtonCustomizationState(buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, enabled) + remember(buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, enabled, toggleCount) { + ButtonCustomizationState(toggleCount, buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, enabled) } class ButtonCustomizationState( + val toggleCount: MutableState, val buttonStyle: MutableState, val textButtonStyle: MutableState, val leadingIcon: MutableState, val fullScreenWidth: MutableState, val enabled: MutableState ) { + companion object { + const val MinToggleCount = 2 + const val MaxToggleCount = 3 + } + val hasLeadingIcon get() = leadingIcon.value 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 index b172533ae..47fffc036 100644 --- 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 @@ -26,21 +26,19 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import com.orange.ods.app.R -import com.orange.ods.app.domain.recipes.LocalCategories +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.component.button.OdsIconToggleButtonsRowItem 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 maxToggleCount = 2 val textToggleButtons = - LocalCategories.current.distinctBy { it.name }.filter { it.name != "" }.take(maxToggleCount).map { category -> - OdsTextToggleButtonsRowItem(category.name, customizationState.isEnabled) + LocalRecipes.current.distinctBy { it.title }.filter { it.title != "" }.take(ButtonCustomizationState.MaxToggleCount).map { recipe -> + OdsTextToggleButtonsRowItem(recipe.title, customizationState.isEnabled) } var selectedIndex by rememberSaveable { mutableStateOf(0) } @@ -52,20 +50,20 @@ fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { .padding(vertical = dimensionResource(id = R.dimen.screen_vertical_margin)) ) { ToggleButtonsRow( - iconToggleButtons = textToggleButtons, + textToggleButtons = textToggleButtons, selectedIndex = selectedIndex, onSelectedIndexChange = { index -> selectedIndex = index }, - toggleCount = maxToggleCount + toggleCount = toggleCount.value ) Spacer(modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_s))) InvertedBackgroundColumn { ToggleButtonsRow( - iconToggleButtons = textToggleButtons, + textToggleButtons = textToggleButtons, selectedIndex = selectedIndex, onSelectedIndexChange = { index -> selectedIndex = index }, - toggleCount = maxToggleCount, + toggleCount = toggleCount.value, displaySurface = displaySurface ) } @@ -74,14 +72,14 @@ fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.screen_horizontal_margin)) ) { FunctionCallCode( - name = OdsComposable.OdsIconToggleButtonsRow.name, + name = OdsComposable.OdsTextToggleButtonsRow.name, exhaustiveParameters = false, parameters = { - list("iconsToggleButtons") { - repeat(maxToggleCount) { - classInstance(OdsIconToggleButtonsRowItem::class.java) { - painter() - string("iconDescription", "icon description") + list("textToggleButtons") { + repeat(toggleCount.value) { + classInstance(OdsTextToggleButtonsRowItem::class.java) { + string("text", "text bottom") + selected(customizationState.isEnabled) } } } @@ -95,7 +93,7 @@ fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { @Composable private fun ToggleButtonsRow( - iconToggleButtons: List, + textToggleButtons: List, selectedIndex: Int, onSelectedIndexChange: (Int) -> Unit, toggleCount: Int, @@ -109,7 +107,7 @@ private fun ToggleButtonsRow( horizontalArrangement = Arrangement.Center ) { OdsTextToggleButtonsRow( - textToggleButtons = iconToggleButtons.take(toggleCount), + textToggleButtons = textToggleButtons.take(toggleCount), selectedIndex = selectedIndex, onSelectedIndexChange = onSelectedIndexChange, displaySurface = displaySurface 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 7767bd99e..07430f355 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 @@ -59,15 +60,15 @@ fun ComponentButtons(variant: Variant) { bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { if (variant == Variant.ButtonsTextToggleGroup) { - /*ComponentCountRow( + ComponentCountRow( modifier = Modifier.padding(start = dimensionResource(id = 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 = ButtonIconCustomizationState.MinToggleCount, - maxCount = ButtonIconCustomizationState.MaxToggleCount - )*/ + minCount = ButtonCustomizationState.MinToggleCount, + maxCount = ButtonCustomizationState.MaxToggleCount + ) OdsListItem( text = stringResource(id = R.string.component_state_enabled), trailing = OdsSwitchTrailing(checked = enabled) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 079b3357d..fed86b26b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,7 +8,7 @@ ~ */ --> - + Orange Design System Code implementation @@ -153,6 +153,7 @@ Functional Positive Negative + Toggle text buttons group Buttons: Icons @@ -163,7 +164,6 @@ Search Toggle icon button Toggle icon button group - Toggle text buttons group Add to favorites Toggle count Remove toggle diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt index 707b10826..b82451248 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.utilities.EnumPreviewParameterProvider @@ -40,6 +41,8 @@ enum class OdsTextButtonStyle { companion object } +public const val MAX_VALUE: Int = 2147483647 + /** * ODS Buttons. * @@ -64,6 +67,8 @@ fun OdsTextButton( modifier: Modifier = Modifier, icon: Painter? = null, enabled: Boolean = true, + maxLines: Int? = null, + overflow: TextOverflow? = null, style: OdsTextButtonStyle = OdsTextButtonStyle.Default, displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default ) { @@ -85,7 +90,10 @@ fun OdsTextButton( ) ) { icon?.let { ButtonIcon(it) } - Text(text = text.uppercase(), style = OdsTheme.typography.button) + Text( + text = text.uppercase(), style = OdsTheme.typography.button, maxLines = maxLines ?: MAX_VALUE, + overflow = overflow ?: TextOverflow.Clip + ) } } } @@ -104,7 +112,7 @@ private fun OdsColors.buttonTextDisabledColor(displaySurface: OdsDisplaySurface) @UiModePreviews.Button @Composable private fun PreviewOdsTextButton(@PreviewParameter(OdsTextButtonPreviewParameterProvider::class) style: OdsTextButtonStyle) = Preview { - OdsTextButton(text = "Text", onClick = {}, style = style) + OdsTextButton(text = "Text", maxLines = 1, overflow = TextOverflow.Clip, onClick = {}, style = style) } private class OdsTextButtonPreviewParameterProvider : EnumPreviewParameterProvider(OdsTextButtonStyle::class) diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt index b4345b56d..d5ee574e5 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt @@ -13,6 +13,7 @@ package com.orange.ods.compose.component.button import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight @@ -26,6 +27,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.utilities.Preview @@ -65,13 +67,20 @@ fun OdsTextToggleButtonsRow( ) ) { textToggleButtons.forEachIndexed { index, textToggleButton -> - TextToggleButtonsRowItem( - index = index, - textToggleButton = textToggleButton, - selected = selectedIndex == index, - displaySurface = displaySurface - ) { clickedButtonIndex -> - onSelectedIndexChange(clickedButtonIndex) + val backgroundAlpha by animateFloatAsState(if (selectedIndex == index) 0.12f else 0f) + Column( + modifier = Modifier + .weight(1f) + .background(color = buttonToggleBackgroundColor(displaySurface).copy(alpha = backgroundAlpha)) + ) { + TextToggleButtonsRowItem( + index = index, + textToggleButton = textToggleButton, + selected = selectedIndex == index, + displaySurface = displaySurface + ) { clickedButtonIndex -> + onSelectedIndexChange(clickedButtonIndex) + } } if (index < textToggleButtons.size) { Divider( @@ -98,13 +107,11 @@ private fun TextToggleButtonsRowItem( displaySurface: OdsDisplaySurface, onClick: (Int) -> Unit ) { - val backgroundAlpha by animateFloatAsState(if (selected) 0.12f else 0f) - OdsTextButton( - modifier = Modifier - .background(color = buttonToggleBackgroundColor(displaySurface).copy(alpha = backgroundAlpha)), text = textToggleButton.text, enabled = textToggleButton.enabled, + maxLines = 1, + overflow = TextOverflow.Ellipsis, displaySurface = displaySurface, style = if (selected) OdsTextButtonStyle.Primary else OdsTextButtonStyle.Default, onClick = { onClick(index) } @@ -127,7 +134,6 @@ private fun buttonToggleBorderColor(displaySurface: OdsDisplaySurface) = OdsDisplaySurface.Light -> OdsTheme.lightThemeColors.onSurface }.copy(alpha = 0.12f) - @UiModePreviews.Default @Composable private fun PreviewOdsTextToggleButtonsGroupRow() = Preview { From 914f3f86b71ec876084c46d7fafc5242bdfe1f99 Mon Sep 17 00:00:00 2001 From: dolinetouko <50101555+dolinetouko@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:13:28 +0200 Subject: [PATCH 048/132] [#530] Review: Update changelog.md Co-authored-by: Florent Maitre --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index ec6154239..d92c99042 100644 --- a/changelog.md +++ b/changelog.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - \[App\] Add list item component ([#555](https://github.com/Orange-OpenSource/ods-android/issues/555)) -- \[App\] Add component buttons Text Toggle Group([#530](https://github.com/Orange-OpenSource/ods-android/issues/530)) +- \[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 From 3fc4dfb4267aa7cd5f9ed683229f30988ba0a36c Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Wed, 2 Aug 2023 11:21:46 +0200 Subject: [PATCH 049/132] [#530] Review : remove max_value --- .../com/orange/ods/compose/component/button/OdsTextButton.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt index b82451248..5bb2b9371 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt @@ -41,8 +41,6 @@ enum class OdsTextButtonStyle { companion object } -public const val MAX_VALUE: Int = 2147483647 - /** * ODS Buttons. * @@ -91,7 +89,7 @@ fun OdsTextButton( ) { icon?.let { ButtonIcon(it) } Text( - text = text.uppercase(), style = OdsTheme.typography.button, maxLines = maxLines ?: MAX_VALUE, + text = text.uppercase(), style = OdsTheme.typography.button, maxLines = maxLines ?: Int.MAX_VALUE, overflow = overflow ?: TextOverflow.Clip ) } From 06a06bd6b2c632408d1aa4526d69ba91339ff00c Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Wed, 2 Aug 2023 14:10:52 +0200 Subject: [PATCH 050/132] [#530] Review : Add OdsToggleButtonsRowsCommon --- .../button/OdsIconToggleButtonsRow.kt | 8 ------- .../compose/component/button/OdsTextButton.kt | 10 ++++----- .../button/OdsTextToggleButtonsRow.kt | 16 -------------- .../button/OdsToggleButtonsRowsCommon.kt | 21 +++++++++++++++++++ 4 files changed, 26 insertions(+), 29 deletions(-) create mode 100644 lib/src/main/java/com/orange/ods/compose/component/button/OdsToggleButtonsRowsCommon.kt diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt index d16875f4d..35c264f4e 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsIconToggleButtonsRow.kt @@ -142,14 +142,6 @@ private fun buttonToggleIconColor(displaySurface: OdsDisplaySurface, selected: B if (selected && enabled) primary else onSurface.enable(enabled = enabled) } -@Composable -private fun buttonToggleBackgroundColor(displaySurface: OdsDisplaySurface) = - displaySurface.themeColors.primary - -@Composable -private fun buttonToggleBorderColor(displaySurface: OdsDisplaySurface) = displaySurface.themeColors.onSurface.copy(alpha = 0.12f) - - @UiModePreviews.Default @Composable private fun PreviewOdsIconToggleButtonsGroupRow() = Preview { diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt index 5bb2b9371..dbdd7acce 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt @@ -59,14 +59,14 @@ enum class OdsTextButtonStyle { */ @Composable @OdsComposable -fun OdsTextButton( +internal fun OdsTextButton( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, icon: Painter? = null, enabled: Boolean = true, - maxLines: Int? = null, - overflow: TextOverflow? = null, + maxLines: Int = Int.MAX_VALUE, + overflow: TextOverflow = TextOverflow.Clip, style: OdsTextButtonStyle = OdsTextButtonStyle.Default, displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default ) { @@ -89,8 +89,8 @@ fun OdsTextButton( ) { icon?.let { ButtonIcon(it) } Text( - text = text.uppercase(), style = OdsTheme.typography.button, maxLines = maxLines ?: Int.MAX_VALUE, - overflow = overflow ?: TextOverflow.Clip + text = text.uppercase(), style = OdsTheme.typography.button, maxLines = maxLines, + overflow = overflow ) } } diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt index d5ee574e5..c197d4a86 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt @@ -118,22 +118,6 @@ private fun TextToggleButtonsRowItem( ) } -@Composable -private fun buttonToggleBackgroundColor(displaySurface: OdsDisplaySurface) = - when (displaySurface) { - OdsDisplaySurface.Default -> OdsTheme.colors.primary - OdsDisplaySurface.Dark -> OdsTheme.darkThemeColors.primary - OdsDisplaySurface.Light -> OdsTheme.lightThemeColors.primary - } - -@Composable -private fun buttonToggleBorderColor(displaySurface: OdsDisplaySurface) = - when (displaySurface) { - OdsDisplaySurface.Default -> OdsTheme.colors.onSurface - OdsDisplaySurface.Dark -> OdsTheme.darkThemeColors.onSurface - OdsDisplaySurface.Light -> OdsTheme.lightThemeColors.onSurface - }.copy(alpha = 0.12f) - @UiModePreviews.Default @Composable private fun PreviewOdsTextToggleButtonsGroupRow() = Preview { diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsToggleButtonsRowsCommon.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsToggleButtonsRowsCommon.kt new file mode 100644 index 000000000..eb0f0f2e0 --- /dev/null +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsToggleButtonsRowsCommon.kt @@ -0,0 +1,21 @@ +/* + * + * Copyright 2021 Orange + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * / + */ + +package com.orange.ods.compose.component.button + +import androidx.compose.runtime.Composable +import com.orange.ods.compose.theme.OdsDisplaySurface +import com.orange.ods.compose.theme.OdsTheme + +@Composable +internal fun buttonToggleBackgroundColor(displaySurface: OdsDisplaySurface) = displaySurface.themeColors.primary + +@Composable +internal fun buttonToggleBorderColor(displaySurface: OdsDisplaySurface) = displaySurface.themeColors.onSurface.copy(alpha = 0.12f) \ No newline at end of file From 2720f6340e3e99dc30b9cb380fef71ada3ef1e93 Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Wed, 2 Aug 2023 14:25:18 +0200 Subject: [PATCH 051/132] [#530] Review : change string value --- app/src/main/res/values/strings.xml | 2 +- .../com/orange/ods/compose/component/button/OdsTextButton.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fed86b26b..7941daf6e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -153,7 +153,7 @@ Functional Positive Negative - Toggle text buttons group + Toggle text button group Buttons: Icons diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt index dbdd7acce..0cfb7a0fd 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt @@ -59,7 +59,7 @@ enum class OdsTextButtonStyle { */ @Composable @OdsComposable -internal fun OdsTextButton( +fun OdsTextButton( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, From 1d5917299bad30bb85aa5339f966dc022a6682bd Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Wed, 2 Aug 2023 14:31:43 +0200 Subject: [PATCH 052/132] [#530] Review: remove filter in the recipe list --- .../ods/app/ui/components/buttons/ButtonsTextToggleGroup.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 47fffc036..cb293ff8b 100644 --- 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 @@ -37,7 +37,7 @@ import com.orange.ods.compose.theme.OdsDisplaySurface @Composable fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { val textToggleButtons = - LocalRecipes.current.distinctBy { it.title }.filter { it.title != "" }.take(ButtonCustomizationState.MaxToggleCount).map { recipe -> + LocalRecipes.current.distinctBy { it.title }.take(ButtonCustomizationState.MaxToggleCount).map { recipe -> OdsTextToggleButtonsRowItem(recipe.title, customizationState.isEnabled) } From 4e91f97c60ff64346e611407292c9461981b7f6b Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Wed, 2 Aug 2023 14:36:06 +0200 Subject: [PATCH 053/132] [#530] Review: update code implementation --- .../app/ui/components/buttons/ButtonsTextToggleGroup.kt | 8 ++++---- .../ui/components/buttons/icons/ButtonsIconToggleGroup.kt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) 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 index cb293ff8b..35619745c 100644 --- 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 @@ -76,14 +76,14 @@ fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { exhaustiveParameters = false, parameters = { list("textToggleButtons") { - repeat(toggleCount.value) { + textToggleButtons.take(toggleCount.value).forEach { item -> classInstance(OdsTextToggleButtonsRowItem::class.java) { - string("text", "text bottom") - selected(customizationState.isEnabled) + text(item.text) + enabled(customizationState.isEnabled) } } } - stringRepresentation("selectedButtonIndex", selectedIndex) + stringRepresentation("selectedIndex", selectedIndex) } ) } 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 ba3a5e217..6d471842c 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 @@ -89,7 +89,7 @@ fun ButtonsIconToggleGroup(customizationState: ButtonIconCustomizationState) { } } } - stringRepresentation("selectedButtonIndex", selectedIndex) + stringRepresentation("selectedIndex", selectedIndex) } ) } From 8e77a8cd0cb07ff0aa21bd7d14a4cdaba9e107af Mon Sep 17 00:00:00 2001 From: Doline Touko Date: Wed, 2 Aug 2023 17:38:17 +0200 Subject: [PATCH 054/132] [#530] Review : update OdsTextToggleButtonsRow --- .../button/OdsTextToggleButtonsRow.kt | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt index c197d4a86..7daf4d859 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt @@ -13,9 +13,9 @@ package com.orange.ods.compose.component.button import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width @@ -33,7 +33,6 @@ import com.orange.ods.compose.component.OdsComposable import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews import com.orange.ods.compose.theme.OdsDisplaySurface -import com.orange.ods.compose.theme.OdsTheme /** * ODS Buttons. @@ -67,20 +66,13 @@ fun OdsTextToggleButtonsRow( ) ) { textToggleButtons.forEachIndexed { index, textToggleButton -> - val backgroundAlpha by animateFloatAsState(if (selectedIndex == index) 0.12f else 0f) - Column( - modifier = Modifier - .weight(1f) - .background(color = buttonToggleBackgroundColor(displaySurface).copy(alpha = backgroundAlpha)) - ) { - TextToggleButtonsRowItem( - index = index, - textToggleButton = textToggleButton, - selected = selectedIndex == index, - displaySurface = displaySurface - ) { clickedButtonIndex -> - onSelectedIndexChange(clickedButtonIndex) - } + TextToggleButtonsRowItem( + index = index, + textToggleButton = textToggleButton, + selected = selectedIndex == index, + displaySurface = displaySurface + ) { clickedButtonIndex -> + onSelectedIndexChange(clickedButtonIndex) } if (index < textToggleButtons.size) { Divider( @@ -100,16 +92,21 @@ data class OdsTextToggleButtonsRowItem( ) @Composable -private fun TextToggleButtonsRowItem( +private fun RowScope.TextToggleButtonsRowItem( index: Int, textToggleButton: OdsTextToggleButtonsRowItem, selected: Boolean, displaySurface: OdsDisplaySurface, onClick: (Int) -> Unit ) { + val backgroundAlpha by animateFloatAsState(if (selected) 0.12f else 0f) + OdsTextButton( text = textToggleButton.text, enabled = textToggleButton.enabled, + modifier = Modifier + .background(color = buttonToggleBackgroundColor(displaySurface).copy(alpha = backgroundAlpha)) + .weight(1f), maxLines = 1, overflow = TextOverflow.Ellipsis, displaySurface = displaySurface, From d0e867e52e81eba6a341ecb2ff5395c2f6d7d43f Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 8 Aug 2023 15:18:38 +0200 Subject: [PATCH 055/132] [#530] Review: OdsTextButton method with maxLines and overflow parameters is now internal --- .../compose/component/button/OdsTextButton.kt | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt index 0cfb7a0fd..17cf0fd59 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextButton.kt @@ -65,8 +65,31 @@ fun OdsTextButton( modifier: Modifier = Modifier, icon: Painter? = null, enabled: Boolean = true, - maxLines: Int = Int.MAX_VALUE, - overflow: TextOverflow = TextOverflow.Clip, + style: OdsTextButtonStyle = OdsTextButtonStyle.Default, + displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default +) { + OdsTextButton( + text = text, + onClick = onClick, + modifier = modifier, + icon = icon, + enabled = enabled, + maxLines = Int.MAX_VALUE, + overflow = TextOverflow.Clip, + style = style, + displaySurface = displaySurface + ) +} + +@Composable +internal fun OdsTextButton( + text: String, + onClick: () -> Unit, + maxLines: Int, + overflow: TextOverflow, + modifier: Modifier = Modifier, + icon: Painter? = null, + enabled: Boolean = true, style: OdsTextButtonStyle = OdsTextButtonStyle.Default, displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default ) { From cc565dbab3fd3473dff723c83d7ac3ef39bdf165 Mon Sep 17 00:00:00 2001 From: Florent Maitre Date: Tue, 8 Aug 2023 16:21:41 +0200 Subject: [PATCH 056/132] [#530] Fix build error following dependencies update --- .../ui/components/buttons/ButtonsTextToggleGroup.kt | 10 +++++----- .../ods/app/ui/components/buttons/ComponentButtons.kt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) 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 index 35619745c..4b5b2e7ac 100644 --- 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 @@ -47,7 +47,7 @@ fun ButtonsTextToggleButtonsRow(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)) ) { ToggleButtonsRow( textToggleButtons = textToggleButtons, @@ -56,7 +56,7 @@ fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { 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( @@ -69,7 +69,7 @@ fun ButtonsTextToggleButtonsRow(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)) ) { FunctionCallCode( name = OdsComposable.OdsTextToggleButtonsRow.name, @@ -102,8 +102,8 @@ 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 ) { OdsTextToggleButtonsRow( 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 07430f355..ada90af0d 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 @@ -61,7 +61,7 @@ fun ComponentButtons(variant: Variant) { bottomSheetContent = { if (variant == Variant.ButtonsTextToggleGroup) { 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), From 92cc7179c9e592eda71e4366008a09018fa4b3f6 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 9 Aug 2023 17:23:18 +0200 Subject: [PATCH 057/132] [#530] Allow to set same items weight in buttons text toggle group customization --- .../buttons/ButtonCustomizationState.kt | 9 +++- .../buttons/ButtonsTextToggleGroup.kt | 11 ++-- .../ui/components/buttons/ComponentButtons.kt | 50 +++++++++++-------- app/src/main/res/values/strings.xml | 1 + .../button/OdsTextToggleButtonsRow.kt | 13 +++-- 5 files changed, 53 insertions(+), 31 deletions(-) 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 6231e0591..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 @@ -26,10 +26,11 @@ fun rememberButtonCustomizationState( 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, toggleCount) { - ButtonCustomizationState(toggleCount, buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, enabled) + remember(buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, sameItemsWeight, enabled, toggleCount) { + ButtonCustomizationState(toggleCount, buttonStyle, textButtonStyle, leadingIcon, fullScreenWidth, sameItemsWeight, enabled) } class ButtonCustomizationState( @@ -38,6 +39,7 @@ class ButtonCustomizationState( val textButtonStyle: MutableState, val leadingIcon: MutableState, val fullScreenWidth: MutableState, + val sameItemsWeight: MutableState, val enabled: MutableState ) { companion object { @@ -53,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/ButtonsTextToggleGroup.kt b/app/src/main/java/com/orange/ods/app/ui/components/buttons/ButtonsTextToggleGroup.kt index 4b5b2e7ac..f1eab4b87 100644 --- 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 @@ -25,7 +25,6 @@ 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.R 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 @@ -37,8 +36,8 @@ import com.orange.ods.compose.theme.OdsDisplaySurface @Composable fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { val textToggleButtons = - LocalRecipes.current.distinctBy { it.title }.take(ButtonCustomizationState.MaxToggleCount).map { recipe -> - OdsTextToggleButtonsRowItem(recipe.title, customizationState.isEnabled) + LocalRecipes.current.first().ingredients.distinctBy { it.food }.take(ButtonCustomizationState.MaxToggleCount).map { ingredient -> + OdsTextToggleButtonsRowItem(ingredient.food.name, customizationState.isEnabled) } var selectedIndex by rememberSaveable { mutableStateOf(0) } @@ -53,7 +52,8 @@ fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { textToggleButtons = textToggleButtons, selectedIndex = selectedIndex, onSelectedIndexChange = { index -> selectedIndex = index }, - toggleCount = toggleCount.value + toggleCount = toggleCount.value, + sameItemsWeight = hasSameItemsWeight, ) Spacer(modifier = Modifier.padding(top = dimensionResource(com.orange.ods.R.dimen.spacing_s))) @@ -64,6 +64,7 @@ fun ButtonsTextToggleButtonsRow(customizationState: ButtonCustomizationState) { selectedIndex = selectedIndex, onSelectedIndexChange = { index -> selectedIndex = index }, toggleCount = toggleCount.value, + sameItemsWeight = hasSameItemsWeight, displaySurface = displaySurface ) } @@ -97,6 +98,7 @@ private fun ToggleButtonsRow( selectedIndex: Int, onSelectedIndexChange: (Int) -> Unit, toggleCount: Int, + sameItemsWeight: Boolean, displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default ) { Row( @@ -110,6 +112,7 @@ private fun ToggleButtonsRow( textToggleButtons = textToggleButtons.take(toggleCount), selectedIndex = selectedIndex, onSelectedIndexChange = onSelectedIndexChange, + sameItemsWeight = sameItemsWeight, displaySurface = displaySurface ) } 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 ada90af0d..e945a5638 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 @@ -59,22 +59,8 @@ fun ComponentButtons(variant: Variant) { ComponentCustomizationBottomSheetScaffold( bottomSheetScaffoldState = rememberBottomSheetScaffoldState(), bottomSheetContent = { - if (variant == 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_state_enabled), - trailing = OdsSwitchTrailing(checked = enabled) - ) - } else { - if (variant == Variant.ButtonsFunctional) { + when (variant) { + Variant.ButtonsFunctional -> { Subtitle(textRes = R.string.component_button_style_functional, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = buttonStyle, @@ -84,7 +70,8 @@ fun ComponentButtons(variant: Variant) { OdsChoiceChip(textRes = R.string.component_button_style_functional_positive, value = OdsButtonStyle.FunctionalPositive) OdsChoiceChip(textRes = R.string.component_button_style_functional_negative, value = OdsButtonStyle.FunctionalNegative) } - } else if (variant == Variant.ButtonsText) { + } + Variant.ButtonsText -> { Subtitle(textRes = R.string.component_style, horizontalPadding = true) OdsChoiceChipsFlowRow( selectedChip = textButtonStyle, @@ -95,6 +82,26 @@ fun ComponentButtons(variant: Variant) { OdsChoiceChip(textRes = 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_toogle_group_same_weight), + trailing = OdsSwitchTrailing(checked = sameItemsWeight) + ) + } + else -> {} + } + + if (variant != Variant.ButtonsTextToggleGroup) { OdsListItem( text = stringResource(id = R.string.component_element_icon), trailing = OdsSwitchTrailing(checked = leadingIcon) @@ -103,11 +110,12 @@ fun ComponentButtons(variant: Variant) { 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) - ) } + + OdsListItem( + text = stringResource(id = R.string.component_state_enabled), + trailing = OdsSwitchTrailing(checked = enabled) + ) }) { when (variant) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7941daf6e..ebf046513 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -146,6 +146,7 @@ Medium emphasis buttons Low emphasis buttons Functional buttons + Same items weight Full screen width Primary diff --git a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt index 7daf4d859..42b87c6f8 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/button/OdsTextToggleButtonsRow.kt @@ -43,8 +43,9 @@ import com.orange.ods.compose.theme.OdsDisplaySurface * @param textToggleButtons Contains the [OdsTextToggleButtonsRowItem] to display in the toggle group * @param selectedIndex The [textToggleButtons] list index of the selected button. * @param onSelectedIndexChange Callback to be invoked when the selection change. - * @param modifier optional [Modifier] for this OdsTextToggleButtonsRow - * @param displaySurface optional allow to force the group display on a dark or light + * @param modifier [Modifier] for this OdsTextToggleButtonsRow + * @param sameItemsWeight if true, same weight of importance will be applied to each item, they will occupy the same width. + * @param displaySurface allow to force the group display on a dark or light * surface. By default the appearance applied is based on the system night mode value. */ @Composable @@ -54,6 +55,7 @@ fun OdsTextToggleButtonsRow( selectedIndex: Int, onSelectedIndexChange: (Int) -> Unit, modifier: Modifier = Modifier, + sameItemsWeight: Boolean = false, displaySurface: OdsDisplaySurface = OdsDisplaySurface.Default ) { Row( @@ -70,6 +72,7 @@ fun OdsTextToggleButtonsRow( index = index, textToggleButton = textToggleButton, selected = selectedIndex == index, + sameItemsWeight = sameItemsWeight, displaySurface = displaySurface ) { clickedButtonIndex -> onSelectedIndexChange(clickedButtonIndex) @@ -96,6 +99,7 @@ private fun RowScope.TextToggleButtonsRowItem( index: Int, textToggleButton: OdsTextToggleButtonsRowItem, selected: Boolean, + sameItemsWeight: Boolean, displaySurface: OdsDisplaySurface, onClick: (Int) -> Unit ) { @@ -105,8 +109,9 @@ private fun RowScope.TextToggleButtonsRowItem( text = textToggleButton.text, enabled = textToggleButton.enabled, modifier = Modifier - .background(color = buttonToggleBackgroundColor(displaySurface).copy(alpha = backgroundAlpha)) - .weight(1f), + .background(color = buttonToggleBackgroundColor(displaySurface).copy(alpha = backgroundAlpha)).let { + if (sameItemsWeight) it.weight(1f) else it + }, maxLines = 1, overflow = TextOverflow.Ellipsis, displaySurface = displaySurface, From d9b0d7765cb8a56a835702b4acf676de17938d63 Mon Sep 17 00:00:00 2001 From: Pauline Auvray Date: Wed, 9 Aug 2023 17:35:05 +0200 Subject: [PATCH 058/132] [#530] Add documentation --- docs/components/Buttons.md | 43 +++++++++++++++++- .../images/button_text_toggle_group_dark.png | Bin 0 -> 11658 bytes .../images/button_text_toggle_group_light.png | Bin 0 -> 11062 bytes 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 docs/components/images/button_text_toggle_group_dark.png create mode 100644 docs/components/images/button_text_toggle_group_light.png diff --git a/docs/components/Buttons.md b/docs/components/Buttons.md index e4ad3dd9c..f2b83d20b 100644 --- a/docs/components/Buttons.md +++ b/docs/components/Buttons.md @@ -14,9 +14,10 @@ description: Buttons allow users to take actions, and make choices, with a singl * [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 row](#icon-toggle-buttons-row) + * [Icon toggle buttons group](#icon-toggle-buttons-group) * [Component specific tokens](#component-specific-tokens) --- @@ -66,6 +67,7 @@ style `@style/Widget.Orange.Button.Text` on your `Button` layout In the layout: ```xml +