Skip to content

Commit 4fa62ec

Browse files
author
Alexander Matečný
committed
Add option to define custom switch icons
1 parent 3acd6dc commit 4fa62ec

File tree

1 file changed

+55
-2
lines changed
  • ui/src/androidMain/kotlin/kiwi/orbit/compose/ui/controls

1 file changed

+55
-2
lines changed

ui/src/androidMain/kotlin/kiwi/orbit/compose/ui/controls/Switch.kt

+55-2
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,22 @@ import androidx.compose.runtime.remember
3434
import androidx.compose.runtime.rememberUpdatedState
3535
import androidx.compose.ui.Alignment
3636
import androidx.compose.ui.Modifier
37+
import androidx.compose.ui.draw.paint
3738
import androidx.compose.ui.draw.shadow
3839
import androidx.compose.ui.geometry.Offset
3940
import androidx.compose.ui.graphics.Color
41+
import androidx.compose.ui.graphics.ColorFilter
4042
import androidx.compose.ui.graphics.StrokeCap
4143
import androidx.compose.ui.graphics.drawscope.DrawScope
44+
import androidx.compose.ui.graphics.painter.Painter
4245
import androidx.compose.ui.platform.LocalDensity
4346
import androidx.compose.ui.platform.LocalLayoutDirection
4447
import androidx.compose.ui.semantics.Role
48+
import androidx.compose.ui.unit.Dp
4549
import androidx.compose.ui.unit.IntOffset
4650
import androidx.compose.ui.unit.LayoutDirection
4751
import androidx.compose.ui.unit.dp
52+
import kiwi.orbit.compose.icons.Icons
4853
import kiwi.orbit.compose.ui.OrbitTheme
4954
import kiwi.orbit.compose.ui.controls.internal.OrbitPreviews
5055
import kiwi.orbit.compose.ui.controls.internal.Preview
@@ -60,6 +65,25 @@ public fun Switch(
6065
modifier: Modifier = Modifier,
6166
enabled: Boolean = true,
6267
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
68+
) {
69+
Switch(
70+
checked = checked,
71+
onCheckedChange = onCheckedChange,
72+
modifier = modifier,
73+
icon = null,
74+
enabled = enabled,
75+
interactionSource = interactionSource,
76+
)
77+
}
78+
79+
@Composable
80+
public fun Switch(
81+
checked: Boolean,
82+
onCheckedChange: ((Boolean) -> Unit)?,
83+
icon: Painter?,
84+
modifier: Modifier = Modifier,
85+
enabled: Boolean = true,
86+
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
6387
) {
6488
val density = LocalDensity.current
6589
val toggleableModifier =
@@ -107,6 +131,7 @@ public fun Switch(
107131
SwitchImpl(
108132
checked = checked,
109133
enabled = enabled,
134+
icon = icon,
110135
state = swipeableState,
111136
interactionSource = interactionSource,
112137
)
@@ -117,6 +142,7 @@ public fun Switch(
117142
private fun BoxScope.SwitchImpl(
118143
checked: Boolean,
119144
enabled: Boolean,
145+
icon: Painter?,
120146
state: SwipeableV2State<Boolean>,
121147
interactionSource: InteractionSource,
122148
) {
@@ -152,13 +178,30 @@ private fun BoxScope.SwitchImpl(
152178
}
153179
},
154180
)
181+
SwitchTrack(mainColor)
182+
SwitchThumb(state, interactionSource, enabled, elevation, icon, mainColor)
183+
}
184+
185+
@Composable
186+
private fun BoxScope.SwitchTrack(mainColor: Color) {
155187
Canvas(
156188
Modifier
157189
.align(Alignment.Center)
158190
.fillMaxSize(),
159191
) {
160192
drawTrack(mainColor, TrackWidth.toPx(), TrackStrokeWidth.toPx())
161193
}
194+
}
195+
196+
@Composable
197+
private fun BoxScope.SwitchThumb(
198+
state: SwipeableV2State<Boolean>,
199+
interactionSource: InteractionSource,
200+
enabled: Boolean,
201+
elevation: Dp,
202+
icon: Painter?,
203+
mainColor: Color,
204+
) {
162205
Spacer(
163206
Modifier
164207
.align(Alignment.CenterStart)
@@ -186,7 +229,15 @@ private fun BoxScope.SwitchImpl(
186229
)
187230
.background(OrbitTheme.colors.surface.main, CircleShape)
188231
.padding((ThumbDiameter - ThumbInnerDiameter - ThumbStrokeWidth * 2) / 2)
189-
.background(mainColor, CircleShape),
232+
.then(
233+
if (icon != null) {
234+
Modifier.paint(painter = icon, colorFilter = ColorFilter.tint(mainColor))
235+
} else {
236+
Modifier
237+
.padding(ThumbInnerPadding)
238+
.background(mainColor, CircleShape)
239+
},
240+
),
190241
)
191242
}
192243

@@ -235,7 +286,8 @@ private val TrackWidth = SwitchWidth - SwitchPadding * 2
235286
private val TrackStrokeWidth = SwitchHeight - SwitchPadding * 2
236287
private val ThumbDiameter = SwitchHeight
237288
private val ThumbStrokeWidth = 0.5.dp
238-
private val ThumbInnerDiameter = 10.dp
289+
private val ThumbInnerDiameter = 16.dp
290+
private val ThumbInnerPadding = 3.dp
239291
private val ThumbRippleRadius = 24.dp
240292

241293
private val AnimationSpec = TweenSpec<Float>(durationMillis = 100)
@@ -255,6 +307,7 @@ internal fun SwitchPreview() {
255307
Switch(
256308
checked = true,
257309
onCheckedChange = {},
310+
icon = Icons.Circle,
258311
)
259312
Switch(
260313
checked = false,

0 commit comments

Comments
 (0)