diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt index 7fa7f5676..76d55495b 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics +import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Separator import kiwi.orbit.compose.ui.controls.Switch @@ -62,6 +63,18 @@ private fun SwitchScreenInner() { Separator() Spacer(Modifier.height(16.dp)) + var iconValue by rememberSaveable { mutableStateOf(true) } + + Switch(checked = iconValue, onCheckedChange = { iconValue = it }, icon = Icons.Notification) + + Spacer(Modifier.height(8.dp)) + + Switch(checked = !iconValue, onCheckedChange = { iconValue = !it }, icon = Icons.NotificationOff) + + Spacer(Modifier.height(16.dp)) + Separator() + Spacer(Modifier.height(16.dp)) + Switch(checked = true, onCheckedChange = {}, enabled = false) Spacer(Modifier.height(8.dp)) diff --git a/ui/src/androidMain/kotlin/kiwi/orbit/compose/ui/controls/Switch.kt b/ui/src/androidMain/kotlin/kiwi/orbit/compose/ui/controls/Switch.kt index 987614edf..f7977246a 100644 --- a/ui/src/androidMain/kotlin/kiwi/orbit/compose/ui/controls/Switch.kt +++ b/ui/src/androidMain/kotlin/kiwi/orbit/compose/ui/controls/Switch.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.PressInteraction import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -34,17 +35,22 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.paint import androidx.compose.ui.draw.shadow import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.semantics.Role +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.internal.OrbitPreviews import kiwi.orbit.compose.ui.controls.internal.Preview @@ -60,6 +66,25 @@ public fun Switch( modifier: Modifier = Modifier, enabled: Boolean = true, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + Switch( + checked = checked, + onCheckedChange = onCheckedChange, + modifier = modifier, + icon = null, + enabled = enabled, + interactionSource = interactionSource, + ) +} + +@Composable +public fun Switch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + icon: Painter?, + modifier: Modifier = Modifier, + enabled: Boolean = true, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, ) { val density = LocalDensity.current val toggleableModifier = @@ -107,6 +132,7 @@ public fun Switch( SwitchImpl( checked = checked, enabled = enabled, + icon = icon, state = swipeableState, interactionSource = interactionSource, ) @@ -117,6 +143,7 @@ public fun Switch( private fun BoxScope.SwitchImpl( checked: Boolean, enabled: Boolean, + icon: Painter?, state: SwipeableV2State, interactionSource: InteractionSource, ) { @@ -152,6 +179,12 @@ private fun BoxScope.SwitchImpl( } }, ) + SwitchTrack(mainColor) + SwitchThumb(state, interactionSource, enabled, elevation, icon, mainColor) +} + +@Composable +private fun BoxScope.SwitchTrack(mainColor: Color) { Canvas( Modifier .align(Alignment.Center) @@ -159,6 +192,17 @@ private fun BoxScope.SwitchImpl( ) { drawTrack(mainColor, TrackWidth.toPx(), TrackStrokeWidth.toPx()) } +} + +@Composable +private fun BoxScope.SwitchThumb( + state: SwipeableV2State, + interactionSource: InteractionSource, + enabled: Boolean, + elevation: Dp, + icon: Painter?, + mainColor: Color, +) { Spacer( Modifier .align(Alignment.CenterStart) @@ -186,7 +230,15 @@ private fun BoxScope.SwitchImpl( ) .background(OrbitTheme.colors.surface.main, CircleShape) .padding((ThumbDiameter - ThumbInnerDiameter - ThumbStrokeWidth * 2) / 2) - .background(mainColor, CircleShape), + .then( + if (icon != null) { + Modifier.paint(painter = icon, colorFilter = ColorFilter.tint(mainColor)) + } else { + Modifier + .padding(ThumbInnerPadding) + .background(mainColor, CircleShape) + }, + ), ) } @@ -235,7 +287,8 @@ private val TrackWidth = SwitchWidth - SwitchPadding * 2 private val TrackStrokeWidth = SwitchHeight - SwitchPadding * 2 private val ThumbDiameter = SwitchHeight private val ThumbStrokeWidth = 0.5.dp -private val ThumbInnerDiameter = 10.dp +private val ThumbInnerDiameter = 16.dp +private val ThumbInnerPadding = 3.dp private val ThumbRippleRadius = 24.dp private val AnimationSpec = TweenSpec(durationMillis = 100) @@ -247,25 +300,52 @@ private val ThumbPressedElevation = 6.dp @Composable internal fun SwitchPreview() { Preview { - Row { - Switch( - checked = false, - onCheckedChange = {}, - ) - Switch( - checked = true, - onCheckedChange = {}, - ) - Switch( - checked = false, - enabled = false, - onCheckedChange = {}, - ) - Switch( - checked = true, - enabled = false, - onCheckedChange = {}, - ) + Column { + Row { + Switch( + checked = false, + onCheckedChange = {}, + ) + Switch( + checked = true, + onCheckedChange = {}, + icon = Icons.Circle, + ) + Switch( + checked = false, + enabled = false, + onCheckedChange = {}, + ) + Switch( + checked = true, + enabled = false, + onCheckedChange = {}, + ) + } + Row { + Switch( + checked = false, + onCheckedChange = {}, + icon = Icons.LockOpen, + ) + Switch( + checked = true, + onCheckedChange = {}, + icon = Icons.Lock, + ) + Switch( + checked = false, + enabled = false, + onCheckedChange = {}, + icon = Icons.VisibilityOff, + ) + Switch( + checked = true, + enabled = false, + onCheckedChange = {}, + icon = Icons.Visibility, + ) + } } } } diff --git a/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch.png b/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch.png index 59933d004..9dd0aa414 100644 --- a/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch.png +++ b/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d1ede06c879fe351e10a05534d07c046567fd41b04ce923a95961760e09414b -size 14537 +oid sha256:8b1a0f1bf7c667d4aa36326dddca7212caf7b1da2a7f060b89b62c242e886a41 +size 30303 diff --git a/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_big.png b/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_big.png index 59933d004..9dd0aa414 100644 --- a/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_big.png +++ b/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_big.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d1ede06c879fe351e10a05534d07c046567fd41b04ce923a95961760e09414b -size 14537 +oid sha256:8b1a0f1bf7c667d4aa36326dddca7212caf7b1da2a7f060b89b62c242e886a41 +size 30303 diff --git a/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_dark.png b/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_dark.png index f01b568b7..dcbfc9944 100644 --- a/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_dark.png +++ b/ui/src/test/snapshots/images/kiwi.orbit.compose.ui_ScreenshotTest_switch_dark.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86a22b3229cc5c043be389e923c750483e16c0aee69fddda7be7fc56d08fddb2 -size 11985 +oid sha256:d30cdf06d2e54f38450f620900c5cf790ecd2fbf191921acc9f7415fca4c1eb2 +size 25354