Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/src/commonMain/kotlin/FourthPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ fun FourthPage(
}
val floatingToolbarOrientationOptions = remember { listOf("Horizontal", "Vertical") }
val fabPositionOptions = remember { listOf("Start", "Center", "End", "EndOverlay") }
val colorModeOptions = remember { listOf("System", "Light", "Dark") }
val colorModeOptions = remember { listOf("System", "Light", "Dark", "DynamicSystem", "DynamicLight", "DynamicDark") }

LazyColumn(
modifier = Modifier
Expand Down
35 changes: 33 additions & 2 deletions example/src/commonMain/kotlin/ThirdPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.theme.Colors
import top.yukonga.miuix.kmp.theme.darkColorScheme
import top.yukonga.miuix.kmp.theme.lightColorScheme
import top.yukonga.miuix.kmp.theme.material3StaticColors
import top.yukonga.miuix.kmp.theme.platformDynamicColors
import top.yukonga.miuix.kmp.utils.overScrollVertical
import top.yukonga.miuix.kmp.utils.scrollEndHaptic

Expand Down Expand Up @@ -62,16 +64,40 @@ fun ThirdPage(
ColorsPreview(lightColorScheme())
}
}
item(key = "dynamic_light") {
SmallTitle("Dynamic Light Colors")
val dynLight = platformDynamicColors(dark = false)
Card(
modifier = Modifier.padding(horizontal = 12.dp).padding(bottom = 12.dp),
colors = CardDefaults.defaultColors(color = (dynLight ?: lightColorScheme()).surface),
cornerRadius = 16.dp,
insideMargin = PaddingValues(horizontal = 16.dp)
) {
if (dynLight != null) ColorsPreview(dynLight) else ColorsPreview((material3StaticColors(dark = false)))
}
}
item(key = "dark") {
SmallTitle("Dark Theme Colors")
Card(
modifier = Modifier.padding(horizontal = 12.dp),
modifier = Modifier.padding(horizontal = 12.dp).padding(bottom = 12.dp),
colors = CardDefaults.defaultColors(color = darkColorScheme().surface),
cornerRadius = 16.dp,
insideMargin = PaddingValues(horizontal = 16.dp)
) {
ColorsPreview(darkColorScheme())
}
}
item(key = "dynamic_dark") {
SmallTitle("Dynamic Dark Colors")
val dynDark = platformDynamicColors(dark = true)
Card(
modifier = Modifier.padding(horizontal = 12.dp),
colors = CardDefaults.defaultColors(color = (dynDark ?: darkColorScheme()).surface),
cornerRadius = 16.dp,
insideMargin = PaddingValues(horizontal = 16.dp)
) {
if (dynDark != null) ColorsPreview(dynDark) else ColorsPreview((material3StaticColors(dark = true)))
}
Spacer(modifier = Modifier.height(12.dp + padding.calculateBottomPadding()))
}
}
Expand All @@ -84,6 +110,10 @@ fun ColorsPreview(colors: Colors) {
"onPrimary" to colors.onPrimary,
"primaryVariant" to colors.primaryVariant,
"onPrimaryVariant" to colors.onPrimaryVariant,
"error" to colors.error,
"onError" to colors.onError,
"errorContainer" to colors.errorContainer,
"onErrorContainer" to colors.onErrorContainer,
"disabledPrimary" to colors.disabledPrimary,
"disabledOnPrimary" to colors.disabledOnPrimary,
"disabledPrimaryButton" to colors.disabledPrimaryButton,
Expand Down Expand Up @@ -118,6 +148,8 @@ fun ColorsPreview(colors: Colors) {
"disabledOnSurface" to colors.disabledOnSurface,
"outline" to colors.outline,
"dividerLine" to colors.dividerLine,
"sliderKeyPoint" to colors.sliderKeyPoint,
"sliderKeyPointForeground" to colors.sliderKeyPointForeground,
"surfaceContainer" to colors.surfaceContainer,
"onSurfaceContainer" to colors.onSurfaceContainer,
"onSurfaceContainerVariant" to colors.onSurfaceContainerVariant,
Expand Down Expand Up @@ -185,4 +217,3 @@ private fun ColorBlock(name: String, surfaceColor: Color, textColor: Color, modi
}
}
}

17 changes: 9 additions & 8 deletions example/src/commonMain/kotlin/ui/Theme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@

package ui

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import top.yukonga.miuix.kmp.theme.ColorSchemeMode
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.theme.darkColorScheme
import top.yukonga.miuix.kmp.theme.lightColorScheme
import top.yukonga.miuix.kmp.theme.ThemeController

