# Kepko Kepko is a work-in-progress design system for Compose Multiplatform, providing a comprehensive set of themed UI components that work across Android, iOS, JVM Desktop, macOS, JavaScript, and WebAssembly platforms. The library offers a cohesive visual language with multiple theme styles (Light, Dark, Black, Solarized Light, Solarized Dark) and semantic color tokens for consistent design across applications. Built on top of Material 3, Kepko provides simplified, opinionated composable functions that automatically handle theming, content colors, and accessibility. The library is split into two main modules: `foundation` (containing theme, colors, dimensions, shapes, and typography) and `component` (containing ready-to-use UI components like buttons, text fields, switches, and preference screens). ## Installation Add Kepko dependencies to your Kotlin Multiplatform project. ```kotlin // build.gradle.kts dependencies { implementation("glass.yasan.kepko:foundation:") implementation("glass.yasan.kepko:component:") } ``` ## KepkoTheme The root composable that provides theming context to all Kepko components. Must wrap your app content to enable proper styling and color tokens. ```kotlin import glass.yasan.kepko.component.Text import glass.yasan.kepko.foundation.theme.KepkoTheme import glass.yasan.kepko.foundation.theme.ThemeStyle // Basic usage with automatic light/dark mode detection @Composable fun App() { KepkoTheme { Text("Hello, Kepko!") } } // Explicit theme style @Composable fun AppWithStyle() { KepkoTheme(style = ThemeStyle.DARK) { Column { Text("Dark mode content") Text( text = "Subtle text", color = KepkoTheme.colors.contentSubtle ) } } } // Custom isDark parameter @Composable fun AppWithDarkFlag() { KepkoTheme(isDark = true, grayscale = false) { // Content renders in dark mode Text("Dark themed content") } } ``` ## ThemeStyle Enumeration of available theme styles with associated color palettes. ```kotlin import glass.yasan.kepko.foundation.theme.ThemeStyle // Available theme styles val styles = listOf( ThemeStyle.LIGHT, // Standard light theme ThemeStyle.DARK, // Standard dark theme ThemeStyle.BLACK, // OLED-friendly black theme ThemeStyle.SOLARIZED_LIGHT, // Solarized light palette ThemeStyle.SOLARIZED_DARK // Solarized dark palette ) // Get theme from system preference @Composable fun DynamicTheme() { val style = ThemeStyle.fromSystemDarkTheme() KepkoTheme(style = style) { Text("System-aware theming") } } // Parse theme from stored preference ID @Composable fun StoredTheme(savedThemeId: String?) { val style = ThemeStyle.fromIdOrSystemDarkTheme(savedThemeId) // style.id returns: "light", "dark", "black", "solarized-light", "solarized-dark" KepkoTheme(style = style) { Text("Restored theme: ${style.title()}") } } ``` ## Colors Theme-aware color tokens providing semantic colors for consistent UI design. ```kotlin import glass.yasan.kepko.foundation.theme.KepkoTheme @Composable fun ColorExample() { KepkoTheme { // Layer colors for backgrounds val foreground = KepkoTheme.colors.foreground // Card/elevated surface val midground = KepkoTheme.colors.midground // Main background val background = KepkoTheme.colors.background // Deeper background // Content colors for text and icons val content = KepkoTheme.colors.content // Primary text val contentSubtle = KepkoTheme.colors.contentSubtle // Secondary text val contentDisabled = KepkoTheme.colors.contentDisabled // Disabled state // Semantic colors for states val success = KepkoTheme.colors.success // Success states (green) val information = KepkoTheme.colors.information // Info states (blue) val caution = KepkoTheme.colors.caution // Warning states (yellow/orange) val danger = KepkoTheme.colors.danger // Error states (red) // Inverse colors for contrasting elements val inverseContent = KepkoTheme.colors.inverseContent val inverseForeground = KepkoTheme.colors.inverseForeground Column( modifier = Modifier.background(midground) ) { Text(text = "Primary text", color = content) Text(text = "Secondary text", color = contentSubtle) } } } ``` ## Text Simple text component with theme-aware default colors. ```kotlin import glass.yasan.kepko.component.Text import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.sp @Composable fun TextExamples() { KepkoTheme { Column { // Basic text (inherits content color from theme) Text(text = "Hello, Kepko!") // Styled text Text( text = "Bold Heading", fontWeight = FontWeight.Bold, fontSize = 24.sp ) // Custom color and alignment Text( text = "Centered subtitle", color = KepkoTheme.colors.contentSubtle, textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth() ) // Truncated text Text( text = "This is a very long text that will be truncated with ellipsis", maxLines = 1, overflow = TextOverflow.Ellipsis ) } } } ``` ## Button Themed button component with customizable colors, borders, and content. ```kotlin import glass.yasan.kepko.component.Button import glass.yasan.kepko.component.Text @Composable fun ButtonExamples() { KepkoTheme { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { // Basic button with text content Button( onClick = { println("Clicked!") }, content = { Text("Click Me") } ) // Semantic colored buttons Button( onClick = { /* Save action */ }, containerColor = KepkoTheme.colors.success, content = { Text("Save") } ) Button( onClick = { /* Delete action */ }, containerColor = KepkoTheme.colors.danger, content = { Text("Delete") } ) // Disabled button Button( onClick = {}, enabled = false, content = { Text("Disabled") } ) // Button with icon and text Button( onClick = { /* Navigate */ }, content = { Icon( imageVector = Icons.Default.ArrowForward, contentDescription = null, modifier = Modifier.padding(end = 8.dp) ) Text("Continue") } ) } } } ``` ## ButtonText Pre-styled button variant optimized for text labels with optional leading/trailing icons. ```kotlin import glass.yasan.kepko.component.ButtonText import glass.yasan.kepko.component.PreferenceAnnotation @Composable fun ButtonTextExamples() { KepkoTheme { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { // Simple text button ButtonText( text = "Submit", onClick = { /* Handle submit */ } ) // Button with icons (using Painter) ButtonText( text = "Settings", onClick = { /* Open settings */ }, leadingIcon = painterResource(Res.drawable.ic_settings), trailingIcon = painterResource(Res.drawable.ic_chevron_right) ) // Button with annotation badge ButtonText( text = "New Feature", onClick = { /* Handle click */ }, annotation = PreferenceAnnotation.new, containerColor = KepkoTheme.colors.information ) // Custom styled button ButtonText( text = "Custom", onClick = {}, containerColor = KepkoTheme.colors.success, fontWeight = FontWeight.Medium, textAlign = TextAlign.Center, fillWidth = true ) } } } ``` ## TextField Themed text input field with label, placeholder, and icon support. ```kotlin import glass.yasan.kepko.component.TextField import glass.yasan.kepko.component.Text import glass.yasan.kepko.component.Icon import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @Composable fun TextFieldExamples() { KepkoTheme { var username by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } var email by remember { mutableStateOf("") } Column( verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.padding(16.dp) ) { // Basic text field with placeholder TextField( value = username, onValueChange = { username = it }, placeholder = { Text("Enter username") }, modifier = Modifier.fillMaxWidth() ) // Text field with label TextField( value = email, onValueChange = { email = it }, label = "Email Address", singleLine = true, modifier = Modifier.fillMaxWidth() ) // Text field with icons TextField( value = password, onValueChange = { password = it }, label = "Password", singleLine = true, leadingIcon = { Icon( painter = painterResource(Res.drawable.ic_lock), contentDescription = null ) }, trailingIcon = { Icon( painter = painterResource(Res.drawable.ic_visibility), contentDescription = "Toggle visibility" ) }, modifier = Modifier.fillMaxWidth() ) // Error state TextField( value = "invalid@", onValueChange = {}, label = "Email", isError = true, modifier = Modifier.fillMaxWidth() ) // Disabled and read-only states TextField( value = "Read only content", onValueChange = {}, readOnly = true, modifier = Modifier.fillMaxWidth() ) // Multiline text field TextField( value = "Line 1\nLine 2\nLine 3", onValueChange = {}, minLines = 3, modifier = Modifier.fillMaxWidth() ) } } } ``` ## Switch Toggle switch component for boolean settings. ```kotlin import glass.yasan.kepko.component.Switch import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @Composable fun SwitchExamples() { KepkoTheme { var notificationsEnabled by remember { mutableStateOf(true) } var darkModeEnabled by remember { mutableStateOf(false) } Column(verticalArrangement = Arrangement.spacedBy(16.dp)) { // Basic switch Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() ) { Text("Enable Notifications") Switch( checked = notificationsEnabled, onCheckedChange = { notificationsEnabled = it } ) } // Switch with enabled/disabled state Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() ) { Text("Dark Mode") Switch( checked = darkModeEnabled, onCheckedChange = { darkModeEnabled = it }, enabled = true ) } // Disabled switch Switch( checked = true, onCheckedChange = {}, enabled = false ) } } } ``` ## Checkbox Themed checkbox for multiple selection scenarios. ```kotlin import glass.yasan.kepko.component.Checkbox import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @Composable fun CheckboxExamples() { KepkoTheme { var termsAccepted by remember { mutableStateOf(false) } var newsletterOptIn by remember { mutableStateOf(true) } Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { // Basic checkbox with label Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( checked = termsAccepted, onCheckedChange = { termsAccepted = it } ) Text( text = "I accept the terms and conditions", modifier = Modifier.padding(start = 8.dp) ) } // Pre-checked checkbox Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( checked = newsletterOptIn, onCheckedChange = { newsletterOptIn = it } ) Text( text = "Subscribe to newsletter", modifier = Modifier.padding(start = 8.dp) ) } // Disabled checkbox Checkbox( checked = true, onCheckedChange = {}, enabled = false ) } } } ``` ## RadioButton Radio button for single-selection option groups. ```kotlin import glass.yasan.kepko.component.RadioButton import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @Composable fun RadioButtonExamples() { KepkoTheme { var selectedOption by remember { mutableStateOf("option1") } Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { val options = listOf( "option1" to "Small", "option2" to "Medium", "option3" to "Large" ) options.forEach { (value, label) -> Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() .clickable { selectedOption = value } ) { RadioButton( selected = selectedOption == value, onClick = { selectedOption = value } ) Text( text = label, modifier = Modifier.padding(start = 8.dp) ) } } // Disabled radio button RadioButton( selected = false, onClick = null, enabled = false ) } } } ``` ## Slider Range slider for numeric value selection. ```kotlin import glass.yasan.kepko.component.Slider import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember @Composable fun SliderExamples() { KepkoTheme { var volume by remember { mutableFloatStateOf(0.5f) } var brightness by remember { mutableFloatStateOf(0.75f) } Column( verticalArrangement = Arrangement.spacedBy(24.dp), modifier = Modifier.padding(16.dp) ) { // Basic slider (0 to 1 range) Column { Text("Volume: ${(volume * 100).toInt()}%") Slider( value = volume, onValueChange = { volume = it }, modifier = Modifier.fillMaxWidth() ) } // Slider with steps Column { Text("Brightness: ${(brightness * 100).toInt()}%") Slider( value = brightness, onValueChange = { brightness = it }, steps = 4, // Creates 5 discrete positions onValueChangeFinished = { println("Final brightness: ${brightness}") }, modifier = Modifier.fillMaxWidth() ) } // Custom range slider var temperature by remember { mutableFloatStateOf(22f) } Column { Text("Temperature: ${temperature.toInt()}°C") Slider( value = temperature, onValueChange = { temperature = it }, valueRange = 16f..30f, modifier = Modifier.fillMaxWidth() ) } // Disabled slider Slider( value = 0.5f, onValueChange = {}, enabled = false, modifier = Modifier.fillMaxWidth() ) } } } ``` ## Icon Themed icon component supporting ImageVector, Painter, and ImageBitmap sources. ```kotlin import glass.yasan.kepko.component.Icon import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.vectorResource @Composable fun IconExamples() { KepkoTheme { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.padding(16.dp) ) { // Icon from vector resource Icon( imageVector = vectorResource(Res.drawable.ic_asterisk), contentDescription = "Asterisk icon" ) // Icon from painter resource Icon( painter = painterResource(Res.drawable.ic_settings), contentDescription = "Settings" ) // Custom colored icon Icon( imageVector = vectorResource(Res.drawable.ic_warning), contentDescription = "Warning", color = KepkoTheme.colors.danger ) // Custom sized icon Icon( painter = painterResource(Res.drawable.ic_large), contentDescription = null, size = 48.dp ) } } } ``` ## ProgressIndicator Circular and linear progress indicators for loading states. ```kotlin import glass.yasan.kepko.component.CircularProgressIndicator import glass.yasan.kepko.component.LinearProgressIndicator @Composable fun ProgressIndicatorExamples() { KepkoTheme { Column( verticalArrangement = Arrangement.spacedBy(24.dp), horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(16.dp) ) { // Indeterminate circular progress CircularProgressIndicator() // Indeterminate linear progress LinearProgressIndicator( modifier = Modifier.fillMaxWidth() ) // Custom colored indicators CircularProgressIndicator( color = KepkoTheme.colors.success, trackColor = KepkoTheme.colors.background ) LinearProgressIndicator( color = KepkoTheme.colors.information, trackColor = KepkoTheme.colors.contentSubtle, modifier = Modifier.fillMaxWidth() ) } } } ``` ## Scaffold Page layout component with title bar, back navigation, and content areas. ```kotlin import glass.yasan.kepko.component.Scaffold import glass.yasan.kepko.component.Text import glass.yasan.kepko.component.Icon import glass.yasan.kepko.component.PreferenceAnnotation @Composable fun ScaffoldExamples() { // Basic scaffold with title KepkoTheme { Scaffold(title = "Home") { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { Text("Page content goes here") } } } } @Composable fun ScaffoldWithBackNavigation(onBackClick: () -> Unit) { KepkoTheme { Scaffold( title = "Settings", onBackClick = onBackClick ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { Text("Settings content") } } } } @Composable fun ScaffoldWithExtras(onBackClick: () -> Unit) { KepkoTheme { Scaffold( title = "Profile", onBackClick = onBackClick, annotation = PreferenceAnnotation.new, trailingContent = { Icon( painter = Icons.chevronForward, contentDescription = "More options", modifier = Modifier.padding(end = 16.dp) ) }, bottomBar = { Button( onClick = { /* Save */ }, content = { Text("Save Changes") }, modifier = Modifier.padding(16.dp) ) } ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { Text("Profile content") } } } } @Composable fun ScaffoldCentered() { KepkoTheme { Scaffold( title = "Centered Title", textAlign = TextAlign.Center ) { paddingValues -> Text( text = "Content", modifier = Modifier.padding(paddingValues) ) } } } ``` ## PreferenceSwitch Settings row component combining a label, description, and switch toggle. ```kotlin import glass.yasan.kepko.component.PreferenceSwitch import glass.yasan.kepko.component.PreferenceAnnotation import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @Composable fun PreferenceSwitchExamples() { KepkoTheme { var notificationsEnabled by remember { mutableStateOf(true) } var autoUpdateEnabled by remember { mutableStateOf(false) } var experimentalFeature by remember { mutableStateOf(false) } Column( verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier .background(KepkoTheme.colors.midground) .padding(16.dp) ) { // Basic preference switch with icon PreferenceSwitch( title = "Push Notifications", description = "Receive alerts for new messages and updates", checked = notificationsEnabled, onCheckedChange = { notificationsEnabled = it }, leadingIcon = painterResource(Res.drawable.ic_notifications) ) // Without description PreferenceSwitch( title = "Auto-Update", checked = autoUpdateEnabled, onCheckedChange = { autoUpdateEnabled = it }, leadingIcon = painterResource(Res.drawable.ic_update) ) // With annotation badge PreferenceSwitch( title = "Experimental Features", description = "Enable beta functionality that may be unstable", checked = experimentalFeature, onCheckedChange = { experimentalFeature = it }, annotation = PreferenceAnnotation.experimental, leadingIcon = painterResource(Res.drawable.ic_science) ) // Without leading icon (custom content) PreferenceSwitch( title = "Dark Mode", description = "Use dark color scheme throughout the app", checked = true, onCheckedChange = {}, leadingContent = { Icon( imageVector = Icons.Default.DarkMode, contentDescription = null ) } ) } } } ``` ## PreferenceContainer Flexible container for building custom preference/settings rows. ```kotlin import glass.yasan.kepko.component.PreferenceContainer import glass.yasan.kepko.component.PreferenceAnnotation import glass.yasan.kepko.component.Text import glass.yasan.kepko.component.Icon @Composable fun PreferenceContainerExamples() { KepkoTheme { Column( verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier .background(KepkoTheme.colors.midground) .padding(16.dp) ) { // Container with leading and trailing content PreferenceContainer( title = "Account", description = "Manage your account settings", onClick = { /* Navigate to account */ }, leadingContent = { Icon( painter = painterResource(Res.drawable.ic_account), contentDescription = null ) }, trailingContent = { Icon( painter = Icons.chevronForward, contentDescription = null ) } ) // Container with annotation PreferenceContainer( title = "Privacy", description = "Control your privacy preferences", onClick = { /* Navigate to privacy */ }, annotation = PreferenceAnnotation.new, leadingContent = { Icon( painter = painterResource(Res.drawable.ic_privacy), contentDescription = null ) }, trailingContent = { Icon( painter = Icons.chevronForward, contentDescription = null ) } ) // Container with custom content slot PreferenceContainer( title = "Storage Usage", description = "2.5 GB of 10 GB used", onClick = { /* Navigate to storage */ } ) { contentPadding -> LinearProgressIndicator( modifier = Modifier .fillMaxWidth() .padding(contentPadding) ) } // Disabled container PreferenceContainer( title = "Premium Features", description = "Upgrade to unlock", enabled = false, onClick = {} ) { contentPadding -> Text( text = "Locked", modifier = Modifier.padding(contentPadding) ) } } } } ``` ## Surface Experimental surface composables for layered backgrounds (Foreground, Midground, Background). ```kotlin import glass.yasan.kepko.component.Surface import glass.yasan.kepko.component.Foreground import glass.yasan.kepko.component.Midground import glass.yasan.kepko.component.Background import glass.yasan.kepko.foundation.annotation.ExperimentalKepkoApi @OptIn(ExperimentalKepkoApi::class) @Composable fun SurfaceExamples() { KepkoTheme { // Custom colored surface Surface( color = KepkoTheme.colors.information, shape = RoundedCornerShape(16.dp), modifier = Modifier.padding(16.dp) ) { Text( text = "Info card content", modifier = Modifier.padding(16.dp) ) } // Layered surfaces using convenience composables Background { Column(modifier = Modifier.padding(16.dp)) { Midground( shape = RoundedCornerShape(12.dp), modifier = Modifier.fillMaxWidth() ) { Foreground( shape = RoundedCornerShape(8.dp), modifier = Modifier.padding(16.dp) ) { Text( text = "Card content", modifier = Modifier.padding(16.dp) ) } } } } } } ``` ## PreferenceAnnotation Badge annotations for marking preference items as new, experimental, preview, etc. ```kotlin import glass.yasan.kepko.component.PreferenceAnnotation import glass.yasan.kepko.component.TextPill import glass.yasan.kepko.component.PreferenceSwitch @Composable fun PreferenceAnnotationExamples() { KepkoTheme { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { // Available annotation types TextPill(annotation = PreferenceAnnotation.new) TextPill(annotation = PreferenceAnnotation.experimental) TextPill(annotation = PreferenceAnnotation.preview) // Usage in preferences PreferenceSwitch( title = "New Feature", checked = false, onCheckedChange = {}, annotation = PreferenceAnnotation.new, leadingIcon = painterResource(Res.drawable.ic_star) ) } } } ``` ## Summary Kepko is ideal for building cross-platform applications that require consistent, themed UI components with minimal configuration. The design system excels in settings screens, preference panels, and form-heavy interfaces where semantic colors and accessibility matter. Common integration patterns include wrapping your app root with `KepkoTheme`, using `Scaffold` for page structure with navigation, and composing `PreferenceSwitch`/`PreferenceContainer` components for settings interfaces. For custom theming, access `KepkoTheme.colors`, `KepkoTheme.dimensions`, and `KepkoTheme.shapes` within any composable to retrieve theme-aware values. The library integrates seamlessly with existing Compose Multiplatform projects and Material 3 components, allowing gradual adoption. Components automatically handle disabled states, content colors, and border styling based on the current theme, reducing boilerplate code while maintaining visual consistency across all supported platforms (Android, iOS, JVM Desktop, macOS, JavaScript, WebAssembly).