mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-08-05 19:59:51 +00:00
feat: add Toggle component and update UI to use it in place of Switch
This commit is contained in:
parent
6ac934ad19
commit
1ef1eff3cb
@ -299,6 +299,26 @@ fun IconButton(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GhostButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
theme: BaseUITheme.ButtonStyle? = null,
|
||||
content: @Composable RowScope.() -> Unit,
|
||||
) {
|
||||
val baseTheme = LocalBaseUITheme.current
|
||||
val style = theme ?: baseTheme.buttons.ghost
|
||||
OutlineButton(
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
enabled = enabled,
|
||||
hoverOnly = true,
|
||||
theme = style,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GhostIconButton(
|
||||
onClick: () -> Unit,
|
||||
@ -308,43 +328,13 @@ fun GhostIconButton(
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
val baseTheme = LocalBaseUITheme.current
|
||||
val outlineStyle = baseTheme.iconButtons.outline
|
||||
val ghostStyle = theme ?: BaseUITheme.ButtonStyle(
|
||||
colors = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(Color.Transparent, Color.Transparent)),
|
||||
foreground = outlineStyle.colors.normal.foreground,
|
||||
highlight = outlineStyle.colors.normal.highlight,
|
||||
),
|
||||
hovered = outlineStyle.colors.hovered,
|
||||
pressed = outlineStyle.colors.pressed,
|
||||
focused = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(Color.Transparent, Color.Transparent)),
|
||||
foreground = outlineStyle.colors.normal.foreground,
|
||||
highlight = outlineStyle.colors.normal.highlight,
|
||||
),
|
||||
),
|
||||
shape = outlineStyle.shape,
|
||||
shadow = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.Shadow(0.dp, false, Color.Transparent, Color.Transparent),
|
||||
hovered = outlineStyle.shadow.hovered,
|
||||
pressed = outlineStyle.shadow.pressed,
|
||||
focused = BaseUITheme.Shadow(0.dp, false, Color.Transparent, Color.Transparent),
|
||||
),
|
||||
border = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.Border(Color.Transparent, 0.dp),
|
||||
hovered = outlineStyle.border.hovered,
|
||||
pressed = outlineStyle.border.pressed,
|
||||
focused = BaseUITheme.Border(Color.Transparent, 0.dp),
|
||||
),
|
||||
padding = outlineStyle.padding,
|
||||
)
|
||||
val style = theme ?: baseTheme.iconButtons.ghost
|
||||
OutlineButton(
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
enabled = enabled,
|
||||
hoverOnly = true,
|
||||
theme = ghostStyle,
|
||||
theme = style,
|
||||
) {
|
||||
content()
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ data class BaseUITheme(
|
||||
val slider: SliderTheme,
|
||||
val checkBox: CheckBoxTheme,
|
||||
val chipTab: ChipTabTheme,
|
||||
val toggle: ToggleTheme,
|
||||
val card: CardTheme,
|
||||
val listRowTile: ListRowTheme,
|
||||
) {
|
||||
@ -177,6 +178,13 @@ data class BaseUITheme(
|
||||
val selected: ButtonStyle,
|
||||
val unselected: ButtonStyle,
|
||||
)
|
||||
|
||||
data class ToggleTheme(
|
||||
val checked: ButtonStyle,
|
||||
val unchecked: ButtonStyle,
|
||||
val thumb: InteractionState<Color>,
|
||||
val thumbShadow: InteractionState<Shadow>,
|
||||
)
|
||||
}
|
||||
|
||||
val LocalBaseUITheme = staticCompositionLocalOf<BaseUITheme> {
|
||||
@ -519,6 +527,16 @@ fun rememberBaseUITheme(): BaseUITheme {
|
||||
PaddingValues(horizontal = 14.dp, vertical = 4.dp),
|
||||
)
|
||||
|
||||
val toggleShape = RoundedCornerShape(50)
|
||||
val toggleShapeState =
|
||||
BaseUITheme.InteractionState<Shape>(toggleShape, toggleShape, toggleShape, toggleShape)
|
||||
val togglePadding = BaseUITheme.InteractionState(
|
||||
PaddingValues(2.dp),
|
||||
PaddingValues(2.dp),
|
||||
PaddingValues(2.dp),
|
||||
PaddingValues(2.dp),
|
||||
)
|
||||
|
||||
return BaseUITheme(
|
||||
buttons = BaseUITheme.ButtonVariants(
|
||||
primary = primaryStyle,
|
||||
@ -731,6 +749,161 @@ fun rememberBaseUITheme(): BaseUITheme {
|
||||
padding = chipTabPadding,
|
||||
),
|
||||
),
|
||||
toggle = BaseUITheme.ToggleTheme(
|
||||
checked = BaseUITheme.ButtonStyle(
|
||||
colors = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(scheme.primary, scheme.primary)),
|
||||
foreground = scheme.onPrimary,
|
||||
highlight = Color.White.copy(alpha = 0.25f),
|
||||
),
|
||||
hovered = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(scheme.primary, scheme.primary)),
|
||||
foreground = scheme.onPrimary,
|
||||
highlight = Color.White.copy(alpha = 0.25f),
|
||||
),
|
||||
pressed = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(
|
||||
listOf(
|
||||
scheme.primary.copy(alpha = 0.85f),
|
||||
scheme.primary
|
||||
)
|
||||
),
|
||||
foreground = scheme.onPrimary,
|
||||
highlight = Color.White.copy(alpha = 0.25f),
|
||||
),
|
||||
focused = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(scheme.primary, scheme.primary)),
|
||||
foreground = scheme.onPrimary,
|
||||
highlight = Color.White.copy(alpha = 0.25f),
|
||||
),
|
||||
),
|
||||
shape = toggleShapeState,
|
||||
shadow = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.Shadow(
|
||||
4.dp,
|
||||
true,
|
||||
scheme.primary.copy(alpha = 0.3f),
|
||||
scheme.primary.copy(alpha = 0.35f)
|
||||
),
|
||||
hovered = BaseUITheme.Shadow(
|
||||
6.dp,
|
||||
true,
|
||||
scheme.primary.copy(alpha = 0.4f),
|
||||
scheme.primary.copy(alpha = 0.45f)
|
||||
),
|
||||
pressed = BaseUITheme.Shadow(
|
||||
1.dp,
|
||||
true,
|
||||
scheme.primary.copy(alpha = 0.2f),
|
||||
scheme.primary.copy(alpha = 0.25f)
|
||||
),
|
||||
focused = BaseUITheme.Shadow(
|
||||
4.dp,
|
||||
true,
|
||||
scheme.primary.copy(alpha = 0.3f),
|
||||
scheme.primary.copy(alpha = 0.35f)
|
||||
),
|
||||
),
|
||||
border = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.Border(scheme.primary, 0.5.dp),
|
||||
hovered = BaseUITheme.Border(scheme.primary, 0.5.dp),
|
||||
pressed = BaseUITheme.Border(scheme.primary, 0.5.dp),
|
||||
focused = BaseUITheme.Border(scheme.primary, 0.5.dp),
|
||||
),
|
||||
padding = togglePadding,
|
||||
),
|
||||
unchecked = BaseUITheme.ButtonStyle(
|
||||
colors = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(containerLighter, containerDarker)),
|
||||
foreground = scheme.onSurface,
|
||||
highlight = highlight,
|
||||
),
|
||||
hovered = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(containerLighter, containerDarker)),
|
||||
foreground = scheme.onSurface,
|
||||
highlight = highlight,
|
||||
),
|
||||
pressed = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(containerPressed, containerPressed)),
|
||||
foreground = scheme.onSurface,
|
||||
highlight = highlight,
|
||||
),
|
||||
focused = BaseUITheme.ButtonColors(
|
||||
background = Brush.verticalGradient(listOf(containerLighter, containerDarker)),
|
||||
foreground = scheme.onSurface,
|
||||
highlight = highlight,
|
||||
),
|
||||
),
|
||||
shape = toggleShapeState,
|
||||
shadow = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.Shadow(
|
||||
4.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.15f),
|
||||
shadowColor.copy(alpha = 0.18f)
|
||||
),
|
||||
hovered = BaseUITheme.Shadow(
|
||||
6.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.22f),
|
||||
shadowColor.copy(alpha = 0.26f)
|
||||
),
|
||||
pressed = BaseUITheme.Shadow(
|
||||
1.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.08f),
|
||||
shadowColor.copy(alpha = 0.1f)
|
||||
),
|
||||
focused = BaseUITheme.Shadow(
|
||||
4.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.15f),
|
||||
shadowColor.copy(alpha = 0.18f)
|
||||
),
|
||||
),
|
||||
border = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.Border(border, 0.5.dp),
|
||||
hovered = BaseUITheme.Border(border, 0.5.dp),
|
||||
pressed = BaseUITheme.Border(border.copy(alpha = 0.7f), 0.5.dp),
|
||||
focused = BaseUITheme.Border(border, 0.5.dp),
|
||||
),
|
||||
padding = togglePadding,
|
||||
),
|
||||
thumb = BaseUITheme.InteractionState(
|
||||
normal = Color.White,
|
||||
hovered = Color.White,
|
||||
pressed = Color.White,
|
||||
focused = Color.White,
|
||||
),
|
||||
thumbShadow = BaseUITheme.InteractionState(
|
||||
normal = BaseUITheme.Shadow(
|
||||
3.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.2f),
|
||||
shadowColor.copy(alpha = 0.25f)
|
||||
),
|
||||
hovered = BaseUITheme.Shadow(
|
||||
4.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.28f),
|
||||
shadowColor.copy(alpha = 0.32f)
|
||||
),
|
||||
pressed = BaseUITheme.Shadow(
|
||||
1.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.12f),
|
||||
shadowColor.copy(alpha = 0.15f)
|
||||
),
|
||||
focused = BaseUITheme.Shadow(
|
||||
3.dp,
|
||||
true,
|
||||
shadowColor.copy(alpha = 0.2f),
|
||||
shadowColor.copy(alpha = 0.25f)
|
||||
),
|
||||
),
|
||||
),
|
||||
card = BaseUITheme.CardTheme(
|
||||
background = Brush.verticalGradient(listOf(containerLighter, containerDarker)),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
|
||||
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Kingkor Roy Tirtho and Spotube Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package dev.krtirtho.spotube.core.ui.base
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.hoverable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
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.draw.shadow
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private val ToggleWidth = 44.dp
|
||||
private val ToggleHeight = 24.dp
|
||||
private val ThumbSize = 20.dp
|
||||
|
||||
private data class ResolvedToggleState(
|
||||
val colors: BaseUITheme.ButtonColors,
|
||||
val shape: Shape,
|
||||
val shadow: BaseUITheme.Shadow,
|
||||
val border: BaseUITheme.Border,
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun resolveToggleState(
|
||||
style: BaseUITheme.ButtonStyle,
|
||||
isPressed: Boolean,
|
||||
isHovered: Boolean,
|
||||
): ResolvedToggleState {
|
||||
return when {
|
||||
isPressed -> ResolvedToggleState(
|
||||
style.colors.pressed,
|
||||
style.shape.pressed,
|
||||
style.shadow.pressed,
|
||||
style.border.pressed,
|
||||
)
|
||||
|
||||
isHovered -> ResolvedToggleState(
|
||||
style.colors.hovered,
|
||||
style.shape.hovered,
|
||||
style.shadow.hovered,
|
||||
style.border.hovered,
|
||||
)
|
||||
|
||||
else -> ResolvedToggleState(
|
||||
style.colors.normal,
|
||||
style.shape.normal,
|
||||
style.shadow.normal,
|
||||
style.border.normal,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Toggle(
|
||||
checked: Boolean,
|
||||
onCheckedChange: ((Boolean) -> Unit)?,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource? = null,
|
||||
theme: BaseUITheme.ToggleTheme? = null,
|
||||
) {
|
||||
val baseTheme = LocalBaseUITheme.current.toggle
|
||||
val toggleTheme = theme ?: baseTheme
|
||||
val source = interactionSource ?: remember { MutableInteractionSource() }
|
||||
val isPressed by source.collectIsPressedAsState()
|
||||
val isHovered by source.collectIsHoveredAsState()
|
||||
|
||||
val style = if (checked) toggleTheme.checked else toggleTheme.unchecked
|
||||
val resolved = resolveToggleState(style, isPressed, isHovered)
|
||||
|
||||
val thumbColor = when {
|
||||
isPressed -> toggleTheme.thumb.pressed
|
||||
isHovered -> toggleTheme.thumb.hovered
|
||||
else -> toggleTheme.thumb.normal
|
||||
}
|
||||
|
||||
val thumbShadowState = when {
|
||||
isPressed -> toggleTheme.thumbShadow.pressed
|
||||
isHovered -> toggleTheme.thumbShadow.hovered
|
||||
else -> toggleTheme.thumbShadow.normal
|
||||
}
|
||||
|
||||
val borderColor = when {
|
||||
!enabled -> resolved.colors.foreground.copy(alpha = 0.38f)
|
||||
else -> resolved.border.color
|
||||
}
|
||||
|
||||
val thumbProgress by animateFloatAsState(
|
||||
targetValue = if (checked) 1f else 0f,
|
||||
animationSpec = tween(durationMillis = 200),
|
||||
label = "thumbProgress",
|
||||
)
|
||||
|
||||
val thumbScale by animateFloatAsState(
|
||||
targetValue = when {
|
||||
isPressed -> 0.92f
|
||||
isHovered -> 1.05f
|
||||
else -> 1f
|
||||
},
|
||||
animationSpec = tween(durationMillis = 150),
|
||||
label = "thumbScale",
|
||||
)
|
||||
|
||||
val lift = if (isHovered && !isPressed && onCheckedChange != null) (-1).dp else 0.dp
|
||||
val density = LocalDensity.current
|
||||
val thumbOffsetXPx by animateDpAsState(
|
||||
targetValue = with(density) {
|
||||
val trackWidth = ToggleWidth - ThumbSize
|
||||
max((thumbProgress * trackWidth.toPx()).toDp() - 4.dp, 2.dp)
|
||||
},
|
||||
animationSpec = tween(durationMillis = 200),
|
||||
label = "thumbOffsetX",
|
||||
)
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.width(ToggleWidth)
|
||||
.height(ToggleHeight)
|
||||
.graphicsLayer {
|
||||
translationY = lift.toPx()
|
||||
}
|
||||
.then(
|
||||
if (resolved.shadow.elevation > 0.dp) {
|
||||
Modifier.shadow(
|
||||
elevation = resolved.shadow.elevation,
|
||||
shape = resolved.shape,
|
||||
ambientColor = resolved.shadow.ambientColor,
|
||||
spotColor = resolved.shadow.spotColor,
|
||||
)
|
||||
} else Modifier
|
||||
)
|
||||
.clip(resolved.shape)
|
||||
.background(resolved.colors.background, resolved.shape)
|
||||
.border(BorderStroke(resolved.border.width, borderColor), resolved.shape)
|
||||
.highlight(resolved.colors.highlight)
|
||||
.then(
|
||||
if (onCheckedChange != null) {
|
||||
Modifier
|
||||
.hoverable(interactionSource = source, enabled = enabled)
|
||||
.clickable(
|
||||
enabled = enabled,
|
||||
interactionSource = source,
|
||||
indication = null,
|
||||
onClick = { onCheckedChange(!checked) },
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.offset(x = thumbOffsetXPx)
|
||||
.size(ThumbSize)
|
||||
.graphicsLayer {
|
||||
scaleX = thumbScale
|
||||
scaleY = thumbScale
|
||||
}
|
||||
.shadow(
|
||||
elevation = thumbShadowState.elevation,
|
||||
shape = CircleShape,
|
||||
ambientColor = thumbShadowState.ambientColor,
|
||||
spotColor = thumbShadowState.spotColor,
|
||||
)
|
||||
.background(
|
||||
brush = Brush.radialGradient(
|
||||
colors = listOf(
|
||||
Color.White.copy(alpha = 0.6f),
|
||||
thumbColor.copy(alpha = 0.95f),
|
||||
thumbColor,
|
||||
),
|
||||
center = Offset(0f, -0.55f),
|
||||
radius = 1.1f,
|
||||
),
|
||||
shape = CircleShape,
|
||||
)
|
||||
.border(
|
||||
width = 0.8.dp,
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
Color.White.copy(alpha = 0.55f),
|
||||
Color.White.copy(alpha = 0.08f),
|
||||
),
|
||||
),
|
||||
shape = CircleShape,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun TogglePreview() {
|
||||
MaterialTheme {
|
||||
val theme = rememberBaseUITheme()
|
||||
CompositionLocalProvider(LocalBaseUITheme provides theme) {
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
modifier = Modifier.padding(24.dp),
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Toggle(checked = true, onCheckedChange = {})
|
||||
Toggle(checked = false, onCheckedChange = {})
|
||||
Toggle(checked = true, onCheckedChange = null)
|
||||
Toggle(checked = false, onCheckedChange = null, enabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,7 +34,6 @@ import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -52,6 +51,7 @@ import coil3.compose.AsyncImage
|
||||
import dev.krtirtho.spotube.core.ui.base.OutlineButton
|
||||
import dev.krtirtho.spotube.core.ui.base.PrimaryButton
|
||||
import dev.krtirtho.spotube.core.ui.base.TextField
|
||||
import dev.krtirtho.spotube.core.ui.base.Toggle
|
||||
import io.github.vinceglb.filekit.dialogs.FileKitType
|
||||
import io.github.vinceglb.filekit.dialogs.compose.rememberFilePickerLauncher
|
||||
import io.github.vinceglb.filekit.readBytes
|
||||
@ -265,7 +265,7 @@ private fun PlaylistFormFields(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
Switch(checked = isPublic, onCheckedChange = onIsPublicChange)
|
||||
Toggle(checked = isPublic, onCheckedChange = onIsPublicChange)
|
||||
}
|
||||
|
||||
Row(
|
||||
@ -285,7 +285,7 @@ private fun PlaylistFormFields(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
Switch(checked = isCollaborating, onCheckedChange = onIsCollaboratingChange)
|
||||
Toggle(checked = isCollaborating, onCheckedChange = onIsCollaboratingChange)
|
||||
}
|
||||
|
||||
Column(
|
||||
|
||||
@ -32,7 +32,7 @@ import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Switch
|
||||
import dev.krtirtho.spotube.core.ui.base.Toggle
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
@ -64,7 +64,7 @@ internal fun SwitchSettingCard(
|
||||
subtitle = subtitle,
|
||||
icon = icon,
|
||||
trailingContent = {
|
||||
Switch(
|
||||
Toggle(
|
||||
checked = checked,
|
||||
onCheckedChange = onCheckedChange,
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user