MyUI – Compose Multiplatform Component Library
A component library for Kotlin Multiplatform and Compose Multiplatform.
MyUI is a UI component library for Kotlin Multiplatform (KMP) and Compose Multiplatform. It provides a shared set of components that run on Android, iOS, Desktop (JVM), and Web (JS/Wasm) from a single codebase.
The library includes a token-based design system (colors, spacing, typography, shapes), an overlay management architecture for dialogs, drawers and notifications, and an Interaction DSL for consistent event handling.
Status: The library is under active development. While most components are usable, APIs may change between releases.
📑 Table of Contents
- Supported Platforms
- Installation
- Getting Started
- Design System
- Component Catalog
- Overlay System
- Interaction DSL
- License
📖 Dokumentation
Detaillierte Beschreibungen der verfügbaren Komponenten findest du im Dokumentations-Ordner!!missing!!.
- Buttons!!missing!!
- Dialoge & Overlays!!missing!!
- Charts!!missing!!
- Eingabefelder!!missing!!
- Navigation!!missing!!
- Layout!!missing!!
- Node Editor!!missing!!
🛠️ Entwicklung & Design-Philosophie
MyUI verfolgt den Ansatz der Atomic Component Construction:
- Atomare Basis-Komponenten: Wir bauen in der
libdie kleinstmöglichen, wiederverwendbaren Funktionseinheiten (z.B.Button,Slider,Text,ProgressBar,Card). - Komposition statt Komplexität: Komplexe Benutzeroberflächen (z.B. Media Player, Dashboards, Editoren) werden nicht als monolithische Riesen-Komponenten in der Library gebaut. Stattdessen werden sie im
example-Modul durch Kombination der atomaren Komponenten erstellt. - Modularität: Wenn eine komplexe UI-Zusammenstellung so universell wird, dass sie überall benötigt wird, kann sie als neue zusammengesetzte Komponente in die
libaufgenommen werden – basierend auf den bestehenden Atomen.
🚀 Supported Platforms
| Platform | Status | Notes |
|---|---|---|
| Android | ✅ Supported | Min SDK 24 |
| iOS | ✅ Supported | arm64, simulatorArm64 |
| Desktop (JVM) | ✅ Supported | Windows, macOS, Linux |
| Web (JS) | 🛠️ Experimental | Browser only |
| Web (WasmJs) | 🛠️ Experimental | Browser only |
🛠️ Installation
MyUI is distributed via Gitea Packages.
1. Configure Repositories
In your settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://gitea.schwartmann.io/api/packages/Allround/maven")
}
}
2. Add the Dependency
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.schwarju:myui:1.0.7")
}
}
}
3. Version Catalog (Optional)
[versions]
myui = "1.0.7"
[libraries]
myui = { group = "io.github.schwarju", name = "myui", version.ref = "myui" }
Then in your build.gradle.kts:
implementation(libs.myui)
🛠️ Getting Started
Theme Setup
Wrap your root composable with MyThemeProvider:
import io.github.schwarju.myui.theme.MyTheme
import io.github.schwarju.myui.theme.MyThemeProvider
@Composable
fun App() {
MyThemeProvider(theme = MyTheme()) {
// your content
}
}
MyTheme accepts optional overrides for colors, shapes, typography and spacing:
MyTheme(
colors = MyColors.Dark,
spacing = MySpacing(grid = 4.dp),
shapes = MyShapes(grid = 8.dp),
typography = MyTypography.Default
)
Basic Example
import io.github.schwarju.myui.components.basic.Text
import io.github.schwarju.myui.components.buttons.TextButton
import io.github.schwarju.myui.components.layout.Card
import io.github.schwarju.myui.theme.tokens.ComponentVariant
@Composable
fun MainLayout() {
Column(modifier = Modifier.padding(16.dp)) {
Text.Headline("MyUI Showcase")
Card(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.padding(16.dp)) {
Text("Welcome to MyUI.")
TextButton(
text = "Get Started",
variant = ComponentVariant.Primary,
interaction = {
onClick { /* action */ }
}
)
}
}
}
}
🎨 Design System
Colors
MyColors defines the full color palette. Light and dark presets are provided, and all derived colors
(surface, border, semantic) are computed automatically:
val myColors = MyColors.Light.copy(
primary = Color(0xFF1A73E8),
secondary = Color(0xFF757575)
)
Switch between themes at runtime:
var isDark by remember { mutableStateOf(false) }
MyThemeProvider(theme = MyTheme(colors = if (isDark) MyColors.Dark else MyColors.Light)) {
// ...
}
Component Variants
Most components accept a ComponentVariant that controls background, content, and border colors:
| Variant | Description |
|---|---|
Primary / PrimaryOutline | Brand color, filled or outlined |
Neutral / NeutralOutline | Secondary color, filled or outlined |
Ghost | Transparent with low-opacity background on interaction |
Background / Surface / Raised | Theme surface colors |
Error / Warn / Success + outlines | Semantic states |
Custom(...) | Arbitrary color triple |
Component Sizes
ComponentSize defines height, padding and typography: ExtraSmall, Small, Medium, Large, ExtraLarge.
Component Shapes
ComponentShape controls corner radius: Sharp, Small, Medium, Large, Pill, Custom.
Spacing
MySpacing is grid-based (default 4 dp). Named steps: xs, s, m, l, xl, xxl.
Typography
MyTypography provides named text styles: caption, body, subtitle, headline levels.
📚 Component Catalog
The library currently ships ~100 components across the following categories.
Basic
Divider · Image · ScrollBar · Spacer · Text
Buttons
Button (base) · TextButton · IconButton · LoadingButton · SplitButton · ToggleButton · ButtonGroup
Charts
LineChart · BarChart · AreaChart · PieChart · ScatterPlot
Display
Alert · Avatar · Badge · Carousel · EmptyState · Skeleton · Statistic · Table · Tag · Timeline · TreeView
Dialogs & Drawers
Dialog · AlertDialog · CommandPalette · Drawer
(managed via DialogHost, DrawerHost and UnifiedHost)
Icons
Icon · CustomIcon · ResourceIcon
A bundled SVG icon library (Lucide-style) is included as Compose resources.
Inputs
Input · ClearableInput · TextArea · NumberInput · PasswordInput · EmailInput · UrlInput ·
SearchInput · OTPInput · PhoneInput · CreditCardInput · DateInput · ColorInput ·
ComboBox · TagInput · Rating · Form · DropTarget
Layout
Card · Accordion · Collapsible · SplitLayout · Grid · Resizable · AspectRatio · DividerGroup
Menus
Dropdown · ContextMenu · MenuBar
Navigation
Tabs · Sidebar · Breadcrumb · Stepper · Pagination · Link
Notifications
Toast · Snackbar · Banner · Notification
(managed via NotificationHost)
Overlays
Tooltip · Popover · HoverCard · Popup
Pickers
Calendar · DateRangePicker · DateTimePicker · TimePicker · MonthPicker · QuarterPicker ·
YearPicker · DurationPicker · ColorPicker · EmojiPicker · IconPicker · FontSizePicker
Progress
ProgressBar · ProgressCircle · StepProgress
Pro Audio (Specialized)
AudioKnob · AudioFader · AudioLevelMeter · AudioChannelStrip · WaveformVisualizer
Selection
Checkbox · CheckboxGroup · RadioButton · RadioGroup · ToggleSwitch
Sliders
Slider · RangeSlider · StepSlider · VerticalSlider · ComplexSlider
Window (JVM only)
ModernTitleBar · ModernWindow · WindowManager
🏛️ Overlay System
MyUI uses a host-based architecture for managing overlays. If you are using ModernWindow, hosts are provided automatically by default.
Manual Setup
If not using ModernWindow, place the MyUI component at the root of your app:
MyUI(theme = MyTheme()) {
MainContent()
}
This installs a UnifiedHost which provides LocalDialogHost, LocalDrawerHost, and LocalNotificationHost.
Advanced: Manual Host Management
You can also initialize a UnifiedHost manually. This allows you to interact with the host from outside of any Composable scope (e.g., in a View-Model or a background service).
// 1. Create the host instance manually
val myHost = UnifiedHost()
// 2. Pass it to ModernWindow (or UIHost directly)
ModernWindow(
onCloseRequest = { /* ... */ },
host = myHost
) {
MainPage()
}
// 3. Show overlays from anywhere using the instance
fun onSomeBackgroundEvent() {
myHost.show(Notification(text = "External Event!"))
}
Showing Overlays
Trigger overlays from anywhere using the host providers. You can either use host.show(element) or element.show(host) for a more fluid syntax:
// Get the host (e.g. via UnifiedHost or specific Local...Host)
val host = LocalUnifiedHost.current
// Show a Dialog (Fluent Syntax)
InfoDialog(
title = "Info",
message = "This is a simple dialog."
).show(host)
// Or via host.show (Equivalent)
val myDialog = AlertDialog(
title = "Delete record?",
message = "This action cannot be undone.",
confirmText = "Delete",
onConfirm = { /* ... */ }
)
host.show(myDialog)
// Show a Notification (Fluent Syntax)
Notification(
title = "Done",
text = "Changes saved.",
variant = ComponentVariant.Success
).show(host)
// Show a Drawer (Fluent Syntax)
object : Drawer(position = DrawerPosition.Right) {
@Composable
override fun DrawerBody() {
Text("Drawer Content")
}
}.show(host)
🔧 Interaction DSL
All interactive components accept an interaction lambda that configures event handlers:
TextButton(
text = "Save",
interaction = {
onClick { /* perform action */ }
onLongClick { /* long press */ }
onHover { isHovered -> /* update state */ }
onFocusChanged { isFocused -> /* ... */ }
}
)
📄 License
MyUI is licensed under the Apache License 2.0.
Copyright 2026 Julian Schwartmann
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
See LICENSE for the full text.
MyUI – built by Allround