
Token-driven theme system with semantic and component tokens, reusable UI components, root-level component customization, and a demo app showcasing light/dark themes, token presets, and component behavior.
Palette is a Compose Multiplatform component library for Android, Desktop (JVM), and iOS. It provides a token-driven theme system, reusable UI components, and a desktop demo app for validating component behavior across light and dark themes.
PaletteTheme.PaletteComponentThemes lets product teams tune component styles from the app theme instead of per-instance overrides.app module includes searchable component demos, dark/light theme switching, language switching, and global token presets.The demo app currently groups components into these categories:
| Category | Components |
|---|---|
| Form | Button, Checkbox, Radio, Switch, Slider, TextField, Rate, Form, SearchBar, InputNumber, Cascader, Transfer, Calendar, Segmented, InputOTP, Autocomplete, TreeSelect, ColorPicker, Toggle, Mentions, CascaderPanel |
| Feedback | Loading, Progress, Badge, Dialog, Toast, Skeleton, Tag, Popup, ActionSheet, ContextMenu, DashboardProgress, Alert, Popconfirm, Result, InfiniteScroll, Watermark, FloatButton |
| Navigation | Toolbar, Affix, Backtop, PageHeader |
| Layout | RowLayout, BorderBox, Card, Avatar, Collapse, Grid, Space |
| Data display | Table, List, Descriptions, Statistic, Timeline, Tree, Image, Carousel, Pagination, Empty, QRCode |
// build.gradle.kts
dependencies {
implementation("xyz.junerver.compose:palette:0.1.0")
}Palette targets Android minSdk 24, Desktop JVM, and iOS arm64 / simulatorArm64.
import androidx.compose.runtime.Composable
import xyz.junerver.compose.palette.PaletteMaterialTheme
import xyz.junerver.compose.palette.Screen
@Composable
fun MyApp() {
PaletteMaterialTheme(darkTheme = true) {
Screen(title = "Hello Palette") {
// Your content
}
}
}Palette exposes two theme layers:
PaletteTheme.colors, spacing, shapes, typography, opacity, motion, elevation, and control.PaletteTheme.componentThemes, backed by PaletteComponentThemes.Use derive() when changing brand colors so dependent semantic colors can be recomputed:
val colors = PaletteColors.light().derive(
primary = Color(0xFF0057D9),
surface = Color.White,
)
PaletteMaterialTheme(colors = colors) {
App()
}Use PaletteComponentThemes for root-level component customization:
val colors = PaletteColors.light().derive(primary = Color(0xFF0057D9))
val components = PaletteComponentThemes.default(colors = colors).let { base ->
base.copy(
button = base.button.copy(disabledAlpha = 0.56f),
card = base.card.copy(cornerRadius = 0.dp, elevation = 0.dp),
)
}
PaletteMaterialTheme(
colors = colors,
componentThemes = components,
) {
App()
}See docs/theming.md for precedence rules, component token groups, and migration guidance.
./gradlew :palette:build
./gradlew :palette:allTests
./gradlew :app:run
./gradlew :app:hotRunDesktopUseful scoped tasks:
./gradlew :palette:desktopTest
./gradlew :palette:testDebugUnitTest
./gradlew :palette:publishToMavenLocal
./gradlew :palette:desktopBenchmarkBenchmarkPalette/
├── palette/ # Component library module
│ └── src/
│ ├── commonMain/ # Shared component, token, and theme code
│ ├── commonJvmAndroid/ # JVM + Android shared code
│ ├── androidMain/ # Android-specific implementation
│ ├── desktopMain/ # Desktop-specific implementation
│ └── iosMain/ # iOS-specific implementation
├── app/ # Demo application
├── docs/ # Design and migration notes
├── benchmark/ # Benchmark module
└── art/ # Screenshots used by the README
palette/src/commonMain/kotlin/xyz/junerver/compose/palette/Palette.kt.XxxDefaults.kt file.See LICENSE.
Palette is a Compose Multiplatform component library for Android, Desktop (JVM), and iOS. It provides a token-driven theme system, reusable UI components, and a desktop demo app for validating component behavior across light and dark themes.
PaletteTheme.PaletteComponentThemes lets product teams tune component styles from the app theme instead of per-instance overrides.app module includes searchable component demos, dark/light theme switching, language switching, and global token presets.The demo app currently groups components into these categories:
| Category | Components |
|---|---|
| Form | Button, Checkbox, Radio, Switch, Slider, TextField, Rate, Form, SearchBar, InputNumber, Cascader, Transfer, Calendar, Segmented, InputOTP, Autocomplete, TreeSelect, ColorPicker, Toggle, Mentions, CascaderPanel |
| Feedback | Loading, Progress, Badge, Dialog, Toast, Skeleton, Tag, Popup, ActionSheet, ContextMenu, DashboardProgress, Alert, Popconfirm, Result, InfiniteScroll, Watermark, FloatButton |
| Navigation | Toolbar, Affix, Backtop, PageHeader |
| Layout | RowLayout, BorderBox, Card, Avatar, Collapse, Grid, Space |
| Data display | Table, List, Descriptions, Statistic, Timeline, Tree, Image, Carousel, Pagination, Empty, QRCode |
// build.gradle.kts
dependencies {
implementation("xyz.junerver.compose:palette:0.1.0")
}Palette targets Android minSdk 24, Desktop JVM, and iOS arm64 / simulatorArm64.
import androidx.compose.runtime.Composable
import xyz.junerver.compose.palette.PaletteMaterialTheme
import xyz.junerver.compose.palette.Screen
@Composable
fun MyApp() {
PaletteMaterialTheme(darkTheme = true) {
Screen(title = "Hello Palette") {
// Your content
}
}
}Palette exposes two theme layers:
PaletteTheme.colors, spacing, shapes, typography, opacity, motion, elevation, and control.PaletteTheme.componentThemes, backed by PaletteComponentThemes.Use derive() when changing brand colors so dependent semantic colors can be recomputed:
val colors = PaletteColors.light().derive(
primary = Color(0xFF0057D9),
surface = Color.White,
)
PaletteMaterialTheme(colors = colors) {
App()
}Use PaletteComponentThemes for root-level component customization:
val colors = PaletteColors.light().derive(primary = Color(0xFF0057D9))
val components = PaletteComponentThemes.default(colors = colors).let { base ->
base.copy(
button = base.button.copy(disabledAlpha = 0.56f),
card = base.card.copy(cornerRadius = 0.dp, elevation = 0.dp),
)
}
PaletteMaterialTheme(
colors = colors,
componentThemes = components,
) {
App()
}See docs/theming.md for precedence rules, component token groups, and migration guidance.
./gradlew :palette:build
./gradlew :palette:allTests
./gradlew :app:run
./gradlew :app:hotRunDesktopUseful scoped tasks:
./gradlew :palette:desktopTest
./gradlew :palette:testDebugUnitTest
./gradlew :palette:publishToMavenLocal
./gradlew :palette:desktopBenchmarkBenchmarkPalette/
├── palette/ # Component library module
│ └── src/
│ ├── commonMain/ # Shared component, token, and theme code
│ ├── commonJvmAndroid/ # JVM + Android shared code
│ ├── androidMain/ # Android-specific implementation
│ ├── desktopMain/ # Desktop-specific implementation
│ └── iosMain/ # iOS-specific implementation
├── app/ # Demo application
├── docs/ # Design and migration notes
├── benchmark/ # Benchmark module
└── art/ # Screenshots used by the README
palette/src/commonMain/kotlin/xyz/junerver/compose/palette/Palette.kt.XxxDefaults.kt file.See LICENSE.