Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add map month name (Issue 12) #38

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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(
Expand All @@ -41,6 +43,7 @@ fun WheelDatePicker(
textStyle,
textColor,
selectorProperties,
monthRepresentation = monthRepresentation,
onSnappedDate = { snappedDate ->
onSnappedDate(snappedDate.snappedLocalDate)
snappedDate.snappedIndex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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(
Expand All @@ -46,6 +48,7 @@ fun WheelDateTimePicker(
textStyle,
textColor,
selectorProperties,
monthRepresentation = monthRepresentation,
onSnappedDateTime = { snappedDateTime ->
onSnappedDateTime(snappedDateTime.snappedLocalDateTime)
snappedDateTime.snappedIndex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
) {

Expand Down Expand Up @@ -61,6 +62,7 @@ internal fun DefaultWheelDateTimePicker(
selectorProperties = WheelPickerDefaults.selectorProperties(
enabled = false
),
monthRepresentation = monthRepresentation,
onSnappedDate = { snappedDate ->

val newDateTime = when (snappedDate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,6 +39,9 @@ import kotlinx.datetime.toLocalDateTime

@Composable
internal fun App() = AppTheme {
var monthRepresentation by remember {
mutableStateOf<MonthRepresentation>(MonthRepresentation.Default)
}
Surface(
modifier = Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.safeDrawing),
color = MaterialTheme.colorScheme.background
Expand All @@ -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(
Expand All @@ -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
)
}
}
}
}