MFlisar/ComposeThemer

User Defined Compose Theme for Android - Material3 Design

โ˜… 10Forks 0KotlinGitHub โ†—Compare

Project website โ†—

README

Maven Central API Kotlin Kotlin Multiplatform

ComposeThemer

Platforms Android iOS Windows macOS WebAssembly

This library provides following main features:

  • allows to define custom user themes and applies them automatically
  • ability to retrieve all registered themes
  • supports system ui theming (status bar + navigation bar)
  • build on top of MaterialTheme
  • supports dynamic theming as well as system and user contrast settings
  • comes with optional collections of predefined themes
    • metro colors based theme collection
    • flat UI based theme collection
    • material 500 colors based theme collection
  • offers some edgeToEdge helper functions

Note

All features are splitted into separate modules, just include the modules you want to use!

Table of Contents

๐Ÿ“ท Screenshots

defaultpicker

android1 android2 android3
android4 desktop1 desktop2
desktop3 desktop4 desktop5

๐Ÿ’ป Supported Platforms

Module android iOS windows macOS wasm Notes
core โœ… โœ… โœ… โœ… โœ… provides all the basic ComposeThemer classes to use and apply Themes
modules-picker โœ… โœ… โœ… โœ… โœ… provides states and composables to create a theme picker UI
modules-defaultpicker โœ… โœ… โœ… โœ… โœ… provides a default theme picker UI
themes-flatui โœ… โœ… โœ… โœ… โœ… provides a list of themes based on the 20 flatui colors (each one in 5 variations)
themes-material500 โœ… โœ… โœ… โœ… โœ… provides a list of themes based on the 19 material500 colors (each one in 5 variations)
themes-metro โœ… โœ… โœ… โœ… โœ… provides a list of themes based on the 20 metro colors (each one in 5 variations)

โžก๏ธ Versions

Dependency Version
Kotlin 2.4.0
Jetbrains Compose 1.11.1
Jetbrains Compose Material3 1.9.0

๐Ÿ”ง Setup

Using Version Catalogs

Define the dependencies inside your libs.versions.toml file.

[versions]

composethemer = "<LATEST-VERSION>"

[libraries]

composethemer-core = { module = "io.github.mflisar.composethemer:core", version.ref = "composethemer" }
composethemer-modules-picker = { module = "io.github.mflisar.composethemer:modules-picker", version.ref = "composethemer" }
composethemer-modules-defaultpicker = { module = "io.github.mflisar.composethemer:modules-defaultpicker", version.ref = "composethemer" }
composethemer-themes-flatui = { module = "io.github.mflisar.composethemer:themes-flatui", version.ref = "composethemer" }
composethemer-themes-material500 = { module = "io.github.mflisar.composethemer:themes-material500", version.ref = "composethemer" }
composethemer-themes-metro = { module = "io.github.mflisar.composethemer:themes-metro", version.ref = "composethemer" }

And then use the definitions in your projects build.gradle.kts file like following:

implementation(libs.composethemer.core)
implementation(libs.composethemer.modules.picker)
implementation(libs.composethemer.modules.defaultpicker)
implementation(libs.composethemer.themes.flatui)
implementation(libs.composethemer.themes.material500)
implementation(libs.composethemer.themes.metro)
Direct Dependency Notation

Simply add the dependencies inside your build.gradle.kts file.

val composethemer = "<LATEST-VERSION>"

implementation("io.github.mflisar.composethemer:core:${composethemer}")
implementation("io.github.mflisar.composethemer:modules-picker:${composethemer}")
implementation("io.github.mflisar.composethemer:modules-defaultpicker:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-flatui:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-material500:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-metro:${composethemer}")

๐Ÿš€ Usage

1) Register available themes

You should do this once only, e.g. in your Application class.

// register all themes that you want to use (our just a subset of them, even a single one is enough)
val allThemes: List<ComposeTheme.Theme> =
    DefaultThemes.getAllThemes() +
            MetroThemes.getAllThemes() +
            FlatUIThemes.getAllThemes() +
            Material500Themes.getAllThemes()
ComposeTheme.register(*allThemes.toTypedArray())

2) Apply the theme

// create a state that holds the current theme settings
val baseTheme = rememberSaveable { mutableStateOf(ComposeTheme.BaseTheme.System) }
val contrast = rememberSaveable { mutableStateOf(ComposeTheme.Contrast.Normal) }
val dynamic = rememberSaveable { mutableStateOf(false) }
val theme = rememberSaveable { mutableStateOf(ThemeDefault.Theme.id) } // id of the current theme
val state = ComposeTheme.State(baseTheme, contrast, dynamic, theme)

// use ComposeTheme instead of MaterialTheme
ComposeTheme(state = state) {
    // app content
}

3) Navigation and statusbar theming

On android you can use ComposeTheme to set the status bar and navigation bar colors based on the current theme.

ComposeTheme(
    state = state
) {
    // set the color that you use behind the status bar and navigation bar (e.g. primary toolbar + surface bottom navigation)
    val statusBarColor = ...
    val navigationBarColor = ...

    // UpdateEdgeToEdgeDefault...helper function to easily enable edgeToEdge
    // SystemBarStyle also offers some extensions (statusBar, navigationBar, transparent) that can be used

    // this app draws a bottom navigation behind the navigation bar in portrait only, in landscape mode it doesn't
    val landscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE
    val isDark = state.base.value.isDark()

    UpdateEdgeToEdgeDefault(
        activity = this,
        themeState = state,
        statusBarColor = statusBarColor,
        navigationBarColor = if (landscape) {
            SystemBarStyle.defaultScrim(resources, isDark)
        } else navigationBarColor,
        isNavigationBarContrastEnforced = landscape
    )
}

๐Ÿ“ Modules

โœจ Demo

A full demo is included inside the demo module, it shows nearly every usage with working examples.

โ„น๏ธ More

๐Ÿ“š API

Check out the API documentation.

๐Ÿ’ก Other Libraries

You can find more libraries (all multiplatform) of mine that all do work together nicely here.

Contributors

MFlisarWorkMFlisargithub-actions[bot]

Issues