Skip to content

Commit b5a15fe

Browse files
committed
Add rich text to alert message demo
Add rich text to alert message demo # Conflicts: # app/src/main/java/com/orange/ouds/app/ui/components/ComponentCode.kt # app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoScreen.kt # app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoState.kt
1 parent d0e64f0 commit b5a15fe

7 files changed

Lines changed: 153 additions & 45 deletions

File tree

app/src/main/java/com/orange/ouds/app/ui/components/ComponentCode.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import com.orange.ouds.app.ui.utilities.Code
2222
import com.orange.ouds.app.ui.utilities.FunctionCall
2323
import com.orange.ouds.core.component.OudsColoredBoxColor
2424
import com.orange.ouds.core.component.common.OudsError
25+
import com.orange.ouds.core.component.common.text.OudsAnnotatedErrorMessage
26+
import com.orange.ouds.core.component.common.text.OudsAnnotatedString
2527

2628
fun Code.Builder.coloredBoxCall(onColoredBox: Boolean, content: Code.Builder.() -> Unit) {
2729
if (onColoredBox) {
@@ -35,6 +37,16 @@ fun Code.Builder.coloredBoxCall(onColoredBox: Boolean, content: Code.Builder.()
3537
}
3638
}
3739

40+
internal inline fun <reified T> FunctionCall.Builder.annotatedStringArgument(name: String?) where T : OudsAnnotatedString<T> {
41+
val functionName = "build${T::class.simpleName}"
42+
functionCallArgument(name, functionName) {
43+
trailingLambda = true
44+
lambdaArgument("builder") {
45+
comment("Build annotated string")
46+
}
47+
}
48+
}
49+
3850
inline fun <reified T> FunctionCall.Builder.iconArgument(
3951
name: String,
4052
@DrawableRes resId: Int,
@@ -77,9 +89,13 @@ fun FunctionCall.Builder.enabledArgument(value: Boolean) = typedArgument(Argumen
7789

7890
fun FunctionCall.Builder.tintedArgument(value: Boolean) = typedArgument(Argument.Tinted, value)
7991

80-
fun FunctionCall.Builder.errorArgument(message: String) {
92+
fun FunctionCall.Builder.errorArgument(message: String, annotatedMessage: Boolean = false) {
8193
constructorCallArgument<OudsError>(Argument.Error) {
82-
typedArgument("message", message)
94+
if (annotatedMessage) {
95+
annotatedStringArgument<OudsAnnotatedErrorMessage>(name = "message")
96+
} else {
97+
typedArgument("message", message)
98+
}
8399
}
84100
}
85101

app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoScreen.kt

Lines changed: 100 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import androidx.compose.ui.res.painterResource
2222
import androidx.compose.ui.res.stringResource
2323
import androidx.compose.ui.tooling.preview.PreviewLightDark
2424
import com.orange.ouds.app.R
25-
import com.orange.ouds.app.ui.components.alert.AlertMessageDemoState.Companion.MaxBulletCount
25+
import com.orange.ouds.app.ui.components.annotatedStringArgument
2626
import com.orange.ouds.app.ui.components.iconArgument
2727
import com.orange.ouds.app.ui.components.labelArgument
2828
import com.orange.ouds.app.ui.components.onClickArgument
@@ -44,6 +44,13 @@ import com.orange.ouds.core.component.OudsAlertMessage
4444
import com.orange.ouds.core.component.OudsAlertMessageActionLink
4545
import com.orange.ouds.core.component.OudsAlertMessageActionLinkPosition
4646
import com.orange.ouds.core.component.OudsAlertMessageStatus
47+
import com.orange.ouds.core.component.common.text.OudsAnnotatedAlertMessageBulletListLabel
48+
import com.orange.ouds.core.component.common.text.OudsAnnotatedAlertMessageDescription
49+
import com.orange.ouds.core.component.common.text.OudsLinkAnnotation
50+
import com.orange.ouds.core.component.common.text.buildOudsAnnotatedAlertMessageBulletListLabel
51+
import com.orange.ouds.core.component.common.text.buildOudsAnnotatedAlertMessageDescription
52+
import com.orange.ouds.core.component.common.text.withLink
53+
import com.orange.ouds.core.component.common.text.withStrong
4754
import com.orange.ouds.foundation.extensions.toSentenceCase
4855
import com.orange.ouds.foundation.extensions.tryOrNull
4956
import com.orange.ouds.theme.OudsVersion
@@ -123,7 +130,9 @@ private fun AlertMessageDemoBottomSheetContent(state: AlertMessageDemoState) {
123130
applyTopPadding = true,
124131
label = stringResource(R.string.app_components_common_description_tech),
125132
value = description.orEmpty(),
126-
onValueChange = { value -> description = value }
133+
onValueChange = { value -> description = value },
134+
enabled = descriptionTextInputEnabled,
135+
helperText = stringResource(id = R.string.app_components_common_annotatedTextHelperText_tech)
127136
)
128137
CustomizationTextInput(
129138
applyTopPadding = true,
@@ -143,16 +152,23 @@ private fun AlertMessageDemoBottomSheetContent(state: AlertMessageDemoState) {
143152
selectedChipIndex = OudsAlertMessageActionLinkPosition.entries.indexOf(actionLinkPosition),
144153
onSelectionChange = { id -> actionLinkPosition = OudsAlertMessageActionLinkPosition.entries[id] }
145154
)
146-
for (id in 1..MaxBulletCount) {
155+
for (index in 0..<AlertMessageDemoState.MaxBulletCount) {
147156
CustomizationTextInput(
148157
applyTopPadding = true,
149-
label = stringResource(R.string.app_components_alert_alertMessage_bullet_tech, id),
150-
value = bulletList?.get(id).orEmpty(),
158+
label = stringResource(R.string.app_components_alert_alertMessage_bullet_tech, index + 1),
159+
value = bulletList[index],
151160
onValueChange = { value ->
152-
bulletList = bulletList.orEmpty().toMutableMap().apply { put(id, value) }
153-
}
161+
bulletList = bulletList.toMutableList().apply { set(index, value) }.toList()
162+
},
163+
enabled = bulletListTextInputsEnabled,
164+
helperText = stringResource(id = R.string.app_components_common_annotatedTextHelperText_tech)
154165
)
155166
}
167+
CustomizationSwitchItem(
168+
label = stringResource(R.string.app_components_common_annotatedText_tech),
169+
checked = annotatedText,
170+
onCheckedChange = { annotatedText = it },
171+
)
156172
}
157173
}
158174

@@ -164,27 +180,67 @@ private fun AlertMessageDemoContent(state: AlertMessageDemoState) {
164180
AlertMessageDemoState.Icon.Tinted -> OudsAlertIcon(painter = painterResource(LocalThemeDrawableResources.current.tipsAndTricks), tinted = true)
165181
AlertMessageDemoState.Icon.Untinted -> OudsAlertIcon(painter = rememberUntintedIconPainter(), tinted = false)
166182
}
167-
OudsAlertMessage(
168-
label = label,
169-
description = description,
170-
status = when (status) {
171-
is OudsAlertMessageStatus.Accent -> OudsAlertMessageStatus.Accent(alertIcon)
172-
is OudsAlertMessageStatus.Neutral -> OudsAlertMessageStatus.Neutral(alertIcon)
173-
is OudsAlertMessageStatus.Info -> OudsAlertMessageStatus.Info
174-
is OudsAlertMessageStatus.Negative -> OudsAlertMessageStatus.Negative
175-
is OudsAlertMessageStatus.Positive -> OudsAlertMessageStatus.Positive
176-
is OudsAlertMessageStatus.Warning -> OudsAlertMessageStatus.Warning
177-
},
178-
onClose = if (hasCloseButton) {
179-
{}
180-
} else {
181-
null
182-
},
183-
actionLink = actionLink?.let { actionLinkLabel ->
184-
OudsAlertMessageActionLink(label = actionLinkLabel, onClick = {}, position = actionLinkPosition)
185-
},
186-
bulletList = bulletList?.toSortedMap()?.values?.toList()
187-
)
183+
val status = when (status) {
184+
is OudsAlertMessageStatus.Accent -> OudsAlertMessageStatus.Accent(alertIcon)
185+
is OudsAlertMessageStatus.Neutral -> OudsAlertMessageStatus.Neutral(alertIcon)
186+
is OudsAlertMessageStatus.Info -> OudsAlertMessageStatus.Info
187+
is OudsAlertMessageStatus.Negative -> OudsAlertMessageStatus.Negative
188+
is OudsAlertMessageStatus.Positive -> OudsAlertMessageStatus.Positive
189+
is OudsAlertMessageStatus.Warning -> OudsAlertMessageStatus.Warning
190+
}
191+
val onClose = if (hasCloseButton) {
192+
{}
193+
} else {
194+
null
195+
}
196+
val actionLink = actionLink?.let { actionLinkLabel ->
197+
OudsAlertMessageActionLink(label = actionLinkLabel, onClick = {}, position = actionLinkPosition)
198+
}
199+
if (annotatedText) {
200+
val annotatedDescription = buildOudsAnnotatedAlertMessageDescription {
201+
append("Your last payment attempt was ")
202+
withStrong { append("declined") }
203+
append(". Please check your payment details or ")
204+
withStrong { append("available balance") }
205+
append(" and try again, or ")
206+
withLink(OudsLinkAnnotation.Url("https://unified-design-system.orange.com")) { append("update your payment details") }
207+
append(".")
208+
}
209+
val annotatedBulletList = listOf(
210+
buildOudsAnnotatedAlertMessageBulletListLabel {
211+
append("Your payment was ")
212+
withStrong { append("declined") }
213+
append(".")
214+
},
215+
buildOudsAnnotatedAlertMessageBulletListLabel {
216+
append("Check your ")
217+
withStrong { append("available balance") }
218+
append(" before retrying.")
219+
},
220+
buildOudsAnnotatedAlertMessageBulletListLabel {
221+
append("Update your ")
222+
withStrong { append("payment details") }
223+
append(" if needed.")
224+
}
225+
)
226+
OudsAlertMessage(
227+
label = label,
228+
description = annotatedDescription,
229+
status = status,
230+
onClose = onClose,
231+
actionLink = actionLink,
232+
bulletList = annotatedBulletList
233+
)
234+
} else {
235+
OudsAlertMessage(
236+
label = label,
237+
description = description,
238+
status = status,
239+
onClose = onClose,
240+
actionLink = actionLink,
241+
bulletList = bulletList
242+
)
243+
}
188244
}
189245
}
190246

@@ -209,7 +265,11 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
209265
}
210266
}
211267
labelArgument(label)
212-
description?.let { typedArgument("description", description) }
268+
if (annotatedText) {
269+
annotatedStringArgument<OudsAnnotatedAlertMessageDescription>(name = "description")
270+
} else {
271+
description?.let { typedArgument("description", description) }
272+
}
213273
if (hasCloseButton) {
214274
lambdaArgument("onClose") {
215275
comment("Close alert message")
@@ -224,10 +284,18 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
224284
typedArgument("position", actionLinkPosition)
225285
}
226286
}
227-
bulletList?.let { bulletLabelById ->
287+
if (bulletList.any { it.isNotBlank() } || annotatedText) {
228288
functionCallArgument("bulletList", "listOf") {
229-
bulletLabelById.toSortedMap().values.forEach { label ->
230-
typedArgument(null, label)
289+
if (annotatedText) {
290+
repeat(AlertMessageDemoState.MaxBulletCount) {
291+
annotatedStringArgument<OudsAnnotatedAlertMessageBulletListLabel>(null)
292+
}
293+
} else {
294+
bulletList.forEach { label ->
295+
if (label.isNotBlank()) {
296+
typedArgument(null, label)
297+
}
298+
}
231299
}
232300
}
233301
}

app/src/main/java/com/orange/ouds/app/ui/components/alert/AlertMessageDemoState.kt

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
2121
import androidx.compose.runtime.setValue
2222
import androidx.compose.ui.res.stringResource
2323
import com.orange.ouds.app.R
24+
import com.orange.ouds.app.ui.components.alert.AlertMessageDemoState.Companion.MaxBulletCount
2425
import com.orange.ouds.core.component.OudsAlertMessageActionLinkPosition
2526
import com.orange.ouds.core.component.OudsAlertMessageDefaults
2627
import com.orange.ouds.core.component.OudsAlertMessageStatus
@@ -35,7 +36,8 @@ fun rememberAlertMessageDemoState(
3536
description: String? = null,
3637
actionLink: String? = null,
3738
actionLinkPosition: OudsAlertMessageActionLinkPosition = OudsAlertMessageDefaults.ActionLinkPosition,
38-
bulletList: Map<Int, String>? = null,
39+
bulletList: List<String> = List(MaxBulletCount) { "" },
40+
annotatedText: Boolean = false
3941
) = rememberSaveable(
4042
status,
4143
icon,
@@ -45,9 +47,10 @@ fun rememberAlertMessageDemoState(
4547
actionLink,
4648
actionLinkPosition,
4749
bulletList,
50+
annotatedText,
4851
saver = AlertMessageDemoState.Saver
4952
) {
50-
AlertMessageDemoState(status, icon, hasCloseButton, label, description, actionLink, actionLinkPosition, bulletList)
53+
AlertMessageDemoState(status, icon, hasCloseButton, label, description, actionLink, actionLinkPosition, bulletList, annotatedText)
5154
}
5255

5356
class AlertMessageDemoState(
@@ -58,7 +61,8 @@ class AlertMessageDemoState(
5861
description: String?,
5962
actionLink: String?,
6063
actionLinkPosition: OudsAlertMessageActionLinkPosition,
61-
bulletList: Map<Int, String>?
64+
bulletList: List<String>,
65+
annotatedText: Boolean
6266
) {
6367

6468
@Suppress("UNCHECKED_CAST")
@@ -83,7 +87,8 @@ class AlertMessageDemoState(
8387
description,
8488
actionLink,
8589
actionLinkPosition,
86-
bulletList
90+
bulletList,
91+
annotatedText
8792
)
8893
}
8994
},
@@ -99,7 +104,8 @@ class AlertMessageDemoState(
99104
list[4] as String?,
100105
list[5] as String?,
101106
list[6] as OudsAlertMessageActionLinkPosition,
102-
list[7] as Map<Int, String>?
107+
list[7] as List<String>,
108+
list[8] as Boolean
103109
)
104110
}
105111
)
@@ -129,8 +135,16 @@ class AlertMessageDemoState(
129135

130136
val actionLinkPositionChipsEnabled: Boolean
131137
get() = !actionLink.isNullOrEmpty()
138+
139+
var bulletList: List<String> by mutableStateOf(bulletList)
132140

133-
var bulletList: Map<Int, String>? by mutableStateOf(bulletList)
141+
val descriptionTextInputEnabled: Boolean
142+
get() = !annotatedText
143+
144+
val bulletListTextInputsEnabled: Boolean
145+
get() = !annotatedText
146+
147+
var annotatedText: Boolean by mutableStateOf(annotatedText)
134148

135149
val enabledIcons: List<Icon>
136150
get() = if (status !in FunctionalStatuses) Icon.entries else listOf(Icon.Tinted)

app/src/main/java/com/orange/ouds/app/ui/components/bottomsheet/ModalBottomSheetDemoScreen.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ private fun Code.Builder.modalBottomSheetDemoCodeSnippet(state: ModalBottomSheet
117117
typedArgument("sheetGesturesEnabled", state.sheetGesturesEnabled)
118118
functionCallArgument("sheetState", "rememberModalBottomSheetState")
119119
lambdaArgument("onDismissRequest") {
120-
comment("do something on dismiss")
120+
comment("Do something on dismiss")
121121
}
122122
lambdaArgument(null) {
123-
comment("sheet content")
123+
comment("Sheet content")
124124
}
125125
}
126126
}

app/src/main/java/com/orange/ouds/app/ui/utilities/composable/CustomizationElements.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fun CustomizationFilterChips(
128128
} else {
129129
true
130130
}
131-
131+
132132
Row(
133133
modifier = Modifier
134134
.fillMaxWidth()
@@ -159,6 +159,9 @@ fun CustomizationTextInput(
159159
modifier: Modifier = Modifier,
160160
enabled: Boolean = true,
161161
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
162+
suffix: String? = null,
163+
helperText: String? = null,
164+
resetValue: String = ""
162165
) {
163166
var textFieldValue by remember { mutableStateOf(TextFieldValue(text = value, selection = TextRange(value.length))) }
164167

@@ -173,6 +176,9 @@ fun CustomizationTextInput(
173176
modifier = modifier,
174177
enabled = enabled,
175178
keyboardOptions = keyboardOptions,
179+
suffix = suffix,
180+
helperText = helperText,
181+
resetValue = resetValue
176182
)
177183
}
178184

@@ -186,6 +192,7 @@ fun CustomizationTextInput(
186192
enabled: Boolean = true,
187193
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
188194
suffix: String? = null,
195+
helperText: String? = null,
189196
resetValue: String = ""
190197
) {
191198
@Suppress("NAME_SHADOWING")
@@ -211,6 +218,7 @@ fun CustomizationTextInput(
211218
null
212219
},
213220
suffix = suffix,
221+
helperText = helperText,
214222
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
215223
)
216224
}

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@
122122
<string name="app_tokens_typography_lineHeight_tech" translatable="false">Line height: %s sp</string>
123123

124124
<!-- Components -->
125+
<string name="app_components_common_annotatedText_tech" translatable="false">Annotated text</string>
126+
<string name="app_components_common_annotatedTextHelperText_tech" translatable="false">This parameter supports annotated text.</string>
125127
<string name="app_components_common_appearance_tech" translatable="false">Appearance</string>
126128
<string name="app_components_common_color_tech" translatable="false">Color</string>
127129
<string name="app_components_common_constrainedMaxWidth_tech" translatable="false">Constrained max width</string>

core/src/main/java/com/orange/ouds/core/component/OudsAlertMessage.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,9 @@ private fun OudsAlertMessage(
258258
val descriptionModifier = Modifier.widthIn(max = OudsTheme.sizes.maxWidth.label.medium)
259259
val descriptionColor = status.contentColor
260260
val descriptionStyle = OudsTheme.typography.label.default.medium
261-
if (annotatedDescription != null) {
261+
if (!annotatedDescription.isNullOrBlank()) {
262262
Text(modifier = descriptionModifier, text = annotatedDescription.annotatedString(), color = descriptionColor, style = descriptionStyle)
263-
} else if (description != null) {
263+
} else if (!description.isNullOrBlank()) {
264264
Text(modifier = descriptionModifier, text = description, color = descriptionColor, style = descriptionStyle)
265265
}
266266
annotatedBulletList.orElse { bulletList }?.let { list ->

0 commit comments

Comments
 (0)