Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
db8a773
Fix alert message demo
florentmaitre Feb 16, 2026
f106211
Review: Fix code snippet and action link position configuration disab…
paulinea Feb 16, 2026
60013fd
Initialize OudsInlineAlert
paulinea Feb 19, 2026
82da18d
Add previews for OudsInlineAlert
paulinea Feb 19, 2026
fd36ace
Add missing resources in NOTICE.txt
paulinea Feb 19, 2026
93ff5ed
Add inline alert component to demo app
paulinea Feb 19, 2026
85773f6
Add OudsInlineAlert samples
paulinea Feb 19, 2026
b537d38
Update vertical alignement for OudsInlineAlert icon
paulinea Feb 19, 2026
871ab0e
Improve kdoc
paulinea Feb 19, 2026
ecb32b5
Improve kdoc
paulinea Feb 19, 2026
0353846
Remove useless annotation
paulinea Feb 19, 2026
84adc18
Add Arabic description translation
paulinea Feb 20, 2026
059bfd6
Review: Specify statuses instead of using else branch
paulinea Feb 25, 2026
26f3b68
Review: Keep OudAlertStatus internal
paulinea Feb 25, 2026
10ac9ae
Review: Transform assetColor to property
paulinea Feb 25, 2026
a5504f1
Review: Update status kdoc
paulinea Feb 25, 2026
d5d6751
Review: Reorder statuses to match Figma
paulinea Feb 25, 2026
6d97508
Review: Rename file
paulinea Feb 25, 2026
dde45ec
Review: Update long label string for preview
paulinea Feb 25, 2026
a6f51d8
Review: Use tech prefix for non-translatable strings
paulinea Feb 25, 2026
188b223
Review: Rename OudsVersion.AlertMessage to OudsVersion.Alert
paulinea Feb 25, 2026
1c34fb1
Review: Use labelArgument method instead of typedArgument everywhere …
paulinea Feb 25, 2026
736c61c
Link OudsInlineAlert file to Alert component
paulinea Feb 25, 2026
b7e8cb2
Minor fixes
florentmaitre Feb 26, 2026
d2a9183
Reorder alert statuses in previews
florentmaitre Feb 26, 2026
eb4661c
Add default icon for accent status
florentmaitre Feb 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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() })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -88,7 +91,7 @@ private fun AlertMessageDemoBottomSheetContent(state: AlertMessageDemoState) {
Box(
modifier = Modifier
.fillMaxSize()
.background(status.backgroundColor())
.background(status.backgroundColor)
)
}
)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -187,7 +190,7 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
is OudsAlertMessageStatus.Neutral -> {
functionCallArgument(statusParameterName, status::class.java.nestedName) {
if (hasStatusIcon) {
constructorCallArgument<OudsAlertMessageIcon>("icon") {
constructorCallArgument<OudsAlertIcon>("icon") {
painterArgument(themeDrawableResources.tipsAndTricks)
}
}
Expand All @@ -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") {
Expand All @@ -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")
}
Expand All @@ -225,4 +228,10 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
}
}
}
}

@PreviewLightDark
@Composable
private fun PreviewAlertMessageDemoScreen() = AppPreview {
AlertMessageDemoScreen()
}
Original file line number Diff line number Diff line change
@@ -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<OudsAlertIcon>("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()
}
Original file line number Diff line number Diff line change
@@ -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<Any?> ->
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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
Loading