Skip to content

Commit 3950113

Browse files
committed
library: android: Fix DynamicColors on Android 12-13
1 parent 9c6b8e0 commit 3950113

File tree

7 files changed

+172
-73
lines changed

7 files changed

+172
-73
lines changed

.idea/.name

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/ios/iosApp/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundleShortVersionString</key>
1818
<string>1.0.8</string>
1919
<key>CFBundleVersion</key>
20-
<string>839</string>
20+
<string>840</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>CADisableMinimumFrameDurationOnPhone</key>

example/shared/src/commonMain/kotlin/AboutPage.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ fun AboutPage(
168168
title = "View Source",
169169
endActions = {
170170
Text(
171-
modifier = Modifier.padding(end = 8.dp),
172171
text = "GitHub",
172+
fontSize = MiuixTheme.textStyles.body2.fontSize,
173173
color = colorScheme.onSurfaceVariantActions,
174174
)
175175
},
@@ -179,8 +179,8 @@ fun AboutPage(
179179
title = "Join Group",
180180
endActions = {
181181
Text(
182-
modifier = Modifier.padding(end = 8.dp),
183182
text = "Telegram",
183+
fontSize = MiuixTheme.textStyles.body2.fontSize,
184184
color = colorScheme.onSurfaceVariantActions,
185185
)
186186
},
@@ -196,8 +196,8 @@ fun AboutPage(
196196
title = "License",
197197
endActions = {
198198
Text(
199-
modifier = Modifier.padding(end = 8.dp),
200199
text = "Apache-2.0",
200+
fontSize = MiuixTheme.textStyles.body2.fontSize,
201201
color = colorScheme.onSurfaceVariantActions,
202202
)
203203
},

example/shared/src/commonMain/kotlin/component/TextComponent.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,17 @@ fun TextComponent(
189189
)
190190
},
191191
endActions = {
192-
Text(text = "End1")
192+
Text(
193+
text = "End1",
194+
fontSize = MiuixTheme.textStyles.body2.fontSize,
195+
color = MiuixTheme.colorScheme.onSurfaceVariantActions,
196+
)
193197
Spacer(Modifier.width(8.dp))
194-
Text(text = "End2")
198+
Text(
199+
text = "End2",
200+
fontSize = MiuixTheme.textStyles.body2.fontSize,
201+
color = MiuixTheme.colorScheme.onSurfaceVariantActions,
202+
)
195203
},
196204
enabled = true,
197205
)
@@ -207,11 +215,13 @@ fun TextComponent(
207215
endActions = {
208216
Text(
209217
text = "End1",
218+
fontSize = MiuixTheme.textStyles.body2.fontSize,
210219
color = MiuixTheme.colorScheme.disabledOnSecondaryVariant,
211220
)
212221
Spacer(Modifier.width(8.dp))
213222
Text(
214223
text = "End2",
224+
fontSize = MiuixTheme.textStyles.body2.fontSize,
215225
color = MiuixTheme.colorScheme.disabledOnSecondaryVariant,
216226
)
217227
},
@@ -260,6 +270,7 @@ fun TextComponent(
260270
endActions = {
261271
Text(
262272
text = superEndCheckbox.value,
273+
fontSize = MiuixTheme.textStyles.body2.fontSize,
263274
color = MiuixTheme.colorScheme.onSurfaceVariantActions,
264275
)
265276
},
@@ -378,6 +389,7 @@ fun TextComponent(
378389
endActions = {
379390
Text(
380391
text = "End",
392+
fontSize = MiuixTheme.textStyles.body2.fontSize,
381393
color = MiuixTheme.colorScheme.onSurfaceVariantActions,
382394
)
383395
},
@@ -388,6 +400,7 @@ fun TextComponent(
388400
endActions = {
389401
Text(
390402
text = "${(volume * 100).toInt()}%",
403+
fontSize = MiuixTheme.textStyles.body2.fontSize,
391404
color = MiuixTheme.colorScheme.onSurfaceVariantActions,
392405
)
393406
},
@@ -405,6 +418,7 @@ fun TextComponent(
405418
endActions = {
406419
Text(
407420
text = "End",
421+
fontSize = MiuixTheme.textStyles.body2.fontSize,
408422
color = MiuixTheme.colorScheme.disabledOnSecondaryVariant,
409423
)
410424
},

miuix/src/androidMain/kotlin/top/yukonga/miuix/kmp/theme/DynamicColors.android.kt

Lines changed: 135 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -125,65 +125,142 @@ private fun systemMd3Roles(context: Context, dark: Boolean): MonetRoles {
125125
val n1 = { idx: Int -> systemColor(context, resNeutral1(idx)) }
126126
val n2 = { idx: Int -> systemColor(context, resNeutral2(idx)) }
127127

128+
val isAtLeast34 = Build.VERSION.SDK_INT >= 34
129+
128130
return if (!dark) {
129-
MonetRoles(
130-
primary = a1(600),
131-
onPrimary = a1(0),
132-
primaryFixed = a1(200),
133-
onPrimaryFixed = a1(0),
134-
error = Color(0xFFB3261E),
135-
onError = Color(0xFFFFFFFF),
136-
errorContainer = Color(0xFFF9DEDC),
137-
onErrorContainer = Color(0xFF410E0B),
138-
primaryContainer = a1(100),
139-
onPrimaryContainer = a1(900),
140-
secondary = a2(600),
141-
onSecondary = a2(0),
142-
secondaryContainer = a2(100),
143-
onSecondaryContainer = a2(900),
144-
tertiaryContainer = a3(100),
145-
onTertiaryContainer = a3(900),
146-
background = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(100), 98.0) else n1(100),
147-
onBackground = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(100), 10.0) else n1(10),
148-
surface = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(100), 98.0) else n1(100),
149-
onSurface = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(100), 10.0) else n1(10),
150-
surfaceVariant = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(200), 90.0) else n2(200),
151-
surfaceContainer = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(100), 94.0) else n1(100),
152-
surfaceContainerHigh = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(100), 92.0) else n1(100),
153-
surfaceContainerHighest = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(100), 90.0) else n1(100),
154-
outline = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(200), 50.0) else n2(500),
155-
outlineVariant = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(200), 80.0) else n2(200),
156-
onSurfaceVariant = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(200), 30.0) else n2(700),
157-
)
131+
if (isAtLeast34) {
132+
MonetRoles(
133+
primary = a1(600),
134+
onPrimary = a1(0),
135+
primaryFixed = a1(200),
136+
onPrimaryFixed = a1(0),
137+
error = Color(0xFFB3261E),
138+
onError = Color(0xFFFFFFFF),
139+
errorContainer = Color(0xFFF9DEDC),
140+
onErrorContainer = Color(0xFF410E0B),
141+
primaryContainer = a1(100),
142+
onPrimaryContainer = a1(900),
143+
secondary = a2(600),
144+
onSecondary = a2(0),
145+
secondaryContainer = a2(100),
146+
onSecondaryContainer = a2(900),
147+
tertiaryContainer = a3(100),
148+
onTertiaryContainer = a3(900),
149+
background = toneFrom(n1(100), 98.0),
150+
onBackground = toneFrom(n1(100), 10.0),
151+
surface = toneFrom(n1(100), 98.0),
152+
onSurface = toneFrom(n1(100), 10.0),
153+
surfaceVariant = toneFrom(n2(200), 90.0),
154+
surfaceContainer = toneFrom(n1(100), 94.0),
155+
surfaceContainerHigh = toneFrom(n1(100), 92.0),
156+
surfaceContainerHighest = toneFrom(n1(100), 90.0),
157+
outline = toneFrom(n2(200), 50.0),
158+
outlineVariant = toneFrom(n2(200), 80.0),
159+
onSurfaceVariant = toneFrom(n2(200), 30.0),
160+
)
161+
} else {
162+
val neutralVariantBase = n2(600)
163+
val background = toneFrom(neutralVariantBase, 98.0)
164+
val surfaceContainer = toneFrom(neutralVariantBase, 94.0)
165+
val surfaceContainerHigh = toneFrom(neutralVariantBase, 92.0)
166+
val onBackground = n2(900)
167+
MonetRoles(
168+
primary = a1(600),
169+
onPrimary = a1(0),
170+
primaryFixed = a1(200),
171+
onPrimaryFixed = a1(0),
172+
error = Color(0xFFB3261E),
173+
onError = Color(0xFFFFFFFF),
174+
errorContainer = Color(0xFFF9DEDC),
175+
onErrorContainer = Color(0xFF410E0B),
176+
primaryContainer = a1(100),
177+
onPrimaryContainer = a1(900),
178+
secondary = a2(600),
179+
onSecondary = a2(0),
180+
secondaryContainer = a2(100),
181+
onSecondaryContainer = a2(900),
182+
tertiaryContainer = a3(100),
183+
onTertiaryContainer = a3(900),
184+
background = background,
185+
onBackground = onBackground,
186+
surface = background,
187+
onSurface = onBackground,
188+
surfaceVariant = n2(100),
189+
surfaceContainer = surfaceContainer,
190+
surfaceContainerHigh = surfaceContainerHigh,
191+
surfaceContainerHighest = n2(100),
192+
outline = n2(500),
193+
outlineVariant = n2(200),
194+
onSurfaceVariant = n2(700),
195+
)
196+
}
158197
} else {
159-
MonetRoles(
160-
primary = a1(200),
161-
onPrimary = a1(800),
162-
primaryFixed = a1(200),
163-
onPrimaryFixed = a1(800),
164-
error = Color(0xFFB3261E),
165-
onError = Color(0xFF690005),
166-
errorContainer = Color(0xFF8C1D18),
167-
onErrorContainer = Color(0xFFFFDAD4),
168-
primaryContainer = a1(700),
169-
onPrimaryContainer = a1(100),
170-
secondary = a2(200),
171-
onSecondary = a2(800),
172-
secondaryContainer = a2(700),
173-
onSecondaryContainer = a2(100),
174-
tertiaryContainer = a3(700),
175-
onTertiaryContainer = a3(100),
176-
background = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(10), 6.0) else n1(10),
177-
onBackground = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(10), 90.0) else n1(90),
178-
surface = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(10), 6.0) else n1(10),
179-
onSurface = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(10), 90.0) else n1(90),
180-
surfaceVariant = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(700), 30.0) else n2(700),
181-
surfaceContainer = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(10), 12.0) else n1(10),
182-
surfaceContainerHigh = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(10), 17.0) else n1(10),
183-
surfaceContainerHighest = if (Build.VERSION.SDK_INT >= 34) toneFrom(n1(10), 22.0) else n1(10),
184-
outline = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(700), 60.0) else n2(500),
185-
outlineVariant = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(700), 30.0) else n2(700),
186-
onSurfaceVariant = if (Build.VERSION.SDK_INT >= 34) toneFrom(n2(700), 80.0) else n2(200),
187-
)
198+
if (isAtLeast34) {
199+
MonetRoles(
200+
primary = a1(200),
201+
onPrimary = a1(800),
202+
primaryFixed = a1(200),
203+
onPrimaryFixed = a1(800),
204+
error = Color(0xFFB3261E),
205+
onError = Color(0xFF690005),
206+
errorContainer = Color(0xFF8C1D18),
207+
onErrorContainer = Color(0xFFFFDAD4),
208+
primaryContainer = a1(700),
209+
onPrimaryContainer = a1(100),
210+
secondary = a2(200),
211+
onSecondary = a2(800),
212+
secondaryContainer = a2(700),
213+
onSecondaryContainer = a2(100),
214+
tertiaryContainer = a3(700),
215+
onTertiaryContainer = a3(100),
216+
background = toneFrom(n1(10), 6.0),
217+
onBackground = toneFrom(n1(10), 90.0),
218+
surface = toneFrom(n1(10), 6.0),
219+
onSurface = toneFrom(n1(10), 90.0),
220+
surfaceVariant = toneFrom(n2(700), 30.0),
221+
surfaceContainer = toneFrom(n1(10), 12.0),
222+
surfaceContainerHigh = toneFrom(n1(10), 17.0),
223+
surfaceContainerHighest = toneFrom(n1(10), 22.0),
224+
outline = toneFrom(n2(700), 60.0),
225+
outlineVariant = toneFrom(n2(700), 30.0),
226+
onSurfaceVariant = toneFrom(n2(700), 80.0),
227+
)
228+
} else {
229+
val neutralVariantBase = n2(600)
230+
val background = toneFrom(neutralVariantBase, 6.0)
231+
val surfaceContainer = toneFrom(neutralVariantBase, 12.0)
232+
val surfaceContainerHigh = toneFrom(neutralVariantBase, 17.0)
233+
val surfaceContainerHighest = toneFrom(neutralVariantBase, 22.0)
234+
val onBackground = n2(100)
235+
MonetRoles(
236+
primary = a1(200),
237+
onPrimary = a1(800),
238+
primaryFixed = a1(200),
239+
onPrimaryFixed = a1(800),
240+
error = Color(0xFFB3261E),
241+
onError = Color(0xFF690005),
242+
errorContainer = Color(0xFF8C1D18),
243+
onErrorContainer = Color(0xFFFFDAD4),
244+
primaryContainer = a1(700),
245+
onPrimaryContainer = a1(100),
246+
secondary = a2(200),
247+
onSecondary = a2(800),
248+
secondaryContainer = a2(700),
249+
onSecondaryContainer = a2(100),
250+
tertiaryContainer = a3(700),
251+
onTertiaryContainer = a3(100),
252+
background = background,
253+
onBackground = onBackground,
254+
surface = background,
255+
onSurface = onBackground,
256+
surfaceVariant = n2(700),
257+
surfaceContainer = surfaceContainer,
258+
surfaceContainerHigh = surfaceContainerHigh,
259+
surfaceContainerHighest = surfaceContainerHighest,
260+
outline = n2(400),
261+
outlineVariant = n2(700),
262+
onSurfaceVariant = n2(200),
263+
)
264+
}
188265
}
189266
}

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/theme/ThemeController.kt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,25 @@ enum class ColorSchemeMode {
3030
}
3131

