Skip to content

Commit a75b4c8

Browse files
committed
Improve high contrast management for chips
1 parent 6fac7c3 commit a75b4c8

2 files changed

Lines changed: 61 additions & 19 deletions

File tree

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

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import com.orange.ouds.core.component.content.OudsComponentContent
4949
import com.orange.ouds.core.component.content.OudsComponentIcon
5050
import com.orange.ouds.core.extensions.InteractionState
5151
import com.orange.ouds.core.extensions.collectInteractionStateAsState
52+
import com.orange.ouds.core.extensions.isTransparent
5253
import com.orange.ouds.core.theme.LocalHighContrastModeEnabled
5354
import com.orange.ouds.core.theme.OudsTheme
5455
import com.orange.ouds.core.theme.takeUnlessHairline
@@ -217,12 +218,7 @@ private fun borderWidth(state: OudsChipState, selected: Boolean): Dp? {
217218
private fun borderColor(state: OudsChipState, selected: Boolean): Color {
218219
return with(OudsTheme.componentsTokens.chip) {
219220
when (state) {
220-
OudsChipState.Enabled -> when {
221-
// In order to reach the a11y AAA level, when high contrast mode is enabled, the enabled chip border color must use `color.content.default` token
222-
LocalHighContrastModeEnabled.current -> OudsTheme.colorScheme.content.default
223-
selected -> colorBorderSelectedEnabled.value
224-
else -> colorBorderUnselectedEnabled.value
225-
}
221+
OudsChipState.Enabled -> if (selected) colorBorderSelectedEnabled.value.highContrasted() else colorBorderUnselectedEnabled.value
226222
OudsChipState.Focused -> if (selected) colorBorderSelectedFocus.value else colorBorderUnselectedFocus.value
227223
OudsChipState.Hovered -> if (selected) colorBorderSelectedHover.value else colorBorderUnselectedHover.value
228224
OudsChipState.Pressed -> if (selected) colorBorderSelectedPressed.value else colorBorderUnselectedPressed.value
@@ -235,25 +231,29 @@ private fun borderColor(state: OudsChipState, selected: Boolean): Color {
235231
private fun backgroundColor(state: OudsChipState, selected: Boolean): Color {
236232
return with(OudsTheme.componentsTokens.chip) {
237233
when (state) {
238-
OudsChipState.Enabled -> if (selected) colorBgSelectedEnabled else colorBgUnselectedEnabled
239-
OudsChipState.Focused -> if (selected) colorBgSelectedFocus else colorBgUnselectedFocus
240-
OudsChipState.Hovered -> if (selected) colorBgSelectedHover else colorBgUnselectedHover
241-
OudsChipState.Pressed -> if (selected) colorBgSelectedPressed else colorBgUnselectedPressed
242-
OudsChipState.Disabled -> if (selected) colorBgSelectedDisabled else colorBgUnselectedDisabled
243-
}.value
234+
OudsChipState.Enabled -> if (selected) colorBgSelectedEnabled.value.highContrasted() else colorBgUnselectedEnabled.value
235+
OudsChipState.Focused -> if (selected) colorBgSelectedFocus.value else colorBgUnselectedFocus.value
236+
OudsChipState.Hovered -> if (selected) colorBgSelectedHover.value else colorBgUnselectedHover.value
237+
OudsChipState.Pressed -> if (selected) colorBgSelectedPressed.value else colorBgUnselectedPressed.value
238+
OudsChipState.Disabled -> if (selected) colorBgSelectedDisabled.value else colorBgUnselectedDisabled.value
239+
}
244240
}
245241
}
246242

247243
@Composable
248244
private fun contentColor(state: OudsChipState, selected: Boolean): Color {
249245
return with(OudsTheme.componentsTokens.chip) {
250246
when (state) {
251-
OudsChipState.Enabled -> if (selected) colorContentSelectedEnabled else colorContentUnselectedEnabled
252-
OudsChipState.Focused -> if (selected) colorContentSelectedFocus else colorContentUnselectedFocus
253-
OudsChipState.Hovered -> if (selected) colorContentSelectedHover else colorContentUnselectedHover
254-
OudsChipState.Pressed -> if (selected) colorContentSelectedPressed else colorContentUnselectedPressed
255-
OudsChipState.Disabled -> if (selected) colorContentSelectedDisabled else colorContentUnselectedDisabled
256-
}.value
247+
OudsChipState.Enabled -> if (selected) {
248+
colorContentSelectedEnabled.value.highContrasted(onBackground = colorBgSelectedEnabled.value)
249+
} else {
250+
colorContentUnselectedEnabled.value
251+
}
252+
OudsChipState.Focused -> if (selected) colorContentSelectedFocus.value else colorContentUnselectedFocus.value
253+
OudsChipState.Hovered -> if (selected) colorContentSelectedHover.value else colorContentUnselectedHover.value
254+
OudsChipState.Pressed -> if (selected) colorContentSelectedPressed.value else colorContentUnselectedPressed.value
255+
OudsChipState.Disabled -> if (selected) colorContentSelectedDisabled.value else colorContentUnselectedDisabled.value
256+
}
257257
}
258258
}
259259

@@ -262,7 +262,7 @@ private fun tickColor(state: OudsChipState, selected: Boolean): Color? {
262262
return with(OudsTheme.componentsTokens.chip) {
263263
if (selected) {
264264
when (state) {
265-
OudsChipState.Enabled -> if (LocalHighContrastModeEnabled.current) OudsTheme.colorScheme.content.default else colorContentSelectedTickEnabled.value
265+
OudsChipState.Enabled -> colorContentSelectedTickEnabled.value.highContrasted(onBackground = colorBgSelectedEnabled.value)
266266
OudsChipState.Focused -> colorContentSelectedFocus.value
267267
OudsChipState.Hovered -> colorContentSelectedHover.value
268268
OudsChipState.Pressed -> colorContentSelectedPressed.value
@@ -298,6 +298,31 @@ private fun contentPadding(label: String?, icon: OudsChipIcon?, iconPosition: Ou
298298
}
299299
}
300300

301+
/**
302+
* Returns a high contrast color when high contrast mode is enabled.
303+
*
304+
* This extension replaces the current color with appropriate high contrast alternatives from the theme's color scheme:
305+
* - If [onBackground] is provided (color used on a background):
306+
* - Returns `background.primary` if the current color is opaque
307+
* - Returns `content.default` if the current color is transparent
308+
* - If [onBackground] is null (color not on a background):
309+
* - Returns `content.default` if the current color is opaque
310+
* - Returns the current color unchanged if it is transparent
311+
*
312+
* When high contrast mode is disabled, the current color is returned unchanged.
313+
*
314+
* @param onBackground The background color on which this color will be displayed, or `null` if not applicable.
315+
* @return The high contrast color when enabled, or the current color otherwise.
316+
*/
317+
@Composable
318+
private fun Color.highContrasted(onBackground: Color? = null): Color = when {
319+
!LocalHighContrastModeEnabled.current -> this
320+
onBackground != null && isTransparent() -> OudsTheme.colorScheme.content.default
321+
onBackground != null -> OudsTheme.colorScheme.background.primary
322+
isTransparent() -> this
323+
else -> OudsTheme.colorScheme.content.default
324+
}
325+
301326
/**
302327
* An icon in an [OudsFilterChip] or an [OudsSuggestionChip].
303328
* This icon is not clickable.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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.core.extensions
14+
15+
import androidx.compose.ui.graphics.Color
16+
17+
fun Color.isTransparent() = this.alpha == 0f

0 commit comments

Comments
 (0)