8000 GitHub - jordond/MaterialKolor: 🎨 Generate a dynamic Material3 color sheme from a seed color
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

jordond/MaterialKolor

Repository files navigation

logo


Maven Central Kotlin Build License

Compose Multiplatform badge-android badge-ios badge-desktop badge-js

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

Table of Contents

Platforms

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.

Inspiration

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.

Setup

You can add this library to your project using Gradle.

Multiplatform

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")
            }
        }
    }
}

Single Platform

For an Android only project, add the dependency to app level build.gradle.kts:

dependencies {
  implementation("com.materialkolor:material-kolor:3.0.0-beta07")
}

Version Catalog

[versions]
materialKolor = "3.0.0-beta07"

[libraries]
materialKolor = { module = "com.materialkolor:material-kolor", version.ref = "materialKolor" }

Without compose

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" }

Usage

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,
)

Updated Colors

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`
)

DynamicMaterialTheme

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,
    )
}

DynamicMaterialExpressiveTheme

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.

Extensions

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:

Harmonize Colors

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.

Lighten and Darken

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.

Color Temperature

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()

Generating from an Image

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.

License

The module material-color-utilities is licensed under the Apache License, Version 2.0. See their LICENSE and their repository here for more information.

Changes from original source

  • Convert Java code to Kotlin
  • Convert library to Kotlin Multiplatform

For the remaining code see LICENSE for more information.

Contributors 4

  •  
  •  
  •  
  •  

Languages

0