feat(sidebar): adjust spacing in sidebar and setting cards for improved layout

This commit is contained in:
Kingkor Roy Tirtho 2026-10-14 16:41:48 +06:00
parent 1ccd70a18c
commit fda5bb8a60
3 changed files with 44 additions and 28 deletions

View File

@ -255,7 +255,7 @@ private fun PlaylistFormFields(
style = AppTheme.typography.bodySmall, style = AppTheme.typography.bodySmall,
color = AppTheme.colors.onSurfaceVariant) color = AppTheme.colors.onSurfaceVariant)
} }
MillenniumSwitch(checked = isPublic, onCheckedChange = onIsPublicChange, label = "Public") MillenniumSwitch(checked = isPublic, onCheckedChange = onIsPublicChange)
} }
Row( Row(
@ -273,7 +273,7 @@ private fun PlaylistFormFields(
style = AppTheme.typography.bodySmall, style = AppTheme.typography.bodySmall,
color = AppTheme.colors.onSurfaceVariant) color = AppTheme.colors.onSurfaceVariant)
} }
MillenniumSwitch(checked = isCollaborating, onCheckedChange = onIsCollaboratingChange, label = "Collaborative") MillenniumSwitch(checked = isCollaborating, onCheckedChange = onIsCollaboratingChange)
} }
Column( Column(

View File

@ -18,8 +18,6 @@
package dev.krtirtho.spotube.modules.settings.components package dev.krtirtho.spotube.modules.settings.components
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import com.composeunstyled.currentWindowWidthBreakpoint import com.composeunstyled.currentWindowWidthBreakpoint
import org.spotube.millennium.adaptive.WindowBreakpoints import org.spotube.millennium.adaptive.WindowBreakpoints
@ -65,7 +63,8 @@ internal fun SwitchSettingCard(
subtitle: String? = null, subtitle: String? = null,
checked: Boolean, checked: Boolean,
onCheckedChange: (Boolean) -> Unit, onCheckedChange: (Boolean) -> Unit,
icon: (@Composable () -> Unit)? = null) { icon: (@Composable () -> Unit)? = null
) {
SettingCardItem( SettingCardItem(
title = title, title = title,
subtitle = subtitle, subtitle = subtitle,
@ -74,10 +73,8 @@ internal fun SwitchSettingCard(
MillenniumSwitch( MillenniumSwitch(
checked = checked, checked = checked,
onCheckedChange = onCheckedChange, onCheckedChange = onCheckedChange,
// The row itself already renders the title/subtitle, so the switch must not contentSpacing = 0.dp
// draw a second visible label next to it. )
label = "",
contentSpacing = 0.dp)
}, },
onClick = { onClick = {
onCheckedChange(!checked) onCheckedChange(!checked)
@ -96,7 +93,8 @@ internal fun <T> SelectionSettingCard(
dialogTitle: String = title, dialogTitle: String = title,
icon: (@Composable () -> Unit)? = null, icon: (@Composable () -> Unit)? = null,
inlineSelectorMinWidth: Dp = 700.dp, inlineSelectorMinWidth: Dp = 700.dp,
filter: ((AdaptiveMenuItem, String) -> Boolean)? = null) { filter: ((AdaptiveMenuItem, String) -> Boolean)? = null
) {
var isDialogOpen by remember { mutableStateOf(false) } var isDialogOpen by remember { mutableStateOf(false) }
Box { Box {
@ -112,24 +110,29 @@ internal fun <T> SelectionSettingCard(
AdaptiveMenuItem( AdaptiveMenuItem(
label = optionLabel(option), label = optionLabel(option),
onClick = { onOptionSelected(option) }, onClick = { onOptionSelected(option) },
selected = option == selectedOption) selected = option == selectedOption
)
}, },
trigger = { onClick -> trigger = { onClick ->
MillenniumButton( MillenniumButton(
onClick = onClick, onClick = onClick,
style = MillenniumButtonStyle.Secondary) { style = MillenniumButtonStyle.Secondary
) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(6.dp)) { horizontalArrangement = Arrangement.spacedBy(6.dp)
) {
Text(optionLabel(selectedOption)) Text(optionLabel(selectedOption))
MillenniumIcon( MillenniumIcon(
imageVector = Iconsax.IconsaxArrowDown4, imageVector = Iconsax.IconsaxArrowDown4,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(14.dp)) modifier = Modifier.size(14.dp)
)
} }
} }
}, },
filter = filter) filter = filter
)
}, },
onClick = { onClick = {
if (isWideLayout) { if (isWideLayout) {
@ -143,7 +146,8 @@ internal fun <T> SelectionSettingCard(
MillenniumDialog( MillenniumDialog(
visible = true, visible = true,
onDismissRequest = { isDialogOpen = false }, onDismissRequest = { isDialogOpen = false },
title = dialogTitle) { title = dialogTitle
) {
MillenniumRadioGroup( MillenniumRadioGroup(
value = selectedOption, value = selectedOption,
onValueChange = { option -> onValueChange = { option ->
@ -155,7 +159,8 @@ internal fun <T> SelectionSettingCard(
optionLabel = { option -> labels[options.indexOf(option)] }) optionLabel = { option -> labels[options.indexOf(option)] })
MillenniumButton( MillenniumButton(
onClick = { isDialogOpen = false }, onClick = { isDialogOpen = false },
style = MillenniumButtonStyle.Quiet) { style = MillenniumButtonStyle.Quiet
) {
Text(stringResource(Res.string.settings_action_close)) Text(stringResource(Res.string.settings_action_close))
} }
} }
@ -177,7 +182,8 @@ internal fun TextInputSettingCard(
icon: (@Composable () -> Unit)? = null, icon: (@Composable () -> Unit)? = null,
inlineTextFieldMinWidth: Dp = 700.dp, inlineTextFieldMinWidth: Dp = 700.dp,
inlineTextFieldWidth: Dp = 220.dp, inlineTextFieldWidth: Dp = 220.dp,
enabled: Boolean = true) { enabled: Boolean = true
) {
var isDialogOpen by remember { mutableStateOf(false) } var isDialogOpen by remember { mutableStateOf(false) }
Box { Box {
@ -204,10 +210,10 @@ internal fun TextInputSettingCard(
{ {
MillenniumTextField( MillenniumTextField(
state = inlineState, state = inlineState,
label = title,
modifier = Modifier.width(inlineTextFieldWidth), modifier = Modifier.width(inlineTextFieldWidth),
placeholder = placeholder, placeholder = placeholder,
enabled = enabled) enabled = enabled
)
} }
} else { } else {
null null
@ -235,19 +241,22 @@ internal fun TextInputSettingCard(
MillenniumDialog( MillenniumDialog(
visible = true, visible = true,
onDismissRequest = { isDialogOpen = false }, onDismissRequest = { isDialogOpen = false },
title = dialogTitle) { title = dialogTitle
) {
if (dialogDescription != null) { if (dialogDescription != null) {
Text( Text(
text = dialogDescription, text = dialogDescription,
style = AppTheme.typography.bodySmall, style = AppTheme.typography.bodySmall,
color = AppTheme.colors.onSurfaceVariant) color = AppTheme.colors.onSurfaceVariant
)
} }
MillenniumTextField( MillenniumTextField(
state = dialogState, state = dialogState,
label = title, label = title,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
placeholder = placeholder, placeholder = placeholder,
error = errorMessage) error = errorMessage
)
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) { Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
MillenniumButton( MillenniumButton(
onClick = { onClick = {
@ -256,12 +265,14 @@ internal fun TextInputSettingCard(
isDialogOpen = false isDialogOpen = false
} }
}, },
enabled = errorMessage == null) { enabled = errorMessage == null
) {
Text(stringResource(Res.string.settings_action_save)) Text(stringResource(Res.string.settings_action_save))
} }
MillenniumButton( MillenniumButton(
onClick = { isDialogOpen = false }, onClick = { isDialogOpen = false },
style = MillenniumButtonStyle.Secondary) { style = MillenniumButtonStyle.Secondary
) {
Text(stringResource(Res.string.settings_action_cancel)) Text(stringResource(Res.string.settings_action_cancel))
} }
} }

View File

@ -118,7 +118,9 @@ fun AppSidebar(
} }
} }
} }
MillenniumSidebarContent { MillenniumSidebarContent(
contentSpacing = 0.dp
) {
sidebarTabs.forEach { entry -> sidebarTabs.forEach { entry ->
when (entry) { when (entry) {
is NavigationItem.Group<*> -> { is NavigationItem.Group<*> -> {
@ -126,10 +128,13 @@ fun AppSidebar(
MillenniumSidebarGroup( MillenniumSidebarGroup(
expanded = isGroupExpanded, expanded = isGroupExpanded,
collapsible = true, collapsible = true,
groupSpacing = 0.dp,
onExpandedChange = { groupExpansion[entry.title] = it }) { onExpandedChange = { groupExpansion[entry.title] = it }) {
MillenniumSidebarGroupLabel(entry.title) MillenniumSidebarGroupLabel(entry.title)
MillenniumSidebarGroupContent { MillenniumSidebarGroupContent(
MillenniumSidebarMenu { contentSpacing = 0.dp
) {
MillenniumSidebarMenu(contentSpacing = 0.dp) {
entry.items.forEach { item -> entry.items.forEach { item ->
val selected = val selected =
navigationState.topLevelRoute == item.route && navigationState.topLevelRoute == item.route &&