Skip to content

Commit c098a69

Browse files
authored
feat: create component - inline alert (#1118)
1 parent e7dd3b5 commit c098a69

69 files changed

Lines changed: 838 additions & 162 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NOTICE.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ theme-orange/src/main/res/drawable/ic_orange_functional_actions_delete.xml
123123
theme-orange/src/main/res/drawable/ic_orange_functional_navigation_form_chevron_left.xml
124124
theme-orange/src/main/res/drawable/ic_orange_functional_navigation_menu.xml
125125
theme-orange/src/main/res/drawable/ic_orange_functional_settings_and_tools_hide.xml
126+
theme-orange/src/main/res/drawable/ic_orange_functional_social_and_engagement_heart_empty.xml
126127
theme-orange/src/main/res/drawable-ldrtl/ic_orange_component_bullet_list_level0.xml
127128
theme-orange/src/main/res/drawable-ldrtl/ic_orange_component_bullet_list_level1.xml
128129
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
151152
theme-sosh/src/main/res/drawable/ic_sosh_functional_navigation_form_chevron_left.xml
152153
theme-sosh/src/main/res/drawable/ic_sosh_functional_navigation_menu.xml
153154
theme-sosh/src/main/res/drawable/ic_sosh_functional_settings_and_tools_hide.xml
155+
theme-sosh/src/main/res/drawable/ic_sosh_functional_social_and_engagement_heart_empty.xml
154156
theme-sosh/src/main/res/font/sosh_black.ttf
155157
theme-sosh/src/main/res/font/sosh_bold.ttf
156158
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
181183
theme-wireframe/src/main/res/drawable/ic_wireframe_functional_navigation_form_chevron_left.xml
182184
theme-wireframe/src/main/res/drawable/ic_wireframe_functional_navigation_menu.xml
183185
theme-wireframe/src/main/res/drawable/ic_wireframe_functional_settings_and_tools_hide.xml
186+
theme-wireframe/src/main/res/drawable/ic_wireframe_functional_social_and_engagement_heart_empty.xml
184187

185188
End of the parts list under Orange SA Copyright
186189

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import androidx.compose.runtime.Composable
1717
import androidx.compose.runtime.Immutable
1818
import com.orange.ouds.app.R
1919
import com.orange.ouds.app.ui.components.alert.AlertMessageDemoScreen
20+
import com.orange.ouds.app.ui.components.alert.InlineAlertDemoScreen
2021
import com.orange.ouds.app.ui.components.badge.BadgeDemoScreen
2122
import com.orange.ouds.app.ui.components.bulletlist.BulletListDemoScreen
2223
import com.orange.ouds.app.ui.components.button.ButtonDemoScreen
@@ -61,7 +62,7 @@ sealed class Component(
6162
R.string.app_components_alert_label,
6263
R.string.app_components_alert_description_text,
6364
{ AlertIllustration() },
64-
listOf(Variant.AlertMessage)
65+
listOf(Variant.AlertMessage, Variant.InlineAlert)
6566
)
6667

6768
data object Badge : Component(
@@ -190,6 +191,7 @@ sealed class Variant(
190191

191192
// Alert
192193
data object AlertMessage : Variant(R.string.app_components_alert_alertMessage_label, { AlertMessageDemoScreen() })
194+
data object InlineAlert : Variant(R.string.app_components_alert_inlineAlert_tech, { InlineAlertDemoScreen() })
193195

194196
// Checkbox
195197
data object Checkbox : Variant(R.string.app_components_checkbox_checkbox_label, { CheckboxDemoScreen() })

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ import androidx.compose.ui.Modifier
2020
import androidx.compose.ui.platform.LocalInspectionMode
2121
import androidx.compose.ui.res.painterResource
2222
import androidx.compose.ui.res.stringResource
23+
import androidx.compose.ui.tooling.preview.PreviewLightDark
2324
import com.orange.ouds.app.R
2425
import com.orange.ouds.app.ui.components.alert.AlertMessageDemoState.Companion.MaxBulletCount
26+
import com.orange.ouds.app.ui.components.labelArgument
2527
import com.orange.ouds.app.ui.components.painterArgument
2628
import com.orange.ouds.app.ui.utilities.Code
2729
import com.orange.ouds.app.ui.utilities.LocalThemeDrawableResources
2830
import com.orange.ouds.app.ui.utilities.ThemeDrawableResources
31+
import com.orange.ouds.app.ui.utilities.composable.AppPreview
2932
import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenu
3033
import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenuItem
3134
import com.orange.ouds.app.ui.utilities.composable.CustomizationFilterChip
@@ -35,10 +38,10 @@ import com.orange.ouds.app.ui.utilities.composable.CustomizationTextInput
3538
import com.orange.ouds.app.ui.utilities.composable.DemoScreen
3639
import com.orange.ouds.app.ui.utilities.nestedName
3740
import com.orange.ouds.app.ui.utilities.toSentenceCase
41+
import com.orange.ouds.core.component.OudsAlertIcon
3842
import com.orange.ouds.core.component.OudsAlertMessage
3943
import com.orange.ouds.core.component.OudsAlertMessageActionLink
4044
import com.orange.ouds.core.component.OudsAlertMessageActionLinkPosition
41-
import com.orange.ouds.core.component.OudsAlertMessageIcon
4245
import com.orange.ouds.core.component.OudsAlertMessageStatus
4346
import com.orange.ouds.foundation.extensions.tryOrNull
4447
import com.orange.ouds.theme.OudsVersion
@@ -88,7 +91,7 @@ private fun AlertMessageDemoBottomSheetContent(state: AlertMessageDemoState) {
8891
Box(
8992
modifier = Modifier
9093
.fillMaxSize()
91-
.background(status.backgroundColor())
94+
.background(status.backgroundColor)
9295
)
9396
}
9497
)
@@ -152,7 +155,7 @@ private fun AlertMessageDemoBottomSheetContent(state: AlertMessageDemoState) {
152155

153156
@Composable
154157
private fun AlertMessageDemoContent(state: AlertMessageDemoState) {
155-
val icon = OudsAlertMessageIcon(painter = painterResource(LocalThemeDrawableResources.current.tipsAndTricks))
158+
val icon = OudsAlertIcon(painter = painterResource(LocalThemeDrawableResources.current.tipsAndTricks))
156159
with(state) {
157160
OudsAlertMessage(
158161
label = label,
@@ -187,7 +190,7 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
187190
is OudsAlertMessageStatus.Neutral -> {
188191
functionCallArgument(statusParameterName, status::class.java.nestedName) {
189192
if (hasStatusIcon) {
190-
constructorCallArgument<OudsAlertMessageIcon>("icon") {
193+
constructorCallArgument<OudsAlertIcon>("icon") {
191194
painterArgument(themeDrawableResources.tipsAndTricks)
192195
}
193196
}
@@ -200,7 +203,7 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
200203
rawArgument(statusParameterName, status::class.java.nestedName)
201204
}
202205
}
203-
typedArgument("label", label)
206+
labelArgument(label)
204207
description?.let { typedArgument("description", description) }
205208
if (hasCloseButton) {
206209
lambdaArgument("onClose") {
@@ -209,7 +212,7 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
209212
}
210213
if (!actionLink.isNullOrEmpty()) {
211214
functionCallArgument("actionLink", OudsAlertMessageActionLink::class.java.simpleName) {
212-
typedArgument("label", actionLink)
215+
labelArgument(actionLink)
213216
lambdaArgument("onClick") {
214217
comment("Implement click")
215218
}
@@ -225,4 +228,10 @@ private fun Code.Builder.alertMessageDemoCodeSnippet(state: AlertMessageDemoStat
225228
}
226229
}
227230
}
231+
}
232+
233+
@PreviewLightDark
234+
@Composable
235+
private fun PreviewAlertMessageDemoScreen() = AppPreview {
236+
AlertMessageDemoScreen()
228237
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Software Name: OUDS Android
3+
* SPDX-FileCopyrightText: Copyright (c) Orange SA
4+
* SPDX-License-Identifier: MIT
5+
*
6+
* This software is distributed under the MIT license,
7+
* the text of which is available at https://opensource.org/license/MIT/
8+
* or see the "LICENSE" file for more details.
9+
*
10+
* Software description: Android library of reusable graphical components
11+
*/
12+
13+
package com.orange.ouds.app.ui.components.alert
14+
15+
import androidx.compose.foundation.background
16+
import androidx.compose.foundation.layout.Box
17+
import androidx.compose.foundation.layout.fillMaxSize
18+
import androidx.compose.runtime.Composable
19+
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.graphics.Color
21+
import androidx.compose.ui.platform.LocalInspectionMode
22+
import androidx.compose.ui.res.painterResource
23+
import androidx.compose.ui.res.stringResource
24+
import androidx.compose.ui.tooling.preview.PreviewLightDark
25+
import com.orange.ouds.app.R
26+
import com.orange.ouds.app.ui.components.labelArgument
27+
import com.orange.ouds.app.ui.components.painterArgument
28+
import com.orange.ouds.app.ui.utilities.Code
29+
import com.orange.ouds.app.ui.utilities.LocalThemeDrawableResources
30+
import com.orange.ouds.app.ui.utilities.ThemeDrawableResources
31+
import com.orange.ouds.app.ui.utilities.composable.AppPreview
32+
import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenu
33+
import com.orange.ouds.app.ui.utilities.composable.CustomizationDropdownMenuItem
34+
import com.orange.ouds.app.ui.utilities.composable.CustomizationTextInput
35+
import com.orange.ouds.app.ui.utilities.composable.DemoScreen
36+
import com.orange.ouds.app.ui.utilities.nestedName
37+
import com.orange.ouds.app.ui.utilities.toSentenceCase
38+
import com.orange.ouds.core.component.OudsAlertIcon
39+
import com.orange.ouds.core.component.OudsInlineAlert
40+
import com.orange.ouds.core.component.OudsInlineAlertStatus
41+
import com.orange.ouds.foundation.extensions.orElse
42+
import com.orange.ouds.foundation.extensions.tryOrNull
43+
import com.orange.ouds.theme.OudsVersion
44+
45+
@Composable
46+
fun InlineAlertDemoScreen() {
47+
val state = rememberInlineAlertDemoState()
48+
val themeDrawableResources = LocalThemeDrawableResources.current
49+
DemoScreen(
50+
description = stringResource(id = R.string.app_components_alert_inlineAlert_description_text),
51+
bottomSheetContent = { InlineAlertDemoBottomSheetContent(state = state) },
52+
codeSnippet = { inlineAlertDemoCodeSnippet(state = state, themeDrawableResources = themeDrawableResources) },
53+
demoContent = { InlineAlertDemoContent(state = state) },
54+
version = OudsVersion.Component.Alert
55+
)
56+
}
57+
58+
@Composable
59+
private fun InlineAlertDemoBottomSheetContent(state: InlineAlertDemoState) {
60+
with(state) {
61+
val statuses = if (LocalInspectionMode.current) {
62+
// Fixes a bug where calling sealedSubclasses returns an empty list in Compose previews
63+
// See https://issuetracker.google.com/issues/240601093
64+
listOf(
65+
OudsInlineAlertStatus.Accent(OudsAlertIcon.Default),
66+
OudsInlineAlertStatus.Neutral(OudsAlertIcon.Default),
67+
OudsInlineAlertStatus.Positive,
68+
OudsInlineAlertStatus.Info,
69+
OudsInlineAlertStatus.Warning,
70+
OudsInlineAlertStatus.Negative
71+
)
72+
} else {
73+
OudsInlineAlertStatus::class.sealedSubclasses.mapNotNull { kClass ->
74+
tryOrNull {
75+
when (kClass) {
76+
OudsInlineAlertStatus.Neutral::class -> OudsInlineAlertStatus.Neutral(OudsAlertIcon.Default)
77+
OudsInlineAlertStatus.Accent::class -> OudsInlineAlertStatus.Accent(OudsAlertIcon.Default)
78+
else -> kClass.objectInstance
79+
}
80+
}
81+
}
82+
}
83+
CustomizationDropdownMenu(
84+
applyTopPadding = false,
85+
label = stringResource(id = R.string.app_components_common_status_label),
86+
items = statuses.map { status ->
87+
CustomizationDropdownMenuItem(
88+
label = status::class.simpleName.orEmpty().toSentenceCase(),
89+
leadingIcon = {
90+
Box(
91+
modifier = Modifier
92+
.fillMaxSize()
93+
.background(status.assetColor.takeIf { it != Color.Unspecified }.orElse { status.textColor })
94+
)
95+
}
96+
)
97+
},
98+
selectedItemIndex = statuses.indexOfFirst { it::class.qualifiedName == status::class.qualifiedName },
99+
onSelectionChange = { status = statuses[it] }
100+
)
101+
CustomizationTextInput(
102+
applyTopPadding = true,
103+
label = stringResource(R.string.app_components_common_label_label),
104+
value = label,
105+
onValueChange = { value -> label = value }
106+
)
107+
}
108+
}
109+
110+
@Composable
111+
private fun InlineAlertDemoContent(state: InlineAlertDemoState) {
112+
val icon = OudsAlertIcon(painter = painterResource(LocalThemeDrawableResources.current.tipsAndTricks))
113+
with(state) {
114+
OudsInlineAlert(
115+
label = label,
116+
status = when (status) {
117+
is OudsInlineAlertStatus.Accent -> OudsInlineAlertStatus.Accent(icon)
118+
is OudsInlineAlertStatus.Neutral -> OudsInlineAlertStatus.Neutral(icon)
119+
is OudsInlineAlertStatus.Info -> OudsInlineAlertStatus.Info
120+
is OudsInlineAlertStatus.Negative -> OudsInlineAlertStatus.Negative
121+
is OudsInlineAlertStatus.Positive -> OudsInlineAlertStatus.Positive
122+
is OudsInlineAlertStatus.Warning -> OudsInlineAlertStatus.Warning
123+
},
124+
)
125+
}
126+
}
127+
128+
private fun Code.Builder.inlineAlertDemoCodeSnippet(state: InlineAlertDemoState, themeDrawableResources: ThemeDrawableResources) {
129+
with(state) {
130+
functionCall("OudsInlineAlert") {
131+
val statusParameterName = "status"
132+
when (status) {
133+
is OudsInlineAlertStatus.Accent,
134+
is OudsInlineAlertStatus.Neutral -> {
135+
functionCallArgument(statusParameterName, status::class.java.nestedName) {
136+
constructorCallArgument<OudsAlertIcon>("icon") {
137+
painterArgument(themeDrawableResources.tipsAndTricks)
138+
}
139+
}
140+
}
141+
OudsInlineAlertStatus.Info,
142+
OudsInlineAlertStatus.Negative,
143+
OudsInlineAlertStatus.Positive,
144+
OudsInlineAlertStatus.Warning -> {
145+
rawArgument(statusParameterName, status::class.java.nestedName)
146+
}
147+
}
148+
labelArgument(label)
149+
}
150+
}
151+
}
152+
153+
@PreviewLightDark
154+
@Composable
155+
private fun PreviewInlineAlertDemoScreen() = AppPreview {
156+
InlineAlertDemoScreen()
157+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Software Name: OUDS Android
3+
* SPDX-FileCopyrightText: Copyright (c) Orange SA
4+
* SPDX-License-Identifier: MIT
5+
*
6+
* This software is distributed under the MIT license,
7+
* the text of which is available at https://opensource.org/license/MIT/
8+
* or see the "LICENSE" file for more details.
9+
*
10+
* Software description: Android library of reusable graphical components
11+
*/
12+
13+
package com.orange.ouds.app.ui.components.alert
14+
15+
import androidx.compose.runtime.Composable
16+
import androidx.compose.runtime.getValue
17+
import androidx.compose.runtime.mutableStateOf
18+
import androidx.compose.runtime.saveable.listSaver
19+
import androidx.compose.runtime.saveable.rememberSaveable
20+
import androidx.compose.runtime.setValue
21+
import androidx.compose.ui.res.stringResource
22+
import com.orange.ouds.app.R
23+
import com.orange.ouds.core.component.OudsAlertIcon
24+
import com.orange.ouds.core.component.OudsInlineAlertDefaults
25+
import com.orange.ouds.core.component.OudsInlineAlertStatus
26+
27+
@Composable
28+
fun rememberInlineAlertDemoState(
29+
label: String = stringResource(id = R.string.app_components_common_label_label),
30+
status: OudsInlineAlertStatus = OudsInlineAlertDefaults.Status,
31+
) = rememberSaveable(
32+
label,
33+
status,
34+
saver = InlineAlertDemoState.Saver
35+
) {
36+
InlineAlertDemoState(label, status)
37+
}
38+
39+
class InlineAlertDemoState(
40+
label: String,
41+
status: OudsInlineAlertStatus
42+
) {
43+
44+
companion object {
45+
val Saver = listSaver(
46+
save = { state ->
47+
with(state) {
48+
listOf(
49+
label,
50+
status::class.java.name
51+
)
52+
}
53+
},
54+
restore = { list: List<Any?> ->
55+
val statusClassName = list[1] as String
56+
val status = when (val kClass = Class.forName(statusClassName).kotlin) {
57+
OudsInlineAlertStatus.Neutral::class -> OudsInlineAlertStatus.Neutral(OudsAlertIcon.Default)
58+
OudsInlineAlertStatus.Accent::class -> OudsInlineAlertStatus.Accent(OudsAlertIcon.Default)
59+
else -> kClass.objectInstance as OudsInlineAlertStatus
60+
}
61+
62+
InlineAlertDemoState(
63+
list[0] as String,
64+
status
65+
)
66+
}
67+
)
68+
}
69+
70+
var status: OudsInlineAlertStatus by mutableStateOf(status)
71+
72+
var label: String by mutableStateOf(label)
73+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.orange.ouds.app.R
2424
import com.orange.ouds.app.ui.components.Component
2525
import com.orange.ouds.app.ui.components.bulletlist.BulletListDemoState.Companion.MaxLevelCount
2626
import com.orange.ouds.app.ui.components.bulletlist.BulletListDemoState.Companion.MinLevelCount
27+
import com.orange.ouds.app.ui.components.labelArgument
2728
import com.orange.ouds.app.ui.components.painterArgument
2829
import com.orange.ouds.app.ui.utilities.Code
2930
import com.orange.ouds.app.ui.utilities.LocalThemeDrawableResources
@@ -216,7 +217,7 @@ private fun Code.Builder.bulletListDemoCodeSnippet(state: BulletListDemoState, t
216217
private fun Code.Builder.itemFunctionCall(label: String, content: (Code.Builder.() -> Unit)? = null) = functionCall("item") {
217218
trailingLambda = true
218219
isMultiline = false
219-
typedArgument("label", label)
220+
labelArgument(label)
220221
content?.let {
221222
lambdaArgument("builder") {
222223
content()

0 commit comments

Comments
 (0)