A Compose Multiplatform library for creating dynamic Material Design 3 color palettes from any color.
Check out MaterialKolor Builder to see MaterialKolor in action and generate your own color schemes. It can export to MaterialKolor code, or plain Material 3 code.
The KDoc is published at docs.materialkolor.com
This library is written for Compose Multiplatform, and can be used on the following platforms:
- Android
- iOS
- JVM (Desktop)
- JavaScript/wasm (Browser)
You can see it in action by using MaterialKolor Builder.
The heart of this library comes from the material-color-utilities repository. It is currently only a Java library, and I wanted to make it available to Kotlin Multiplatform projects. The source code was taken and converted into a Kotlin Multiplatform library.
I also incorporated the Compose ideas from another open source library m3color.
You can add this library to your project using Gradle.
To add to a multiplatform project, add the dependency to the common source-set:
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("com.materialkolor:material-kolor:3.0.0-beta07")
}
}
}
}
For an Android only project, add the dependency to app level build.gradle.kts
:
dependencies {
implementation("com.materialkolor:material-kolor:3.0.0-beta07")
}
[versions]
materialKolor = "3.0.0-beta07"
[libraries]
materialKolor = { module = "com.materialkolor:material-kolor", version.ref = "materialKolor" }
If you don't use Compose and don't need any of the extension functions provided by material-kolor
,
you can use the material-color-utilities
artifact instead.
It is a Kotlin Multiplatform port of
Google's Material Color Utilities.
[versions]
materialKolor = "3.0.0-beta07"
[libraries]
materialKolor-utilities = { module = "com.materialkolor:material-color-utilities", version.ref = "materialKolor" }
To generate a custom ColorScheme
you simply need to call dynamicColorScheme()
with your target
seed color:
@Composable
fun MyTheme(
seedColor: Color,
isDark: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = rememberDynamicColorScheme(seedColor = seedColor, isDark = isDark)
MaterialTheme(
colors = colorScheme,
content = content,
)
}
You can also pass in
a PaletteStyle
to
customize the generated palette:
dynamicColorScheme(
seedColor = seedColor,
isDark = isDark,
style = PaletteStyle.Expressive,
)
With the release of Material3 Expressive, Google has added a new color spec used when generating
colors. By default MaterialKolor uses the SPEC_2021
version. If you want to try out the new colors
you will need to use ColorSpec.SpecVersion.SPEC_2025
:
val scheme = rememberDynamicColorScheme(
seedColor = seedColor,
isDark = isDark,
specVersion = ColorSpec.SpecVersion.SPEC_2025,
style = PaletteStyle.Expressive, // Optional but recommended if you are using `MaterialExpressiveTheme`
)
A DynamicMaterialTheme
Composable is also available. It is a wrapper around MaterialTheme
that
uses dynamicColorScheme()
to generate a ColorScheme
for you. You can animate the color scheme by
passing in animate = true
.
Example:
@Composable
fun MyTheme(
seedColor: Color,
isDark: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
DynamicMaterialTheme(
seedColor = seedColor,
isDark = isDark,
animate = true,
content = content,
)
}
For more vibrant and playful themes, use DynamicMaterialExpressiveTheme
. This composable is
designed
for the Material 3 Expressive design system and defaults to using PaletteStyle.Expressive
and
ColorSpec.SpecVersion.SPEC_2025
for optimal color generation.
Important: Make sure to use SPEC_2025
and PaletteStyle.Expressive
for the best results:
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun MyExpressiveTheme(
seedColor: Color,
isDark: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
DynamicMaterialExpressiveTheme(
seedColor = seedColor,
motionScheme = MotionScheme.expressive(),
isDark = isDark,
animate = true,
content = content,
)
}
The Expressive theme generates vibrant color schemes where the source color's hue may not directly appear in the final theme, creating more dynamic and playful color palettes.
Included in the library are some extensions for working with colors. You can check out the /ktx package for more information.
But here are a couple useful examples:
If you want to harmonize a color with another you can use the Color.harmonize()
function. You can
read more about color harmonization on
the Material 3 Documentation.
Example:
val newColor = MaterialTheme.colorScheme.primary.harmonize(Color.Blue)
There is an additional function specifically for harmonizing with the primary color:
val newColor = Color.Blue.harmonizeWithPrimary()
Note: Color.harmonize()
has an optional parameter matchSaturation
which when set to true
will adjust the saturation from the other color.
You can lighten or darken a color using the Color.lighten()
and Color.darken()
functions.
For example:
val newColor = MaterialTheme.colorScheme.primary.lighten(0.2f)
Check out the demo app for a full example.
You can determine if a Color
is warm or cold using the following:
val isWarm = MaterialTheme.colorScheme.primary.isWarm()
val isCold = MaterialTheme.colorScheme.primary.isCold()
You can calculate a seed color, or colors that are suitable for UI theming from an image. This is useful for generating a color scheme from a user's profile picture, or a background image.
To do so you can call ImageBitmap.themeColors()
, ImageBitmap.themeColor()
or the @Composable
function rememberThemeColors()
or rememberThemeColor()
:
fun calculateSeedColor(bitmap: ImageBitmap): Color {
val suitableColors = bitmap.themeColors(fallback = Color.Blue)
return suitableColors.first()
}
See ImageBitmap.kt
for more information.
Or in Compose land:
@Composable
fun DynamicTheme(image: ImageBitmap, content: @Composable () -> Unit) {
val seedColor = rememberThemeColor(image, fallback = MaterialTheme.colorScheme.primary)
DynamicMaterialTheme(
seedColor = seedColor,
content = content
)
}
Note: This approach can be pretty slow, so I wouldn't really recommend using it in your UI unless you are eagerly loading the colors.
The module material-color-utilities
is licensed under the Apache License, Version 2.0. See
their LICENSE and their
repository here for more
information.
- Convert Java code to Kotlin
- Convert library to Kotlin Multiplatform
For the remaining code see LICENSE for more information.