3232
@Stable
33-
internal fun colorsFromSeed(seed: Color, dark: Boolean): Colors {
33+
internal fun colorsFromSeed(
34+
seed: Color,
35+
colorSpec: ColorSpec.SpecVersion,
36+
dark: Boolean,
37+
): Colors {
3438
val hctColor = Hct.fromInt(seed.toArgb())
3539
val tonalSpot = SchemeTonalSpot(
3640
sourceColorHct = hctColor,
3741
isDark = dark,
3842
contrastLevel = 0.0,
39-
specVersion = ColorSpec.SpecVersion.SPEC_2025,
43+
specVersion = colorSpec,
4044
platform = DynamicScheme.Platform.PHONE,
4145
)
4246
val colors = DynamicScheme(
4347
sourceColorHct = hctColor,
4448
variant = Variant.TONAL_SPOT,
4549
isDark = dark,
4650
contrastLevel = 0.0,
47-
specVersion = ColorSpec.SpecVersion.SPEC_2025,
51+
specVersion = colorSpec,
4852
platform = DynamicScheme.Platform.PHONE,
4953
primaryPalette = tonalSpot.primaryPalette,
5054
secondaryPalette = tonalSpot.secondaryPalette,
@@ -86,7 +90,7 @@ internal fun colorsFromSeed(seed: Color, dark: Boolean): Colors {
8690
}
8791

8892
@Stable
89-
internal fun monetSystemColors(dark: Boolean): Colors = colorsFromSeed(seed = Color(0xFF6750A4), dark = dark)
93+
internal fun monetSystemColors(dark: Boolean): Colors = colorsFromSeed(seed = Color(0xFF6750A4), colorSpec = ColorSpec.SpecVersion.SPEC_2021, dark = dark)
9094

9195
/**
9296
* A controller for managing the current color scheme of the Miuix theme.
@@ -102,6 +106,8 @@ internal fun monetSystemColors(dark: Boolean): Colors = colorsFromSeed(seed = Co
102106
* dark theme is selected.
103107
* @param keyColor The key color for generating dynamic color schemes. This is used when the
104108
* [colorSchemeMode] is set to a Monet mode.
109+
* @param colorSpec The color specification version to use when generating dynamic color schemes. This
110+
* is used when the [colorSchemeMode] is set to a Monet mode.
105111
* @param isDark Whether the system is in dark mode. This is used when the [colorSchemeMode] is
106112
* set to a System or MonetSystem mode and the dark mode is not explicitly specified.
107113
*/
@@ -111,12 +117,14 @@ class ThemeController(
111117
lightColors: Colors = lightColorScheme(),
112118
darkColors: Colors = darkColorScheme(),
113119
keyColor: Color? = null,
120+
colorSpec: ColorSpec.SpecVersion = ColorSpec.SpecVersion.SPEC_2021,
114121
isDark: Boolean? = null,
115122
) {
116123
val colorSchemeMode: ColorSchemeMode by mutableStateOf(colorSchemeMode)
117124
val lightColors: Colors by mutableStateOf(lightColors)
118125
val darkColors: Colors by mutableStateOf(darkColors)
119126
val keyColor: Color? by mutableStateOf(keyColor)
127+
val colorSpec: ColorSpec.SpecVersion by mutableStateOf(colorSpec)
120128
val isDark: Boolean? by mutableStateOf(isDark)
121129

122130
@Composable
@@ -133,19 +141,19 @@ class ThemeController(
133141
ColorSchemeMode.MonetSystem -> {
134142
val dark = isDark ?: isSystemInDarkTheme()
135143
keyColor?.let {
136-
remember(keyColor, dark) { colorsFromSeed(seed = it, dark = dark) }
144+
remember(keyColor, dark) { colorsFromSeed(seed = it, colorSpec = colorSpec, dark = dark) }
137145
} ?: platformDynamicColors(dark = dark)
138146
}
139147

140148
ColorSchemeMode.MonetLight -> {
141149
keyColor?.let {
142-
remember(keyColor) { colorsFromSeed(seed = it, dark = false) }
150+
remember(keyColor) { colorsFromSeed(seed = it, colorSpec = colorSpec, dark = false) }
143151
} ?: platformDynamicColors(dark = false)
144152
}
145153

146154
ColorSchemeMode.MonetDark -> {
147155
keyColor?.let {
148-
remember(keyColor) { colorsFromSeed(seed = it, dark = true) }
156+
remember(keyColor) { colorsFromSeed(seed = it, colorSpec = colorSpec, dark = true) }
149157
} ?: platformDynamicColors(dark = true)
150158
}
151159
}

0 commit comments

Comments
 (0)