feat(#30): replace category swatch grid with HSV color picker #35

Merged
admin merged 1 commits from feat/30-category-rgb-color-picker into main 2026-06-28 14:21:44 +00:00
3 changed files with 20 additions and 50 deletions
+1
View File
@@ -94,4 +94,5 @@ dependencies {
implementation(libs.vico.compose) implementation(libs.vico.compose)
implementation(libs.vico.compose.m3) implementation(libs.vico.compose.m3)
implementation(libs.vico.core) implementation(libs.vico.core)
implementation(libs.colorpicker.compose)
} }
@@ -3,7 +3,6 @@ package dev.achmad.ledgerr.ui.screens.category
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
@@ -15,11 +14,10 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.items as lazyListItems import androidx.compose.foundation.lazy.items as lazyListItems
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Delete
@@ -45,11 +43,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import com.github.skydoves.colorpicker.compose.HsvColorPicker
import com.github.skydoves.colorpicker.compose.rememberColorPickerController
import dev.achmad.ledgerr.R import dev.achmad.ledgerr.R
import dev.achmad.ledgerr.domain.category.model.Category import dev.achmad.ledgerr.domain.category.model.Category
import dev.achmad.ledgerr.ui.components.AppBar import dev.achmad.ledgerr.ui.components.AppBar
@@ -237,16 +238,7 @@ private fun CategoryEditDialog(
var name by rememberSaveable(initial?.id) { mutableStateOf(initial?.name.orEmpty()) } var name by rememberSaveable(initial?.id) { mutableStateOf(initial?.name.orEmpty()) }
var color by rememberSaveable(initial?.id) { mutableStateOf(initial?.color ?: Category.DEFAULT_COLOR_OTHER) } var color by rememberSaveable(initial?.id) { mutableStateOf(initial?.color ?: Category.DEFAULT_COLOR_OTHER) }
val swatches = listOf( val controller = rememberColorPickerController()
Category.DEFAULT_COLOR_FOOD,
Category.DEFAULT_COLOR_TRANSPORT,
Category.DEFAULT_COLOR_HOUSING,
Category.DEFAULT_COLOR_HEALTH,
Category.DEFAULT_COLOR_ENTERTAINMENT,
Category.DEFAULT_COLOR_SHOPPING,
Category.DEFAULT_COLOR_EDUCATION,
Category.DEFAULT_COLOR_OTHER,
)
AlertDialog( AlertDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
@@ -259,7 +251,7 @@ private fun CategoryEditDialog(
) )
}, },
text = { text = {
Column { Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
OutlinedTextField( OutlinedTextField(
value = name, value = name,
onValueChange = { name = it }, onValueChange = { name = it },
@@ -273,22 +265,18 @@ private fun CategoryEditDialog(
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
LazyVerticalGrid( HsvColorPicker(
columns = GridCells.Fixed(8),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(56.dp), .height(280.dp),
) { controller = controller,
items(items = swatches, key = { it }) { swatch -> initialColor = Color(color),
ColorSwatch( onColorChanged = { envelope ->
color = Color(swatch), if (envelope.fromUser) {
selected = color == swatch, color = envelope.color.toArgb()
onClick = { color = swatch }, }
) },
} )
}
} }
}, },
confirmButton = { confirmButton = {
@@ -316,24 +304,3 @@ private fun CategoryEditDialog(
}, },
) )
} }
@Composable
private fun ColorSwatch(
color: Color,
selected: Boolean,
onClick: () -> Unit,
) {
Box(
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.background(color)
.clickable(onClick = onClick)
.border(
width = if (selected) 3.dp else 1.dp,
color = if (selected) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.outline.copy(alpha = 0.3f),
shape = CircleShape,
),
)
}
+2
View File
@@ -22,6 +22,7 @@ material = "1.14.0"
room = "2.7.1" room = "2.7.1"
pdfboxAndroid = "2.0.27.0" pdfboxAndroid = "2.0.27.0"
vico = "2.0.0" vico = "2.0.0"
colorpickerCompose = "1.2.0"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -68,6 +69,7 @@ pdfbox-android = { group = "com.tom-roush", name = "pdfbox-android", version.ref
vico-compose = { group = "com.patrykandpatrick.vico", name = "compose", version.ref = "vico" } vico-compose = { group = "com.patrykandpatrick.vico", name = "compose", version.ref = "vico" }
vico-compose-m3 = { group = "com.patrykandpatrick.vico", name = "compose-m3", version.ref = "vico" } vico-compose-m3 = { group = "com.patrykandpatrick.vico", name = "compose-m3", version.ref = "vico" }
vico-core = { group = "com.patrykandpatrick.vico", name = "core", version.ref = "vico" } vico-core = { group = "com.patrykandpatrick.vico", name = "core", version.ref = "vico" }
colorpicker-compose = { module = "com.github.skydoves:colorpicker-compose", version.ref = "colorpickerCompose" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }