Introduce "Black" theme and refactor theme handling

* Add `Theme.Black` to the `Theme` enum and update `isDark()` to include it.
* Refactor `ElementTheme` to accept a `Theme` object instead of a `darkTheme` boolean, allowing for more specific color mapping (e.g., setting `bgCanvasDefault` to `Color.Black` for the Black theme).
* Update `AdvancedSettingsPresenter` and `AdvancedSettingsState` to include "Black" as a user-selectable theme option.
* Adjust `ElementThemeApp` and `MaterialTextPreview` to handle the expanded theme selection.
* Add `ElementPreviewBlack` and update existing preview components to support the new theme.
* Update Konsist tests to ensure `@PreviewsDayNight` annotated functions don't have "BlackPreview" suffix.
This commit is contained in:
Timur Gilfanov 2026-03-23 15:26:16 +04:00
parent fdbe518db3
commit a96c146d30
23 changed files with 121 additions and 36 deletions

View file

@ -31,6 +31,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import io.element.android.compound.annotations.CoreColorToken
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.theme.Theme
import io.element.android.compound.tokens.generated.internal.DarkColorTokens
import io.element.android.compound.tokens.generated.internal.LightColorTokens
import io.element.android.libraries.designsystem.R
@ -50,7 +51,7 @@ fun SunsetPage(
) {
ElementTheme(
// Always use the opposite value of the current theme
darkTheme = ElementTheme.isLightTheme,
theme = if (ElementTheme.isLightTheme) Theme.Dark else Theme.Light,
applySystemBarsUpdate = false,
) {
Box(

View file

@ -19,6 +19,7 @@ import coil3.asImage
import coil3.compose.AsyncImagePreviewHandler
import coil3.compose.LocalAsyncImagePreviewHandler
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.theme.Theme
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.utils.CommonDrawables
@ -26,7 +27,7 @@ import io.element.android.libraries.designsystem.utils.CommonDrawables
@Composable
@Suppress("ModifierMissing")
fun ElementPreview(
darkTheme: Boolean = isSystemInDarkTheme(),
theme: Theme = if (isSystemInDarkTheme()) Theme.Dark else Theme.Light,
showBackground: Boolean = true,
@DrawableRes
drawableFallbackForImages: Int = CommonDrawables.sample_background,
@ -38,7 +39,7 @@ fun ElementPreview(
ResourcesCompat.getDrawable(context.resources, drawableFallbackForImages, null)!!.asImage()
}
) {
ElementTheme(darkTheme = darkTheme) {
ElementTheme(theme = theme) {
if (showBackground) {
// If we have a proper contentColor applied we need a Surface instead of a Box
Surface(content = content)

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2023-2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.designsystem.preview
import androidx.compose.runtime.Composable
import io.element.android.compound.theme.Theme
@Composable
fun ElementPreviewBlack(
showBackground: Boolean = true,
content: @Composable () -> Unit
) {
ElementPreview(
theme = Theme.Black,
showBackground = showBackground,
content = content
)
}

View file

@ -9,6 +9,7 @@
package io.element.android.libraries.designsystem.preview
import androidx.compose.runtime.Composable
import io.element.android.compound.theme.Theme
@Composable
fun ElementPreviewDark(
@ -16,7 +17,7 @@ fun ElementPreviewDark(
content: @Composable () -> Unit
) {
ElementPreview(
darkTheme = true,
theme = Theme.Dark,
showBackground = showBackground,
content = content
)

View file

@ -9,6 +9,7 @@
package io.element.android.libraries.designsystem.preview
import androidx.compose.runtime.Composable
import io.element.android.compound.theme.Theme
@Composable
fun ElementPreviewLight(
@ -16,7 +17,7 @@ fun ElementPreviewLight(
content: @Composable () -> Unit
) {
ElementPreview(
darkTheme = false,
theme = Theme.Light,
showBackground = showBackground,
content = content
)

View file

@ -21,6 +21,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.Theme
import io.element.android.libraries.designsystem.utils.CommonDrawables
@Composable
@ -40,14 +41,14 @@ fun ElementThemedPreview(
if (vertical) {
Column {
ElementPreview(
darkTheme = false,
theme = Theme.Light,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content,
)
Spacer(modifier = Modifier.height(4.dp))
ElementPreview(
darkTheme = true,
theme = Theme.Dark,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content
@ -56,14 +57,14 @@ fun ElementThemedPreview(
} else {
Row {
ElementPreview(
darkTheme = false,
theme = Theme.Light,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content,
)
Spacer(modifier = Modifier.width(4.dp))
ElementPreview(
darkTheme = true,
theme = Theme.Dark,
showBackground = showBackground,
drawableFallbackForImages = drawableFallbackForImages,
content = content

View file

@ -18,7 +18,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.theme.Theme
import io.element.android.compound.theme.isDark
import io.element.android.compound.theme.mapToTheme
import io.element.android.compound.tokens.generated.SemanticColors
import io.element.android.libraries.core.meta.BuildMeta
@ -68,7 +67,7 @@ fun ElementThemeApp(
when (theme) {
Theme.System -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
Theme.Light -> AppCompatDelegate.MODE_NIGHT_NO
Theme.Dark -> AppCompatDelegate.MODE_NIGHT_YES
Theme.Dark, Theme.Black -> AppCompatDelegate.MODE_NIGHT_YES
}
)
}
@ -76,7 +75,7 @@ fun ElementThemeApp(
LocalBuildMeta provides buildMeta,
) {
ElementTheme(
darkTheme = theme.isDark(),
theme = theme,
content = content,
compoundLight = compoundLight,
compoundDark = compoundDark,