@Composable
fun AppTheme(
colorMode: Int = 0,
content: @Composable () -> Unit
) {
val darkTheme = isSystemInDarkTheme()
return MiuixTheme(
colors = when (colorMode) {
1 -> lightColorScheme()
2 -> darkColorScheme()
else -> if (darkTheme) darkColorScheme() else lightColorScheme()
controller = when (colorMode) {
1 -> ThemeController(ColorSchemeMode.Light)
2 -> ThemeController(ColorSchemeMode.Dark)
3 -> ThemeController(ColorSchemeMode.DynamicSystem)
4 -> ThemeController(ColorSchemeMode.DynamicLight)
5 -> ThemeController(ColorSchemeMode.DynamicDark)
else -> ThemeController(ColorSchemeMode.System)
},
content = content
)
Expand Down
2 changes: 1 addition & 1 deletion iosApp/iosApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundleShortVersionString</key>
<string>1.0.6</string>
<key>CFBundleVersion</key>
<string>610</string>
<string>611</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
Expand Down
1 change: 1 addition & 0 deletions miuix/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ kotlin {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.ui)
implementation(compose.material3)

implementation(libs.jetbrains.compose.ui.backhandler)
implementation(libs.jetbrains.compose.window.size)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2025, compose-miuix-ui contributors
// SPDX-License-Identifier: Apache-2.0
package top.yukonga.miuix.kmp.theme

import android.os.Build
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.graphics.Color

@Composable
actual fun platformDynamicColors(dark: Boolean): Colors? {
val context = LocalContext.current
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return null
val cs: ColorScheme = try {
if (dark) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
} catch (_: Throwable) {
return null
}
return mapMd3ToMiuixColorsCommon(cs, dark)
}
Original file line number Diff line number Diff line change
Expand Up @@ -1109,8 +1109,8 @@ object SliderDefaults {
foregroundColor: Color = MiuixTheme.colorScheme.primary,
disabledForegroundColor: Color = MiuixTheme.colorScheme.disabledPrimarySlider,
backgroundColor: Color = MiuixTheme.colorScheme.secondaryVariant,
keyPointColor: Color = Color(0x4DA3B3CD),
keyPointForegroundColor: Color = Color(0xFF6EB5FF),
keyPointColor: Color = MiuixTheme.colorScheme.sliderKeyPoint,
keyPointForegroundColor: Color = MiuixTheme.colorScheme.sliderKeyPointForeground,
): SliderColors = SliderColors(
foregroundColor = foregroundColor,
disabledForegroundColor = disabledForegroundColor,
Expand Down Expand Up @@ -1140,4 +1140,4 @@ class SliderColors(

@Stable
internal fun keyPointForegroundColor(): Color = keyPointForegroundColor
}
}
60 changes: 60 additions & 0 deletions miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/theme/Colors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class Colors(
onPrimary: Color,
primaryVariant: Color,
onPrimaryVariant: Color,
error: Color,
onError: Color,
errorContainer: Color,
onErrorContainer: Color,
disabledPrimary: Color,
disabledOnPrimary: Color,
disabledPrimaryButton: Color,
Expand Down Expand Up @@ -111,6 +115,8 @@ class Colors(
surfaceContainerHighest: Color,
onSurfaceContainerHighest: Color,
windowDimming: Color,
sliderKeyPoint: Color,
sliderKeyPointForeground: Color,
) {
var primary by mutableStateOf(primary, structuralEqualityPolicy())
internal set
Expand All @@ -120,6 +126,14 @@ class Colors(
internal set
var onPrimaryVariant by mutableStateOf(onPrimaryVariant, structuralEqualityPolicy())
internal set
var error by mutableStateOf(error, structuralEqualityPolicy())
internal set
var onError by mutableStateOf(onError, structuralEqualityPolicy())
internal set
var errorContainer by mutableStateOf(errorContainer, structuralEqualityPolicy())
internal set
var onErrorContainer by mutableStateOf(onErrorContainer, structuralEqualityPolicy())
internal set
var disabledPrimary by mutableStateOf(disabledPrimary, structuralEqualityPolicy())
internal set
var disabledOnPrimary by mutableStateOf(disabledOnPrimary, structuralEqualityPolicy())
Expand Down Expand Up @@ -204,12 +218,20 @@ class Colors(
internal set
var windowDimming by mutableStateOf(windowDimming, structuralEqualityPolicy())
internal set
var sliderKeyPoint by mutableStateOf(sliderKeyPoint, structuralEqualityPolicy())
internal set
var sliderKeyPointForeground by mutableStateOf(sliderKeyPointForeground, structuralEqualityPolicy())
internal set

fun copy(
primary: Color = this.primary,
onPrimary: Color = this.onPrimary,
primaryVariant: Color = this.primaryVariant,
onPrimaryVariant: Color = this.onPrimaryVariant,
error: Color = this.error,
onError: Color = this.onError,
errorContainer: Color = this.errorContainer,
onErrorContainer: Color = this.onErrorContainer,
disabledPrimary: Color = this.disabledPrimary,
disabledOnPrimary: Color = this.disabledOnPrimary,
disabledPrimaryButton: Color = this.disabledPrimaryButton,
Expand Down Expand Up @@ -252,12 +274,18 @@ class Colors(
surfaceContainerHighest: Color = this.surfaceContainerHighest,
onSurfaceContainerHighest: Color = this.onSurfaceContainerHighest,
windowDimming: Color = this.windowDimming,
sliderKeyPoint: Color = this.sliderKeyPoint,
sliderKeyPointForeground: Color = this.sliderKeyPointForeground,
): Colors =
Colors(
primary,
onPrimary,
primaryVariant,
onPrimaryVariant,
error,
onError,
errorContainer,
onErrorContainer,
disabledPrimary,
disabledOnPrimary,
disabledPrimaryButton,
Expand Down Expand Up @@ -300,6 +328,8 @@ class Colors(
surfaceContainerHighest,
onSurfaceContainerHighest,
windowDimming,
sliderKeyPoint,
sliderKeyPointForeground,
)
}

Expand All @@ -308,6 +338,10 @@ fun lightColorScheme(
onPrimary: Color = Color.White,
primaryVariant: Color = Color(0xFF3482FF),
onPrimaryVariant: Color = Color(0xFFAECDFF),
error: Color = Color(0xFFBA1A1A),
onError: Color = Color(0xFFFFFFFF),
errorContainer: Color = Color(0xFFFFDAD6),
onErrorContainer: Color = Color(0xFF410002),
disabledPrimary: Color = Color(0xFFC2D9FF),
disabledOnPrimary: Color = Color(0xFFF3F8FF),
disabledPrimaryButton: Color = Color(0xFFC2D9FF),
Expand Down Expand Up @@ -350,12 +384,18 @@ fun lightColorScheme(
surfaceContainerHighest: Color = Color(0xFFE8E8E8),
onSurfaceContainerHighest: Color = Color.Black,
windowDimming: Color = Color.Black.copy(alpha = 0.3F),
sliderKeyPoint: Color = Color(0x4DA3B3CD),
sliderKeyPointForeground: Color = Color(0xFF6EB5FF),
): Colors =
Colors(
primary,
onPrimary,
primaryVariant,
onPrimaryVariant,
error,
onError,
errorContainer,
onErrorContainer,
disabledPrimary,
disabledOnPrimary,
disabledPrimaryButton,
Expand Down Expand Up @@ -398,13 +438,19 @@ fun lightColorScheme(
surfaceContainerHighest,
onSurfaceContainerHighest,
windowDimming,
sliderKeyPoint,
sliderKeyPointForeground,
)

fun darkColorScheme(
primary: Color = Color(0xFF277AF7),
onPrimary: Color = Color.White,
primaryVariant: Color = Color(0xFF0073DD),
onPrimaryVariant: Color = Color(0xFF99C7F1),
error: Color = Color(0xFFFFB4AB),
onError: Color = Color(0xFF690005),
errorContainer: Color = Color(0xFF93000A),
onErrorContainer: Color = Color(0xFFFFDAD6),
disabledPrimary: Color = Color(0xFF253E64),
disabledOnPrimary: Color = Color(0xFF677993),
disabledPrimaryButton: Color = Color(0xFF253E64),
Expand Down Expand Up @@ -447,12 +493,18 @@ fun darkColorScheme(
surfaceContainerHighest: Color = Color(0xFF2D2D2D),
onSurfaceContainerHighest: Color = Color(0xFFE9E9E9),
windowDimming: Color = Color.Black.copy(alpha = 0.6F),
sliderKeyPoint: Color = Color(0x4D7A8AA6),
sliderKeyPointForeground: Color = Color(0xFF5DAAFF),
): Colors =
Colors(
primary,
onPrimary,
primaryVariant,
onPrimaryVariant,
error,
onError,
errorContainer,
onErrorContainer,
disabledPrimary,
disabledOnPrimary,
disabledPrimaryButton,
Expand Down Expand Up @@ -495,6 +547,8 @@ fun darkColorScheme(
surfaceContainerHighest,
onSurfaceContainerHighest,
windowDimming,
sliderKeyPoint,
sliderKeyPointForeground,
)

@Stable
Expand All @@ -503,6 +557,10 @@ internal fun Colors.updateColorsFrom(other: Colors) {
onPrimary = other.onPrimary
primaryVariant = other.primaryVariant
onPrimaryVariant = other.onPrimaryVariant
error = other.error
onError = other.onError
errorContainer = other.errorContainer
onErrorContainer = other.onErrorContainer
disabledPrimary = other.disabledPrimary
disabledOnPrimary = other.disabledOnPrimary
disabledPrimaryButton = other.disabledPrimaryButton
Expand Down Expand Up @@ -545,6 +603,8 @@ internal fun Colors.updateColorsFrom(other: Colors) {
surfaceContainerHighest = other.surfaceContainerHighest
onSurfaceContainerHighest = other.onSurfaceContainerHighest
windowDimming = other.windowDimming
sliderKeyPoint = other.sliderKeyPoint
sliderKeyPointForeground = other.sliderKeyPointForeground
}

internal val LocalColors = staticCompositionLocalOf { lightColorScheme() }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright 2025, compose-miuix-ui contributors
// SPDX-License-Identifier: Apache-2.0
package top.yukonga.miuix.kmp.theme

import androidx.compose.runtime.Composable

@Composable
expect fun platformDynamicColors(dark: Boolean): Colors?
Loading
Loading