diff --git a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDatePicker.kt b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDatePicker.kt index 2acca59..0f2c089 100644 --- a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDatePicker.kt +++ b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDatePicker.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.unit.dp import dev.darkokoa.datetimewheelpicker.core.CYB3R_1N1T_ZOLL import dev.darkokoa.datetimewheelpicker.core.DefaultWheelDatePicker import dev.darkokoa.datetimewheelpicker.core.EPOCH +import dev.darkokoa.datetimewheelpicker.core.MonthRepresentation import dev.darkokoa.datetimewheelpicker.core.SelectorProperties import dev.darkokoa.datetimewheelpicker.core.WheelPickerDefaults import dev.darkokoa.datetimewheelpicker.core.now @@ -28,6 +29,7 @@ fun WheelDatePicker( textStyle: TextStyle = MaterialTheme.typography.titleMedium, textColor: Color = LocalContentColor.current, selectorProperties: SelectorProperties = WheelPickerDefaults.selectorProperties(), + monthRepresentation: MonthRepresentation = MonthRepresentation.Default, onSnappedDate: (snappedDate: LocalDate) -> Unit = {} ) { DefaultWheelDatePicker( @@ -41,6 +43,7 @@ fun WheelDatePicker( textStyle, textColor, selectorProperties, + monthRepresentation = monthRepresentation, onSnappedDate = { snappedDate -> onSnappedDate(snappedDate.snappedLocalDate) snappedDate.snappedIndex diff --git a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDateTimePicker.kt b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDateTimePicker.kt index 1d6250c..b1137a1 100644 --- a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDateTimePicker.kt +++ b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/WheelDateTimePicker.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.unit.dp import dev.darkokoa.datetimewheelpicker.core.CYB3R_1N1T_ZOLL import dev.darkokoa.datetimewheelpicker.core.DefaultWheelDateTimePicker import dev.darkokoa.datetimewheelpicker.core.EPOCH +import dev.darkokoa.datetimewheelpicker.core.MonthRepresentation import dev.darkokoa.datetimewheelpicker.core.SelectorProperties import dev.darkokoa.datetimewheelpicker.core.TimeFormat import dev.darkokoa.datetimewheelpicker.core.WheelPickerDefaults @@ -32,6 +33,7 @@ fun WheelDateTimePicker( textStyle: TextStyle = MaterialTheme.typography.titleMedium, textColor: Color = LocalContentColor.current, selectorProperties: SelectorProperties = WheelPickerDefaults.selectorProperties(), + monthRepresentation: MonthRepresentation = MonthRepresentation.Default, onSnappedDateTime: (snappedDateTime: LocalDateTime) -> Unit = {} ) { DefaultWheelDateTimePicker( @@ -46,6 +48,7 @@ fun WheelDateTimePicker( textStyle, textColor, selectorProperties, + monthRepresentation = monthRepresentation, onSnappedDateTime = { snappedDateTime -> onSnappedDateTime(snappedDateTime.snappedLocalDateTime) snappedDateTime.snappedIndex diff --git a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDatePicker.kt b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDatePicker.kt index 5324319..a1de1cc 100644 --- a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDatePicker.kt +++ b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDatePicker.kt @@ -29,6 +29,7 @@ internal fun DefaultWheelDatePicker( textStyle: TextStyle = MaterialTheme.typography.titleMedium, textColor: Color = LocalContentColor.current, selectorProperties: SelectorProperties = WheelPickerDefaults.selectorProperties(), + monthRepresentation: MonthRepresentation, onSnappedDate: (snappedDate: SnappedDate) -> Int? = { _ -> null } ) { val itemCount = if (yearsRange == null) 2 else 3 @@ -39,12 +40,13 @@ internal fun DefaultWheelDatePicker( var dayOfMonths = calculateDayOfMonths(snappedDate.month.number, snappedDate.year) val months = (1..12).map { - val monthName = Month(it).name.lowercase().replaceFirstChar { char -> char.titlecase() } + val monthName = monthRepresentation.toMonthName( + month = Month(it), + dpWidthSize = size.width + ) Month( - text = if (size.width / 3 < 55.dp) { - monthName.substring(0, 3) - } else monthName, + text = monthName, value = it, index = it - 1 ) diff --git a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDateTimePicker.kt b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDateTimePicker.kt index 55e5e08..1aa8f36 100644 --- a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDateTimePicker.kt +++ b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/DefaultWheelDateTimePicker.kt @@ -29,6 +29,7 @@ internal fun DefaultWheelDateTimePicker( textStyle: TextStyle = MaterialTheme.typography.titleMedium, textColor: Color = LocalContentColor.current, selectorProperties: SelectorProperties = WheelPickerDefaults.selectorProperties(), + monthRepresentation: MonthRepresentation, onSnappedDateTime: (snappedDateTime: SnappedDateTime) -> Int? = { _ -> null } ) { @@ -61,6 +62,7 @@ internal fun DefaultWheelDateTimePicker( selectorProperties = WheelPickerDefaults.selectorProperties( enabled = false ), + monthRepresentation = monthRepresentation, onSnappedDate = { snappedDate -> val newDateTime = when (snappedDate) { diff --git a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/WheelPicker.kt b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/WheelPicker.kt index bd6a5ad..11124db 100644 --- a/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/WheelPicker.kt +++ b/datetime-wheel-picker/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/core/WheelPicker.kt @@ -18,8 +18,10 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp +import kotlinx.datetime.Month import kotlin.math.abs @OptIn(ExperimentalFoundationApi::class) @@ -192,4 +194,40 @@ internal class DefaultSelectorProperties( } } +sealed interface MonthRepresentation { + data object Default : MonthRepresentation + data object FullName : MonthRepresentation + data object ShortName : MonthRepresentation + data object MonthNumber : MonthRepresentation + data class Custom(val mapper: (monthIndex: Int) -> String) : MonthRepresentation +} + +internal fun MonthRepresentation.toMonthName(month: Month, dpWidthSize: Dp): String { + val monthName = month.name.lowercase().replaceFirstChar { char -> char.titlecase() } + return when(this){ + is MonthRepresentation.Default -> { + if (dpWidthSize / 3 < 55.dp) { + monthName.substring(0, 3) + } else { + monthName + } + } + is MonthRepresentation.FullName -> { + monthName + } + + is MonthRepresentation.ShortName -> { + monthName.substring(0, 3) + } + + is MonthRepresentation.MonthNumber -> { + month.ordinal.plus(1).toString().padStart(2, '0') + } + + is MonthRepresentation.Custom -> { + this.mapper(month.ordinal) + } + } +} + diff --git a/sample/composeApp/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/App.kt b/sample/composeApp/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/App.kt index 7c5de84..2e288a6 100644 --- a/sample/composeApp/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/App.kt +++ b/sample/composeApp/src/commonMain/kotlin/dev/darkokoa/datetimewheelpicker/App.kt @@ -3,18 +3,32 @@ package dev.darkokoa.datetimewheelpicker import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.CheckCircle import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import dev.darkokoa.datetimewheelpicker.core.MonthRepresentation import dev.darkokoa.datetimewheelpicker.core.TimeFormat import dev.darkokoa.datetimewheelpicker.core.WheelPickerDefaults import dev.darkokoa.datetimewheelpicker.theme.AppTheme @@ -25,6 +39,9 @@ import kotlinx.datetime.toLocalDateTime @Composable internal fun App() = AppTheme { + var monthRepresentation by remember { + mutableStateOf(MonthRepresentation.Default) + } Surface( modifier = Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.safeDrawing), color = MaterialTheme.colorScheme.background @@ -36,10 +53,22 @@ internal fun App() = AppTheme { WheelTimePicker { snappedTime -> println(snappedTime) } - WheelDatePicker { snappedDate -> + MonthRepresentationSelector( + modifier = Modifier + .fillMaxWidth(), + selectedMonthRepresentation = monthRepresentation, + onClicked = { + monthRepresentation = it + } + ) + WheelDatePicker( + monthRepresentation = monthRepresentation, + ) { snappedDate -> println(snappedDate) } - WheelDateTimePicker { snappedDateTime -> + WheelDateTimePicker( + monthRepresentation = monthRepresentation, + ) { snappedDateTime -> println(snappedDateTime) } WheelDateTimePicker( @@ -60,10 +89,78 @@ internal fun App() = AppTheme { shape = RoundedCornerShape(0.dp), color = Color(0xFFf1faee).copy(alpha = 0.2f), border = BorderStroke(2.dp, Color(0xFFf1faee)) - ) + ), + monthRepresentation = monthRepresentation ) { snappedDateTime -> println(snappedDateTime) } } } } + +@Composable +internal fun MonthRepresentationSelector( + modifier: Modifier = Modifier, + selectedMonthRepresentation: MonthRepresentation, + onClicked: (MonthRepresentation) -> Unit +) { + val monthRepresentations = listOf( + MonthRepresentation.Default, + MonthRepresentation.FullName, + MonthRepresentation.ShortName, + MonthRepresentation.MonthNumber, + MonthRepresentation.Custom( + mapper = { monthIndex: Int -> + "Mon-${monthIndex.plus(1)}" + } + ) + ) + LazyRow( + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(20.dp) + ) { + items(monthRepresentations) { item -> + MonthRepresentationSelectorItem( + monthRepresentation = item, + onClicked = onClicked, + isSelected = item == selectedMonthRepresentation + ) + } + } +} + +@Composable +internal fun MonthRepresentationSelectorItem( + monthRepresentation: MonthRepresentation, + isSelected: Boolean, + onClicked: (MonthRepresentation) -> Unit +) { + Surface( + color = Color(0xFFf1faee).copy(alpha = 0.2f), + onClick = { + onClicked(monthRepresentation) + }, + shape = CircleShape + ) { + Row( + modifier = Modifier + .padding(horizontal = 20.dp, vertical = 10.dp), + horizontalArrangement = Arrangement.spacedBy(15.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = monthRepresentation::class.simpleName.orEmpty(), + color = Color.White, + fontSize = 13.sp + ) + + if(isSelected){ + Icon( + imageVector = Icons.Outlined.CheckCircle, + contentDescription = null, + tint = Color.White + ) + } + } + } +} \ No newline at end of file