Remove ElementColors. We should use semantics and material colors now.

This commit is contained in:
Benoit Marty 2023-07-10 15:22:54 +02:00 committed by Benoit Marty
parent 288ebab4ac
commit 9b042cf056
9 changed files with 29 additions and 146 deletions

View file

@ -162,7 +162,7 @@ private fun AnalyticsOptInContentRow(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.background( .background(
color = ElementTheme.legacyColors.quinary, color = ElementTheme.materialColors.surfaceVariant,
shape = bgShape, shape = bgShape,
) )
.padding(vertical = 12.dp, horizontal = 20.dp), .padding(vertical = 12.dp, horizontal = 20.dp),

View file

@ -393,7 +393,7 @@ private fun MessageEventBubbleContent(
onLongClick = ::onTimestampLongClick, onLongClick = ::onTimestampLongClick,
modifier = timestampModifier modifier = timestampModifier
.padding(horizontal = 4.dp, vertical = 4.dp) // Outer padding .padding(horizontal = 4.dp, vertical = 4.dp) // Outer padding
.background(ElementTheme.legacyColors.gray300, RoundedCornerShape(10.0.dp)) .background(ElementTheme.colors.bgSubtleSecondary, RoundedCornerShape(10.0.dp))
.align(Alignment.BottomEnd) .align(Alignment.BottomEnd)
.padding(horizontal = 4.dp, vertical = 2.dp) // Inner padding .padding(horizontal = 4.dp, vertical = 2.dp) // Inner padding
) )

View file

