A library of commonly used UI components built on Jetpack Compose and Compose Multiplatform.
| Target | Compose | Material3 backend uses |
|---|---|---|
| Android | Jetpack Compose | androidx Material3 |
iOS (iosArm64, iosSimulatorArm64) |
Compose Multiplatform | Compose Multiplatform Material3 |
| JVM desktop | Compose Multiplatform | Compose Multiplatform Material3 |
Web (js, wasmJs) |
Compose Multiplatform | Compose Multiplatform Material3 |
Add the dependency for one backend (see Choose a backend) — to an Android module's
dependencies, or to commonMain.dependencies in a Kotlin Multiplatform module:
implementation "ru.kode.uikit:uikit-components:$version" // Material3 backend
// or
implementation "ru.kode.uikit:uikit-components-foundation:$version" // Compose Foundation backendAndroid apps with minSdk < 26 need core library desugaring
enabled: dates are kotlinx.datetime.LocalDate, which uses java.time on Android.
Set up the configuration. It's best to do this as high in the component hierarchy as possible
(app theme, Activity):
val configuration = UiKitConfiguration(
// TODO
)
CompositionLocalProvider(
LocalUiKitConfiguration provides configuration
) {
// TODO
}That completes the setup — you can now use any of the components.
Icons and texts in the date picker configuration are composable lambdas, so they work with any resource system:
// Android resources
TextFieldDatePickerConfiguration(leadingIcon = { painterResource(R.drawable.ic_calendar) }, /* … */)
ModalDatePickerConfiguration(title = { stringResource(R.string.pick_date) }, /* … */)
// Compose Multiplatform resources (org.jetbrains.compose.resources)
TextFieldDatePickerConfiguration(leadingIcon = { painterResource(Res.drawable.ic_calendar) }, /* … */)
ModalDatePickerConfiguration(title = { stringResource(Res.string.pick_date) }, /* … */)The library itself does not depend on Compose Multiplatform resources.
The library ships as three artifacts:
| Artifact | Contains | Depends on |
|---|---|---|
uikit-core |
configuration, shared state types, TextField, TextFieldArea, PageIndicator, shimmer |
Compose UI/Foundation, kotlinx-datetime |
uikit-components |
Material3 backend: Button, Checkbox, RadioButton, sliders, DatePicker, ModalBottomSheet |
uikit-core, Material3 (androidx on Android, Compose Multiplatform elsewhere) |
uikit-components-foundation |
the same components, drawn with Compose Foundation | uikit-core, material-ripple |
Both backends expose the same API in ru.kode.uikit.components, so switching is a one-line dependency change.
Depend on exactly one: adding both fails the build with duplicate classes. uikit-core comes in transitively.
Pick uikit-components if your app already uses Material3, or you need Material3's exact look.
Pick uikit-components-foundation to keep Material3 out of your APK. It renders the same as the Material3
backend (CI checks both against the same screenshots); see the CHANGELOG for the few known differences.
To change one visual part without forking, override its slot. Slots work the same on both backends:
Checkbox(checked = checked, onClick = onClick, box = { state -> MyCheckboxBox(state.checked, state.enabled) })
ModalBottomSheet(onDismissRequest = onDismiss, dragHandle = null) { /* content */ }Available slots: Checkbox.box, RadioButton.indicator, the sliders' thumb/track,
Button.loadingIndicator, ModalBottomSheet.dragHandle and TextFieldDatePicker.title/headline. Their
defaults are in UikitCheckboxDefaults, UikitRadioButtonDefaults, UikitButtonDefaults,
UikitBottomSheetDefaults and UikitDatePickerDefaults.
- Button
- Checkbox
- RadioButton
- ModalBottomSheet
- Slider
- TextField
- TextFieldArea
- PageIndicator
- Shimmer (component and modifier)
- DatePicker
The :sample module is a runnable demo app that hosts a component browser powered by
Showkase. It lets you browse every component (grouped by
type, with light/dark, RTL and font-scale toggles) so you can visually track the library as it
changes.
Run it on a device or emulator:
./gradlew :sample:installDebugThen launch Uikit Gallery and tap Open browser. Alternatively, open the module in Android
Studio and run the sample configuration, or view any preview inline via the IDE Compose preview.
Adding a component to the gallery: drop a parameterless @Preview @ShowkaseComposable(...) function
under sample/src/main/kotlin/ru/kode/uikit/sample/previews/, wrapping the body in PreviewTheme { }
(which supplies a concrete LocalUikitConfiguration). Showkase discovers it automatically — no
registration needed.
The gallery configuration in
PreviewUikitConfiguration.ktis illustrative and sample-only; it is not the library's canonical theme and is not published.
The library is published to Maven Central (Central Portal) via the
vanniktech/gradle-maven-publish-plugin.
The version is defined by versionName in gradle.properties.
Releases run automatically through GitHub Actions (.github/workflows/release.yml) on a git tag push:
git tag 0.1.3
git push origin 0.1.3The workflow runs ./gradlew publishAndReleaseToMavenCentral on macOS (iOS klibs only build there). It requires the following secrets in the
release environment: NEXUS_USERTOKEN_NAME, NEXUS_USERTOKEN_PASSWORD, SIGNING_KEY_ID,
SIGNING_PASSWORD, SIGNING_SECRET_KEY_RING_FILE_BASE64.
To verify the artifact build locally: ./gradlew publishToMavenLocal.
See CHANGELOG.md for the release history.