@@ -34,17 +34,22 @@ import androidx.compose.runtime.remember
34
34
import androidx.compose.runtime.rememberUpdatedState
35
35
import androidx.compose.ui.Alignment
36
36
import androidx.compose.ui.Modifier
37
+ import androidx.compose.ui.draw.paint
37
38
import androidx.compose.ui.draw.shadow
38
39
import androidx.compose.ui.geometry.Offset
39
40
import androidx.compose.ui.graphics.Color
41
+ import androidx.compose.ui.graphics.ColorFilter
40
42
import androidx.compose.ui.graphics.StrokeCap
41
43
import androidx.compose.ui.graphics.drawscope.DrawScope
44
+ import androidx.compose.ui.graphics.painter.Painter
42
45
import androidx.compose.ui.platform.LocalDensity
43
46
import androidx.compose.ui.platform.LocalLayoutDirection
44
47
import androidx.compose.ui.semantics.Role
48
+ import androidx.compose.ui.unit.Dp
45
49
import androidx.compose.ui.unit.IntOffset
46
50
import androidx.compose.ui.unit.LayoutDirection
47
51
import androidx.compose.ui.unit.dp
52
+ import kiwi.orbit.compose.icons.Icons
48
53
import kiwi.orbit.compose.ui.OrbitTheme
49
54
import kiwi.orbit.compose.ui.controls.internal.OrbitPreviews
50
55
import kiwi.orbit.compose.ui.controls.internal.Preview
@@ -60,6 +65,25 @@ public fun Switch(
60
65
modifier : Modifier = Modifier ,
61
66
enabled : Boolean = true,
62
67
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 () },
63
87
) {
64
88
val density = LocalDensity .current
65
89
val toggleableModifier =
@@ -107,6 +131,7 @@ public fun Switch(
107
131
SwitchImpl (
108
132
checked = checked,
109
133
enabled = enabled,
134
+ icon = icon,
110
135
state = swipeableState,
111
136
interactionSource = interactionSource,
112
137
)
@@ -117,6 +142,7 @@ public fun Switch(
117
142
private fun BoxScope.SwitchImpl (
118
143
checked : Boolean ,
119
144
enabled : Boolean ,
145
+ icon : Painter ? ,
120
146
state : SwipeableV2State <Boolean >,
121
147
interactionSource : InteractionSource ,
122
148
) {
@@ -152,13 +178,30 @@ private fun BoxScope.SwitchImpl(
152
178
}
153
179
},
154
180
)
181
+ SwitchTrack (mainColor)
182
+ SwitchThumb (state, interactionSource, enabled, elevation, icon, mainColor)
183
+ }
184
+
185
+ @Composable
186
+ private fun BoxScope.SwitchTrack (mainColor : Color ) {
155
187
Canvas (
156
188
Modifier
157
189
.align(Alignment .Center )
158
190
.fillMaxSize(),
159
191
) {
160
192
drawTrack(mainColor, TrackWidth .toPx(), TrackStrokeWidth .toPx())
161
193
}
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
+ ) {
162
205
Spacer (
163
206
Modifier
164
207
.align(Alignment .CenterStart )
@@ -186,7 +229,15 @@ private fun BoxScope.SwitchImpl(
186
229
)
187
230
.background(OrbitTheme .colors.surface.main, CircleShape )
188
231
.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
+ ),
190
241
)
191
242
}
192
243
@@ -235,7 +286,8 @@ private val TrackWidth = SwitchWidth - SwitchPadding * 2
235
286
private val TrackStrokeWidth = SwitchHeight - SwitchPadding * 2
236
287
private val ThumbDiameter = SwitchHeight
237
288
private val ThumbStrokeWidth = 0.5 .dp
238
- private val ThumbInnerDiameter = 10 .dp
289
+ private val ThumbInnerDiameter = 16 .dp
290
+ private val ThumbInnerPadding = 3 .dp
239
291
private val ThumbRippleRadius = 24 .dp
240
292
241
293
private val AnimationSpec = TweenSpec <Float >(durationMillis = 100 )
@@ -255,6 +307,7 @@ internal fun SwitchPreview() {
255
307
Switch (
256
308
checked = true ,
257
309
onCheckedChange = {},
310
+ icon = Icons .Circle ,
258
311
)
259
312
Switch (
260
313
checked = false ,
0 commit comments