@ -59,7 +59,7 @@ fun RoundedIconAtom(
modifier = modifier modifier = modifier
.size(size.toContainerSize()) .size(size.toContainerSize())
.background( .background(
color = ElementTheme.legacyColors.quinary, color = ElementTheme.materialColors.surfaceVariant,
shape = RoundedCornerShape(size.toCornerSize()) shape = RoundedCornerShape(size.toCornerSize())
) )
) { ) {

View file

@ -156,10 +156,10 @@ object ElementSearchBarDefaults {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun inactiveColors() = SearchBarDefaults.colors( fun inactiveColors() = SearchBarDefaults.colors(
containerColor = ElementTheme.legacyColors.gray300, containerColor = ElementTheme.materialColors.surfaceVariant,
inputFieldColors = TextFieldDefaults.colors( inputFieldColors = TextFieldDefaults.colors(
unfocusedPlaceholderColor = ElementTheme.legacyColors.placeholder, unfocusedPlaceholderColor = ElementTheme.colors.textDisabled,
focusedPlaceholderColor = ElementTheme.legacyColors.placeholder, focusedPlaceholderColor = ElementTheme.colors.textDisabled,
unfocusedLeadingIconColor = MaterialTheme.colorScheme.primary, unfocusedLeadingIconColor = MaterialTheme.colorScheme.primary,
focusedLeadingIconColor = MaterialTheme.colorScheme.primary, focusedLeadingIconColor = MaterialTheme.colorScheme.primary,
unfocusedTrailingIconColor = MaterialTheme.colorScheme.primary, unfocusedTrailingIconColor = MaterialTheme.colorScheme.primary,
@ -172,8 +172,8 @@ object ElementSearchBarDefaults {
fun activeColors() = SearchBarDefaults.colors( fun activeColors() = SearchBarDefaults.colors(
containerColor = Color.Transparent, containerColor = Color.Transparent,
inputFieldColors = TextFieldDefaults.colors( inputFieldColors = TextFieldDefaults.colors(
unfocusedPlaceholderColor = ElementTheme.legacyColors.placeholder, unfocusedPlaceholderColor = ElementTheme.colors.textDisabled,
focusedPlaceholderColor = ElementTheme.legacyColors.placeholder, focusedPlaceholderColor = ElementTheme.colors.textDisabled,
unfocusedLeadingIconColor = MaterialTheme.colorScheme.primary, unfocusedLeadingIconColor = MaterialTheme.colorScheme.primary,
focusedLeadingIconColor = MaterialTheme.colorScheme.primary, focusedLeadingIconColor = MaterialTheme.colorScheme.primary,
unfocusedTrailingIconColor = MaterialTheme.colorScheme.primary, unfocusedTrailingIconColor = MaterialTheme.colorScheme.primary,
@ -243,19 +243,28 @@ internal fun SearchBarPreviewActiveWithContent() = ElementThemedPreview {
active = true, active = true,
resultState = SearchBarResultState.Results("result!"), resultState = SearchBarResultState.Results("result!"),
contentPrefix = { contentPrefix = {
Text(text = "Content that goes before the search results", modifier = Modifier Text(
.background(color = Color.Red) text = "Content that goes before the search results",
.fillMaxWidth()) modifier = Modifier
.background(color = Color.Red)
.fillMaxWidth()
)
}, },
contentSuffix = { contentSuffix = {
Text(text = "Content that goes after the search results", modifier = Modifier Text(
.background(color = Color.Blue) text = "Content that goes after the search results",
.fillMaxWidth()) modifier = Modifier
.background(color = Color.Blue)
.fillMaxWidth()
)
}, },
resultHandler = { resultHandler = {
Text(text = "Results go here", modifier = Modifier Text(
.background(color = Color.Green) text = "Results go here",
.fillMaxWidth()) modifier = Modifier
.background(color = Color.Green)
.fillMaxWidth()
)
} }
) )
} }

View file

@ -69,7 +69,7 @@ fun UnsavedAvatar(
contentDescription = null, contentDescription = null,
) )
} else { } else {
Box(modifier = commonModifier.background(ElementTheme.legacyColors.quinary)) { Box(modifier = commonModifier.background(ElementTheme.materialColors.surfaceVariant)) {
Icon( Icon(
imageVector = Icons.Outlined.AddAPhoto, imageVector = Icons.Outlined.AddAPhoto,
contentDescription = "", contentDescription = "",

View file

@ -8,7 +8,6 @@ The module contains public tokens and color schemes that are later used in `Mate
All tokens can be accessed through the `ElementTheme` object, which contains the following properties: All tokens can be accessed through the `ElementTheme` object, which contains the following properties:
* `ElementTheme.legacyColors`: contains legacy colors and custom colors not present in either Material or Compound. Usage of these colors should be avoided, and they're usually prefixed in Figma with the `Zzz/` prefix or have no name at all.
* `ElementTheme.materialColors`: contains all Material color tokens. In Figma, they're prefixed with `M3/`. It's an alias to `MaterialTheme.colorScheme`. * `ElementTheme.materialColors`: contains all Material color tokens. In Figma, they're prefixed with `M3/`. It's an alias to `MaterialTheme.colorScheme`.
* `ElementTheme.colors`: contains all Compound semantic color tokens. In Figma, they're prefixed with either `Light/` or `Dark/`. * `ElementTheme.colors`: contains all Compound semantic color tokens. In Figma, they're prefixed with either `Light/` or `Dark/`.
* `ElementTheme.materialTypography`: contains the Material `Typography` values. In Figma, they're prefixed with `M3/`. It's an alias to `MaterialTheme.typography`. * `ElementTheme.materialTypography`: contains the Material `Typography` values. In Figma, they're prefixed with `M3/`. It's an alias to `MaterialTheme.typography`.
@ -17,5 +16,3 @@ All tokens can be accessed through the `ElementTheme` object, which contains the
## Adding new tokens ## Adding new tokens
All new tokens **should** come from Compound and added to the `compound.generated` package. To map the literal tokens to the semantic ones, you'll have to update both `compoundColorsLight` and `compoundColorsDark` in `CompoundColors.kt`. All new tokens **should** come from Compound and added to the `compound.generated` package. To map the literal tokens to the semantic ones, you'll have to update both `compoundColorsLight` and `compoundColorsDark` in `CompoundColors.kt`.
As we're still migrating to using Compound tokens, it's possible that you might need to add some tokens manually. In that case, you should add them to `LegacyColors.kt` and map them later in `ElementColors.kt` so they can be used in light and dark themes. However, keep in mind this is just a temporary step, as those tokens should either be added later to Compound or replaced by Compound tokens in the future.

View file

@ -1,107 +0,0 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.theme
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import io.element.android.libraries.theme.compound.generated.internal.DarkDesignTokens
import io.element.android.libraries.theme.compound.generated.internal.LightDesignTokens
import io.element.android.libraries.theme.compound.generated.SemanticColors
/**
* Element Android legacy color palette.
*
* ## IMPORTANT!
* **We should not add any new colors here, all new colors should come from [SemanticColors] instead.**
*
* If a design needs you to add a different color here, talk to some designer first, as they'll probably be using
* the legacy color palette.
*/
@Deprecated("Use SemanticColors instead")
@Stable
class ElementColors(
quaternary: Color,
quinary: Color,
gray300: Color,
accentColor: Color,
placeholder: Color,
isLight: Boolean
) {
var quaternary by mutableStateOf(quaternary)
private set
var quinary by mutableStateOf(quinary)
private set
var gray300 by mutableStateOf(gray300)
private set
var accentColor by mutableStateOf(accentColor)
private set
var placeholder by mutableStateOf(placeholder)
private set
var isLight by mutableStateOf(isLight)
private set
fun copy(
quaternary: Color = this.quaternary,
quinary: Color = this.quinary,
gray300: Color = this.gray300,
accentColor: Color = this.accentColor,
placeholder: Color = this.placeholder,
isLight: Boolean = this.isLight,
) = ElementColors(
quaternary = quaternary,
quinary = quinary,
gray300 = gray300,
accentColor = accentColor,
placeholder = placeholder,
isLight = isLight,
)
fun updateColorsFrom(other: ElementColors) {
quaternary = other.quaternary
quinary = other.quinary
gray300 = other.gray300
accentColor = other.accentColor
placeholder = other.placeholder
isLight = other.isLight
}
}
internal fun elementColorsLight() = ElementColors(
quaternary = Gray_100,
quinary = Gray_50,
gray300 = LightDesignTokens.colorGray300,
accentColor = ElementGreen,
placeholder = LightDesignTokens.colorGray800,
isLight = true,
)
internal fun elementColorsDark() = ElementColors(
quaternary = Gray_400,
quinary = Gray_450,
gray300 = DarkDesignTokens.colorGray300,
accentColor = ElementGreen,
placeholder = DarkDesignTokens.colorGray800,
isLight = false,
)

View file

@ -44,15 +44,6 @@ import io.element.android.libraries.theme.compound.generated.TypographyTokens
* Inspired from https://medium.com/@lucasyujideveloper/54cbcbde1ace * Inspired from https://medium.com/@lucasyujideveloper/54cbcbde1ace
*/ */
object ElementTheme { object ElementTheme {
/**
* The current [ElementColors] provided by [ElementTheme]. Usage of these colors is discouraged.
* In Figma, they usually have the `Zzz` prefix or have no name at all.
*/
val legacyColors: ElementColors
@Composable
@ReadOnlyComposable
get() = LocalLegacyColors.current
/** /**
* The current [SemanticColors] provided by [ElementTheme]. * The current [SemanticColors] provided by [ElementTheme].
* These come from Compound and are the recommended colors to use for custom components. * These come from Compound and are the recommended colors to use for custom components.
@ -95,14 +86,12 @@ object ElementTheme {
} }
/* Global variables (application level) */ /* Global variables (application level) */
internal val LocalLegacyColors = staticCompositionLocalOf { elementColorsLight() }
internal val LocalCompoundColors = staticCompositionLocalOf { compoundColorsLight } internal val LocalCompoundColors = staticCompositionLocalOf { compoundColorsLight }
@Composable @Composable
fun ElementTheme( fun ElementTheme(
darkTheme: Boolean = isSystemInDarkTheme(), darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = false, /* true to enable MaterialYou */ dynamicColor: Boolean = false, /* true to enable MaterialYou */
legacyColors: ElementColors = if (darkTheme) elementColorsDark() else elementColorsLight(),
compoundColors: SemanticColors = if (darkTheme) compoundColorsDark else compoundColorsLight, compoundColors: SemanticColors = if (darkTheme) compoundColorsDark else compoundColorsLight,
materialLightColors: ColorScheme = materialColorSchemeLight, materialLightColors: ColorScheme = materialColorSchemeLight,
materialDarkColors: ColorScheme = materialColorSchemeDark, materialDarkColors: ColorScheme = materialColorSchemeDark,
@ -110,9 +99,6 @@ fun ElementTheme(
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
val systemUiController = rememberSystemUiController() val systemUiController = rememberSystemUiController()
val currentLegacyColor = remember(darkTheme) {
legacyColors.copy()
}.apply { updateColorsFrom(legacyColors) }
val currentCompoundColor = remember(darkTheme) { val currentCompoundColor = remember(darkTheme) {
compoundColors.copy() compoundColors.copy()
}.apply { updateColorsFrom(compoundColors) } }.apply { updateColorsFrom(compoundColors) }
@ -128,7 +114,6 @@ fun ElementTheme(
systemUiController.applyTheme(colorScheme = colorScheme, darkTheme = darkTheme) systemUiController.applyTheme(colorScheme = colorScheme, darkTheme = darkTheme)
} }
CompositionLocalProvider( CompositionLocalProvider(
LocalLegacyColors provides currentLegacyColor,
LocalCompoundColors provides currentCompoundColor, LocalCompoundColors provides currentCompoundColor,
) { ) {
MaterialTheme( MaterialTheme(
@ -149,7 +134,7 @@ fun ForcedDarkElementTheme(
) { ) {
val systemUiController = rememberSystemUiController() val systemUiController = rememberSystemUiController()
val colorScheme = MaterialTheme.colorScheme val colorScheme = MaterialTheme.colorScheme
val wasDarkTheme = !ElementTheme.legacyColors.isLight val wasDarkTheme = !ElementTheme.colors.isLight
DisposableEffect(Unit) { DisposableEffect(Unit) {
onDispose { onDispose {
systemUiController.applyTheme(colorScheme, wasDarkTheme) systemUiController.applyTheme(colorScheme, wasDarkTheme)

View file

@ -113,8 +113,7 @@ Compose:
CompositionLocalAllowlist: CompositionLocalAllowlist:
active: true active: true
# You can optionally define a list of CompositionLocals that are allowed here # You can optionally define a list of CompositionLocals that are allowed here
allowedCompositionLocals: LocalCompoundColors, LocalSnackbarDispatcher
allowedCompositionLocals: LocalLegacyColors, LocalCompoundColors, LocalSnackbarDispatcher
CompositionLocalNaming: CompositionLocalNaming:
active: true active: true
ContentEmitterReturningValues: ContentEmitterReturningValues: