diff --git a/NOTICE.txt b/NOTICE.txt index a7cbf72036..a4f52b8b0a 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -123,6 +123,7 @@ theme-orange/src/main/res/drawable/ic_orange_functional_actions_delete.xml theme-orange/src/main/res/drawable/ic_orange_functional_navigation_form_chevron_left.xml theme-orange/src/main/res/drawable/ic_orange_functional_navigation_menu.xml theme-orange/src/main/res/drawable/ic_orange_functional_settings_and_tools_hide.xml +theme-orange/src/main/res/drawable/ic_orange_functional_social_and_engagement_heart_empty.xml theme-orange/src/main/res/drawable-ldrtl/ic_orange_component_bullet_list_level0.xml theme-orange/src/main/res/drawable-ldrtl/ic_orange_component_bullet_list_level1.xml theme-orange/src/main/res/drawable-ldrtl/ic_orange_component_bullet_list_level2.xml @@ -151,6 +152,7 @@ theme-sosh/src/main/res/drawable/ic_sosh_functional_actions_delete.xml theme-sosh/src/main/res/drawable/ic_sosh_functional_navigation_form_chevron_left.xml theme-sosh/src/main/res/drawable/ic_sosh_functional_navigation_menu.xml theme-sosh/src/main/res/drawable/ic_sosh_functional_settings_and_tools_hide.xml +theme-sosh/src/main/res/drawable/ic_sosh_functional_social_and_engagement_heart_empty.xml theme-sosh/src/main/res/font/sosh_black.ttf theme-sosh/src/main/res/font/sosh_bold.ttf theme-sosh/src/main/res/font/sosh_medium.ttf @@ -181,6 +183,7 @@ theme-wireframe/src/main/res/drawable/ic_wireframe_functional_actions_delete.xml theme-wireframe/src/main/res/drawable/ic_wireframe_functional_navigation_form_chevron_left.xml theme-wireframe/src/main/res/drawable/ic_wireframe_functional_navigation_menu.xml theme-wireframe/src/main/res/drawable/ic_wireframe_functional_settings_and_tools_hide.xml +theme-wireframe/src/main/res/drawable/ic_wireframe_functional_social_and_engagement_heart_empty.xml End of the parts list under Orange SA Copyright diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/Component.kt b/app/src/main/java/com/orange/ouds/app/ui/components/Component.kt index be30e26bd3..8d89f3286b 100644 --- a/app/src/main/java/com/orange/ouds/app/ui/components/Component.kt +++ b/app/src/main/java/com/orange/ouds/app/ui/components/Component.kt @@ -17,6 +17,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import com.orange.ouds.app.R import com.orange.ouds.app.ui.components.alert.AlertMessageDemoScreen +import com.orange.ouds.app.ui.components.alert.InlineAlertDemoScreen import com.orange.ouds.app.ui.components.badge.BadgeDemoScreen import com.orange.ouds.app.ui.components.bulletlist.BulletListDemoScreen import com.orange.ouds.app.ui.components.button.ButtonDemoScreen @@ -61,7 +62,7 @@ sealed class Component( R.string.app_components_alert_label, R.string.app_components_alert_description_text, { AlertIllustration() }, - listOf(Variant.AlertMessage) + listOf(Variant.AlertMessage, Variant.InlineAlert) ) data object Badge : Component( @@ -190,6 +191,7 @@ sealed class Variant( // Alert data object AlertMessage : Variant(R.string.app_components_alert_alertMessage_label, { AlertMessageDemoScreen() }) + data object InlineAlert : Variant(R.string.app_components_alert_inlineAlert_tech, { InlineAlertDemoScreen() }) // Checkbox data object Checkbox : Variant(R.string.app_components_checkbox_checkbox_label, { CheckboxDemoScreen() }) diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoScreen.kt b/app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoScreen.kt index 22a42ec1a3..89293bb0c5 100644 --- a/app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoScreen.kt +++ b/app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoScreen.kt @@ -20,12 +20,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewLightDark import com.orange.ouds.app.R import com.orange.ouds.app.ui.components.alert.AlertMessageDemoState.Companion.MaxBulletCount +import com.orange.ouds.app.ui.components.labelArgument import com.orange.ouds.app.ui.components.painterArgument import com.orange.ouds.app.ui.utilities.Code import com.orange.ouds.app.ui.utilities.LocalThemeDrawableResources import com.orange.ouds.app.ui.utilities.ThemeDrawableResources +import com.orange.ouds.app.ui.utilities.composable.AppPreview import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenu import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenuItem import com.orange.ouds.app.ui.utilities.composable.CustomizationFilterChip @@ -35,10 +38,10 @@ import com.orange.ouds.app.ui.utilities.composable.CustomizationTextInput import com.orange.ouds.app.ui.utilities.composable.DemoScreen import com.orange.ouds.app.ui.utilities.nestedName import com.orange.ouds.app.ui.utilities.toSentenceCase +import com.orange.ouds.core.component.OudsAlertIcon import com.orange.ouds.core.component.OudsAlertMessage import com.orange.ouds.core.component.OudsAlertMessageActionLink import com.orange.ouds.core.component.OudsAlertMessageActionLinkPosition -import com.orange.ouds.core.component.OudsAlertMessageIcon import com.orange.ouds.core.component.OudsAlertMessageStatus import com.orange.ouds.foundation.extensions.tryOrNull import com.orange.ouds.theme.OudsVersion @@ -88,7 +91,7 @@ private fun AlertMessageDemoBottomSheetContent(state: AlertMessageDemoState) { Box( modifier = Modifier .fillMaxSize() - .background(status.backgroundColor()) + .background(status.backgroundColor) ) } ) @@ -152,7 +155,7 @@ private fun AlertMessageDemoBottomSheetContent(state: AlertMessageDemoState) { @Composable private fun AlertMessageDemoContent(state: AlertMessageDemoState) { - val icon = OudsAlertMessageIcon(painter = painterResource(LocalThemeDrawableResources.current.tipsAndTricks)) + val icon = OudsAlertIcon(painter = painterResource(LocalThemeDrawableResources.current.tipsAndTricks)) with(state) { OudsAlertMessage( label = label, @@ -187,7 +190,7 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat is OudsAlertMessageStatus.Neutral -> { functionCallArgument(statusParameterName, status::class.java.nestedName) { if (hasStatusIcon) { - constructorCallArgument("icon") { + constructorCallArgument("icon") { painterArgument(themeDrawableResources.tipsAndTricks) } } @@ -200,7 +203,7 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat rawArgument(statusParameterName, status::class.java.nestedName) } } - typedArgument("label", label) + labelArgument(label) description?.let { typedArgument("description", description) } if (hasCloseButton) { lambdaArgument("onClose") { @@ -209,7 +212,7 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat } if (!actionLink.isNullOrEmpty()) { functionCallArgument("actionLink", OudsAlertMessageActionLink::class.java.simpleName) { - typedArgument("label", actionLink) + labelArgument(actionLink) lambdaArgument("onClick") { comment("Implement click") } @@ -225,4 +228,10 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat } } } +} + +@PreviewLightDark +@Composable +private fun PreviewAlertMessageDemoScreen() = AppPreview { + AlertMessageDemoScreen() } \ No newline at end of file diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/alert/InlineAlertDemoScreen.kt b/app/src/main/java/com/orange/ouds/app/ui/components/alert/InlineAlertDemoScreen.kt new file mode 100644 index 0000000000..48dee8d6d2 --- /dev/null +++ b/app/src/main/java/com/orange/ouds/app/ui/components/alert/InlineAlertDemoScreen.kt @@ -0,0 +1,157 @@ +/* + * Software Name: OUDS Android + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT license, + * the text of which is available at https://opensource.org/license/MIT/ + * or see the "LICENSE" file for more details. + * + * Software description: Android library of reusable graphical components + */ + +package com.orange.ouds.app.ui.components.alert + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import com.orange.ouds.app.R +import com.orange.ouds.app.ui.components.labelArgument +import com.orange.ouds.app.ui.components.painterArgument +import com.orange.ouds.app.ui.utilities.Code +import com.orange.ouds.app.ui.utilities.LocalThemeDrawableResources +import com.orange.ouds.app.ui.utilities.ThemeDrawableResources +import com.orange.ouds.app.ui.utilities.composable.AppPreview +import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenu +import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenuItem +import com.orange.ouds.app.ui.utilities.composable.CustomizationTextInput +import com.orange.ouds.app.ui.utilities.composable.DemoScreen +import com.orange.ouds.app.ui.utilities.nestedName +import com.orange.ouds.app.ui.utilities.toSentenceCase +import com.orange.ouds.core.component.OudsAlertIcon +import com.orange.ouds.core.component.OudsInlineAlert +import com.orange.ouds.core.component.OudsInlineAlertStatus +import com.orange.ouds.foundation.extensions.orElse +import com.orange.ouds.foundation.extensions.tryOrNull +import com.orange.ouds.theme.OudsVersion + +@Composable +fun InlineAlertDemoScreen() { + val state = rememberInlineAlertDemoState() + val themeDrawableResources = LocalThemeDrawableResources.current + DemoScreen( + description = stringResource(id = R.string.app_components_alert_inlineAlert_description_text), + bottomSheetContent = { InlineAlertDemoBottomSheetContent(state = state) }, + codeSnippet = { inlineAlertDemoCodeSnippet(state = state, themeDrawableResources = themeDrawableResources) }, + demoContent = { InlineAlertDemoContent(state = state) }, + version = OudsVersion.Component.Alert + ) +} + +@Composable +private fun InlineAlertDemoBottomSheetContent(state: InlineAlertDemoState) { + with(state) { + val statuses = if (LocalInspectionMode.current) { + // Fixes a bug where calling sealedSubclasses returns an empty list in Compose previews + // See https://issuetracker.google.com/issues/240601093 + listOf( + OudsInlineAlertStatus.Accent(OudsAlertIcon.Default), + OudsInlineAlertStatus.Neutral(OudsAlertIcon.Default), + OudsInlineAlertStatus.Positive, + OudsInlineAlertStatus.Info, + OudsInlineAlertStatus.Warning, + OudsInlineAlertStatus.Negative + ) + } else { + OudsInlineAlertStatus::class.sealedSubclasses.mapNotNull { kClass -> + tryOrNull { + when (kClass) { + OudsInlineAlertStatus.Neutral::class -> OudsInlineAlertStatus.Neutral(OudsAlertIcon.Default) + OudsInlineAlertStatus.Accent::class -> OudsInlineAlertStatus.Accent(OudsAlertIcon.Default) + else -> kClass.objectInstance + } + } + } + } + CustomizationDropdownMenu( + applyTopPadding = false, + label = stringResource(id = R.string.app_components_common_status_label), + items = statuses.map { status -> + CustomizationDropdownMenuItem( + label = status::class.simpleName.orEmpty().toSentenceCase(), + leadingIcon = { + Box( + modifier = Modifier + .fillMaxSize() + .background(status.assetColor.takeIf { it != Color.Unspecified }.orElse { status.textColor }) + ) + } + ) + }, + selectedItemIndex = statuses.indexOfFirst { it::class.qualifiedName == status::class.qualifiedName }, + onSelectionChange = { status = statuses[it] } + ) + CustomizationTextInput( + applyTopPadding = true, + label = stringResource(R.string.app_components_common_label_label), + value = label, + onValueChange = { value -> label = value } + ) + } +} + +@Composable +private fun InlineAlertDemoContent(state: InlineAlertDemoState) { + val icon = OudsAlertIcon(painter = painterResource(LocalThemeDrawableResources.current.tipsAndTricks)) + with(state) { + OudsInlineAlert( + label = label, + status = when (status) { + is OudsInlineAlertStatus.Accent -> OudsInlineAlertStatus.Accent(icon) + is OudsInlineAlertStatus.Neutral -> OudsInlineAlertStatus.Neutral(icon) + is OudsInlineAlertStatus.Info -> OudsInlineAlertStatus.Info + is OudsInlineAlertStatus.Negative -> OudsInlineAlertStatus.Negative + is OudsInlineAlertStatus.Positive -> OudsInlineAlertStatus.Positive + is OudsInlineAlertStatus.Warning -> OudsInlineAlertStatus.Warning + }, + ) + } +} + +private fun Code.Builder.inlineAlertDemoCodeSnippet(state: InlineAlertDemoState, themeDrawableResources: ThemeDrawableResources) { + with(state) { + functionCall("OudsInlineAlert") { + val statusParameterName = "status" + when (status) { + is OudsInlineAlertStatus.Accent, + is OudsInlineAlertStatus.Neutral -> { + functionCallArgument(statusParameterName, status::class.java.nestedName) { + constructorCallArgument("icon") { + painterArgument(themeDrawableResources.tipsAndTricks) + } + } + } + OudsInlineAlertStatus.Info, + OudsInlineAlertStatus.Negative, + OudsInlineAlertStatus.Positive, + OudsInlineAlertStatus.Warning -> { + rawArgument(statusParameterName, status::class.java.nestedName) + } + } + labelArgument(label) + } + } +} + +@PreviewLightDark +@Composable +private fun PreviewInlineAlertDemoScreen() = AppPreview { + InlineAlertDemoScreen() +} \ No newline at end of file diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/alert/InlineAlertDemoState.kt b/app/src/main/java/com/orange/ouds/app/ui/components/alert/InlineAlertDemoState.kt new file mode 100644 index 0000000000..4bcb50d2e4 --- /dev/null +++ b/app/src/main/java/com/orange/ouds/app/ui/components/alert/InlineAlertDemoState.kt @@ -0,0 +1,73 @@ +/* + * Software Name: OUDS Android + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT license, + * the text of which is available at https://opensource.org/license/MIT/ + * or see the "LICENSE" file for more details. + * + * Software description: Android library of reusable graphical components + */ + +package com.orange.ouds.app.ui.components.alert + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.listSaver +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.res.stringResource +import com.orange.ouds.app.R +import com.orange.ouds.core.component.OudsAlertIcon +import com.orange.ouds.core.component.OudsInlineAlertDefaults +import com.orange.ouds.core.component.OudsInlineAlertStatus + +@Composable +fun rememberInlineAlertDemoState( + label: String = stringResource(id = R.string.app_components_common_label_label), + status: OudsInlineAlertStatus = OudsInlineAlertDefaults.Status, +) = rememberSaveable( + label, + status, + saver = InlineAlertDemoState.Saver +) { + InlineAlertDemoState(label, status) +} + +class InlineAlertDemoState( + label: String, + status: OudsInlineAlertStatus +) { + + companion object { + val Saver = listSaver( + save = { state -> + with(state) { + listOf( + label, + status::class.java.name + ) + } + }, + restore = { list: List -> + val statusClassName = list[1] as String + val status = when (val kClass = Class.forName(statusClassName).kotlin) { + OudsInlineAlertStatus.Neutral::class -> OudsInlineAlertStatus.Neutral(OudsAlertIcon.Default) + OudsInlineAlertStatus.Accent::class -> OudsInlineAlertStatus.Accent(OudsAlertIcon.Default) + else -> kClass.objectInstance as OudsInlineAlertStatus + } + + InlineAlertDemoState( + list[0] as String, + status + ) + } + ) + } + + var status: OudsInlineAlertStatus by mutableStateOf(status) + + var label: String by mutableStateOf(label) +} \ No newline at end of file diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/bulletlist/BulletListDemoScreen.kt b/app/src/main/java/com/orange/ouds/app/ui/components/bulletlist/BulletListDemoScreen.kt index 13e6e7e30a..e1479dc8e4 100644 --- a/app/src/main/java/com/orange/ouds/app/ui/components/bulletlist/BulletListDemoScreen.kt +++ b/app/src/main/java/com/orange/ouds/app/ui/components/bulletlist/BulletListDemoScreen.kt @@ -24,6 +24,7 @@ import com.orange.ouds.app.R import com.orange.ouds.app.ui.components.Component import com.orange.ouds.app.ui.components.bulletlist.BulletListDemoState.Companion.MaxLevelCount import com.orange.ouds.app.ui.components.bulletlist.BulletListDemoState.Companion.MinLevelCount +import com.orange.ouds.app.ui.components.labelArgument import com.orange.ouds.app.ui.components.painterArgument import com.orange.ouds.app.ui.utilities.Code import com.orange.ouds.app.ui.utilities.LocalThemeDrawableResources @@ -216,7 +217,7 @@ private fun Code.Builder.bulletListDemoCodeSnippet(state: BulletListDemoState, t private fun Code.Builder.itemFunctionCall(label: String, content: (Code.Builder.() -> Unit)? = null) = functionCall("item") { trailingLambda = true isMultiline = false - typedArgument("label", label) + labelArgument(label) content?.let { lambdaArgument("builder") { content() diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/floatingactionbutton/FloatingActionButtonDemoScreen.kt b/app/src/main/java/com/orange/ouds/app/ui/components/floatingactionbutton/FloatingActionButtonDemoScreen.kt index 60b9e023c6..25e8c3617b 100644 --- a/app/src/main/java/com/orange/ouds/app/ui/components/floatingactionbutton/FloatingActionButtonDemoScreen.kt +++ b/app/src/main/java/com/orange/ouds/app/ui/components/floatingactionbutton/FloatingActionButtonDemoScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import com.orange.ouds.app.R import com.orange.ouds.app.ui.components.Component import com.orange.ouds.app.ui.components.contentDescriptionArgument +import com.orange.ouds.app.ui.components.labelArgument import com.orange.ouds.app.ui.components.onClickArgument import com.orange.ouds.app.ui.components.painterArgument import com.orange.ouds.app.ui.utilities.Code @@ -151,7 +152,7 @@ private fun Code.Builder.floatingActionButtonDemoCodeSnippet(state: FloatingActi } functionCall(functionName) { if (layout != FloatingActionButtonDemoState.Layout.IconOnly) { - typedArgument("label", label) + labelArgument(label) } if (layout != FloatingActionButtonDemoState.Layout.TextOnly) { constructorCallArgument("icon") { diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/passwordinput/PasswordInputDemoScreen.kt b/app/src/main/java/com/orange/ouds/app/ui/components/passwordinput/PasswordInputDemoScreen.kt index aa3932bc55..a3a3f3d9ac 100644 --- a/app/src/main/java/com/orange/ouds/app/ui/components/passwordinput/PasswordInputDemoScreen.kt +++ b/app/src/main/java/com/orange/ouds/app/ui/components/passwordinput/PasswordInputDemoScreen.kt @@ -21,6 +21,7 @@ import com.orange.ouds.app.R import com.orange.ouds.app.ui.components.Component import com.orange.ouds.app.ui.components.constrainedMaxWidthArgument import com.orange.ouds.app.ui.components.enabledArgument +import com.orange.ouds.app.ui.components.labelArgument import com.orange.ouds.app.ui.components.readOnlyArgument import com.orange.ouds.app.ui.utilities.Code import com.orange.ouds.app.ui.utilities.composable.AppPreview @@ -162,7 +163,7 @@ private fun Code.Builder.passwordInputDemoCodeSnippet(state: PasswordInputDemoSt lambdaArgument("onValueChange") { comment("Update value") } - if (label.isNotEmpty()) typedArgument("label", label) + if (label.isNotEmpty()) labelArgument(label) if (placeholder.isNotEmpty()) typedArgument("placeholder", placeholder) typedArgument("outlined", outlined) if (lockIcon) typedArgument("lockIcon", lockIcon) diff --git a/app/src/main/java/com/orange/ouds/app/ui/components/textinput/TextInputDemoScreen.kt b/app/src/main/java/com/orange/ouds/app/ui/components/textinput/TextInputDemoScreen.kt index 6645539c31..ed069da3cb 100644 --- a/app/src/main/java/com/orange/ouds/app/ui/components/textinput/TextInputDemoScreen.kt +++ b/app/src/main/java/com/orange/ouds/app/ui/components/textinput/TextInputDemoScreen.kt @@ -22,6 +22,7 @@ import com.orange.ouds.app.ui.components.Component import com.orange.ouds.app.ui.components.constrainedMaxWidthArgument import com.orange.ouds.app.ui.components.contentDescriptionArgument import com.orange.ouds.app.ui.components.enabledArgument +import com.orange.ouds.app.ui.components.labelArgument import com.orange.ouds.app.ui.components.onClickArgument import com.orange.ouds.app.ui.components.painterArgument import com.orange.ouds.app.ui.components.readOnlyArgument @@ -189,7 +190,7 @@ private fun Code.Builder.textInputDemoCodeSnippet(state: TextInputDemoState, the with(state) { functionCall("OudsTextInput") { functionCallArgument("textFieldState", "rememberTextFieldState") - if (label.isNotEmpty()) typedArgument("label", label) + if (label.isNotEmpty()) labelArgument(label) if (placeholder.isNotEmpty()) typedArgument("placeholder", placeholder) typedArgument("outlined", outlined) if (leadingIcon) { diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index a2c6bb6230..cd6a6cae96 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -98,6 +98,7 @@ مكونات alerte هي عناصر واجهة المستخدم التي تعرض معلومات، ردود فعل النظام أو تغييرات الحالة. Alert message (أو رسالة التحذير) هي عنصر من عناصر واجهة المستخدم التي تعرض معلومات النظام، تغييرات الحالة أو إجراء مطلوب؛ وذلك من خلال تواصل مفصل، مرئي، مستمر وقابل للاستخدام. + Inline alert هو عنصر واجهة مستخدم خفيف الوزن، يتم وضعه داخل تدفّق المحتوى، ويُستخدم لعرض المعلومات أو ملاحظات النظام أو تغيّرات الحالة، من خلال رسائل قصيرة وواضحة وبارزة ومستمرّة، وغير قابلة لاتخاذ إجراء. Badge هي عنصر صغير في واجهة المستخدم يُستخدم لتسليط الضوء على الحالة أو الإشعارات أو التصنيف داخل الواجهة. غالبًا ما يتم عرضها كعلامة أو مؤشر بلون خلفية مميز ونص. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index bd0d353ad1..ee6ad31e0b 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -96,6 +96,7 @@ Les composants d\'alerte sont des éléments d\'interface utilisateur qui affichent des informations, des retours système ou des changements d\'état. Un Alert message (ou message d\'alerte) est un élément d\'interface utilisateur qui affiche des informations système, des changements d\'état ou une action requise ; le tout grâce à une communication détaillée, visible, persistante et exploitable. + Une Inline alert est un élément d\'interface utilisateur léger, placé dans le flux de contenu, qui affiche des informations, des commentaires système et des changements d\'état au moyen d\'une communication courte, visible, persistante et non exploitable. Un Badge est un élément d\'interface utilisateur qui met en évidence les notifications système, l\'état ou la catégorisation d\'une information, uniquement par le biais de la couleur. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9538b3cfc2..65010eca3c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -170,6 +170,8 @@ Action link Action link position Bullet %d + Inline alert + Inline alert is a lightweight UI element, placed in the content flow, that displays information, system feedback, status changes throughout short, prominent, persistent and non actionable communication. Badge diff --git a/buildSrc/src/main/kotlin/com/orange/ouds/gradle/Component.kt b/buildSrc/src/main/kotlin/com/orange/ouds/gradle/Component.kt index cf853666af..0c8c807034 100644 --- a/buildSrc/src/main/kotlin/com/orange/ouds/gradle/Component.kt +++ b/buildSrc/src/main/kotlin/com/orange/ouds/gradle/Component.kt @@ -53,7 +53,7 @@ enum class Component { fun getSourceFilePaths(project: Project): List { val filenames = when (this) { - Alert -> listOf("OudsAlertMessage") + Alert -> listOf("OudsAlertMessage", "OudsInlineAlert") Badge -> listOf("OudsBadge") Bar -> listOf("OudsNavigationBar", "OudsTopAppBar") BulletList -> listOf("OudsBulletList") diff --git a/core-test/src/main/java/com/orange/ouds/core/test/OudsAlertMessageTest.kt b/core-test/src/main/java/com/orange/ouds/core/test/OudsAlertMessageTest.kt index 669ff7edca..b78be7e437 100644 --- a/core-test/src/main/java/com/orange/ouds/core/test/OudsAlertMessageTest.kt +++ b/core-test/src/main/java/com/orange/ouds/core/test/OudsAlertMessageTest.kt @@ -29,5 +29,4 @@ internal class OudsAlertMessageTest(parameter: Any) : OudsComponentSnapshotTest( @Parameterized.Parameters internal fun data() = OudsPreviewableComponent.AlertMessage.parameters } -} - +} \ No newline at end of file diff --git a/core-test/src/main/java/com/orange/ouds/core/test/OudsComponentTestSuite.kt b/core-test/src/main/java/com/orange/ouds/core/test/OudsComponentTestSuite.kt index 4b6f17c2fa..6b4e983441 100644 --- a/core-test/src/main/java/com/orange/ouds/core/test/OudsComponentTestSuite.kt +++ b/core-test/src/main/java/com/orange/ouds/core/test/OudsComponentTestSuite.kt @@ -25,9 +25,10 @@ import org.junit.runners.Suite OudsCheckboxItemTest::class, OudsCheckboxTest::class, OudsColoredBoxTest::class, + OudsDividerTest::class, OudsFloatingActionButtonTest::class, OudsFilterChipTest::class, - OudsDividerTest::class, + OudsInlineAlertTest::class, OudsInputTagTest::class, OudsLinkTest::class, OudsNavigationBarTest::class, diff --git a/core-test/src/main/java/com/orange/ouds/core/test/OudsInlineAlertTest.kt b/core-test/src/main/java/com/orange/ouds/core/test/OudsInlineAlertTest.kt new file mode 100644 index 0000000000..ca826d2919 --- /dev/null +++ b/core-test/src/main/java/com/orange/ouds/core/test/OudsInlineAlertTest.kt @@ -0,0 +1,31 @@ +/* + * Software Name: OUDS Android + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT license, + * the text of which is available at https://opensource.org/license/MIT/ + * or see the "LICENSE" file for more details. + * + * Software description: Android library of reusable graphical components + */ + +package com.orange.ouds.core.test + +import com.orange.ouds.core.utilities.OudsPreviewableComponent +import org.junit.runner.RunWith +import org.junit.runners.Parameterized + +@RunWith(Parameterized::class) +internal class OudsInlineAlertTest(parameter: Any) : OudsComponentSnapshotTest( + OudsPreviewableComponent.InlineAlert, + parameter, + OudsComponentTestSuite.theme +) { + + companion object { + @JvmStatic + @Parameterized.Parameters + internal fun data() = OudsPreviewableComponent.InlineAlert.parameters + } +} \ No newline at end of file diff --git a/core/src/main/java/com/orange/ouds/core/component/OudsAlert.kt b/core/src/main/java/com/orange/ouds/core/component/OudsAlert.kt new file mode 100644 index 0000000000..bdac33cf1e --- /dev/null +++ b/core/src/main/java/com/orange/ouds/core/component/OudsAlert.kt @@ -0,0 +1,155 @@ +/* + * Software Name: OUDS Android + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT license, + * the text of which is available at https://opensource.org/license/MIT/ + * or see the "LICENSE" file for more details. + * + * Software description: Android library of reusable graphical components + */ + +package com.orange.ouds.core.component + +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 androidx.compose.ui.res.painterResource +import com.orange.ouds.core.component.content.OudsComponentContent +import com.orange.ouds.core.component.content.OudsComponentIcon +import com.orange.ouds.core.theme.OudsTheme +import com.orange.ouds.core.theme.value +import com.orange.ouds.core.utilities.LayeredTintedPainter +import com.orange.ouds.foundation.extensions.orElse + +/** + * Base class for defining the semantic status of an alert component ([OudsInlineAlert] or [OudsAlertMessage]). + * It holds the common logic for determining the colors and default icons. + */ +internal sealed class OudsAlertStatus(private val defaultIconPainterProvider: (@Composable (OudsAlertStatus) -> Painter?)) { + + class Accent(defaultIconPainterProvider: (@Composable (OudsAlertStatus) -> Painter?) = { getDefaultIconPainter(it) }) : + OudsAlertStatus(defaultIconPainterProvider) + + class Neutral(defaultIconPainterProvider: (@Composable (OudsAlertStatus) -> Painter?) = { getDefaultIconPainter(it) }) : + OudsAlertStatus(defaultIconPainterProvider) + + class Negative(defaultIconPainterProvider: (@Composable (OudsAlertStatus) -> Painter?) = { getDefaultIconPainter(it) }) : + OudsAlertStatus(defaultIconPainterProvider) + + class Positive(defaultIconPainterProvider: (@Composable (OudsAlertStatus) -> Painter?) = { getDefaultIconPainter(it) }) : + OudsAlertStatus(defaultIconPainterProvider) + + class Info(defaultIconPainterProvider: (@Composable (OudsAlertStatus) -> Painter?) = { getDefaultIconPainter(it) }) : + OudsAlertStatus(defaultIconPainterProvider) + + class Warning(defaultIconPainterProvider: (@Composable (OudsAlertStatus) -> Painter?) = { getDefaultIconPainter(it) }) : + OudsAlertStatus(defaultIconPainterProvider) + + companion object { + + @Composable + protected fun getDefaultIconPainter(status: OudsAlertStatus): Painter? { + return when (status) { + is Negative -> painterResource(OudsTheme.drawableResources.component.alert.importantFill) + is Positive -> painterResource(OudsTheme.drawableResources.component.alert.tickConfirmationFill) + is Info -> painterResource(OudsTheme.drawableResources.component.alert.infoFill) + is Warning -> { + val iconTokens = OudsTheme.componentsTokens.icon + LayeredTintedPainter( + backPainter = painterResource(id = OudsTheme.drawableResources.component.alert.warningExternalShape), + backPainterColor = iconTokens.colorContentStatusWarningExternalShape.value, + frontPainter = painterResource(id = OudsTheme.drawableResources.component.alert.warningInternalShape), + frontPainterColor = iconTokens.colorContentStatusWarningInternalShape.value + ) + } + is Accent, + is Neutral -> null + } + } + } + + /** + * The default painter associated with a functional status (e.g., success, warning). + * Returns `null` for non-functional statuses like Accent or Neutral, which do not have a default icon. + */ + val defaultIconPainter: Painter? + @Composable + get() = defaultIconPainterProvider(this) + + /** + * The asset color associated with this status. + */ + val assetColor + @Composable + get() = with(OudsTheme.colorScheme.content) { + when (this@OudsAlertStatus) { + is Neutral -> default + is Accent -> status.accent + is Positive -> status.positive + is Warning -> Color.Unspecified + is Negative -> status.negative + is Info -> status.info + } + } +} + +/** + * Represents a non-clickable icon to be displayed within an [OudsAlertMessage] or an [OudsInlineAlert]. + * + * This class handles the creation of the icon from different sources like [Painter], [ImageVector], or [ImageBitmap]. + * An accessibility description is not required, as the alert's main `label` should provide the necessary context. + */ +open class OudsAlertIcon private constructor(graphicsObjectProvider: @Composable (OudsAlertIcon) -> Any) : + OudsComponentIcon( + ExtraParameters::class.java, + graphicsObjectProvider, + { "" } + ) { + + /** + * The default icon of an [OudsAlertMessage] or an [OudsInlineAlert]. + * This icon is non-clickable. No content description is needed because an alert always contains a label. + */ + object Default : OudsAlertIcon({ icon -> + with(icon.extraParameters) { + status.defaultIconPainter.orElse { + error("No default icon for status ${status::class.simpleName}") + } + } + }) + + /** + * Creates an instance of [OudsAlertIcon]. + * + * @property painter Painter of the icon. + */ + constructor(painter: Painter) : this({ painter }) + + /** + * Creates an instance of [OudsAlertIcon]. + * + * @property imageVector Image vector of the icon. + */ + constructor(imageVector: ImageVector) : this({ imageVector }) + + /** + * Creates an instance of [OudsAlertIcon]. + * + * @property bitmap Image bitmap of the icon. + */ + constructor(bitmap: ImageBitmap) : this({ bitmap }) + + override val tint: Color? + @Composable + get() = extraParameters.tint + + @ConsistentCopyVisibility + data class ExtraParameters internal constructor( + internal val tint: Color, + internal val status: OudsAlertStatus + ) : OudsComponentContent.ExtraParameters() +} \ No newline at end of file diff --git a/core/src/main/java/com/orange/ouds/core/component/OudsAlertMessage.kt b/core/src/main/java/com/orange/ouds/core/component/OudsAlertMessage.kt index f29afc2adb..859d4719be 100644 --- a/core/src/main/java/com/orange/ouds/core/component/OudsAlertMessage.kt +++ b/core/src/main/java/com/orange/ouds/core/component/OudsAlertMessage.kt @@ -40,10 +40,6 @@ 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.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.platform.LocalConfiguration import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -52,18 +48,15 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import com.orange.ouds.core.R import com.orange.ouds.core.component.content.OudsComponentContent -import com.orange.ouds.core.component.content.OudsComponentIcon import com.orange.ouds.core.theme.LocalDrawableResources import com.orange.ouds.core.theme.LocalThemeSettings import com.orange.ouds.core.theme.OudsTheme import com.orange.ouds.core.theme.takeUnlessHairline import com.orange.ouds.core.theme.value -import com.orange.ouds.core.utilities.LayeredTintedPainter import com.orange.ouds.core.utilities.OudsPreview import com.orange.ouds.core.utilities.OudsPreviewDevice import com.orange.ouds.core.utilities.OudsPreviewableComponent import com.orange.ouds.core.utilities.getPreviewTheme -import com.orange.ouds.foundation.extensions.orElse import com.orange.ouds.foundation.utilities.BasicPreviewParameterProvider import com.orange.ouds.theme.OudsThemeContract @@ -123,11 +116,11 @@ fun OudsAlertMessage( modifier = modifier .widthIn(min = sizeMinWidth.dp) .heightIn(min = if (hasActionLink && actionLink.position == OudsAlertMessageActionLinkPosition.Bottom) sizeMinHeightBottomActionPlacement.dp else sizeMinHeight.value) - .background(color = status.backgroundColor(), shape = shape) + .background(color = status.backgroundColor, shape = shape) .clip(shape) .run { borderWidth.value.takeUnlessHairline?.let { - border(width = it, color = status.borderColor(), shape = shape) + border(width = it, color = status.borderColor, shape = shape) } ?: this } .padding(start = spacePaddingInline.value, end = if (hasCloseButton) 0.dp else spacePaddingInline.value), @@ -137,9 +130,9 @@ fun OudsAlertMessage( modifier = Modifier .padding(top = spacePaddingBlock.value) .size(sizeIcon.value * scale), - extraParameters = OudsAlertMessageIcon.ExtraParameters( - tint = status.assetColor(), - status = status + extraParameters = OudsAlertIcon.ExtraParameters( + tint = status.assetColor, + status = status.value ) ) Column( @@ -259,91 +252,70 @@ enum class OudsAlertMessageActionLinkPosition { /** * The status of an [OudsAlertMessage]. Each status is designed to convey a specific meaning and ensure clarity in communication. * It determines the background and the icon colors of the alert message. - * It also carries the optional icon to be displayed in the alert message. Depending on the status, this icon can be customizable or be a status dedicated icon. + * It also defines the icon to be displayed in the alert message. For non-functional statuses ([Neutral] and [Accent]), a custom icon can be provided optionally. + * For functional statuses, a dedicated, non-overridable icon is used to guarantee semantic consistency. * - * @property icon The icon to be displayed in the alert message, or `null` if there is no icon. + * @property value The [OudsAlertStatus] associated with this status. + * @property icon The [OudsAlertIcon] to be displayed in the alert message, or `null` if there is no icon. */ -sealed class OudsAlertMessageStatus(val icon: OudsAlertMessageIcon? = null) { - - internal open val defaultIconPainter: Painter? - @Composable - get() = null +sealed class OudsAlertMessageStatus(internal val value: OudsAlertStatus, val icon: OudsAlertIcon? = null) { /** - * Neutral status can be used as a generic informative alert without semantic meaning or colour association. Suitable for a wide range of contexts — such as - * tips, general information, or descriptive labels — where no specific feedback or urgency is required. Appropriate for help sections, dashboards, or - * onboarding flows. + * Neutral status can be used as a generic informative alert without semantic meaning or colour association. + * Suitable for a wide range of contexts — such as tips, general information, or descriptive labels — where no specific feedback or urgency is required. + * Appropriate for help sections, dashboards, or onboarding flows. * - * @param icon Optional icon to be displayed in the alert message. Pass `null` if no icon is needed. + * @property icon The optional [OudsAlertIcon] to be displayed at the start of the alert message. */ - class Neutral(icon: OudsAlertMessageIcon? = null) : OudsAlertMessageStatus(icon) + class Neutral(icon: OudsAlertIcon? = null) : OudsAlertMessageStatus(OudsAlertStatus.Neutral(), icon) /** - * Accent status uses brand colours to draw attention to promotional or highlighted information while remaining non-critical. Ideal for marketing content, - * announcements, or feature highlights, where you want to subtly engage users without introducing functional semantics. Ideal for promotional banners, - * product updates, or customer engagement moments. + * Accent status uses brand colours to draw attention to promotional or highlighted information while remaining non-critical. + * Ideal for marketing content, announcements, or feature highlights, where you want to subtly engage users without introducing functional semantics. + * Ideal for promotional banners, product updates, or customer engagement moments. * - * @param icon Optional icon to be displayed in the alert message. Pass `null` if no icon is needed. + * @property icon The optional [OudsAlertIcon] to be displayed at the start of the alert message. */ - class Accent(icon: OudsAlertMessageIcon? = null) : OudsAlertMessageStatus(icon) + class Accent(icon: OudsAlertIcon? = null) : OudsAlertMessageStatus(OudsAlertStatus.Accent(), icon) /** - * Positive status indicates that a task or process has been completed successfully. These alerts reassure users and confirm that no further action is needed. + * Negative status communicates a critical issue or error that prevents the user from proceeding until it is resolved. + * These alerts remain visible until the problem is fixed or dismissed by the user. * This status displays a dedicated default icon. */ - data object Positive : OudsAlertMessageStatus(OudsAlertMessageIcon.Default) { - override val defaultIconPainter: Painter? - @Composable - get() = painterResource(OudsTheme.drawableResources.component.alert.tickConfirmationFill) - } + data object Negative : OudsAlertMessageStatus(OudsAlertStatus.Negative(), OudsAlertIcon.Default) /** - * Info status is used to share neutral system information or service updates that do not require immediate action. Ideal for background processes or status - * messages where users simply need to stay informed. + * Positive status indicates that a task or process has been completed successfully. + * These alerts reassure users and confirm that no further action is needed. * This status displays a dedicated default icon. */ - data object Info : OudsAlertMessageStatus(OudsAlertMessageIcon.Default) { - override val defaultIconPainter: Painter? - @Composable - get() = painterResource(OudsTheme.drawableResources.component.alert.infoFill) - } + data object Positive : OudsAlertMessageStatus(OudsAlertStatus.Positive(), OudsAlertIcon.Default) /** - * Used to draw attention to potential issues or upcoming changes that might affect the user’s service or experience. Warnings encourage awareness but - * typically do not block actions. + * Info status is used to share neutral system information or service updates that do not require immediate action. + * Ideal for background processes or status messages where users simply need to stay informed. * This status displays a dedicated default icon. */ - data object Warning : OudsAlertMessageStatus(OudsAlertMessageIcon.Default) { - override val defaultIconPainter: Painter? - @Composable - get() { - val iconTokens = OudsTheme.componentsTokens.icon - return LayeredTintedPainter( - backPainter = painterResource(id = OudsTheme.drawableResources.component.alert.warningExternalShape), - backPainterColor = iconTokens.colorContentStatusWarningExternalShape.value, - frontPainter = painterResource(id = OudsTheme.drawableResources.component.alert.warningInternalShape), - frontPainterColor = iconTokens.colorContentStatusWarningInternalShape.value - ) - } - } + data object Info : OudsAlertMessageStatus(OudsAlertStatus.Info(), OudsAlertIcon.Default) /** - * Negative status communicates a critical issue or error that prevents the user from proceeding until it is resolved. These alerts remain visible until - * the problem is fixed or dismissed by the user. + * Used to draw attention to potential issues or upcoming changes that might affect the user’s service or experience. + * Warnings encourage awareness but typically do not block actions. * This status displays a dedicated default icon. */ - data object Negative : OudsAlertMessageStatus(OudsAlertMessageIcon.Default) { - override val defaultIconPainter: Painter? - @Composable - get() = painterResource(OudsTheme.drawableResources.component.alert.importantFill) - } + data object Warning : OudsAlertMessageStatus(OudsAlertStatus.Warning(), OudsAlertIcon.Default) + + internal val assetColor + @Composable + get() = value.assetColor /** - * The color associated with this status. + * The background color associated with this status. */ - @Composable - fun backgroundColor(): Color { - return with(OudsTheme.colorScheme.surface) { + val backgroundColor + @Composable + get() = with(OudsTheme.colorScheme.surface) { when (this@OudsAlertMessageStatus) { is Neutral -> secondary is Accent -> status.accent.muted @@ -353,25 +325,10 @@ sealed class OudsAlertMessageStatus(val icon: OudsAlertMessageIcon? = null) { is Info -> status.info.muted } } - } - @Composable - internal fun assetColor(): Color { - return with(OudsTheme.colorScheme.content) { - when (this@OudsAlertMessageStatus) { - is Neutral -> default - is Accent -> status.accent - is Positive -> status.positive - is Warning -> Color.Unspecified - is Negative -> status.negative - is Info -> status.info - } - } - } - - @Composable - internal fun borderColor(): Color { - return with(OudsTheme.colorScheme.border) { + internal val borderColor + @Composable + get() = with(OudsTheme.colorScheme.border) { when (this@OudsAlertMessageStatus) { is Neutral -> default is Accent -> status.accent @@ -381,60 +338,6 @@ sealed class OudsAlertMessageStatus(val icon: OudsAlertMessageIcon? = null) { is Info -> status.info } } - } -} - -/** - * Represents a non-clickable icon to be displayed within an [OudsAlertMessage]. - * - * This class handles the creation of the icon from different sources like [Painter], [ImageVector], or [ImageBitmap]. - * An accessibility description is not required as the alert's main `label` should provide the necessary context. - */ -open class OudsAlertMessageIcon private constructor(graphicsObjectProvider: @Composable (OudsAlertMessageIcon) -> Any) : - OudsComponentIcon( - OudsAlertMessageIcon.ExtraParameters::class.java, - graphicsObjectProvider, - { "" } - ) { - - object Default : OudsAlertMessageIcon({ icon -> - with(icon.extraParameters) { - status.defaultIconPainter.orElse { - error("No default icon for status ${status::class.simpleName}") - } - } - }) - - /** - * Creates an instance of [OudsAlertMessageIcon]. - * - * @param painter Painter of the icon. - */ - constructor(painter: Painter) : this({ painter }) - - /** - * Creates an instance of [OudsAlertMessageIcon]. - * - * @param imageVector Image vector of the icon. - */ - constructor(imageVector: ImageVector) : this({ imageVector }) - - /** - * Creates an instance of [OudsAlertMessageIcon]. - * - * @param bitmap Image bitmap of the icon. - */ - constructor(bitmap: ImageBitmap) : this({ bitmap }) - - override val tint: Color? - @Composable - get() = extraParameters.tint - - @ConsistentCopyVisibility - data class ExtraParameters internal constructor( - internal val tint: Color, - internal val status: OudsAlertMessageStatus - ) : OudsComponentContent.ExtraParameters() } @Composable @@ -474,7 +377,12 @@ private fun OudsAlertMessageBulletListItem(label: String) { } @Preview(name = "Light", heightDp = OudsPreviewableComponent.AlertMessage.PreviewHeightDp, device = OudsPreviewDevice) -@Preview(name = "Dark", uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL, heightDp = OudsPreviewableComponent.AlertMessage.PreviewHeightDp, device = OudsPreviewDevice) +@Preview( + name = "Dark", + uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL, + heightDp = OudsPreviewableComponent.AlertMessage.PreviewHeightDp, + device = OudsPreviewDevice +) @Composable @Suppress("PreviewShouldNotBeCalledRecursively") private fun PreviewOudsAlertMessage(@PreviewParameter(OudsAlertMessagePreviewParameterProvider::class) parameter: OudsAlertMessagePreviewParameter) { @@ -488,15 +396,15 @@ internal fun PreviewOudsAlertMessage( parameter: OudsAlertMessagePreviewParameter ) = OudsPreview(theme = theme, darkThemeEnabled = darkThemeEnabled) { with(parameter) { - val icon = if (hasIcon) OudsAlertMessageIcon(Icons.Outlined.FavoriteBorder) else null + val icon = if (hasIcon) OudsAlertIcon(Icons.Outlined.FavoriteBorder) else null Column { listOf( OudsAlertMessageStatus.Neutral(icon), OudsAlertMessageStatus.Accent(icon), - OudsAlertMessageStatus.Positive, - OudsAlertMessageStatus.Warning, OudsAlertMessageStatus.Negative, - OudsAlertMessageStatus.Info + OudsAlertMessageStatus.Positive, + OudsAlertMessageStatus.Info, + OudsAlertMessageStatus.Warning ).forEach { status -> OudsAlertMessage( modifier = Modifier.padding(all = 10.dp), diff --git a/core/src/main/java/com/orange/ouds/core/component/OudsInlineAlert.kt b/core/src/main/java/com/orange/ouds/core/component/OudsInlineAlert.kt new file mode 100644 index 0000000000..674f9d648a --- /dev/null +++ b/core/src/main/java/com/orange/ouds/core/component/OudsInlineAlert.kt @@ -0,0 +1,212 @@ +/* + * Software Name: OUDS Android + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT license, + * the text of which is available at https://opensource.org/license/MIT/ + * or see the "LICENSE" file for more details. + * + * Software description: Android library of reusable graphical components + */ + +package com.orange.ouds.core.component + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.widthIn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.FavoriteBorder +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import com.orange.ouds.core.theme.OudsTheme +import com.orange.ouds.core.theme.value +import com.orange.ouds.core.utilities.OudsPreview +import com.orange.ouds.core.utilities.getPreviewTheme +import com.orange.ouds.foundation.utilities.BasicPreviewParameterProvider +import com.orange.ouds.theme.OudsThemeContract + +/** + * Inline alert is a lightweight UI element, placed in the content flow, that displays information, system feedback, status changes throughout short, prominent, + * persistent and non actionable communication. Inline alert includes functional icon and semantic colour, and does not include a close button and/or action + * link. Inline alert does not disappear and remains visible. + * + * > Design guidelines: [unified-design-system.orange.com](https://r.orange.fr/r/S-ouds-doc-inline-alert) + * + * > Design version: 1.0.0 + * + * @param label Label displayed in the inline alert. Main message that should be short, clear, and readable at a glance. + * @param modifier [Modifier] applied to the inline alert. + * @param status The status of the inline alert. Its background color and its icon color are based on this status. + * There are two types of statuses: + * - Non-functional statuses ([OudsInlineAlertStatus.Neutral] or [OudsInlineAlertStatus.Accent]) used for informational or decorative messages not tied to system logic. + * They are flexible in tone and visual expression, allowing the use of custom or brand-related (decorative) icons depending on context. + * These alerts help highlight content or support communication in a subtle, branded way. + * - Functional statuses communicate specific system statuses, results, or warnings tied directly to UX logic or user actions: [OudsInlineAlertStatus.Positive], + * [OudsInlineAlertStatus.Warning], [OudsInlineAlertStatus.Negative], [OudsInlineAlertStatus.Info]. + * These alerts follow strict semantic conventions for icon, color, and tone — ensuring clear, accessible communication across all digital products. + * Each type has a dedicated, standardized icon that expresses its meaning clearly. + * + * @sample com.orange.ouds.core.component.samples.OudsInlineAlertNonFunctionalStatusSample + * + * @sample com.orange.ouds.core.component.samples.OudsInlineAlertFunctionalStatusSample + */ +@Composable +fun OudsInlineAlert( + label: String, + modifier: Modifier = Modifier, + status: OudsInlineAlertStatus = OudsInlineAlertDefaults.Status +) { + with(OudsTheme.componentsTokens.alert) { + val scale = LocalConfiguration.current.fontScale + Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(spaceColumnGap.value)) { + status.icon.Content( + modifier = Modifier + .size(sizeIcon.value * scale), + extraParameters = OudsAlertIcon.ExtraParameters( + tint = status.assetColor, + status = status.value + ) + ) + Text( + modifier = Modifier.widthIn(max = OudsTheme.sizes.maxWidth.type.label.large), + text = label, + color = status.textColor, + style = OudsTheme.typography.label.moderate.large + ) + } + } +} + + +/** + * Default values for [OudsInlineAlert]. + */ +object OudsInlineAlertDefaults { + + /** + * Default status of an [OudsInlineAlert]. + */ + val Status: OudsInlineAlertStatus = OudsInlineAlertStatus.Neutral(OudsAlertIcon.Default) +} + +/** + * The status of an [OudsInlineAlert]. Each status is designed to convey a specific meaning and ensure clarity in communication. + * It determines the text and the icon colors of the inline alert. + * It also carries the icon to be displayed in the inline alert. Depending on the status, this icon can be customizable or be a status dedicated icon. + * + * @property value The [OudsAlertStatus] associated with this status. + * @property icon The [OudsAlertIcon] to be displayed in the inline alert. + */ +sealed class OudsInlineAlertStatus(internal val value: OudsAlertStatus, val icon: OudsAlertIcon) { + + /** + * Neutral status can be used for generic informational messages that provide context but carry no semantic meaning. + * Ideal for subtle notices, contextual help, or content highlights within pages. + * + * @property icon The [OudsAlertIcon] to be displayed in the inline alert. + */ + class Neutral(icon: OudsAlertIcon) : OudsInlineAlertStatus( + OudsAlertStatus.Neutral({ painterResource(OudsTheme.drawableResources.functional.socialAndEngagement.heartEmpty) }), + icon + ) + + /** + * Accent status uses brand colours and can include decorative icons to draw attention to key marketing or communication content. + * Perfect for promotional, inspirational, or brand-driven highlights that engage the user positively. + * + * @property icon The [OudsAlertIcon] to be displayed in the inline alert. + */ + class Accent(icon: OudsAlertIcon) : OudsInlineAlertStatus( + OudsAlertStatus.Accent({ painterResource(OudsTheme.drawableResources.functional.socialAndEngagement.heartEmpty) }), + icon + ) + + /** + * Negative status indicates a failure, error, or blocking issue that needs user attention. + * It uses the red “error” color and includes the standardized error icon. + */ + object Negative : OudsInlineAlertStatus(OudsAlertStatus.Negative(), OudsAlertIcon.Default) + + /** + * Positive status confirms that an action was completed successfully. + * It uses a green color and the standard success icon. + */ + object Positive : OudsInlineAlertStatus(OudsAlertStatus.Positive(), OudsAlertIcon.Default) + + /** + * Info status provides neutral information or updates about the system or account status. + * It uses blue for neutrality and clarity, and a dedicated default icon. + */ + object Info : OudsInlineAlertStatus(OudsAlertStatus.Info(), OudsAlertIcon.Default) + + /** + * Warning status draws attention to potential issues or upcoming changes. + * It uses yellow to signal caution while remaining non-blocking and a dedicated default icon. + */ + object Warning : OudsInlineAlertStatus(OudsAlertStatus.Warning(), OudsAlertIcon.Default) + + val assetColor + @Composable + get() = value.assetColor + + /** + * The text color associated with this status. + */ + val textColor + @Composable + get() = with(OudsTheme.colorScheme.content) { + when (this@OudsInlineAlertStatus) { + is Neutral, is Accent -> default + is Positive -> status.positive + is Warning -> status.warning + is Negative -> status.negative + is Info -> status.info + } + } +} + +@PreviewLightDark +@Composable +@Suppress("PreviewShouldNotBeCalledRecursively") +private fun PreviewOudsInlineAlert(@PreviewParameter(OudsInlineAlertPreviewParameterProvider::class) label: String) { + PreviewOudsInlineAlert(theme = getPreviewTheme(), darkThemeEnabled = isSystemInDarkTheme(), label = label) +} + +@Composable +internal fun PreviewOudsInlineAlert( + theme: OudsThemeContract, + darkThemeEnabled: Boolean, + label: String +) = OudsPreview(theme = theme, darkThemeEnabled = darkThemeEnabled) { + val icon = OudsAlertIcon(Icons.Outlined.FavoriteBorder) + Column { + listOf( + OudsInlineAlertStatus.Neutral(icon), + OudsInlineAlertStatus.Accent(icon), + OudsInlineAlertStatus.Negative, + OudsInlineAlertStatus.Positive, + OudsInlineAlertStatus.Info, + OudsInlineAlertStatus.Warning + ).forEach { status -> + OudsInlineAlert( + modifier = Modifier.padding(all = 10.dp), + label = label, + status = status + ) + } + } +} + +internal class OudsInlineAlertPreviewParameterProvider : + BasicPreviewParameterProvider("Label", "Very long label that needs more than one line to be displayed.") \ No newline at end of file diff --git a/core/src/main/java/com/orange/ouds/core/component/samples/OudsAlertMessageSamples.kt b/core/src/main/java/com/orange/ouds/core/component/samples/OudsAlertMessageSamples.kt index 3e1653b485..51ea6dd973 100644 --- a/core/src/main/java/com/orange/ouds/core/component/samples/OudsAlertMessageSamples.kt +++ b/core/src/main/java/com/orange/ouds/core/component/samples/OudsAlertMessageSamples.kt @@ -17,9 +17,9 @@ import androidx.compose.material.icons.filled.FavoriteBorder import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.PreviewLightDark import com.orange.ouds.core.component.OudsAlertMessage +import com.orange.ouds.core.component.OudsAlertIcon import com.orange.ouds.core.component.OudsAlertMessageActionLink import com.orange.ouds.core.component.OudsAlertMessageActionLinkPosition -import com.orange.ouds.core.component.OudsAlertMessageIcon import com.orange.ouds.core.component.OudsAlertMessageStatus import com.orange.ouds.core.utilities.OudsPreview @@ -28,7 +28,7 @@ internal fun OudsAlertMessageSample() { OudsAlertMessage( label = "Label", description = "Description of the alert message.", - status = OudsAlertMessageStatus.Accent(OudsAlertMessageIcon(imageVector = Icons.Filled.FavoriteBorder)), + status = OudsAlertMessageStatus.Accent(OudsAlertIcon(imageVector = Icons.Filled.FavoriteBorder)), onClose = { /* Close the alert message */ }, actionLink = OudsAlertMessageActionLink(label = "Action", onClick = { /* Do something */ }), bulletList = listOf( diff --git a/core/src/main/java/com/orange/ouds/core/component/samples/OudsInlineAlertSamples.kt b/core/src/main/java/com/orange/ouds/core/component/samples/OudsInlineAlertSamples.kt new file mode 100644 index 0000000000..34fd143972 --- /dev/null +++ b/core/src/main/java/com/orange/ouds/core/component/samples/OudsInlineAlertSamples.kt @@ -0,0 +1,48 @@ +/* + * Software Name: OUDS Android + * SPDX-FileCopyrightText: Copyright (c) Orange SA + * SPDX-License-Identifier: MIT + * + * This software is distributed under the MIT license, + * the text of which is available at https://opensource.org/license/MIT/ + * or see the "LICENSE" file for more details. + * + * Software description: Android library of reusable graphical components + */ + +package com.orange.ouds.core.component.samples + +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.PreviewLightDark +import com.orange.ouds.core.component.OudsAlertIcon +import com.orange.ouds.core.component.OudsInlineAlert +import com.orange.ouds.core.component.OudsInlineAlertStatus +import com.orange.ouds.core.utilities.OudsPreview + +@Composable +internal fun OudsInlineAlertNonFunctionalStatusSample() { + OudsInlineAlert( + label = "Label", + status = OudsInlineAlertStatus.Accent(OudsAlertIcon.Default) + ) +} + +@Composable +internal fun OudsInlineAlertFunctionalStatusSample() { + OudsInlineAlert( + label = "Label", + status = OudsInlineAlertStatus.Positive + ) +} + +@PreviewLightDark +@Composable +private fun PreviewOudsInlineAlertNonFunctionalStatusSample() = OudsPreview { + OudsInlineAlertNonFunctionalStatusSample() +} + +@PreviewLightDark +@Composable +private fun PreviewOudsInlineAlertFunctionalStatusSample() = OudsPreview { + OudsInlineAlertFunctionalStatusSample() +} \ No newline at end of file diff --git a/core/src/main/java/com/orange/ouds/core/utilities/OudsPreviewableComponent.kt b/core/src/main/java/com/orange/ouds/core/utilities/OudsPreviewableComponent.kt index bcf4a5e257..6b23c451e2 100644 --- a/core/src/main/java/com/orange/ouds/core/utilities/OudsPreviewableComponent.kt +++ b/core/src/main/java/com/orange/ouds/core/utilities/OudsPreviewableComponent.kt @@ -40,6 +40,7 @@ import com.orange.ouds.core.component.OudsFilterChipPreviewParameter import com.orange.ouds.core.component.OudsFilterChipPreviewParameterProvider import com.orange.ouds.core.component.OudsFloatingActionButtonAppearance import com.orange.ouds.core.component.OudsFloatingActionButtonPreviewParameterProvider +import com.orange.ouds.core.component.OudsInlineAlertPreviewParameterProvider import com.orange.ouds.core.component.OudsLinkPreviewParameter import com.orange.ouds.core.component.OudsLinkPreviewParameterProvider import com.orange.ouds.core.component.OudsNavigationBarItemPreviewParameterProvider @@ -85,6 +86,7 @@ import com.orange.ouds.core.component.PreviewOudsDivider import com.orange.ouds.core.component.PreviewOudsExtendedFloatingActionButton import com.orange.ouds.core.component.PreviewOudsFilterChip import com.orange.ouds.core.component.PreviewOudsFloatingActionButton +import com.orange.ouds.core.component.PreviewOudsInlineAlert import com.orange.ouds.core.component.PreviewOudsInputTag import com.orange.ouds.core.component.PreviewOudsLargeFloatingActionButton import com.orange.ouds.core.component.PreviewOudsLargeTopAppBar @@ -495,6 +497,20 @@ interface OudsPreviewableComponent { } } + object InlineAlert : OudsPreviewableComponent { + + override val parameters: List = OudsInlineAlertPreviewParameterProvider().values.toList() + + @Composable + override fun Preview(theme: OudsThemeContract, darkThemeEnabled: Boolean, highContrastModeEnabled: Boolean, parameter: Any?) { + PreviewOudsInlineAlert( + theme = theme, + darkThemeEnabled = darkThemeEnabled, + label = parameter as String + ) + } + } + object InputTag : OudsPreviewableComponent { override val parameters: List = emptyList() diff --git a/theme-contract/src/main/java/com/orange/ouds/theme/OudsDrawableResources.kt b/theme-contract/src/main/java/com/orange/ouds/theme/OudsDrawableResources.kt index 32ce6b54f3..7315f2cc9e 100644 --- a/theme-contract/src/main/java/com/orange/ouds/theme/OudsDrawableResources.kt +++ b/theme-contract/src/main/java/com/orange/ouds/theme/OudsDrawableResources.kt @@ -127,6 +127,7 @@ interface OudsDrawableResources { val actions: Actions val navigation: Navigation val settingsAndTools: SettingsAndTools + val socialAndEngagement: SocialAndEngagement interface Actions { @get:DrawableRes @@ -145,5 +146,10 @@ interface OudsDrawableResources { @get:DrawableRes val hide: Int } + + interface SocialAndEngagement { + @get:DrawableRes + val heartEmpty: Int + } } } \ No newline at end of file diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png index 0c3b8497ff..ae05e0888e 100644 Binary files a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png index e5b5aeb89d..df372eb1b3 100644 Binary files a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png index 3b083e8f1e..f6fbb74584 100644 Binary files a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png index 4e07c9a2df..807847d501 100644 Binary files a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png index d0a193b9e6..b69a8e450d 100644 Binary files a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png index 8f87608e82..c23b2e38ef 100644 Binary files a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png new file mode 100644 index 0000000000..29bb8dfd79 Binary files /dev/null and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png new file mode 100644 index 0000000000..339d26a178 Binary files /dev/null and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png new file mode 100644 index 0000000000..7b78c78812 Binary files /dev/null and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png new file mode 100644 index 0000000000..39cd878591 Binary files /dev/null and b/theme-orange-compact/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png differ diff --git a/theme-orange/src/main/java/com/orange/ouds/theme/orange/OrangeDrawableResources.kt b/theme-orange/src/main/java/com/orange/ouds/theme/orange/OrangeDrawableResources.kt index fd9973c86d..10e6b708bd 100644 --- a/theme-orange/src/main/java/com/orange/ouds/theme/orange/OrangeDrawableResources.kt +++ b/theme-orange/src/main/java/com/orange/ouds/theme/orange/OrangeDrawableResources.kt @@ -98,6 +98,7 @@ class OrangeDrawableResources : OudsDrawableResources { override val actions = Actions() override val navigation = Navigation() override val settingsAndTools = SettingsAndTools() + override val socialAndEngagement = SocialAndEngagement() class Actions : OudsDrawableResources.Functional.Actions { override val delete = R.drawable.ic_orange_functional_actions_delete @@ -111,5 +112,9 @@ class OrangeDrawableResources : OudsDrawableResources { class SettingsAndTools : OudsDrawableResources.Functional.SettingsAndTools { override val hide = R.drawable.ic_orange_functional_settings_and_tools_hide } + + class SocialAndEngagement : OudsDrawableResources.Functional.SocialAndEngagement { + override val heartEmpty = R.drawable.ic_orange_functional_social_and_engagement_heart_empty + } } } diff --git a/theme-orange/src/main/res/drawable/ic_orange_functional_social_and_engagement_heart_empty.xml b/theme-orange/src/main/res/drawable/ic_orange_functional_social_and_engagement_heart_empty.xml new file mode 100644 index 0000000000..4a33d01da8 --- /dev/null +++ b/theme-orange/src/main/res/drawable/ic_orange_functional_social_and_engagement_heart_empty.xml @@ -0,0 +1,10 @@ + + + diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png index a193fd198a..59a6f10cb6 100644 Binary files a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png index 8ad6e929cf..45f64499ae 100644 Binary files a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png index fb0e54f862..d0d4e762c6 100644 Binary files a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png index 35f29a2584..c7b3aa90e5 100644 Binary files a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png index 445e3f98d5..5ad3977c25 100644 Binary files a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png index 5fc8467063..63862cbc4c 100644 Binary files a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png new file mode 100644 index 0000000000..5213a49162 Binary files /dev/null and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png new file mode 100644 index 0000000000..3134593f4b Binary files /dev/null and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png new file mode 100644 index 0000000000..406d4a1f71 Binary files /dev/null and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png new file mode 100644 index 0000000000..94fc4d20ca Binary files /dev/null and b/theme-orange/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png differ diff --git a/theme-sosh/src/main/java/com/orange/ouds/theme/sosh/SoshDrawableResources.kt b/theme-sosh/src/main/java/com/orange/ouds/theme/sosh/SoshDrawableResources.kt index bed1ec2898..1d79f588fc 100644 --- a/theme-sosh/src/main/java/com/orange/ouds/theme/sosh/SoshDrawableResources.kt +++ b/theme-sosh/src/main/java/com/orange/ouds/theme/sosh/SoshDrawableResources.kt @@ -93,6 +93,7 @@ internal class SoshDrawableResources : OudsDrawableResources { override val actions = Actions() override val navigation = Navigation() override val settingsAndTools = SettingsAndTools() + override val socialAndEngagement = SocialAndEngagement() class Actions : OudsDrawableResources.Functional.Actions { override val delete = R.drawable.ic_sosh_functional_actions_delete @@ -106,5 +107,9 @@ internal class SoshDrawableResources : OudsDrawableResources { class SettingsAndTools : OudsDrawableResources.Functional.SettingsAndTools { override val hide = R.drawable.ic_sosh_functional_settings_and_tools_hide } + + class SocialAndEngagement : OudsDrawableResources.Functional.SocialAndEngagement { + override val heartEmpty = R.drawable.ic_sosh_functional_social_and_engagement_heart_empty + } } } diff --git a/theme-sosh/src/main/res/drawable/ic_sosh_functional_social_and_engagement_heart_empty.xml b/theme-sosh/src/main/res/drawable/ic_sosh_functional_social_and_engagement_heart_empty.xml new file mode 100644 index 0000000000..b813dbffb2 --- /dev/null +++ b/theme-sosh/src/main/res/drawable/ic_sosh_functional_social_and_engagement_heart_empty.xml @@ -0,0 +1,14 @@ + + + + diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png index 46bd9770f4..b249a29d41 100644 Binary files a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png index 09a486ae77..a98091d1bd 100644 Binary files a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png index ff2d8f950a..4034ffe16d 100644 Binary files a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png index c2e0c51fa9..de98f9fe37 100644 Binary files a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png index 51bca76a5c..a5b8c5c9e0 100644 Binary files a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png index 6341426425..4c5e286752 100644 Binary files a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png new file mode 100644 index 0000000000..5ab26e5c7d Binary files /dev/null and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png new file mode 100644 index 0000000000..eae7e6e3b4 Binary files /dev/null and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png new file mode 100644 index 0000000000..0785f2ea10 Binary files /dev/null and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png new file mode 100644 index 0000000000..5da7a7dea3 Binary files /dev/null and b/theme-sosh/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png differ diff --git a/theme-wireframe/src/main/java/com/orange/ouds/theme/wireframe/WireframeDrawableResources.kt b/theme-wireframe/src/main/java/com/orange/ouds/theme/wireframe/WireframeDrawableResources.kt index 1e2d2eda48..280330e44b 100644 --- a/theme-wireframe/src/main/java/com/orange/ouds/theme/wireframe/WireframeDrawableResources.kt +++ b/theme-wireframe/src/main/java/com/orange/ouds/theme/wireframe/WireframeDrawableResources.kt @@ -93,6 +93,7 @@ internal class WireframeDrawableResources : OudsDrawableResources { override val actions = Actions() override val navigation = Navigation() override val settingsAndTools = SettingsAndTools() + override val socialAndEngagement = SocialAndEngagement() class Actions : OudsDrawableResources.Functional.Actions { override val delete = R.drawable.ic_wireframe_functional_actions_delete @@ -106,5 +107,9 @@ internal class WireframeDrawableResources : OudsDrawableResources { class SettingsAndTools : OudsDrawableResources.Functional.SettingsAndTools { override val hide = R.drawable.ic_wireframe_functional_settings_and_tools_hide } + + class SocialAndEngagement : OudsDrawableResources.Functional.SocialAndEngagement { + override val heartEmpty = R.drawable.ic_wireframe_functional_social_and_engagement_heart_empty + } } } diff --git a/theme-wireframe/src/main/res/drawable/ic_wireframe_functional_social_and_engagement_heart_empty.xml b/theme-wireframe/src/main/res/drawable/ic_wireframe_functional_social_and_engagement_heart_empty.xml new file mode 100644 index 0000000000..efceeb6dee --- /dev/null +++ b/theme-wireframe/src/main/res/drawable/ic_wireframe_functional_social_and_engagement_heart_empty.xml @@ -0,0 +1,9 @@ + + + diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png index dd4a93f07e..0dc5de18b5 100644 Binary files a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png index b02b2aa39c..fa32a0a9f3 100644 Binary files a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png index 6086e6e177..9b5c0236ee 100644 Binary files a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeDarkThemeSnapshot[2].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png index 9d1faa8698..24e10f210d 100644 Binary files a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png index 7de54538c2..962e5f1b30 100644 Binary files a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[1].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png index d4c2488dbf..bc43b40721 100644 Binary files a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsAlertMessageTest_takeLightThemeSnapshot[2].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png new file mode 100644 index 0000000000..63e2616246 Binary files /dev/null and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[0].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png new file mode 100644 index 0000000000..eb4d6b658a Binary files /dev/null and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeDarkThemeSnapshot[1].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png new file mode 100644 index 0000000000..886be5150f Binary files /dev/null and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[0].png differ diff --git a/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png new file mode 100644 index 0000000000..df8dcf6be1 Binary files /dev/null and b/theme-wireframe/src/test/snapshots/images/com.orange.ouds.core.test_OudsInlineAlertTest_takeLightThemeSnapshot[1].png differ