Android Compose bindings catalog
develop specs/develop/android-compose.kmd
Native Android Jetpack Compose surface for Koder Design — the set of `@Composable` widgets, theming primitives, and packaging artifacts that mirror Koder's canonical components 1:1 for apps that want a native Android build (not via Flutter). Material parity (`/develop/android/jetpack-compose`).
When this spec applies
Primary triggers
- Add Android Compose bindings
All triggers
- Ship a native Android app that uses Koder Design tokens / widgets
- Replace Material 3 Compose with Koder Design Compose
- Document the Compose surface contract
Specification body
Spec — Android Compose bindings catalog
Facet Develop of Koder Design. Material parity: https://m3.material.io/develop/android/jetpack-compose.
Surface: native Android Jetpack Compose. Catalog page:
https://kds.koder.dev/{locale}/develop/android-compose/.
Why a native Compose surface
Flutter covers most Koder targets, but native Android apps benefit from:
- Better integration with Android system APIs (WorkManager, custom tile services, ML Kit, etc.)
- Lighter package size when the app is Android-only
- Compose ecosystem reuse (existing in-house Compose codebases)
Koder Design Compose is kept feature-parity with the canonical component specs. A Compose-only app should look indistinguishable from a Flutter-based app on the same preset.
Package layout
| Package | Maven coordinate | Purpose |
|---|---|---|
koder-design-compose | dev.koder:design-compose:<version> | Core widgets + theme |
koder-design-compose-icons | dev.koder:design-compose-icons:<version> | Icon set |
koder-design-compose-fonts | dev.koder:design-compose-fonts:<version> | Self-hosted woff2 assets adapted to Android font resources |
Published to Maven Central + Koder Hub (hub.koder.dev/maven/).
R1 — Catalog page contents
For each canonical component (wave 1 + wave 2 + future waves):
| Section | Contents |
|---|---|
| Composable signature | @Composable fun KoderButton(...) parameters |
| Theme tokens consumed | List of --kds-* tokens read via KoderDesignTheme |
| Variant matrix | Compose parameter combinations → canonical spec variants |
| Code sample | Idiomatic snippet with proper imports |
| State preview | Side-by-side @Preview-rendered states matching spec R-rules |
| Accessibility | Modifier.semantics { … } recommendations |
| Cross-link | Link to the canonical specs/components/<slug>.kmd |
R2 — KoderDesignTheme composable
Wraps the entire app:
@Composable
fun KoderDesignTheme(
preset: KoderPreset = KoderPreset.Material3,
darkTheme: Boolean = isSystemInDarkTheme(),
seedColor: Color? = null,
density: KoderDensity = KoderDensity.Default,
content: @Composable () -> Unit,
)
Internally:
- Derives the 18-role palette per
themes/color-dynamic.kmd - Maps to
MaterialTheme.colorSchemefor composability with existing Material widgets (escape hatch) - Provides
LocalKoderTokens,LocalKoderDensity, etc.
R3 — Composable naming
| Canonical component | Compose name |
|---|---|
| Button (filled) | KoderButton(variant = Filled, …) |
| Button (tonal) | KoderButton(variant = Tonal, …) |
| Button (icon-only) | KoderIconButton(...) |
| Card | KoderCard(...) |
| Text field | KoderTextField(...) |
| Dialog | KoderDialog(...) |
| Navigation bar / drawer / rail | KoderNavigationBar(...) / Drawer / Rail |
| Snackbar | KoderSnackbar(...) |
| Tabs | KoderTabRow(...) + KoderTab(...) |
Pattern: Koder<ComponentName> for top-level, with variants exposed
as enums.
R4 — Density propagation
KoderDensity.Compact / Default / Comfortable flows via
LocalKoderDensity. Each Composable reads it and adjusts its padding
/ size per specs/foundations/customization.kmd.
R5 — Per-preset adaptation
Same composable can render with different presets via the preset
parameter on KoderDesignTheme. Switching presets at runtime is
supported (palette + density + shape recompose without lifecycle
restart).
R6 — Accessibility
- Every Koder composable exposes
Modifierparameter for the caller to extend - Internal semantics conform to canonical specs (e.g.,
KoderCheckboxaddsRole.Checkbox+ state) - Auto-content-description for icon-only buttons via
contentDescriptionparameter - TalkBack tested per release
R7 — Versioning
Compose surface follows Koder Design semver:
- Major: breaking spec change (R-rule removal, signature break)
- Minor: spec additions (new component, new variant)
- Patch: bug fix, no surface change
Each release tagged engines/sdk/koder-design-compose/v* and published
to Maven Central + Hub.
R8 — Out of scope
- ❌ Material 2 Compose support (Material 2 deprecated; not back-ported)
- ❌ View-based (
android.view.View) bindings — Compose-only - ❌ Custom build flavor per preset (preset is runtime, not buildtime)
R9 — Forbidden patterns
- ❌ Compose composable that bypasses
KoderDesignTheme(always wraps an app) - ❌ Hardcoded color hex in composables (use tokens)
- ❌ Composable that ships strings (use
stringResourceperi18n/contract.kmd) - ❌ Composable that doesn't accept
Modifierparameter
Cross-link
themes/*.kmd— token sources consumed byKoderDesignThemecomponents/*.kmd— composable per component matches anatomyi18n/contract.kmd—stringResourceusagetools/design-kit-export.kmd— Compose tokens exported here
Implementation tracking
Bindings live at engines/sdk/koder-design-compose/ (separate
artifact, not in koder_kit). Multi-day implementation tracked via:
engines/sdk/koder-design-compose#XXX— initial package + themeengines/sdk/koder-design-compose#XXX— wave 1 + wave 2 components
References
specs/themes/color-roles.kmdspecs/themes/typography.kmdspecs/themes/shape.kmdspecs/themes/elevation.kmdspecs/components/buttons.kmdspecs/components/text-fields.kmdspecs/components/navigation.kmdspecs/i18n/contract.kmdspecs/tools/design-kit-export.kmd