From 438c709a4fd4c376268dffac11072f46f48e7d0f Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Mon, 12 Jan 2026 22:49:19 +0300 Subject: [PATCH 01/37] feat(ui): input styles --- .../input/style/appearance/Appearance.kt | 24 ++++++++++++ .../input/style/appearance/Colors.kt | 20 ++++++++++ .../input/style/appearance/Variants.kt | 26 +++++++++++++ .../ui/components/input/style/shape/Shape.kt | 16 ++++++++ .../components/input/style/shape/Variants.kt | 38 +++++++++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Appearance.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Colors.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Shape.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Variants.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Appearance.kt new file mode 100644 index 000000000..155d9c6dd --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Appearance.kt @@ -0,0 +1,24 @@ +package com.atls.hyperion.ui.components.input.style.appearance + +import com.atls.hyperion.ui.components.input.state.InputState + +data class InputAppearance( + val default: Colors, + val filled: Colors, + val focused: Colors, + val disabled: Colors, + val error: Colors, + val active: Colors +) { + companion object Companion + + fun getColorsFromState(state: InputState): Colors = + when (state) { + InputState.Default -> default + InputState.Disabled -> disabled + InputState.Error -> error + InputState.Filled -> filled + InputState.Focused -> focused + InputState.Active -> active + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Colors.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Colors.kt new file mode 100644 index 000000000..9397dd7c5 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Colors.kt @@ -0,0 +1,20 @@ +package com.atls.hyperion.ui.components.input.style.appearance + +import androidx.compose.ui.graphics.Color +import com.atls.hyperion.ui.theme.tokens.colors.ColorSet +import com.atls.hyperion.ui.theme.tokens.colors.Colors as ThemeColors + +data class Colors( + val backgroundColor: Color, + val textColor: Color, + val borderColor: Color = ThemeColors.Palette.transparent, + val cursorColor: Color = textColor +) { + companion object { + fun fromColorSet(colorSet: ColorSet): Colors = Colors( + backgroundColor = colorSet.background, + textColor = colorSet.font, + borderColor = colorSet.border + ) + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt new file mode 100644 index 000000000..5c64c68ed --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt @@ -0,0 +1,26 @@ +package com.atls.hyperion.ui.components.input.style.appearance + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.theme.tokens.colors.Colors as TokenColors + +@Composable +fun InputAppearance.Companion.blue(): InputAppearance = + InputAppearance( + default = Colors.fromColorSet(TokenColors.Input.Blue.Default), + filled = Colors.fromColorSet(TokenColors.Input.Blue.Default), + focused = Colors.fromColorSet(TokenColors.Input.Blue.Focus), + disabled = Colors.fromColorSet(TokenColors.Input.Blue.Disabled), + error = Colors.fromColorSet(TokenColors.Input.Blue.Default), // TODO: Add error colors to tokens + active = Colors.fromColorSet(TokenColors.Input.Blue.Active) + ) + +@Composable +fun InputAppearance.Companion.white(): InputAppearance = + InputAppearance( + default = Colors.fromColorSet(TokenColors.Input.White.Default), + filled = Colors.fromColorSet(TokenColors.Input.White.Default), + focused = Colors.fromColorSet(TokenColors.Input.White.Focus), + disabled = Colors.fromColorSet(TokenColors.Input.White.Disabled), + error = Colors.fromColorSet(TokenColors.Input.White.Default), // TODO: Add error colors to tokens + active = Colors.fromColorSet(TokenColors.Input.White.Active) + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Shape.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Shape.kt new file mode 100644 index 000000000..daab415a8 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Shape.kt @@ -0,0 +1,16 @@ +package com.atls.hyperion.ui.components.input.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp +import com.atls.hyperion.ui.theme.tokens.layout.Space + +data class InputShape( + val cornerRadius: Dp, + val borderStroke: Dp, + val paddings: PaddingValues, + val textPaddings: PaddingValues = PaddingValues(Space.zero), + val typography: TextStyle +) { + companion object Companion +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Variants.kt new file mode 100644 index 000000000..504233cea --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/shape/Variants.kt @@ -0,0 +1,38 @@ +package com.atls.hyperion.ui.components.input.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.TextStyle +import com.atls.hyperion.ui.theme.tokens.layout.BorderStroke +import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius +import com.atls.hyperion.ui.theme.tokens.layout.Space +import com.atls.hyperion.ui.theme.typography.FontSize + +@Composable +fun InputShape.Companion.large(): InputShape = + InputShape( + cornerRadius = CornerRadius.md, + borderStroke = BorderStroke.tiny, + paddings = PaddingValues( + vertical = Space.g12, + horizontal = Space.g16 + ), + textPaddings = PaddingValues(Space.zero), + typography = TextStyle(fontSize = FontSize.md) + ) + +@Composable +fun InputShape.Companion.normal(): InputShape = + InputShape( + cornerRadius = CornerRadius.xs3, + borderStroke = BorderStroke.tiny, + paddings = PaddingValues( + vertical = Space.g8, + horizontal = Space.g12 + ), + textPaddings = PaddingValues( + vertical = Space.g4, + horizontal = Space.zero + ), + typography = TextStyle(fontSize = FontSize.sm) + ) From 0d651efcfe850344a79a22e7c2d2e837b9a7519a Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Mon, 12 Jan 2026 22:49:40 +0300 Subject: [PATCH 02/37] feat(ui): input locals --- .../ui/components/input/locals/LocalAppearance.kt | 8 ++++++++ .../hyperion/ui/components/input/locals/LocalState.kt | 8 ++++++++ .../hyperion/ui/components/input/state/InputState.kt | 10 ++++++++++ 3 files changed, 26 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalAppearance.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalState.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/state/InputState.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalAppearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalAppearance.kt new file mode 100644 index 000000000..3203205af --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalAppearance.kt @@ -0,0 +1,8 @@ +package com.atls.hyperion.ui.components.input.locals + +import androidx.compose.runtime.compositionLocalOf +import com.atls.hyperion.ui.components.input.style.appearance.InputAppearance + +val LocalAppearance = compositionLocalOf { + error("InputAppearance not provided") +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalState.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalState.kt new file mode 100644 index 000000000..70e3ac986 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/locals/LocalState.kt @@ -0,0 +1,8 @@ +package com.atls.hyperion.ui.components.input.locals + +import androidx.compose.runtime.compositionLocalOf +import com.atls.hyperion.ui.components.input.state.InputState + +val LocalState = compositionLocalOf { + error("InputState not provided") +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/state/InputState.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/state/InputState.kt new file mode 100644 index 000000000..8d53590f6 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/state/InputState.kt @@ -0,0 +1,10 @@ +package com.atls.hyperion.ui.components.input.state + +sealed interface InputState { + data object Default : InputState + data object Focused : InputState + data object Filled : InputState + data object Disabled : InputState + data object Error : InputState + data object Active : InputState +} From 25c578614004dcfd762b7d99cf5acb7bc046ac84 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Mon, 12 Jan 2026 22:50:14 +0300 Subject: [PATCH 03/37] feat(ui): input component --- .../hyperion/ui/components/input/Input.kt | 86 +++++++++++++++++ .../input/container/InputContainer.kt | 76 +++++++++++++++ .../input/placeholder/InputPlaceholder.kt | 24 +++++ .../ui/components/input/stories/Component.kt | 94 +++++++++++++++++++ 4 files changed, 280 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/Input.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/container/InputContainer.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/placeholder/InputPlaceholder.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/stories/Component.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/Input.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/Input.kt new file mode 100644 index 000000000..fb0fcaa94 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/Input.kt @@ -0,0 +1,86 @@ +package com.atls.hyperion.ui.components.input + +import androidx.compose.foundation.background +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation +import com.atls.hyperion.ui.components.input.container.InputContainer +import com.atls.hyperion.ui.components.input.state.InputState +import com.atls.hyperion.ui.components.input.style.appearance.InputAppearance +import com.atls.hyperion.ui.components.input.style.shape.InputShape +import com.atls.hyperion.ui.shared.addon.AddonSlotManager +import com.atls.hyperion.ui.theme.tokens.layout.Weight +import com.atls.hyperion.ui.theme.tokens.colors.Colors as ThemeColors + +@Composable +fun Input( + modifier: Modifier = Modifier, + value: TextFieldValue, + onValueChange: (TextFieldValue) -> Unit, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + isError: Boolean = false, + enabled: Boolean = true, + readOnly: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + appearance: InputAppearance, + shape: InputShape, + visualTransformation: VisualTransformation = VisualTransformation.None, + addons: AddonSlotManager = AddonSlotManager(), + placeholder: @Composable (() -> Unit)? = null, +) { + val isFocused = interactionSource.collectIsFocusedAsState().value + val isPressed = interactionSource.collectIsPressedAsState().value + + val currentState = when { + !enabled -> InputState.Disabled + isError -> InputState.Error + isPressed -> InputState.Active + isFocused -> InputState.Focused + value.text.isNotEmpty() -> InputState.Filled + else -> InputState.Default + } + + val colors = appearance.getColorsFromState(currentState) + + InputContainer( + modifier = modifier, + appearance = appearance, + shape = shape, + state = currentState, + addons = addons + ) { + BasicTextField( + value = value, + onValueChange = onValueChange, + enabled = enabled, + readOnly = readOnly, + interactionSource = interactionSource, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + cursorBrush = SolidColor(colors.cursorColor), + textStyle = shape.typography.copy(color = colors.textColor), + visualTransformation = visualTransformation, + decorationBox = { innerTextField -> + if (value.text.isEmpty() && placeholder != null) { + placeholder() + } + innerTextField() + }, + modifier = Modifier + .background(ThemeColors.Palette.transparent) + .padding(shape.textPaddings) + .weight(Weight.full) + ) + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/container/InputContainer.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/container/InputContainer.kt new file mode 100644 index 000000000..e6de4f7ad --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/container/InputContainer.kt @@ -0,0 +1,76 @@ +package com.atls.hyperion.ui.components.input.container + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.components.input.locals.LocalAppearance +import com.atls.hyperion.ui.components.input.locals.LocalState +import com.atls.hyperion.ui.components.input.state.InputState +import com.atls.hyperion.ui.components.input.style.appearance.InputAppearance +import com.atls.hyperion.ui.components.input.style.appearance.blue +import com.atls.hyperion.ui.components.input.style.shape.InputShape +import com.atls.hyperion.ui.components.input.style.shape.normal +import com.atls.hyperion.ui.shared.addon.AddonPosition +import com.atls.hyperion.ui.shared.addon.AddonSlotManager + +@Composable +fun InputContainer( + modifier: Modifier = Modifier, + appearance: InputAppearance = InputAppearance.blue(), + shape: InputShape = InputShape.normal(), + state: InputState? = null, + addons: AddonSlotManager = AddonSlotManager(), + content: @Composable RowScope.(interactionSource: MutableInteractionSource) -> Unit +) { + val interactionSource = remember { MutableInteractionSource() } + val isFocused = interactionSource.collectIsFocusedAsState().value + val isPressed = interactionSource.collectIsPressedAsState().value + + val resolvedState = state ?: when { + isPressed -> InputState.Active + isFocused -> InputState.Focused + else -> InputState.Default + } + + val colors = appearance.getColorsFromState(resolvedState) + + CompositionLocalProvider( + LocalState provides resolvedState, + LocalAppearance provides appearance + ) { + Row( + modifier = modifier + .border( + width = shape.borderStroke, + color = colors.borderColor, + shape = RoundedCornerShape(shape.cornerRadius) + ) + .background(colors.backgroundColor, RoundedCornerShape(shape.cornerRadius)) + .padding(shape.paddings), + verticalAlignment = Alignment.CenterVertically + ) { + addons.get(AddonPosition.Before).forEach { + it.Content() + it.Spacer() + } + + content(interactionSource) + + addons.get(AddonPosition.After).forEach { + it.Spacer() + it.Content() + } + } + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/placeholder/InputPlaceholder.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/placeholder/InputPlaceholder.kt new file mode 100644 index 000000000..9bc572171 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/placeholder/InputPlaceholder.kt @@ -0,0 +1,24 @@ +package com.atls.hyperion.ui.components.input.placeholder + +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.components.input.style.appearance.InputAppearance +import com.atls.hyperion.ui.components.input.style.appearance.blue +import com.atls.hyperion.ui.components.input.style.shape.InputShape +import com.atls.hyperion.ui.components.input.style.shape.normal + +@Composable +fun InputPlaceholder( + modifier: Modifier = Modifier, + text: String, + appearance: InputAppearance = InputAppearance.blue(), + shape: InputShape = InputShape.normal() +) { + Text( + modifier = modifier, + text = text, + color = appearance.default.textColor, + style = shape.typography + ) +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/stories/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/stories/Component.kt new file mode 100644 index 000000000..e2ee2c9f0 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/stories/Component.kt @@ -0,0 +1,94 @@ +package com.atls.hyperion.ui.components.input.stories + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Switch +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.TextFieldValue +import com.atls.hyperion.storybook.shared.model.ComponentExample +import com.atls.hyperion.storybook.shared.ui.ComponentVariants +import com.atls.hyperion.ui.components.input.Input +import com.atls.hyperion.ui.components.input.placeholder.InputPlaceholder +import com.atls.hyperion.ui.components.input.style.appearance.InputAppearance +import com.atls.hyperion.ui.components.input.style.appearance.blue +import com.atls.hyperion.ui.components.input.style.appearance.white +import com.atls.hyperion.ui.components.input.style.shape.InputShape +import com.atls.hyperion.ui.components.input.style.shape.large +import com.atls.hyperion.ui.components.input.style.shape.normal +import com.atls.hyperion.ui.primitives.HorizontalSpacer +import com.atls.hyperion.ui.primitives.VerticalSpacer +import com.atls.hyperion.ui.theme.tokens.layout.Space +import com.atls.hyperion.ui.theme.tokens.layout.Weight + +class InputStory : ComponentExample { + override val name: String = "Input" + + @Composable + override fun Content() { + var enabled by remember { mutableStateOf(true) } + var isError by remember { mutableStateOf(false) } + var textValue by remember { mutableStateOf(TextFieldValue("")) } + + Column { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = Space.g12), + verticalAlignment = Alignment.CenterVertically + ) { + Text(modifier = Modifier.weight(Weight.full), text = "Enabled") + HorizontalSpacer(Space.g12) + Switch(checked = enabled, onCheckedChange = { enabled = it }) + } + VerticalSpacer(Space.g8) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = Space.g12), + verticalAlignment = Alignment.CenterVertically + ) { + Text(modifier = Modifier.weight(Weight.full), text = "Error") + HorizontalSpacer(Space.g12) + Switch(checked = isError, onCheckedChange = { isError = it }) + } + VerticalSpacer(Space.g12) + + ComponentVariants( + name = "Input", + appearances = listOf( + "Blue" to { InputAppearance.blue() }, + "White" to { InputAppearance.white() } + ), + shapes = listOf( + "Large" to { InputShape.large() }, + "Normal" to { InputShape.normal() } + ) + ) { appearance: InputAppearance, shape: InputShape -> + Input( + value = textValue, + onValueChange = { textValue = it }, + appearance = appearance, + shape = shape, + enabled = enabled, + isError = isError, + placeholder = { + InputPlaceholder( + text = "Placeholder", + appearance = appearance, + shape = shape + ) + } + ) + } + } + } +} From 4fa29c243cfbf7bc9d8e42020fe408eddbdafd71 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Mon, 12 Jan 2026 22:54:35 +0300 Subject: [PATCH 04/37] feat(theme): alpha tokens --- .../com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt new file mode 100644 index 000000000..ae0441a7a --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt @@ -0,0 +1,7 @@ +package com.atls.hyperion.ui.theme.tokens.colors + +object Alpha { + val huge = 0.9f + val large = 0.8f + val medium = 0.6f +} From 2a026a31173d38f8309250731270798c731c35bc Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Mon, 12 Jan 2026 23:10:26 +0300 Subject: [PATCH 05/37] feat(ui): switch styles --- .../switch/styles/appearance/Appearance.kt | 19 +++++++++++++++++++ .../switch/styles/appearance/Colors.kt | 10 ++++++++++ .../switch/styles/appearance/Variants.kt | 19 +++++++++++++++++++ .../components/switch/styles/shape/Shape.kt | 12 ++++++++++++ .../switch/styles/shape/Variants.kt | 12 ++++++++++++ .../ui/theme/tokens/components/SwitchSize.kt | 9 +++++++++ 6 files changed, 81 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Appearance.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Colors.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Variants.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Shape.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/SwitchSize.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Appearance.kt new file mode 100644 index 000000000..d2dc4a8d0 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Appearance.kt @@ -0,0 +1,19 @@ +package com.atls.hyperion.ui.components.switch.styles.appearance + +import com.atls.hyperion.ui.components.switch.state.SwitchState + +data class SwitchAppearance( + val default: Colors, + val checked: Colors = default, + val disabled: Colors = default +) { + fun fromState(state: SwitchState): Colors { + return when (state) { + SwitchState.Default -> default + SwitchState.Checked -> checked + SwitchState.Disabled -> disabled + } + } + + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Colors.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Colors.kt new file mode 100644 index 000000000..75eac9fac --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Colors.kt @@ -0,0 +1,10 @@ +package com.atls.hyperion.ui.components.switch.styles.appearance + +import androidx.compose.ui.graphics.Color + +data class Colors( + val trackColor: Color, + val trackBorderColor: Color, + val thumbColor: Color, + val thumbBorderColor: Color, +) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Variants.kt new file mode 100644 index 000000000..b61709f33 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/appearance/Variants.kt @@ -0,0 +1,19 @@ +package com.atls.hyperion.ui.components.switch.styles.appearance + +import com.atls.hyperion.ui.theme.tokens.colors.Colors as ThemeColors + +fun SwitchAppearance.Companion.default(): SwitchAppearance = + SwitchAppearance( + default = Colors( + trackColor = ThemeColors.Palette.transparent, + trackBorderColor = ThemeColors.Palette.blue, + thumbColor = ThemeColors.Palette.blue, + thumbBorderColor = ThemeColors.Palette.blue + ), + disabled = Colors( + trackColor = ThemeColors.Palette.transparent, + trackBorderColor = ThemeColors.Palette.blue, + thumbColor = ThemeColors.Palette.transparent, + thumbBorderColor = ThemeColors.Palette.blue + ) + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Shape.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Shape.kt new file mode 100644 index 000000000..dec93f9d9 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Shape.kt @@ -0,0 +1,12 @@ +package com.atls.hyperion.ui.components.switch.styles.shape + +import androidx.compose.ui.unit.Dp + +data class SwitchShape( + val trackWidth: Dp, + val trackHeight: Dp, + val thumbSize: Dp, + val thumbPadding: Dp +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt new file mode 100644 index 000000000..15e5b743a --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt @@ -0,0 +1,12 @@ +package com.atls.hyperion.ui.components.switch.styles.shape + +import com.atls.hyperion.ui.theme.tokens.components.SwitchSize +import com.atls.hyperion.ui.theme.tokens.layout.Space + +fun SwitchShape.Companion.medium(): SwitchShape = + SwitchShape( + trackWidth = SwitchSize.defaultWidth, + trackHeight = SwitchSize.defaultHeight, + thumbSize = SwitchSize.defaultTrackSize, + thumbPadding = Space.g2 + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/SwitchSize.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/SwitchSize.kt new file mode 100644 index 000000000..72132862e --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/SwitchSize.kt @@ -0,0 +1,9 @@ +package com.atls.hyperion.ui.theme.tokens.components + +import androidx.compose.ui.unit.dp + +object SwitchSize { + val defaultWidth = 44.dp + val defaultHeight = 22.dp + val defaultTrackSize = 18.dp +} From 3888d583cff6212cabf0f0851131d18ee251b0e3 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Mon, 12 Jan 2026 23:10:43 +0300 Subject: [PATCH 06/37] feat(ui): switch component --- .../hyperion/ui/components/switch/Switch.kt | 80 +++++++++++++++++++ .../ui/components/switch/state/SwitchState.kt | 7 ++ .../ui/components/switch/stories/Component.kt | 69 ++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/Switch.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/state/SwitchState.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/stories/Component.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/Switch.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/Switch.kt new file mode 100644 index 000000000..32c7d9df1 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/Switch.kt @@ -0,0 +1,80 @@ +package com.atls.hyperion.ui.components.switch + +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.atls.hyperion.ui.components.switch.state.SwitchState +import com.atls.hyperion.ui.components.switch.styles.appearance.SwitchAppearance +import com.atls.hyperion.ui.components.switch.styles.appearance.default +import com.atls.hyperion.ui.components.switch.styles.shape.SwitchShape +import com.atls.hyperion.ui.components.switch.styles.shape.medium + +@Composable +fun Switch( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + disabled: Boolean = false, + appearance: SwitchAppearance = SwitchAppearance.default(), + shape: SwitchShape = SwitchShape.medium(), +) { + val state = remember(checked, disabled) { + if (disabled) { + SwitchState.Disabled + } else { + if (checked) SwitchState.Checked else SwitchState.Default + } + } + + val colors = appearance.fromState(state) + + val thumbOffset by animateDpAsState( + targetValue = if (checked) shape.trackWidth - shape.thumbSize - shape.thumbPadding else shape.thumbPadding + ) + + Box( + modifier = modifier + .size(width = shape.trackWidth, height = shape.trackHeight) + .clip(RoundedCornerShape(shape.trackHeight / 2)) + .background(colors.trackColor) + .border( + width = 1.dp, + color = colors.trackBorderColor, + shape = RoundedCornerShape(shape.trackHeight / 2) + ) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + enabled = !disabled + ) { + onCheckedChange(!checked) + }, + contentAlignment = Alignment.CenterStart + ) { + Box( + modifier = Modifier + .offset(x = thumbOffset) + .size(shape.thumbSize) + .clip(RoundedCornerShape(shape.thumbSize / 2)) + .background(colors.thumbColor) + .border( + width = 1.dp, + color = colors.thumbBorderColor, + shape = RoundedCornerShape(shape.thumbSize / 2) + ) + ) + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/state/SwitchState.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/state/SwitchState.kt new file mode 100644 index 000000000..659acc8e4 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/state/SwitchState.kt @@ -0,0 +1,7 @@ +package com.atls.hyperion.ui.components.switch.state + +enum class SwitchState { + Default, + Checked, + Disabled +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/stories/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/stories/Component.kt new file mode 100644 index 000000000..5015f5c81 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/stories/Component.kt @@ -0,0 +1,69 @@ +package com.atls.hyperion.ui.components.switch.stories + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.atls.hyperion.storybook.shared.model.ComponentExample +import com.atls.hyperion.storybook.shared.ui.ComponentVariants +import com.atls.hyperion.ui.components.switch.Switch +import com.atls.hyperion.ui.components.switch.styles.appearance.SwitchAppearance +import com.atls.hyperion.ui.components.switch.styles.appearance.default +import com.atls.hyperion.ui.components.switch.styles.shape.SwitchShape +import com.atls.hyperion.ui.components.switch.styles.shape.medium +import com.atls.hyperion.ui.primitives.HorizontalSpacer +import com.atls.hyperion.ui.primitives.VerticalSpacer +import com.atls.hyperion.ui.theme.tokens.layout.Space +import com.atls.hyperion.ui.theme.tokens.layout.Weight + +class SwitchStory : ComponentExample { + override val name: String = "Switch" + + @Composable + override fun Content() { + var checked by remember { mutableStateOf(false) } + var enabled by remember { mutableStateOf(true) } + + Column { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = Space.g12), + verticalAlignment = Alignment.CenterVertically + ) { + Text(modifier = Modifier.weight(Weight.full), text = "Enabled") + HorizontalSpacer(Space.g12) + androidx.compose.material.Switch( + checked = enabled, + onCheckedChange = { enabled = it } + ) + } + VerticalSpacer(Space.g8) + ComponentVariants( + name = "Switch", + appearances = listOf( + "Primary" to { SwitchAppearance.default() } + ), + shapes = listOf( + "Medium" to { SwitchShape.medium() } + ) + ) { appearance: SwitchAppearance, shape: SwitchShape -> + Switch( + checked = checked, + disabled = !enabled, + appearance = appearance, + shape = shape, + onCheckedChange = { checked = it } + ) + } + } + } +} From 44202f0c496f4296b9076353798bf0371664e908 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 00:51:34 +0300 Subject: [PATCH 07/37] feat(ui): column layouts --- .../ui/primitives/layout/column/Lazy.kt | 39 +++++++++++++++++++ .../ui/primitives/layout/column/Static.kt | 23 +++++++++++ 2 files changed, 62 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Lazy.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Static.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Lazy.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Lazy.kt new file mode 100644 index 000000000..e5ac8dd0c --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Lazy.kt @@ -0,0 +1,39 @@ +package com.atls.hyperion.ui.primitives.layout.column + +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.gestures.ScrollableDefaults +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.theme.tokens.layout.Space +import androidx.compose.foundation.lazy.LazyColumn as ComposeColumn + +@Composable +fun LazyColumn( + modifier: Modifier = Modifier, + state: LazyListState = rememberLazyListState(), + contentPadding: PaddingValues = PaddingValues(Space.zero), + reverseLayout: Boolean = false, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), + userScrollEnabled: Boolean = true, + content: LazyListScope.() -> Unit +) { + ComposeColumn( + modifier = modifier, + state = state, + contentPadding = contentPadding, + reverseLayout = reverseLayout, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + flingBehavior = flingBehavior, + userScrollEnabled = userScrollEnabled, + content = content + ) +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Static.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Static.kt new file mode 100644 index 000000000..8a76a92d6 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/column/Static.kt @@ -0,0 +1,23 @@ +package com.atls.hyperion.ui.primitives.layout.column + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.foundation.layout.Column as ComposeColumn + +@Composable +fun Column( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + content: @Composable ColumnScope.() -> Unit +) { + ComposeColumn( + modifier = modifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + content = content + ) +} From c4b5734eb0bd164e10c39d60f03c44d69349d89b Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 00:51:53 +0300 Subject: [PATCH 08/37] feat(ui): grid layout --- .../ui/primitives/layout/grid/Lazy.kt | 42 +++++++++++ .../ui/primitives/layout/grid/Orientation.kt | 6 ++ .../ui/primitives/layout/grid/Static.kt | 70 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Lazy.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Orientation.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Static.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Lazy.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Lazy.kt new file mode 100644 index 000000000..aa828d3b0 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Lazy.kt @@ -0,0 +1,42 @@ +package com.atls.hyperion.ui.primitives.layout.grid + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyGridScope +import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp + +@Composable +fun LazyGrid( + columns: Int, + orientation: GridOrientation, + modifier: Modifier = Modifier, + horizontalSpacing: Dp, + verticalSpacing: Dp, + content: LazyGridScope.() -> Unit +) { + when (orientation) { + GridOrientation.Vertical -> { + LazyVerticalGrid( + columns = GridCells.Fixed(columns), + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), + verticalArrangement = Arrangement.spacedBy(verticalSpacing), + content = content + ) + } + + GridOrientation.Horizontal -> { + LazyHorizontalGrid( + rows = GridCells.Fixed(columns), + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), + verticalArrangement = Arrangement.spacedBy(verticalSpacing), + content = content + ) + } + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Orientation.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Orientation.kt new file mode 100644 index 000000000..78e05afb1 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Orientation.kt @@ -0,0 +1,6 @@ +package com.atls.hyperion.ui.primitives.layout.grid + +enum class GridOrientation { + Vertical, + Horizontal +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Static.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Static.kt new file mode 100644 index 000000000..4d2558604 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/grid/Static.kt @@ -0,0 +1,70 @@ +package com.atls.hyperion.ui.primitives.layout.grid + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import com.atls.hyperion.ui.primitives.VerticalSpacer +import com.atls.hyperion.ui.theme.tokens.layout.Weight + +@Composable +fun Grid( + items: List<@Composable () -> Unit>, + columns: Int, + orientation: GridOrientation, + modifier: Modifier = Modifier, + horizontalSpacing: Dp, + verticalSpacing: Dp +) { + when (orientation) { + GridOrientation.Vertical -> { + Column(modifier = modifier) { + items.chunked(columns).forEach { rowItems -> + Row( + horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), + modifier = Modifier.fillMaxWidth() + ) { + rowItems.forEach { item -> + Box(modifier = Modifier.weight(Weight.full)) { + item() + } + } + + if (rowItems.size < columns) { + repeat(columns - rowItems.size) { + Spacer(modifier = Modifier.weight(Weight.full)) + } + } + } + VerticalSpacer(verticalSpacing) + } + } + } + + GridOrientation.Horizontal -> { + Row(modifier = modifier) { + items.chunked(columns).forEach { columnItems -> + Column( + verticalArrangement = Arrangement.spacedBy(verticalSpacing), + modifier = Modifier.weight(Weight.full) + ) { + columnItems.forEach { item -> + item() + } + + if (columnItems.size < columns) { + repeat(columns - columnItems.size) { + Spacer(modifier = Modifier.weight(Weight.full)) + } + } + } + } + } + } + } +} From 43b1966e9e37777f6c4d9d9d4110008df7b06ede Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 00:52:04 +0300 Subject: [PATCH 09/37] feat(ui): row layout --- .../hyperion/ui/primitives/layout/row/Lazy.kt | 39 +++++++++++++++++++ .../ui/primitives/layout/row/Static.kt | 23 +++++++++++ 2 files changed, 62 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Lazy.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Static.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Lazy.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Lazy.kt new file mode 100644 index 000000000..dea948061 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Lazy.kt @@ -0,0 +1,39 @@ +package com.atls.hyperion.ui.primitives.layout.row + +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.gestures.ScrollableDefaults +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.theme.tokens.layout.Space +import androidx.compose.foundation.lazy.LazyRow as ComposeRow + +@Composable +fun LazyRow( + modifier: Modifier = Modifier, + state: LazyListState = rememberLazyListState(), + contentPadding: PaddingValues = PaddingValues(Space.zero), + reverseLayout: Boolean = false, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.Top, + flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), + userScrollEnabled: Boolean = true, + content: LazyListScope.() -> Unit +) { + ComposeRow( + modifier = modifier, + state = state, + contentPadding = contentPadding, + reverseLayout = reverseLayout, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + flingBehavior = flingBehavior, + userScrollEnabled = userScrollEnabled, + content = content + ) +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Static.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Static.kt new file mode 100644 index 000000000..a7cf0542c --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/layout/row/Static.kt @@ -0,0 +1,23 @@ +package com.atls.hyperion.ui.primitives.layout.row + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.RowScope +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.foundation.layout.Row as ComposeRow + +@Composable +fun Row( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.Top, + content: @Composable RowScope.() -> Unit +) { + ComposeRow( + modifier = modifier, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + content = content + ) +} From e2a437e979bcffcfe0b272cdf1d959e85aea9992 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:00:45 +0300 Subject: [PATCH 10/37] feat(ui): date picker week days --- .../ui/fragment/datepicker/ui/WeekDays.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt new file mode 100644 index 000000000..04eb2f456 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt @@ -0,0 +1,39 @@ +package com.atls.hyperion.ui.fragment.datepicker.ui + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import com.atls.hyperion.ui.fragment.datepicker.config.DAYS_IN_WEEK +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatepickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatepickerShape +import com.atls.hyperion.ui.primitives.Text +import com.atls.hyperion.ui.theme.tokens.layout.Weight +import kotlinx.datetime.DayOfWeek +import kotlinx.datetime.format.DayOfWeekNames + +@Composable +fun WeekDays( + weekDays: List, + appearance: DatepickerAppearance, + shape: DatepickerShape, + dayNames: List = DayOfWeekNames.ENGLISH_ABBREVIATED.names +) { + require(dayNames.size == DAYS_IN_WEEK) { "dayNames must contain exactly 7 elements (Mon → Sun)" } + + Row(modifier = Modifier.fillMaxWidth()) { + weekDays.forEach { dayOfWeek -> + val nameIndex = (dayOfWeek.ordinal - weekDays.first().ordinal + DAYS_IN_WEEK) % DAYS_IN_WEEK + val shortName = dayNames[nameIndex] + + Text( + modifier = Modifier.weight(Weight.full), + textAlign = TextAlign.Center, + text = shortName, + typography = shape.dayHeaderTypography, + color = appearance.colors.weekDaysTextColor, + ) + } + } +} From f0c73fd4bb6fcaf04236e04cb4b3506f30741f78 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:09:07 +0300 Subject: [PATCH 11/37] feat(ui): calendar header component --- .../fragment/datepicker/ui/CalendarHeader.kt | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt new file mode 100644 index 000000000..c04b96ddf --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt @@ -0,0 +1,77 @@ +package com.atls.hyperion.ui.fragment.datepicker.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.Painter +import com.atls.hyperion.ui.components.divider.horizontal.HorizontalDivider +import com.atls.hyperion.ui.fragment.datepicker.model.CalendarDivider +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatepickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatepickerShape +import com.atls.hyperion.ui.generated.resources.Res +import com.atls.hyperion.ui.generated.resources.chevron_left +import com.atls.hyperion.ui.generated.resources.chevron_right +import com.atls.hyperion.ui.primitives.Icon +import org.jetbrains.compose.resources.painterResource + + +@Composable +fun CalendarHeader( + monthName: String, + appearance: DatepickerAppearance, + shape: DatepickerShape, + beforeIcon: Painter = painterResource(Res.drawable.chevron_left), + afterIcon: Painter = painterResource(Res.drawable.chevron_right), + arrangement: Arrangement.Horizontal = Arrangement.SpaceBetween, + alignment: Alignment.Vertical = Alignment.CenterVertically, + onPrevMonth: () -> Unit, + onNextMonth: () -> Unit, +) { + if (shape.divider == CalendarDivider.TOP) { + HorizontalDivider( + appearance = appearance.dividerAppearance, + shape = shape.dividerShape + ) + } + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(shape.headerHorizontalPadding), + horizontalArrangement = arrangement, + verticalAlignment = alignment + ) { + Icon( + icon = beforeIcon, + size = shape.headerIconSize, + modifier = Modifier.clickable { onPrevMonth() }, + color = appearance.colors.arrowColor + ) + + Text( + text = monthName, + style = shape.headerTypography, + color = appearance.colors.headerTextColor + ) + + Icon( + icon = afterIcon, + size = shape.headerIconSize, + modifier = Modifier.clickable { onNextMonth() }, + color = appearance.colors.arrowColor + ) + } + + if (shape.divider == CalendarDivider.BOTTOM) { + HorizontalDivider( + appearance = appearance.dividerAppearance, + shape = shape.dividerShape + ) + } +} From 0bdfe49ebae0c103d5241a27dae368fbd4f9760a Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:18:58 +0300 Subject: [PATCH 12/37] feat(ui): date picker day component --- .../hyperion/ui/fragment/datepicker/ui/Day.kt | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt new file mode 100644 index 000000000..c83a8afa0 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt @@ -0,0 +1,93 @@ +package com.atls.hyperion.ui.fragment.datepicker.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatepickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatepickerShape +import com.atls.hyperion.ui.primitives.Text +import com.atls.hyperion.ui.shared.layout.aspectSquare +import com.atls.hyperion.ui.theme.tokens.colors.Colors +import com.kizitonwose.calendar.core.CalendarDay +import com.kizitonwose.calendar.core.DayPosition +import kotlinx.datetime.LocalDate + +@Composable +fun Day( + day: CalendarDay, + isSelected: Boolean, + isInRange: Boolean, + isRangeStart: Boolean, + isRangeEnd: Boolean, + appearance: DatepickerAppearance, + shape: DatepickerShape, + onClick: (LocalDate) -> Unit, +) { + val isCurrentMonth = day.position == DayPosition.MonthDate + if (!isCurrentMonth) { + Box(modifier = Modifier.aspectSquare()) + return + } + + val date = LocalDate(day.date.year, day.date.monthNumber, day.date.dayOfMonth) + + val backgroundColor = when { + isSelected || isRangeStart || isRangeEnd -> appearance.cellActiveBackgroundColor + isInRange -> appearance.cellInRangeBackgroundColor + else -> appearance.cellBackgroundColor + } + + val textColor = when { + isSelected || isRangeStart || isRangeEnd -> appearance.cellActiveTextColor + isInRange -> appearance.cellInRangeTextColor + else -> appearance.cellTextColor + } + + val containerModifier = Modifier + .aspectSquare() + .padding(shape.cellSpacing) + .clip(shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius)) + .background(backgroundColor) + .padding(shape.cellPadding) + .then( + if ((isSelected || isRangeStart || isRangeEnd) && appearance.cellActiveBorderColor != Colors.Palette.transparent) + Modifier.border( + shape.cellBorderWidth, + appearance.cellActiveBorderColor, + shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius) + ) + else if (isInRange && appearance.cellInRangeBorderColor != Colors.Palette.transparent) + Modifier.border( + shape.cellBorderWidth, + appearance.cellInRangeBorderColor, + shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius) + ) + else if (appearance.cellBorderColor != Colors.Palette.transparent) + Modifier.border( + shape.cellBorderWidth, + appearance.cellBorderColor, + shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius) + ) + else Modifier + ) + .clickable { onClick(date) } + + + Box( + modifier = containerModifier, + contentAlignment = Alignment.Center + ) { + Text( + text = day.date.dayOfMonth.toString(), + color = textColor, + typography = shape.cellTypography + ) + } +} From 202bf44a229356ee1898e268ae193fc6feaa3d97 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:51:48 +0300 Subject: [PATCH 13/37] chore(theme): aspect square util --- .../com/atls/hyperion/ui/shared/layout/AspectSquare.kt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/shared/layout/AspectSquare.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/shared/layout/AspectSquare.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/shared/layout/AspectSquare.kt new file mode 100644 index 000000000..50377e1f5 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/shared/layout/AspectSquare.kt @@ -0,0 +1,9 @@ +package com.atls.hyperion.ui.shared.layout + +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +fun Modifier.aspectSquare(): Modifier = + this.aspectRatio(1f) From 9987ce9bef3c56876691d2ce87781c0b6ed1185e Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:52:12 +0300 Subject: [PATCH 14/37] chore(theme): icon sizes --- .../atls/hyperion/ui/theme/tokens/components/IconSize.kt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/IconSize.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/IconSize.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/IconSize.kt new file mode 100644 index 000000000..33bd8f36b --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/IconSize.kt @@ -0,0 +1,7 @@ +package com.atls.hyperion.ui.theme.tokens.components + +import androidx.compose.ui.unit.dp + +object IconSize { + val medium = 24.dp +} From 7e9c5ceb65f975dd021ded9338df27c3fd72973b Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:52:37 +0300 Subject: [PATCH 15/37] feat(ui): date picker components --- .../fragment/datepicker/ui/CalendarHeader.kt | 24 +-- .../datepicker/ui/DatePickerContent.kt | 149 ++++++++++++++++++ .../hyperion/ui/fragment/datepicker/ui/Day.kt | 24 +-- .../ui/fragment/datepicker/ui/WeekDays.kt | 10 +- 4 files changed, 182 insertions(+), 25 deletions(-) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt index c04b96ddf..62d878968 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt @@ -5,27 +5,27 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import com.atls.hyperion.ui.components.divider.horizontal.HorizontalDivider import com.atls.hyperion.ui.fragment.datepicker.model.CalendarDivider -import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatepickerAppearance -import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatepickerShape +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape import com.atls.hyperion.ui.generated.resources.Res import com.atls.hyperion.ui.generated.resources.chevron_left import com.atls.hyperion.ui.generated.resources.chevron_right import com.atls.hyperion.ui.primitives.Icon +import com.atls.hyperion.ui.primitives.Text +import com.atls.hyperion.ui.primitives.VerticalSpacer import org.jetbrains.compose.resources.painterResource - @Composable fun CalendarHeader( monthName: String, - appearance: DatepickerAppearance, - shape: DatepickerShape, + appearance: DatePickerAppearance, + shape: DatePickerShape, beforeIcon: Painter = painterResource(Res.drawable.chevron_left), afterIcon: Painter = painterResource(Res.drawable.chevron_right), arrangement: Arrangement.Horizontal = Arrangement.SpaceBetween, @@ -38,12 +38,13 @@ fun CalendarHeader( appearance = appearance.dividerAppearance, shape = shape.dividerShape ) + VerticalSpacer(shape.headerSpacing) } Row( modifier = Modifier .fillMaxWidth() - .padding(shape.headerHorizontalPadding), + .padding(horizontal = shape.headerHorizontalPadding), horizontalArrangement = arrangement, verticalAlignment = alignment ) { @@ -51,24 +52,25 @@ fun CalendarHeader( icon = beforeIcon, size = shape.headerIconSize, modifier = Modifier.clickable { onPrevMonth() }, - color = appearance.colors.arrowColor + color = appearance.arrowColor ) Text( text = monthName, - style = shape.headerTypography, - color = appearance.colors.headerTextColor + typography = shape.headerTypography, + color = appearance.headerTextColor ) Icon( icon = afterIcon, size = shape.headerIconSize, modifier = Modifier.clickable { onNextMonth() }, - color = appearance.colors.arrowColor + color = appearance.arrowColor ) } if (shape.divider == CalendarDivider.BOTTOM) { + VerticalSpacer(shape.headerSpacing) HorizontalDivider( appearance = appearance.dividerAppearance, shape = shape.dividerShape diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt new file mode 100644 index 000000000..104b54bfa --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt @@ -0,0 +1,149 @@ +package com.atls.hyperion.ui.fragment.datepicker.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.fragment.datepicker.config.DAYS_IN_WEEK +import com.atls.hyperion.ui.fragment.datepicker.config.WEEK_RANGE +import com.atls.hyperion.ui.fragment.datepicker.lib.next +import com.atls.hyperion.ui.fragment.datepicker.lib.previous +import com.atls.hyperion.ui.fragment.datepicker.model.DateSelection +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape +import com.atls.hyperion.ui.primitives.layout.column.Column +import com.kizitonwose.calendar.compose.HorizontalCalendar +import com.kizitonwose.calendar.compose.rememberCalendarState +import com.kizitonwose.calendar.core.firstDayOfWeekFromLocale +import kotlinx.coroutines.launch +import kotlinx.datetime.DayOfWeek +import kotlinx.datetime.TimeZone +import kotlinx.datetime.YearMonth +import kotlinx.datetime.toLocalDateTime +import kotlin.time.Clock +import kotlin.time.ExperimentalTime + +@OptIn(ExperimentalTime::class) +@Composable +fun DatePickerContent( + modifier: Modifier = Modifier, + selection: DateSelection, + onSelectionChange: (DateSelection) -> Unit, + appearance: DatePickerAppearance, + shape: DatePickerShape, +) { + val today = remember { + Clock.System.now() + .toLocalDateTime(TimeZone.currentSystemDefault()) + .date + } + + val currentMonth = remember { YearMonth(today.year, today.month) } + val startMonth = remember { YearMonth(1, today.month) } + val endMonth = remember { YearMonth(2200, today.month) } + val firstDayOfWeek = remember { firstDayOfWeekFromLocale() } + + val state = rememberCalendarState( + startMonth = startMonth, + endMonth = endMonth, + firstVisibleMonth = currentMonth, + firstDayOfWeek = firstDayOfWeek + ) + + val coroutineScope = rememberCoroutineScope() + + Column(modifier = modifier.background(appearance.backgroundColor)) { + + val visibleMonth = state.firstVisibleMonth.yearMonth + val monthName = + visibleMonth.month.name.lowercase().replaceFirstChar { it.uppercase() } + + CalendarHeader( + monthName = "$monthName ${visibleMonth.year}", + appearance = appearance, + shape = shape, + onPrevMonth = { + coroutineScope.launch { + state.animateScrollToMonth(visibleMonth.previous()) + } + }, + onNextMonth = { + coroutineScope.launch { + state.animateScrollToMonth(visibleMonth.next()) + } + } + ) + + HorizontalCalendar( + modifier = Modifier + .fillMaxWidth() + .padding(shape.calendarPadding), + + state = state, + dayContent = { day -> + val date = day.date + + val isSelected = when (selection) { + is DateSelection.Single -> selection.date == date + is DateSelection.Range -> false + } + + val isRangeStart = when (selection) { + is DateSelection.Range -> selection.start == date + else -> false + } + + val isRangeEnd = when (selection) { + is DateSelection.Range -> selection.end == date + else -> false + } + + val isInRange = when (selection) { + is DateSelection.Range -> + selection.start != null && + selection.end != null && + date > selection.start && + date < selection.end + + else -> false + } + + Day( + day = day, + isSelected = isSelected, + isInRange = isInRange, + isRangeStart = isRangeStart, + isRangeEnd = isRangeEnd, + appearance = appearance, + shape = shape, + onClick = { clicked -> + onSelectionChange( + when (selection) { + is DateSelection.Single -> + selection.copy(date = clicked) + + is DateSelection.Range -> + selection.next(clicked) + } + ) + } + ) + }, + + monthHeader = { + WeekDays( + weekDays = state.firstDayOfWeek.let { first -> + WEEK_RANGE.map { + DayOfWeek.entries[(first.ordinal + it) % DAYS_IN_WEEK] + } + }, + appearance = appearance, + shape = shape + ) + } + ) + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt index c83a8afa0..4c9b836cd 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt @@ -5,13 +5,12 @@ import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatepickerAppearance -import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatepickerShape +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape import com.atls.hyperion.ui.primitives.Text import com.atls.hyperion.ui.shared.layout.aspectSquare import com.atls.hyperion.ui.theme.tokens.colors.Colors @@ -26,8 +25,8 @@ fun Day( isInRange: Boolean, isRangeStart: Boolean, isRangeEnd: Boolean, - appearance: DatepickerAppearance, - shape: DatepickerShape, + appearance: DatePickerAppearance, + shape: DatePickerShape, onClick: (LocalDate) -> Unit, ) { val isCurrentMonth = day.position == DayPosition.MonthDate @@ -44,16 +43,23 @@ fun Day( else -> appearance.cellBackgroundColor } + val cellShape = when { + isSelected -> shape.cellActiveShape + isInRange -> shape.cellRangeShape + else -> shape.cellShape + } + val textColor = when { isSelected || isRangeStart || isRangeEnd -> appearance.cellActiveTextColor isInRange -> appearance.cellInRangeTextColor else -> appearance.cellTextColor } + val containerModifier = Modifier .aspectSquare() .padding(shape.cellSpacing) - .clip(shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius)) + .clip(cellShape) .background(backgroundColor) .padding(shape.cellPadding) .then( @@ -61,19 +67,19 @@ fun Day( Modifier.border( shape.cellBorderWidth, appearance.cellActiveBorderColor, - shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius) + cellShape ) else if (isInRange && appearance.cellInRangeBorderColor != Colors.Palette.transparent) Modifier.border( shape.cellBorderWidth, appearance.cellInRangeBorderColor, - shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius) + cellShape ) else if (appearance.cellBorderColor != Colors.Palette.transparent) Modifier.border( shape.cellBorderWidth, appearance.cellBorderColor, - shape.cellShape ?: RoundedCornerShape(shape.cellCornerRadius) + cellShape ) else Modifier ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt index 04eb2f456..dcf60fd70 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt @@ -6,8 +6,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import com.atls.hyperion.ui.fragment.datepicker.config.DAYS_IN_WEEK -import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatepickerAppearance -import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatepickerShape +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape import com.atls.hyperion.ui.primitives.Text import com.atls.hyperion.ui.theme.tokens.layout.Weight import kotlinx.datetime.DayOfWeek @@ -16,8 +16,8 @@ import kotlinx.datetime.format.DayOfWeekNames @Composable fun WeekDays( weekDays: List, - appearance: DatepickerAppearance, - shape: DatepickerShape, + appearance: DatePickerAppearance, + shape: DatePickerShape, dayNames: List = DayOfWeekNames.ENGLISH_ABBREVIATED.names ) { require(dayNames.size == DAYS_IN_WEEK) { "dayNames must contain exactly 7 elements (Mon → Sun)" } @@ -32,7 +32,7 @@ fun WeekDays( textAlign = TextAlign.Center, text = shortName, typography = shape.dayHeaderTypography, - color = appearance.colors.weekDaysTextColor, + color = appearance.weekDaysTextColor, ) } } From 12d5782feb1a80be5731f9e2b0e973f9e0a18f71 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:52:54 +0300 Subject: [PATCH 16/37] feat(ui): date picker fragment --- .../ui/fragment/datepicker/Fragment.kt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt new file mode 100644 index 000000000..6d08c55c4 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt @@ -0,0 +1,33 @@ +package com.atls.hyperion.ui.fragment.datepicker + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.components.modal.popup.Popup +import com.atls.hyperion.ui.fragment.datepicker.model.DateSelection +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.default +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape +import com.atls.hyperion.ui.fragment.datepicker.style.shape.default +import com.atls.hyperion.ui.fragment.datepicker.ui.DatePickerContent + +@Composable +fun DatePicker( + modifier: Modifier = Modifier, + selection: DateSelection, + onSelectionChange: (DateSelection) -> Unit, + onDismiss: () -> Unit, + appearance: DatePickerAppearance = DatePickerAppearance.default(), + shape: DatePickerShape = DatePickerShape.default() +) { + Popup( + modifier = modifier, + onDismissRequest = onDismiss + ) { + DatePickerContent( + selection = selection, + onSelectionChange = onSelectionChange, + appearance = appearance, + shape = shape + ) + } +} From be5606901f89ea1d113271cf48d64d3dca2ba542 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:53:47 +0300 Subject: [PATCH 17/37] feat(ui): date picker model --- .../ui/fragment/datepicker/model/DateSelection.kt | 15 +++++++++++++++ .../fragment/datepicker/model/DividerPosition.kt | 5 +++++ 2 files changed, 20 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DateSelection.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DividerPosition.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DateSelection.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DateSelection.kt new file mode 100644 index 000000000..2996cd71c --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DateSelection.kt @@ -0,0 +1,15 @@ +package com.atls.hyperion.ui.fragment.datepicker.model + +import kotlinx.datetime.LocalDate + +sealed interface DateSelection { + + data class Single( + val date: LocalDate? = null + ) : DateSelection + + data class Range( + val start: LocalDate? = null, + val end: LocalDate? = null + ) : DateSelection +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DividerPosition.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DividerPosition.kt new file mode 100644 index 000000000..a6340af9e --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/model/DividerPosition.kt @@ -0,0 +1,5 @@ +package com.atls.hyperion.ui.fragment.datepicker.model + +enum class DividerPosition { + TOP, BOTTOM, NONE +} From 27c19d8fd5c78aba4f0f216bf9036946ff42b7e8 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:53:59 +0300 Subject: [PATCH 18/37] feat(ui): date utils --- .../ui/fragment/datepicker/lib/NextDateRange.kt | 16 ++++++++++++++++ .../ui/fragment/datepicker/lib/NextMonth.kt | 10 ++++++++++ .../ui/fragment/datepicker/lib/PreviousMonth.kt | 10 ++++++++++ 3 files changed, 36 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextDateRange.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextMonth.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/PreviousMonth.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextDateRange.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextDateRange.kt new file mode 100644 index 000000000..cb65aa690 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextDateRange.kt @@ -0,0 +1,16 @@ +package com.atls.hyperion.ui.fragment.datepicker.lib + +import com.atls.hyperion.ui.fragment.datepicker.model.DateSelection +import kotlinx.datetime.LocalDate + +fun DateSelection.Range.next(clicked: LocalDate): DateSelection.Range = + when { + start == null || end != null -> + copy(start = clicked, end = null) + + clicked < start -> + copy(start = clicked, end = start) + + else -> + copy(end = clicked) + } diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextMonth.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextMonth.kt new file mode 100644 index 000000000..7d054307f --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/NextMonth.kt @@ -0,0 +1,10 @@ +package com.atls.hyperion.ui.fragment.datepicker.lib + +import kotlinx.datetime.Month +import kotlinx.datetime.YearMonth + +fun YearMonth.next(): YearMonth = + if (month == Month.DECEMBER) + YearMonth(year + 1, Month.JANUARY) + else + YearMonth(year, Month.entries[month.ordinal + 1]) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/PreviousMonth.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/PreviousMonth.kt new file mode 100644 index 000000000..1610c86fb --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/lib/PreviousMonth.kt @@ -0,0 +1,10 @@ +package com.atls.hyperion.ui.fragment.datepicker.lib + +import kotlinx.datetime.Month +import kotlinx.datetime.YearMonth + +fun YearMonth.previous(): YearMonth = + if (month == Month.JANUARY) + YearMonth(year - 1, Month.DECEMBER) + else + YearMonth(year, Month.entries[month.ordinal - 1]) From 22f485a8c984f6949b693df1c9fd67b083f9f3fc Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:54:15 +0300 Subject: [PATCH 19/37] chore(ui): date picker constants --- .../atls/hyperion/ui/fragment/datepicker/config/Constants.kt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/config/Constants.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/config/Constants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/config/Constants.kt new file mode 100644 index 000000000..e86eadb6f --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/config/Constants.kt @@ -0,0 +1,4 @@ +package com.atls.hyperion.ui.fragment.datepicker.config + +internal val DAYS_IN_WEEK = 7 +internal val WEEK_RANGE = 0..6 From b49d5424ec5525cb9d308166247598619a792366 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:54:32 +0300 Subject: [PATCH 20/37] feat(ui): date picker styles --- .../datepicker/style/appearance/Appearance.kt | 27 ++++++++++++ .../datepicker/style/appearance/Variants.kt | 27 ++++++++++++ .../fragment/datepicker/style/shape/Shape.kt | 34 +++++++++++++++ .../datepicker/style/shape/Variants.kt | 43 +++++++++++++++++++ .../fragment/datepicker/ui/CalendarHeader.kt | 6 +-- 5 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Variants.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt new file mode 100644 index 000000000..cb1567a4a --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt @@ -0,0 +1,27 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance + +import androidx.compose.ui.graphics.Color +import com.atls.hyperion.ui.components.divider.style.appearance.DividerAppearance +import com.atls.hyperion.ui.components.modal.style.appearance.ModalAppearance + +data class DatePickerAppearance( + val cellBackgroundColor: Color, + val cellTextColor: Color, + val cellActiveBackgroundColor: Color, + val cellActiveTextColor: Color, + val cellInRangeBackgroundColor: Color, + val cellInRangeTextColor: Color, + val cellBorderColor: Color = Color.Transparent, + val cellActiveBorderColor: Color = Color.Transparent, + val cellInRangeBorderColor: Color = Color.Transparent, + val cellHeaderTextColor: Color, + val backgroundColor: Color, + val headerTextColor: Color, + val weekDaysTextColor: Color = headerTextColor, + val arrowColor: Color, + val dividerColor: Color, + val dividerAppearance: DividerAppearance, + val modalAppearance: ModalAppearance +) { + companion object Companion +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Variants.kt new file mode 100644 index 000000000..e59fdb1fa --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Variants.kt @@ -0,0 +1,27 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.components.divider.style.appearance.DividerAppearance +import com.atls.hyperion.ui.components.divider.style.appearance.default +import com.atls.hyperion.ui.components.modal.style.appearance.ModalAppearance +import com.atls.hyperion.ui.components.modal.style.appearance.default +import com.atls.hyperion.ui.theme.tokens.colors.Colors as TokenColors + +@Composable +fun DatePickerAppearance.Companion.default(): DatePickerAppearance = + DatePickerAppearance( + cellBackgroundColor = TokenColors.Palette.transparent, + cellTextColor = TokenColors.Text.black, + cellActiveBackgroundColor = TokenColors.Palette.blue, + cellActiveTextColor = TokenColors.Text.white, + cellInRangeBackgroundColor = TokenColors.Palette.lightPurple, + cellInRangeTextColor = TokenColors.Text.black, + cellHeaderTextColor = TokenColors.Text.gray, + backgroundColor = TokenColors.Palette.white, + headerTextColor = TokenColors.Text.black, + arrowColor = TokenColors.Text.black, + dividerColor = TokenColors.Palette.gray, + weekDaysTextColor = TokenColors.Text.black, + dividerAppearance = DividerAppearance.default(), + modalAppearance = ModalAppearance.default() + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt new file mode 100644 index 000000000..17d915078 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt @@ -0,0 +1,34 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp +import com.atls.hyperion.ui.components.divider.style.shape.DividerShape +import com.atls.hyperion.ui.components.modal.style.shape.ModalShape +import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition +import com.atls.hyperion.ui.theme.tokens.layout.BorderStroke + +data class DatePickerShape( + val cellSpacing: Dp, + val cellPadding: Dp, + val cellBorderWidth: Dp = BorderStroke.none, + val cellBorderColor: Color = Color.Transparent, + val cellShape: Shape, + val cellActiveShape: Shape = cellShape, + val cellRangeShape: Shape = RectangleShape, + val cellTypography: TextStyle, + val headerTypography: TextStyle, + val headerSpacing: Dp, + val calendarPadding: PaddingValues, + val dayHeaderTypography: TextStyle, + val headerIconSize: Dp, + val headerHorizontalPadding: Dp, + val divider: DividerPosition = DividerPosition.NONE, + val dividerShape: DividerShape, + val modalShape: ModalShape +) { + companion object Companion +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt new file mode 100644 index 000000000..9ad908e0f --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt @@ -0,0 +1,43 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.TextStyle +import com.atls.hyperion.ui.components.divider.style.shape.DividerShape +import com.atls.hyperion.ui.components.divider.style.shape.default +import com.atls.hyperion.ui.components.modal.style.shape.ModalShape +import com.atls.hyperion.ui.components.modal.style.shape.popup +import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition +import com.atls.hyperion.ui.theme.tokens.components.IconSize +import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius +import com.atls.hyperion.ui.theme.tokens.layout.Space +import com.atls.hyperion.ui.theme.typography.FontSize +import com.atls.hyperion.ui.theme.typography.FontWeight + +@Composable +fun DatePickerShape.Companion.default(): DatePickerShape = + DatePickerShape( + cellTypography = TextStyle( + fontSize = FontSize.xs, + fontWeight = FontWeight.regular, + ), + headerTypography = TextStyle( + fontSize = FontSize.md, + fontWeight = FontWeight.bold, + ), + dayHeaderTypography = TextStyle( + fontSize = FontSize.xs2, + fontWeight = FontWeight.medium, + ), + cellSpacing = Space.zero, + cellPadding = Space.g8, + cellShape = RoundedCornerShape(CornerRadius.xs2), + calendarPadding = PaddingValues(Space.g12), + headerIconSize = IconSize.medium, + headerSpacing = Space.g12, + headerHorizontalPadding = Space.g12, + divider = DividerPosition.BOTTOM, + dividerShape = DividerShape.default(), + modalShape = ModalShape.popup() + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt index 62d878968..7fda72508 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt @@ -10,7 +10,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import com.atls.hyperion.ui.components.divider.horizontal.HorizontalDivider -import com.atls.hyperion.ui.fragment.datepicker.model.CalendarDivider +import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape import com.atls.hyperion.ui.generated.resources.Res @@ -33,7 +33,7 @@ fun CalendarHeader( onPrevMonth: () -> Unit, onNextMonth: () -> Unit, ) { - if (shape.divider == CalendarDivider.TOP) { + if (shape.divider == DividerPosition.TOP) { HorizontalDivider( appearance = appearance.dividerAppearance, shape = shape.dividerShape @@ -69,7 +69,7 @@ fun CalendarHeader( ) } - if (shape.divider == CalendarDivider.BOTTOM) { + if (shape.divider == DividerPosition.BOTTOM) { VerticalSpacer(shape.headerSpacing) HorizontalDivider( appearance = appearance.dividerAppearance, From 6b25b13cd684dacddddad2ea1209276ad78d24cd Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:54:56 +0300 Subject: [PATCH 21/37] feat(ui): chevron icons --- .../composeResources/drawable/chevron_left.xml | 10 ++++++++++ .../composeResources/drawable/chevron_right.xml | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_left.xml create mode 100644 mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_right.xml diff --git a/mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_left.xml b/mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_left.xml new file mode 100644 index 000000000..62b41a877 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_left.xml @@ -0,0 +1,10 @@ + + + diff --git a/mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_right.xml b/mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_right.xml new file mode 100644 index 000000000..3979fa801 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/composeResources/drawable/chevron_right.xml @@ -0,0 +1,10 @@ + + + From 278ef5febd41e9dc6845326b41fa16e4654432a7 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:55:11 +0300 Subject: [PATCH 22/37] feat(theme): draghandle sizes --- .../ui/theme/tokens/components/DragHandleSize.kt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/DragHandleSize.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/DragHandleSize.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/DragHandleSize.kt new file mode 100644 index 000000000..c21fa6ed0 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/DragHandleSize.kt @@ -0,0 +1,9 @@ +package com.atls.hyperion.ui.theme.tokens.components + +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +object DragHandleSize { + val height: Dp = 6.dp + val width: Dp = 79.dp +} From 210881adcb7a794a14fedd8f9f81339b94a1474c Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:55:21 +0300 Subject: [PATCH 23/37] chore(theme): new elevation token --- .../kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt index ff5674e06..871c26c28 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt @@ -4,4 +4,5 @@ import androidx.compose.ui.unit.dp object Elevation { val zero = 0.dp + val tiny = 2.dp } From e681594da0eea26eade8bc256a2b8f7e5141ddf8 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:55:54 +0300 Subject: [PATCH 24/37] refactor(ui): rename divider files --- .../divider/horizontal/{HorizontalDivider.kt => Component.kt} | 0 .../divider/vertical/{VerticalDivider.kt => Component.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/horizontal/{HorizontalDivider.kt => Component.kt} (100%) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/vertical/{VerticalDivider.kt => Component.kt} (100%) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/horizontal/HorizontalDivider.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/horizontal/Component.kt similarity index 100% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/horizontal/HorizontalDivider.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/horizontal/Component.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/vertical/VerticalDivider.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/vertical/Component.kt similarity index 100% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/vertical/VerticalDivider.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/divider/vertical/Component.kt From 55eae6d27b09b20851993811ff6cfbfa676d139c Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:57:16 +0300 Subject: [PATCH 25/37] feat(ui): drag handle component --- .../modal/bottom/dragHandle/Component.kt | 29 +++++++++++++++++++ .../dragHandle/style/appearance/Appearance.kt | 9 ++++++ .../dragHandle/style/appearance/Variants.kt | 10 +++++++ .../bottom/dragHandle/style/shape/Shape.kt | 13 +++++++++ .../bottom/dragHandle/style/shape/Variants.kt | 16 ++++++++++ 5 files changed, 77 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/Component.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Appearance.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Variants.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Shape.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/Component.kt new file mode 100644 index 000000000..ecb695f41 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/Component.kt @@ -0,0 +1,29 @@ +package com.atls.hyperion.ui.components.modal.bottom.dragHandle + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.appearance.DragHandleAppearance +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.shape.DragHandleShape + +@Composable +fun DragHandle( + appearance: DragHandleAppearance, + shape: DragHandleShape +) { + Box( + modifier = Modifier + .padding(shape.paddings) + .width(shape.width) + .height(shape.height) + .background( + color = appearance.backgroundColor, + shape = RoundedCornerShape(shape.cornerRadius) + ) + ) +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Appearance.kt new file mode 100644 index 000000000..14cea132b --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Appearance.kt @@ -0,0 +1,9 @@ +package com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.appearance + +import androidx.compose.ui.graphics.Color + +data class DragHandleAppearance( + val backgroundColor: Color +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Variants.kt new file mode 100644 index 000000000..b6b63ace1 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/appearance/Variants.kt @@ -0,0 +1,10 @@ +package com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.appearance + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.theme.tokens.colors.Colors + +@Composable +fun DragHandleAppearance.Companion.default(): DragHandleAppearance = + DragHandleAppearance( + backgroundColor = Colors.Palette.gray + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Shape.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Shape.kt new file mode 100644 index 000000000..78edfd16a --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Shape.kt @@ -0,0 +1,13 @@ +package com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.unit.Dp + +data class DragHandleShape( + val height: Dp, + val width: Dp, + val cornerRadius: Dp, + val paddings: PaddingValues +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt new file mode 100644 index 000000000..8fc610a60 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt @@ -0,0 +1,16 @@ +package com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.theme.tokens.components.DragHandleSize +import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius +import com.atls.hyperion.ui.theme.tokens.layout.Space + +@Composable +fun DragHandleShape.Companion.default(): DragHandleShape = + DragHandleShape( + height = DragHandleSize.height, + width = DragHandleSize.width, + cornerRadius = CornerRadius.xl6, + paddings = PaddingValues(top = Space.g8) + ) From a04a68b30e57e4cffa63f1b2e4a1ad511ad641a4 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:57:31 +0300 Subject: [PATCH 26/37] feat(ui): modal styles --- .../modal/style/appearance/Appearance.kt | 9 +++++ .../modal/style/appearance/Variants.kt | 10 ++++++ .../ui/components/modal/style/shape/Shape.kt | 14 ++++++++ .../components/modal/style/shape/Variants.kt | 34 +++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Appearance.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Variants.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Shape.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Appearance.kt new file mode 100644 index 000000000..45aa7714d --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Appearance.kt @@ -0,0 +1,9 @@ +package com.atls.hyperion.ui.components.modal.style.appearance + +import androidx.compose.ui.graphics.Color + +data class ModalAppearance( + val backgroundColor: Color +) { + companion object Companion +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Variants.kt new file mode 100644 index 000000000..52bafdf81 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/appearance/Variants.kt @@ -0,0 +1,10 @@ +package com.atls.hyperion.ui.components.modal.style.appearance + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.theme.tokens.colors.Colors + +@Composable +fun ModalAppearance.Companion.default(): ModalAppearance = + ModalAppearance( + backgroundColor = Colors.Palette.white + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Shape.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Shape.kt new file mode 100644 index 000000000..5245e4d98 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Shape.kt @@ -0,0 +1,14 @@ +package com.atls.hyperion.ui.components.modal.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Dp + +data class ModalShape( + val shape: Shape, + val shadowElevation: Dp, + val paddings: PaddingValues, + val spacers: PaddingValues +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt new file mode 100644 index 000000000..ea3f71b06 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt @@ -0,0 +1,34 @@ +package com.atls.hyperion.ui.components.modal.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.theme.tokens.Elevation +import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius +import com.atls.hyperion.ui.theme.tokens.layout.Space + +@Composable +fun ModalShape.Companion.popup(): ModalShape = + ModalShape( + shape = RoundedCornerShape(CornerRadius.zero), + shadowElevation = Elevation.tiny, + paddings = PaddingValues(Space.g20), + spacers = PaddingValues(horizontal = Space.g24) + ) + +@Composable +fun ModalShape.Companion.bottom(): ModalShape = + ModalShape( + shape = RoundedCornerShape( + topStart = CornerRadius.xl4, + topEnd = CornerRadius.xl4, + ), + shadowElevation = Elevation.zero, + paddings = PaddingValues( + top = Space.g4, + bottom = Space.g20, + start = Space.g20, + end = Space.g20 + ), + spacers = PaddingValues(horizontal = Space.zero) + ) From f8133688319c27790eeffa8c9bbff47437f6e66d Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:58:11 +0300 Subject: [PATCH 27/37] feat(ui): modal components with stories --- .../ui/components/modal/bottom/Component.kt | 59 ++++++++++++++ .../modal/bottom/stories/Component.kt | 77 +++++++++++++++++++ .../ui/components/modal/popup/Popup.kt | 43 +++++++++++ .../modal/popup/stories/Component.kt | 63 +++++++++++++++ 4 files changed, 242 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/Component.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/stories/Component.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/Popup.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/stories/Component.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/Component.kt new file mode 100644 index 000000000..f691e5306 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/Component.kt @@ -0,0 +1,59 @@ +package com.atls.hyperion.ui.components.modal.bottom + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBars +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.SheetState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.DragHandle +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.appearance.DragHandleAppearance +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.appearance.default +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.shape.DragHandleShape +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.shape.default +import com.atls.hyperion.ui.components.modal.style.appearance.ModalAppearance +import com.atls.hyperion.ui.components.modal.style.appearance.default +import com.atls.hyperion.ui.components.modal.style.shape.ModalShape +import com.atls.hyperion.ui.components.modal.style.shape.bottom + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun BottomDialog( + modifier: Modifier = Modifier, + appearance: ModalAppearance = ModalAppearance.default(), + shape: ModalShape = ModalShape.bottom(), + dragHandleShape: DragHandleShape = DragHandleShape.default(), + dragHandleAppearance: DragHandleAppearance = DragHandleAppearance.default(), + dragHandle: @Composable () -> Unit = { + DragHandle( + appearance = dragHandleAppearance, + shape = dragHandleShape + ) + }, + sheetState: SheetState, + onDismissRequest: () -> Unit, + content: @Composable () -> Unit +) { + ModalBottomSheet( + modifier = modifier + .windowInsetsPadding(WindowInsets.statusBars), + onDismissRequest = onDismissRequest, + sheetState = sheetState, + shape = shape.shape, + dragHandle = dragHandle, + containerColor = appearance.backgroundColor, + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(shape.paddings) + ) { + content() + } + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/stories/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/stories/Component.kt new file mode 100644 index 000000000..8ce2156a5 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/stories/Component.kt @@ -0,0 +1,77 @@ +package com.atls.hyperion.ui.components.modal.bottom.stories + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import com.atls.hyperion.storybook.shared.model.ComponentExample +import com.atls.hyperion.ui.components.button.Button +import com.atls.hyperion.ui.components.button.styles.appearance.ButtonAppearance +import com.atls.hyperion.ui.components.button.styles.appearance.blue +import com.atls.hyperion.ui.components.button.styles.shape.ButtonShape +import com.atls.hyperion.ui.components.button.styles.shape.normal +import com.atls.hyperion.ui.components.modal.bottom.BottomDialog +import com.atls.hyperion.ui.theme.tokens.layout.Space +import kotlinx.coroutines.launch + +class BottomDialogStory : ComponentExample { + override val name: String = "BottomDialog" + + @OptIn(ExperimentalMaterial3Api::class) + @Composable + override fun Content() { + var showDialog by remember { mutableStateOf(false) } + val sheetState = rememberModalBottomSheetState() + val scope = rememberCoroutineScope() + + Column( + modifier = Modifier + .fillMaxWidth() + .padding(Space.g12) + ) { + Button( + text = "Show Bottom Dialog", + appearance = ButtonAppearance.blue(), + shape = ButtonShape.normal(), + onClick = { showDialog = true } + ) + + if (showDialog) { + BottomDialog( + sheetState = sheetState, + onDismissRequest = { showDialog = false } + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(Space.g16) + ) { + Text(text = "This is a Bottom Dialog") + Button( + modifier = Modifier.padding(top = Space.g12), + text = "Close", + appearance = ButtonAppearance.blue(), + shape = ButtonShape.normal(), + onClick = { + scope.launch { sheetState.hide() }.invokeOnCompletion { + if (!sheetState.isVisible) { + showDialog = false + } + } + } + ) + } + } + } + } + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/Popup.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/Popup.kt new file mode 100644 index 000000000..f5f5cd0f8 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/Popup.kt @@ -0,0 +1,43 @@ +package com.atls.hyperion.ui.components.modal.popup + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.atls.hyperion.ui.components.modal.style.appearance.ModalAppearance +import com.atls.hyperion.ui.components.modal.style.appearance.default +import com.atls.hyperion.ui.components.modal.style.shape.ModalShape +import com.atls.hyperion.ui.components.modal.style.shape.popup + +@Composable +fun Popup( + modifier: Modifier = Modifier, + appearance: ModalAppearance = ModalAppearance.default(), + shape: ModalShape = ModalShape.popup(), + onDismissRequest: () -> Unit, + content: @Composable () -> Unit +) { + Dialog( + onDismissRequest = onDismissRequest, + properties = DialogProperties( + usePlatformDefaultWidth = false + ) + ) { + Box( + modifier = modifier + .padding(shape.spacers) + .background( + color = appearance.backgroundColor, + shape = shape.shape + ) + .fillMaxWidth() + .padding(shape.paddings) + ) { + content() + } + } +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/stories/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/stories/Component.kt new file mode 100644 index 000000000..378158877 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/popup/stories/Component.kt @@ -0,0 +1,63 @@ +package com.atls.hyperion.ui.components.modal.popup.stories + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import com.atls.hyperion.storybook.shared.model.ComponentExample +import com.atls.hyperion.ui.components.button.Button +import com.atls.hyperion.ui.components.button.styles.appearance.ButtonAppearance +import com.atls.hyperion.ui.components.button.styles.appearance.blue +import com.atls.hyperion.ui.components.button.styles.shape.ButtonShape +import com.atls.hyperion.ui.components.button.styles.shape.normal +import com.atls.hyperion.ui.components.modal.popup.Popup +import com.atls.hyperion.ui.theme.tokens.layout.Space + +class PopupStory : ComponentExample { + override val name: String = "Popup" + + @Composable + override fun Content() { + var showDialog by remember { mutableStateOf(false) } + + Column( + modifier = Modifier + .fillMaxWidth() + .padding(Space.g12) + ) { + Button( + text = "Show Popup", + appearance = ButtonAppearance.blue(), + shape = ButtonShape.normal(), + onClick = { showDialog = true } + ) + + if (showDialog) { + Popup( + onDismissRequest = { showDialog = false } + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(Space.g16) + ) { + Text(text = "This is a Popup Dialog") + Button( + modifier = Modifier.padding(top = Space.g12), + text = "Close", + appearance = ButtonAppearance.blue(), + shape = ButtonShape.normal(), + onClick = { showDialog = false } + ) + } + } + } + } + } +} From 90c4ea2de764da415d58aac97b2ea2042357108f Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:58:34 +0300 Subject: [PATCH 28/37] feat(ui): date picker stories --- .../fragment/datepicker/stories/Component.kt | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/stories/Component.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/stories/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/stories/Component.kt new file mode 100644 index 000000000..39b06502e --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/stories/Component.kt @@ -0,0 +1,69 @@ +package com.atls.hyperion.ui.fragment.datepicker.stories + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.atls.hyperion.storybook.shared.model.ComponentExample +import com.atls.hyperion.ui.fragment.datepicker.DatePicker +import com.atls.hyperion.ui.fragment.datepicker.model.DateSelection + +class DatePickerStory( + override val name: String = "Date picker" +) : ComponentExample { + + @Composable + override fun Content() { + var selection by remember { + mutableStateOf(DateSelection.Single(null)) + } + + Column(Modifier.padding(16.dp)) { + Text( + text = when (val s = selection) { + is DateSelection.Single -> "Selected: ${s.date ?: "null"}" + else -> "Unexpected state" + } + ) + + DatePicker( + selection = selection, + onSelectionChange = { selection = it }, + onDismiss = {} + ) + } + } +} + +class DateRangePickerStory( + override val name: String = "Date range picker" +) : ComponentExample { + + @Composable + override fun Content() { + var selection by remember { + mutableStateOf(DateSelection.Range(null, null)) + } + + Column(Modifier.padding(16.dp)) { + Text( + text = when (val s = selection) { + is DateSelection.Range -> "From: ${s.start ?: "null"} To: ${s.end ?: "null"}" + else -> "Unexpected state" + } + ) + + DatePicker( + selection = selection, + onSelectionChange = { selection = it }, + onDismiss = {} + ) + } + } +} From 66b844c11bdefdb4eddfa40c597410588740325a Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:58:52 +0300 Subject: [PATCH 29/37] feat(ui): date/calendar deps --- mobile/kmp/ui/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mobile/kmp/ui/build.gradle.kts b/mobile/kmp/ui/build.gradle.kts index 06e228750..4aeef3e65 100644 --- a/mobile/kmp/ui/build.gradle.kts +++ b/mobile/kmp/ui/build.gradle.kts @@ -34,12 +34,15 @@ kotlin { implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material) + implementation(compose.material3) implementation(compose.ui) implementation(compose.components.resources) implementation(compose.components.uiToolingPreview) implementation(libs.compose.shadow) implementation(libs.coil.compose) implementation(libs.coil.network.ktor) + implementation(libs.compose.calendar) + api(libs.kotlinx.datetime) } androidMain { From 6633cda071553deaeb4124ab9d645a16c59da8e9 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 04:59:12 +0300 Subject: [PATCH 30/37] chore(storybook): spacing for component variants --- .../com/atls/hyperion/storybook/shared/ui/ComponentVariants.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mobile/kmp/storybook/src/commonMain/kotlin/com/atls/hyperion/storybook/shared/ui/ComponentVariants.kt b/mobile/kmp/storybook/src/commonMain/kotlin/com/atls/hyperion/storybook/shared/ui/ComponentVariants.kt index c0e6bb68b..dab73d455 100644 --- a/mobile/kmp/storybook/src/commonMain/kotlin/com/atls/hyperion/storybook/shared/ui/ComponentVariants.kt +++ b/mobile/kmp/storybook/src/commonMain/kotlin/com/atls/hyperion/storybook/shared/ui/ComponentVariants.kt @@ -3,8 +3,10 @@ package com.atls.hyperion.storybook.shared.ui import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.Divider @@ -55,6 +57,7 @@ fun ComponentVariants( fontSize = FontSize.small, modifier = Modifier.padding(top = Padding.tiny) ) + Spacer(Modifier.width(Padding.small)) content(appearanceProvider(), shapeProvider()) } Divider() From 5bbdcc52d06c191dabe7b81d8f967aa55cb6a427 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 05:00:17 +0300 Subject: [PATCH 31/37] chore(deps): toml update --- mobile/kmp/gradle/libs.versions.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mobile/kmp/gradle/libs.versions.toml b/mobile/kmp/gradle/libs.versions.toml index 9552d8258..40c85d346 100644 --- a/mobile/kmp/gradle/libs.versions.toml +++ b/mobile/kmp/gradle/libs.versions.toml @@ -1,13 +1,17 @@ [versions] +calendar = "2.9.0" kotlin = "2.2.0" ktor = "3.3.1" compose = "1.10.0-rc02" composeShadow = "2.0.4" coilCompose = "3.3.0" +kotlinxDatetime = "0.6.1" agp = "8.9.0" androidx-activityCompose = "1.9.3" [libraries] +compose-calendar = { module = "com.kizitonwose.calendar:compose-multiplatform", version.ref = "calendar" } +kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } compose-shadow = { module = "com.adamglin:compose-shadow", version.ref = "composeShadow" } coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilCompose" } From 3834a64e5f27b35c1994382188382af02514af07 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 05:00:30 +0300 Subject: [PATCH 32/37] feat(app): new stories usage --- .../src/commonMain/kotlin/com/atls/hyperion/sample/App.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mobile/kmp/sample/src/commonMain/kotlin/com/atls/hyperion/sample/App.kt b/mobile/kmp/sample/src/commonMain/kotlin/com/atls/hyperion/sample/App.kt index 4678edce3..cfcc0b92e 100644 --- a/mobile/kmp/sample/src/commonMain/kotlin/com/atls/hyperion/sample/App.kt +++ b/mobile/kmp/sample/src/commonMain/kotlin/com/atls/hyperion/sample/App.kt @@ -9,7 +9,11 @@ import com.atls.hyperion.ui.components.card.stories.CardStory import com.atls.hyperion.ui.components.checkbox.stories.CheckboxStory import com.atls.hyperion.ui.components.divider.stories.DividerStory import com.atls.hyperion.ui.components.input.stories.InputStory +import com.atls.hyperion.ui.components.modal.bottom.stories.BottomDialogStory +import com.atls.hyperion.ui.components.modal.popup.stories.PopupStory import com.atls.hyperion.ui.components.switch.stories.SwitchStory +import com.atls.hyperion.ui.fragment.datepicker.stories.DatePickerStory +import com.atls.hyperion.ui.fragment.datepicker.stories.DateRangePickerStory import com.atls.hyperion.ui.primitives.stories.LinkStory import com.atls.hyperion.ui.primitives.stories.TextStory @@ -19,10 +23,14 @@ fun App() { Storybook( components = listOf( AvatarStory(), + BottomDialogStory(), ButtonStory(), CheckboxStory(), + DatePickerStory(), + DateRangePickerStory(), DividerStory(), InputStory(), + PopupStory(), SwitchStory(), CardStory(), TextStory(), From fe5a744c1b10a74b478b26b4853054730d4316d8 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Tue, 13 Jan 2026 13:44:54 +0300 Subject: [PATCH 33/37] chore(input): remove todo --- .../hyperion/ui/components/input/style/appearance/Variants.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt index 5c64c68ed..32f59a713 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/input/style/appearance/Variants.kt @@ -10,7 +10,7 @@ fun InputAppearance.Companion.blue(): InputAppearance = filled = Colors.fromColorSet(TokenColors.Input.Blue.Default), focused = Colors.fromColorSet(TokenColors.Input.Blue.Focus), disabled = Colors.fromColorSet(TokenColors.Input.Blue.Disabled), - error = Colors.fromColorSet(TokenColors.Input.Blue.Default), // TODO: Add error colors to tokens + error = Colors.fromColorSet(TokenColors.Input.Blue.Default), active = Colors.fromColorSet(TokenColors.Input.Blue.Active) ) @@ -21,6 +21,6 @@ fun InputAppearance.Companion.white(): InputAppearance = filled = Colors.fromColorSet(TokenColors.Input.White.Default), focused = Colors.fromColorSet(TokenColors.Input.White.Focus), disabled = Colors.fromColorSet(TokenColors.Input.White.Disabled), - error = Colors.fromColorSet(TokenColors.Input.White.Default), // TODO: Add error colors to tokens + error = Colors.fromColorSet(TokenColors.Input.White.Default), active = Colors.fromColorSet(TokenColors.Input.White.Active) ) From 3c881b1364c0e4030b8fd9aa2b67d0f5af32942e Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Wed, 14 Jan 2026 01:52:41 +0300 Subject: [PATCH 34/37] refactor(ui): move alpha from colors to effects --- .../atls/hyperion/ui/theme/tokens/{colors => effects}/Alpha.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/{colors => effects}/Alpha.kt (61%) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/effects/Alpha.kt similarity index 61% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/effects/Alpha.kt index ae0441a7a..6ef296fef 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/colors/Alpha.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/effects/Alpha.kt @@ -1,4 +1,4 @@ -package com.atls.hyperion.ui.theme.tokens.colors +package com.atls.hyperion.ui.theme.tokens.effects object Alpha { val huge = 0.9f From beea2023f00d5b536fc9e2e27b2d23019c3eed81 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Wed, 14 Jan 2026 01:55:22 +0300 Subject: [PATCH 35/37] refactor(theme): move component sizes to components --- .../com/atls/hyperion/ui/components/checkbox/Component.kt | 2 +- .../modal/bottom/dragHandle/style/Size.kt} | 2 +- .../components/modal/bottom/dragHandle/style/shape/Variants.kt | 2 +- .../SwitchSize.kt => components/switch/styles/Size.kt} | 2 +- .../atls/hyperion/ui/components/switch/styles/shape/Variants.kt | 2 +- .../hyperion/ui/fragment/datepicker/style/shape/Variants.kt | 2 +- .../atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt | 2 +- .../atls/hyperion/ui/primitives/{Icon.kt => icon/Primitive.kt} | 2 +- .../tokens/components/IconSize.kt => primitives/icon/Size.kt} | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/{theme/tokens/components/DragHandleSize.kt => components/modal/bottom/dragHandle/style/Size.kt} (68%) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/{theme/tokens/components/SwitchSize.kt => components/switch/styles/Size.kt} (73%) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/{Icon.kt => icon/Primitive.kt} (92%) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/{theme/tokens/components/IconSize.kt => primitives/icon/Size.kt} (60%) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/checkbox/Component.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/checkbox/Component.kt index f09cb7708..f0f1c2bf7 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/checkbox/Component.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/checkbox/Component.kt @@ -16,7 +16,7 @@ import com.atls.hyperion.ui.components.checkbox.locals.LocalState import com.atls.hyperion.ui.components.checkbox.state.State import com.atls.hyperion.ui.components.checkbox.styles.appearance.CheckboxAppearance import com.atls.hyperion.ui.components.checkbox.styles.shape.CheckboxShape -import com.atls.hyperion.ui.primitives.Icon +import com.atls.hyperion.ui.primitives.icon.Icon import com.atls.hyperion.ui.theme.tokens.layout.Weight @Composable diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/DragHandleSize.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/Size.kt similarity index 68% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/DragHandleSize.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/Size.kt index c21fa6ed0..a442f8a74 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/DragHandleSize.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/Size.kt @@ -1,4 +1,4 @@ -package com.atls.hyperion.ui.theme.tokens.components +package com.atls.hyperion.ui.components.modal.bottom.dragHandle.style import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt index 8fc610a60..ed2d95e21 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/bottom/dragHandle/style/shape/Variants.kt @@ -2,7 +2,7 @@ package com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.shape import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable -import com.atls.hyperion.ui.theme.tokens.components.DragHandleSize +import com.atls.hyperion.ui.components.modal.bottom.dragHandle.style.DragHandleSize import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius import com.atls.hyperion.ui.theme.tokens.layout.Space diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/SwitchSize.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/Size.kt similarity index 73% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/SwitchSize.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/Size.kt index 72132862e..d0be7b9ec 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/SwitchSize.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/Size.kt @@ -1,4 +1,4 @@ -package com.atls.hyperion.ui.theme.tokens.components +package com.atls.hyperion.ui.components.switch.styles import androidx.compose.ui.unit.dp diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt index 15e5b743a..bda4ed823 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/switch/styles/shape/Variants.kt @@ -1,6 +1,6 @@ package com.atls.hyperion.ui.components.switch.styles.shape -import com.atls.hyperion.ui.theme.tokens.components.SwitchSize +import com.atls.hyperion.ui.components.switch.styles.SwitchSize import com.atls.hyperion.ui.theme.tokens.layout.Space fun SwitchShape.Companion.medium(): SwitchShape = diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt index 9ad908e0f..d4e609587 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt @@ -9,7 +9,7 @@ import com.atls.hyperion.ui.components.divider.style.shape.default import com.atls.hyperion.ui.components.modal.style.shape.ModalShape import com.atls.hyperion.ui.components.modal.style.shape.popup import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition -import com.atls.hyperion.ui.theme.tokens.components.IconSize +import com.atls.hyperion.ui.primitives.icon.IconSize import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius import com.atls.hyperion.ui.theme.tokens.layout.Space import com.atls.hyperion.ui.theme.typography.FontSize diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt index 7fda72508..a7a1d8772 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt @@ -16,9 +16,9 @@ import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape import com.atls.hyperion.ui.generated.resources.Res import com.atls.hyperion.ui.generated.resources.chevron_left import com.atls.hyperion.ui.generated.resources.chevron_right -import com.atls.hyperion.ui.primitives.Icon import com.atls.hyperion.ui.primitives.Text import com.atls.hyperion.ui.primitives.VerticalSpacer +import com.atls.hyperion.ui.primitives.icon.Icon import org.jetbrains.compose.resources.painterResource @Composable diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/Icon.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/icon/Primitive.kt similarity index 92% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/Icon.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/icon/Primitive.kt index 9aafb876d..2f9897700 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/Icon.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/icon/Primitive.kt @@ -1,4 +1,4 @@ -package com.atls.hyperion.ui.primitives +package com.atls.hyperion.ui.primitives.icon import androidx.compose.foundation.layout.size import androidx.compose.material.Icon diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/IconSize.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/icon/Size.kt similarity index 60% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/IconSize.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/icon/Size.kt index 33bd8f36b..8e6faec47 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/components/IconSize.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/primitives/icon/Size.kt @@ -1,4 +1,4 @@ -package com.atls.hyperion.ui.theme.tokens.components +package com.atls.hyperion.ui.primitives.icon import androidx.compose.ui.unit.dp From 7150f6d67e95e4f977eb2aae0729b4a7c2f0dde9 Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Wed, 14 Jan 2026 01:56:06 +0300 Subject: [PATCH 36/37] refactor(theme): move elevation tokens to layout --- .../kotlin/com/atls/hyperion/ui/components/button/Layout.kt | 2 +- .../ui/components/button/styles/appearance/Appearance.kt | 2 +- .../hyperion/ui/components/card/style/appearance/Appearance.kt | 2 +- .../atls/hyperion/ui/components/modal/style/shape/Variants.kt | 2 +- .../com/atls/hyperion/ui/theme/tokens/{ => layout}/Elevation.kt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/{ => layout}/Elevation.kt (66%) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/Layout.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/Layout.kt index 5e41c0509..3077aaab7 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/Layout.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/Layout.kt @@ -23,7 +23,7 @@ import com.atls.hyperion.ui.components.button.styles.appearance.Colors import com.atls.hyperion.ui.components.button.styles.shape.ButtonShape import com.atls.hyperion.ui.shared.addon.AddonPosition import com.atls.hyperion.ui.shared.addon.AddonSlotManager -import com.atls.hyperion.ui.theme.tokens.Elevation +import com.atls.hyperion.ui.theme.tokens.layout.Elevation import com.atls.hyperion.ui.theme.tokens.colors.Colors as ThemeColors @OptIn(ExperimentalMaterialApi::class) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/styles/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/styles/appearance/Appearance.kt index 5a2048b9e..1c1b0db9c 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/styles/appearance/Appearance.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/button/styles/appearance/Appearance.kt @@ -2,7 +2,7 @@ package com.atls.hyperion.ui.components.button.styles.appearance import androidx.compose.ui.unit.Dp import com.atls.hyperion.ui.components.button.state.ButtonState -import com.atls.hyperion.ui.theme.tokens.Elevation +import com.atls.hyperion.ui.theme.tokens.layout.Elevation data class ButtonAppearance( val default: Colors, diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/card/style/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/card/style/appearance/Appearance.kt index 8af36bcc7..1f874708c 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/card/style/appearance/Appearance.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/card/style/appearance/Appearance.kt @@ -2,7 +2,7 @@ package com.atls.hyperion.ui.components.card.style.appearance import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp -import com.atls.hyperion.ui.theme.tokens.Elevation +import com.atls.hyperion.ui.theme.tokens.layout.Elevation import com.atls.hyperion.ui.theme.tokens.colors.Colors as ThemeColors data class CardAppearance( diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt index ea3f71b06..dd33044dc 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/components/modal/style/shape/Variants.kt @@ -3,8 +3,8 @@ package com.atls.hyperion.ui.components.modal.style.shape import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable -import com.atls.hyperion.ui.theme.tokens.Elevation import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius +import com.atls.hyperion.ui.theme.tokens.layout.Elevation import com.atls.hyperion.ui.theme.tokens.layout.Space @Composable diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/layout/Elevation.kt similarity index 66% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/layout/Elevation.kt index 871c26c28..29d13b027 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/Elevation.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/theme/tokens/layout/Elevation.kt @@ -1,4 +1,4 @@ -package com.atls.hyperion.ui.theme.tokens +package com.atls.hyperion.ui.theme.tokens.layout import androidx.compose.ui.unit.dp From 2c206155d4709e738dd3da7660f59a62f24d215e Mon Sep 17 00:00:00 2001 From: Arina Gazhina Date: Wed, 14 Jan 2026 02:26:57 +0300 Subject: [PATCH 37/37] refactor(picker): split styles --- .../ui/fragment/datepicker/Fragment.kt | 4 +- .../datepicker/style/appearance/Appearance.kt | 27 ------------ .../datepicker/style/appearance/Cell.kt | 18 ++++++++ .../datepicker/style/appearance/Header.kt | 10 +++++ .../datepicker/style/appearance/Picker.kt | 17 ++++++++ .../datepicker/style/appearance/WeekDays.kt | 9 ++++ .../style/appearance/variants/Cell.kt | 17 ++++++++ .../style/appearance/variants/Header.kt | 12 ++++++ .../{Variants.kt => variants/Picker.kt} | 19 ++++---- .../style/appearance/variants/WeekDays.kt | 11 +++++ .../datepicker/style/shape/Calendar.kt | 15 +++++++ .../fragment/datepicker/style/shape/Cell.kt | 22 ++++++++++ .../fragment/datepicker/style/shape/Header.kt | 13 ++++++ .../fragment/datepicker/style/shape/Shape.kt | 31 ++----------- .../datepicker/style/shape/Variants.kt | 43 ------------------- .../style/shape/variants/Calendar.kt | 20 +++++++++ .../datepicker/style/shape/variants/Cell.kt | 26 +++++++++++ .../datepicker/style/shape/variants/Header.kt | 21 +++++++++ .../datepicker/style/shape/variants/Picker.kt | 15 +++++++ .../fragment/datepicker/ui/CalendarHeader.kt | 26 +++++------ .../datepicker/ui/DatePickerContent.kt | 2 +- .../hyperion/ui/fragment/datepicker/ui/Day.kt | 42 +++++++++--------- .../ui/fragment/datepicker/ui/WeekDays.kt | 4 +- 23 files changed, 276 insertions(+), 148 deletions(-) delete mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Cell.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Header.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Picker.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/WeekDays.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Cell.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Header.kt rename mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/{Variants.kt => variants/Picker.kt} (59%) create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/WeekDays.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Calendar.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Cell.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Header.kt delete mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Calendar.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Cell.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Header.kt create mode 100644 mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Picker.kt diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt index 6d08c55c4..6fa36b2df 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/Fragment.kt @@ -5,9 +5,9 @@ import androidx.compose.ui.Modifier import com.atls.hyperion.ui.components.modal.popup.Popup import com.atls.hyperion.ui.fragment.datepicker.model.DateSelection import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance -import com.atls.hyperion.ui.fragment.datepicker.style.appearance.default +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.variants.default import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape -import com.atls.hyperion.ui.fragment.datepicker.style.shape.default +import com.atls.hyperion.ui.fragment.datepicker.style.shape.variants.default import com.atls.hyperion.ui.fragment.datepicker.ui.DatePickerContent @Composable diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt deleted file mode 100644 index cb1567a4a..000000000 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Appearance.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.atls.hyperion.ui.fragment.datepicker.style.appearance - -import androidx.compose.ui.graphics.Color -import com.atls.hyperion.ui.components.divider.style.appearance.DividerAppearance -import com.atls.hyperion.ui.components.modal.style.appearance.ModalAppearance - -data class DatePickerAppearance( - val cellBackgroundColor: Color, - val cellTextColor: Color, - val cellActiveBackgroundColor: Color, - val cellActiveTextColor: Color, - val cellInRangeBackgroundColor: Color, - val cellInRangeTextColor: Color, - val cellBorderColor: Color = Color.Transparent, - val cellActiveBorderColor: Color = Color.Transparent, - val cellInRangeBorderColor: Color = Color.Transparent, - val cellHeaderTextColor: Color, - val backgroundColor: Color, - val headerTextColor: Color, - val weekDaysTextColor: Color = headerTextColor, - val arrowColor: Color, - val dividerColor: Color, - val dividerAppearance: DividerAppearance, - val modalAppearance: ModalAppearance -) { - companion object Companion -} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Cell.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Cell.kt new file mode 100644 index 000000000..bca22879b --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Cell.kt @@ -0,0 +1,18 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance + +import androidx.compose.ui.graphics.Color + +data class CellAppearance( + val backgroundColor: Color, + val textColor: Color, + val activeBackgroundColor: Color, + val activeTextColor: Color, + val inRangeBackgroundColor: Color, + val inRangeTextColor: Color, + val borderColor: Color = Color.Transparent, + val activeBorderColor: Color = Color.Transparent, + val inRangeBorderColor: Color = Color.Transparent, + val headerTextColor: Color +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Header.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Header.kt new file mode 100644 index 000000000..f1b5fc284 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Header.kt @@ -0,0 +1,10 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance + +import androidx.compose.ui.graphics.Color + +data class HeaderAppearance( + val textColor: Color, + val arrowColor: Color +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Picker.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Picker.kt new file mode 100644 index 000000000..a6f0ee657 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Picker.kt @@ -0,0 +1,17 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance + +import androidx.compose.ui.graphics.Color +import com.atls.hyperion.ui.components.divider.style.appearance.DividerAppearance +import com.atls.hyperion.ui.components.modal.style.appearance.ModalAppearance + +data class DatePickerAppearance( + val cellAppearance: CellAppearance, + val headerAppearance: HeaderAppearance, + val weekDaysAppearance: WeekDaysAppearance, + val backgroundColor: Color, + val dividerColor: Color, + val dividerAppearance: DividerAppearance, + val modalAppearance: ModalAppearance +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/WeekDays.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/WeekDays.kt new file mode 100644 index 000000000..8f0b78e56 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/WeekDays.kt @@ -0,0 +1,9 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance + +import androidx.compose.ui.graphics.Color + +data class WeekDaysAppearance( + val textColor: Color +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Cell.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Cell.kt new file mode 100644 index 000000000..0119c7649 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Cell.kt @@ -0,0 +1,17 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance.variants + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.CellAppearance +import com.atls.hyperion.ui.theme.tokens.colors.Colors as TokenColors + +@Composable +fun CellAppearance.Companion.default(): CellAppearance = + CellAppearance( + backgroundColor = TokenColors.Palette.transparent, + textColor = TokenColors.Text.black, + activeBackgroundColor = TokenColors.Palette.blue, + activeTextColor = TokenColors.Text.white, + inRangeBackgroundColor = TokenColors.Palette.lightPurple, + inRangeTextColor = TokenColors.Text.black, + headerTextColor = TokenColors.Text.gray + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Header.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Header.kt new file mode 100644 index 000000000..28afb20bc --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Header.kt @@ -0,0 +1,12 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance.variants + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.HeaderAppearance +import com.atls.hyperion.ui.theme.tokens.colors.Colors as TokenColors + +@Composable +fun HeaderAppearance.Companion.default(): HeaderAppearance = + HeaderAppearance( + textColor = TokenColors.Text.black, + arrowColor = TokenColors.Text.black + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Picker.kt similarity index 59% rename from mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Variants.kt rename to mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Picker.kt index e59fdb1fa..12282c766 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/Variants.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/Picker.kt @@ -1,27 +1,24 @@ -package com.atls.hyperion.ui.fragment.datepicker.style.appearance +package com.atls.hyperion.ui.fragment.datepicker.style.appearance.variants import androidx.compose.runtime.Composable import com.atls.hyperion.ui.components.divider.style.appearance.DividerAppearance import com.atls.hyperion.ui.components.divider.style.appearance.default import com.atls.hyperion.ui.components.modal.style.appearance.ModalAppearance import com.atls.hyperion.ui.components.modal.style.appearance.default +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.CellAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.DatePickerAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.HeaderAppearance +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.WeekDaysAppearance import com.atls.hyperion.ui.theme.tokens.colors.Colors as TokenColors @Composable fun DatePickerAppearance.Companion.default(): DatePickerAppearance = DatePickerAppearance( - cellBackgroundColor = TokenColors.Palette.transparent, - cellTextColor = TokenColors.Text.black, - cellActiveBackgroundColor = TokenColors.Palette.blue, - cellActiveTextColor = TokenColors.Text.white, - cellInRangeBackgroundColor = TokenColors.Palette.lightPurple, - cellInRangeTextColor = TokenColors.Text.black, - cellHeaderTextColor = TokenColors.Text.gray, + cellAppearance = CellAppearance.default(), + headerAppearance = HeaderAppearance.default(), + weekDaysAppearance = WeekDaysAppearance.default(), backgroundColor = TokenColors.Palette.white, - headerTextColor = TokenColors.Text.black, - arrowColor = TokenColors.Text.black, dividerColor = TokenColors.Palette.gray, - weekDaysTextColor = TokenColors.Text.black, dividerAppearance = DividerAppearance.default(), modalAppearance = ModalAppearance.default() ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/WeekDays.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/WeekDays.kt new file mode 100644 index 000000000..61a3199c8 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/appearance/variants/WeekDays.kt @@ -0,0 +1,11 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.appearance.variants + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.fragment.datepicker.style.appearance.WeekDaysAppearance +import com.atls.hyperion.ui.theme.tokens.colors.Colors as TokenColors + +@Composable +fun WeekDaysAppearance.Companion.default(): WeekDaysAppearance = + WeekDaysAppearance( + textColor = TokenColors.Text.black + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Calendar.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Calendar.kt new file mode 100644 index 000000000..5644885c7 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Calendar.kt @@ -0,0 +1,15 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape + +import androidx.compose.foundation.layout.PaddingValues +import com.atls.hyperion.ui.components.divider.style.shape.DividerShape +import com.atls.hyperion.ui.components.modal.style.shape.ModalShape +import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition + +data class CalendarShape( + val padding: PaddingValues, + val divider: DividerPosition = DividerPosition.NONE, + val dividerShape: DividerShape, + val modalShape: ModalShape +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Cell.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Cell.kt new file mode 100644 index 000000000..1ff8bd822 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Cell.kt @@ -0,0 +1,22 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp +import com.atls.hyperion.ui.theme.tokens.layout.BorderStroke + +data class CellShape( + val spacing: Dp, + val padding: Dp, + val borderWidth: Dp = BorderStroke.none, + val borderColor: Color = Color.Transparent, + val shape: Shape, + val activeShape: Shape = shape, + val rangeShape: Shape = RectangleShape, + val typography: TextStyle, + val headerTypography: TextStyle +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Header.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Header.kt new file mode 100644 index 000000000..8f3d4ad94 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Header.kt @@ -0,0 +1,13 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape + +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp + +data class HeaderShape( + val typography: TextStyle, + val spacing: Dp, + val iconSize: Dp, + val horizontalPadding: Dp +) { + companion object +} diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt index 17d915078..b552e3a92 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Shape.kt @@ -1,34 +1,9 @@ package com.atls.hyperion.ui.fragment.datepicker.style.shape -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.Dp -import com.atls.hyperion.ui.components.divider.style.shape.DividerShape -import com.atls.hyperion.ui.components.modal.style.shape.ModalShape -import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition -import com.atls.hyperion.ui.theme.tokens.layout.BorderStroke - data class DatePickerShape( - val cellSpacing: Dp, - val cellPadding: Dp, - val cellBorderWidth: Dp = BorderStroke.none, - val cellBorderColor: Color = Color.Transparent, - val cellShape: Shape, - val cellActiveShape: Shape = cellShape, - val cellRangeShape: Shape = RectangleShape, - val cellTypography: TextStyle, - val headerTypography: TextStyle, - val headerSpacing: Dp, - val calendarPadding: PaddingValues, - val dayHeaderTypography: TextStyle, - val headerIconSize: Dp, - val headerHorizontalPadding: Dp, - val divider: DividerPosition = DividerPosition.NONE, - val dividerShape: DividerShape, - val modalShape: ModalShape + val cellShape: CellShape, + val headerShape: HeaderShape, + val calendarShape: CalendarShape ) { companion object Companion } diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt deleted file mode 100644 index d4e609587..000000000 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/Variants.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.atls.hyperion.ui.fragment.datepicker.style.shape - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.ui.text.TextStyle -import com.atls.hyperion.ui.components.divider.style.shape.DividerShape -import com.atls.hyperion.ui.components.divider.style.shape.default -import com.atls.hyperion.ui.components.modal.style.shape.ModalShape -import com.atls.hyperion.ui.components.modal.style.shape.popup -import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition -import com.atls.hyperion.ui.primitives.icon.IconSize -import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius -import com.atls.hyperion.ui.theme.tokens.layout.Space -import com.atls.hyperion.ui.theme.typography.FontSize -import com.atls.hyperion.ui.theme.typography.FontWeight - -@Composable -fun DatePickerShape.Companion.default(): DatePickerShape = - DatePickerShape( - cellTypography = TextStyle( - fontSize = FontSize.xs, - fontWeight = FontWeight.regular, - ), - headerTypography = TextStyle( - fontSize = FontSize.md, - fontWeight = FontWeight.bold, - ), - dayHeaderTypography = TextStyle( - fontSize = FontSize.xs2, - fontWeight = FontWeight.medium, - ), - cellSpacing = Space.zero, - cellPadding = Space.g8, - cellShape = RoundedCornerShape(CornerRadius.xs2), - calendarPadding = PaddingValues(Space.g12), - headerIconSize = IconSize.medium, - headerSpacing = Space.g12, - headerHorizontalPadding = Space.g12, - divider = DividerPosition.BOTTOM, - dividerShape = DividerShape.default(), - modalShape = ModalShape.popup() - ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Calendar.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Calendar.kt new file mode 100644 index 000000000..9c0f0fc14 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Calendar.kt @@ -0,0 +1,20 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape.variants + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.components.divider.style.shape.DividerShape +import com.atls.hyperion.ui.components.divider.style.shape.default +import com.atls.hyperion.ui.components.modal.style.shape.ModalShape +import com.atls.hyperion.ui.components.modal.style.shape.popup +import com.atls.hyperion.ui.fragment.datepicker.model.DividerPosition +import com.atls.hyperion.ui.fragment.datepicker.style.shape.CalendarShape +import com.atls.hyperion.ui.theme.tokens.layout.Space + +@Composable +fun CalendarShape.Companion.default(): CalendarShape = + CalendarShape( + padding = PaddingValues(Space.g12), + divider = DividerPosition.BOTTOM, + dividerShape = DividerShape.default(), + modalShape = ModalShape.popup() + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Cell.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Cell.kt new file mode 100644 index 000000000..9488b92a8 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Cell.kt @@ -0,0 +1,26 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape.variants + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.TextStyle +import com.atls.hyperion.ui.fragment.datepicker.style.shape.CellShape +import com.atls.hyperion.ui.theme.tokens.layout.CornerRadius +import com.atls.hyperion.ui.theme.tokens.layout.Space +import com.atls.hyperion.ui.theme.typography.FontSize +import com.atls.hyperion.ui.theme.typography.FontWeight + +@Composable +fun CellShape.Companion.default(): CellShape = + CellShape( + spacing = Space.zero, + padding = Space.g8, + shape = RoundedCornerShape(CornerRadius.xs2), + typography = TextStyle( + fontSize = FontSize.xs, + fontWeight = FontWeight.regular, + ), + headerTypography = TextStyle( + fontSize = FontSize.xs2, + fontWeight = FontWeight.medium, + ) + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Header.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Header.kt new file mode 100644 index 000000000..f95c7a479 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Header.kt @@ -0,0 +1,21 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape.variants + +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.TextStyle +import com.atls.hyperion.ui.fragment.datepicker.style.shape.HeaderShape +import com.atls.hyperion.ui.primitives.icon.IconSize +import com.atls.hyperion.ui.theme.tokens.layout.Space +import com.atls.hyperion.ui.theme.typography.FontSize +import com.atls.hyperion.ui.theme.typography.FontWeight + +@Composable +fun HeaderShape.Companion.default(): HeaderShape = + HeaderShape( + typography = TextStyle( + fontSize = FontSize.md, + fontWeight = FontWeight.bold, + ), + spacing = Space.g12, + iconSize = IconSize.medium, + horizontalPadding = Space.g12 + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Picker.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Picker.kt new file mode 100644 index 000000000..5746a0e12 --- /dev/null +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/style/shape/variants/Picker.kt @@ -0,0 +1,15 @@ +package com.atls.hyperion.ui.fragment.datepicker.style.shape.variants + +import androidx.compose.runtime.Composable +import com.atls.hyperion.ui.fragment.datepicker.style.shape.CalendarShape +import com.atls.hyperion.ui.fragment.datepicker.style.shape.CellShape +import com.atls.hyperion.ui.fragment.datepicker.style.shape.DatePickerShape +import com.atls.hyperion.ui.fragment.datepicker.style.shape.HeaderShape + +@Composable +fun DatePickerShape.Companion.default(): DatePickerShape = + DatePickerShape( + cellShape = CellShape.default(), + headerShape = HeaderShape.default(), + calendarShape = CalendarShape.default() + ) diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt index a7a1d8772..1d82b3a63 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/CalendarHeader.kt @@ -33,47 +33,47 @@ fun CalendarHeader( onPrevMonth: () -> Unit, onNextMonth: () -> Unit, ) { - if (shape.divider == DividerPosition.TOP) { + if (shape.calendarShape.divider == DividerPosition.TOP) { HorizontalDivider( appearance = appearance.dividerAppearance, - shape = shape.dividerShape + shape = shape.calendarShape.dividerShape ) - VerticalSpacer(shape.headerSpacing) + VerticalSpacer(shape.headerShape.spacing) } Row( modifier = Modifier .fillMaxWidth() - .padding(horizontal = shape.headerHorizontalPadding), + .padding(horizontal = shape.headerShape.horizontalPadding), horizontalArrangement = arrangement, verticalAlignment = alignment ) { Icon( icon = beforeIcon, - size = shape.headerIconSize, + size = shape.headerShape.iconSize, modifier = Modifier.clickable { onPrevMonth() }, - color = appearance.arrowColor + color = appearance.headerAppearance.arrowColor ) Text( text = monthName, - typography = shape.headerTypography, - color = appearance.headerTextColor + typography = shape.headerShape.typography, + color = appearance.headerAppearance.textColor ) Icon( icon = afterIcon, - size = shape.headerIconSize, + size = shape.headerShape.iconSize, modifier = Modifier.clickable { onNextMonth() }, - color = appearance.arrowColor + color = appearance.headerAppearance.arrowColor ) } - if (shape.divider == DividerPosition.BOTTOM) { - VerticalSpacer(shape.headerSpacing) + if (shape.calendarShape.divider == DividerPosition.BOTTOM) { + VerticalSpacer(shape.headerShape.spacing) HorizontalDivider( appearance = appearance.dividerAppearance, - shape = shape.dividerShape + shape = shape.calendarShape.dividerShape ) } } diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt index 104b54bfa..3e010b20c 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/DatePickerContent.kt @@ -80,7 +80,7 @@ fun DatePickerContent( HorizontalCalendar( modifier = Modifier .fillMaxWidth() - .padding(shape.calendarPadding), + .padding(shape.calendarShape.padding), state = state, dayContent = { day -> diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt index 4c9b836cd..72a8237cd 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/Day.kt @@ -38,47 +38,47 @@ fun Day( val date = LocalDate(day.date.year, day.date.monthNumber, day.date.dayOfMonth) val backgroundColor = when { - isSelected || isRangeStart || isRangeEnd -> appearance.cellActiveBackgroundColor - isInRange -> appearance.cellInRangeBackgroundColor - else -> appearance.cellBackgroundColor + isSelected || isRangeStart || isRangeEnd -> appearance.cellAppearance.activeBackgroundColor + isInRange -> appearance.cellAppearance.inRangeBackgroundColor + else -> appearance.cellAppearance.backgroundColor } val cellShape = when { - isSelected -> shape.cellActiveShape - isInRange -> shape.cellRangeShape - else -> shape.cellShape + isSelected -> shape.cellShape.activeShape + isInRange -> shape.cellShape.rangeShape + else -> shape.cellShape.shape } val textColor = when { - isSelected || isRangeStart || isRangeEnd -> appearance.cellActiveTextColor - isInRange -> appearance.cellInRangeTextColor - else -> appearance.cellTextColor + isSelected || isRangeStart || isRangeEnd -> appearance.cellAppearance.activeTextColor + isInRange -> appearance.cellAppearance.inRangeTextColor + else -> appearance.cellAppearance.textColor } val containerModifier = Modifier .aspectSquare() - .padding(shape.cellSpacing) + .padding(shape.cellShape.spacing) .clip(cellShape) .background(backgroundColor) - .padding(shape.cellPadding) + .padding(shape.cellShape.padding) .then( - if ((isSelected || isRangeStart || isRangeEnd) && appearance.cellActiveBorderColor != Colors.Palette.transparent) + if ((isSelected || isRangeStart || isRangeEnd) && appearance.cellAppearance.activeBorderColor != Colors.Palette.transparent) Modifier.border( - shape.cellBorderWidth, - appearance.cellActiveBorderColor, + shape.cellShape.borderWidth, + appearance.cellAppearance.activeBorderColor, cellShape ) - else if (isInRange && appearance.cellInRangeBorderColor != Colors.Palette.transparent) + else if (isInRange && appearance.cellAppearance.inRangeBorderColor != Colors.Palette.transparent) Modifier.border( - shape.cellBorderWidth, - appearance.cellInRangeBorderColor, + shape.cellShape.borderWidth, + appearance.cellAppearance.inRangeBorderColor, cellShape ) - else if (appearance.cellBorderColor != Colors.Palette.transparent) + else if (appearance.cellAppearance.borderColor != Colors.Palette.transparent) Modifier.border( - shape.cellBorderWidth, - appearance.cellBorderColor, + shape.cellShape.borderWidth, + appearance.cellAppearance.borderColor, cellShape ) else Modifier @@ -93,7 +93,7 @@ fun Day( Text( text = day.date.dayOfMonth.toString(), color = textColor, - typography = shape.cellTypography + typography = shape.cellShape.typography ) } } diff --git a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt index dcf60fd70..d4a355a18 100644 --- a/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt +++ b/mobile/kmp/ui/src/commonMain/kotlin/com/atls/hyperion/ui/fragment/datepicker/ui/WeekDays.kt @@ -31,8 +31,8 @@ fun WeekDays( modifier = Modifier.weight(Weight.full), textAlign = TextAlign.Center, text = shortName, - typography = shape.dayHeaderTypography, - color = appearance.weekDaysTextColor, + typography = shape.cellShape.headerTypography, + color = appearance.weekDaysAppearance.textColor, ) } }