
Highly customizable date and time picker library offers beautiful, Material Design 3 compliant components. Features include multiple themes, formats, easy configuration, validation support, and state management.
A highly customizable and feature-rich date and time picker library for Kotlin Multiplatform Compose applications. This library provides beautiful, Material Design 3 compliant date and time selection components with extensive customization options.
rememberDateTimePickerState
Add the library to your commonMain dependencies:
dependencies {
implementation("io.github.srabbijan:kmpdatetimepicker:1.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
}##Preview https://youtube.com/shorts/GVtyaTCNjf8?feature=share
@Composable
fun MyScreen() {
val dateTimeState = rememberDateTimePickerState()
Column {
// Date Input Field
DateInputField(
label = "Select Date",
selectedDate = dateTimeState.selectedDate,
onDateClick = { dateTimeState.showDatePicker() }
)
// Date Picker Dialog
DateTimePicker(
label = "Select Date",
isVisible = dateTimeState.isDatePickerVisible,
onDateSelected = dateTimeState::onDateSelected,
onDismiss = dateTimeState::hideDatePicker
)
}
}@Composable
fun CustomizedDatePicker() {
val customConfig = dateTimePickerConfig {
colors {
copy(
primary = Color(0xFF6200EE),
background = Color.White,
border = Color(0xFFE0E0E0)
)
}
shapes {
copy(
container = RoundedCornerShape(12.dp),
dialog = RoundedCornerShape(20.dp)
)
}
locale {
copy(
selectDate = "Choose Date",
dateFormat = DateFormat.YYYY_MM_DD,
timeFormat = TimeFormat.TWENTY_FOUR_HOUR
)
}
}
DateInputField(
label = "Custom Date Picker",
selectedDate = selectedDate,
config = customConfig,
onDateClick = { /* show picker */ }
)
}A standalone date picker dialog.
DateTimePicker(
label = "Select Date",
isVisible = isVisible,
initialDate = LocalDate.now(),
minDate = LocalDate.now().minusDays(30),
maxDate = LocalDate.now().plusDays(30),
config = config,
onDateSelected = { date -> /* handle date */ },
onDismiss = { /* handle dismiss */ }
)A standalone time picker dialog.
DateTimeTimePicker(
label = "Select Time",
isVisible = isVisible,
initialTime = LocalTime.now(),
config = config,
onTimeSelected = { time -> /* handle time */ },
onDismiss = { /* handle dismiss */ }
)A combined date and time picker with tabs.
DateTimeFullPicker(
label = "Select Date & Time",
isVisible = isVisible,
initialDateTime = LocalDateTime.now(),
config = config,
onDateTimeSelected = { dateTime -> /* handle datetime */ },
onDismiss = { /* handle dismiss */ }
)DateInputField(
label = "Date",
selectedDate = selectedDate,
config = config,
enabled = true,
isError = false,
errorMessage = null,
leadingIcon = { /* custom icon */ },
trailingIcon = { /* custom icon */ },
onDateClick = { /* show picker */ }
)TimeInputField(
label = "Time",
selectedTime = selectedTime,
config = config,
enabled = true,
isError = false,
errorMessage = null,
leadingIcon = { /* custom icon */ },
trailingIcon = { /* custom icon */ },
onTimeClick = { /* show picker */ }
)DateTimeInputField(
label = "Date & Time",
selectedDateTime = selectedDateTime,
config = config,
enabled = true,
isError = false,
errorMessage = null,
leadingIcon = { /* custom icon */ },
trailingIcon = { /* custom icon */ },
onDateTimeClick = { /* show picker */ }
)The main configuration class that controls the appearance and behavior of all components.
data class DateTimePickerConfig(
val colors: DateTimePickerColors,
val shapes: DateTimePickerShapes,
val typography: DateTimePickerTypography,
val dimensions: DateTimePickerDimensions,
val locale: DateTimePickerLocale
)data class DateTimePickerColors(
val primary: Color,
val background: Color,
val surface: Color,
val onPrimary: Color,
val onBackground: Color,
val onSurface: Color,
val border: Color,
val error: Color,
val placeholder: Color,
val label: Color,
val selectedDay: Color,
val todayBorder: Color
)data class DateTimePickerShapes(
val container: Shape,
val dialog: Shape,
val button: Shape
)data class DateTimePickerTypography(
val title: TextStyle,
val label: TextStyle,
val body: TextStyle,
val button: TextStyle,
val error: TextStyle
)data class DateTimePickerDimensions(
val dialogWidth: Float,
val dialogPadding: Dp,
val fieldHeight: Dp,
val spacing: Dp,
val iconSize: Dp,
val borderWidth: Dp
)data class DateTimePickerLocale(
val selectDate: String,
val selectTime: String,
val selectDateTime: String,
val cancel: String,
val select: String,
val dateTab: String,
val timeTab: String,
val datePlaceholder: String,
val timePlaceholder: String,
val dateTimePlaceholder: String,
val dateFormat: DateFormat,
val timeFormat: TimeFormat
)The library comes with several predefined themes:
// Default theme
DateTimePickerThemes.Default
// Dark theme
DateTimePickerThemes.Dark
// Material 3 theme
DateTimePickerThemes.Material3
// Cupertino (iOS-style) theme
DateTimePickerThemes.CupertinoDateInputField(
label = "Select Date",
selectedDate = selectedDate,
config = DateTimePickerThemes.Dark,
onDateClick = { /* show picker */ }
)Use rememberDateTimePickerState for convenient state management:
@Composable
fun MyScreen() {
val dateTimeState = rememberDateTimePickerState(
initialDate = LocalDate.now(),
initialTime = LocalTime.now(),
initialDateTime = LocalDateTime.now()
)
// Access state
val selectedDate = dateTimeState.selectedDate
val selectedTime = dateTimeState.selectedTime
val selectedDateTime = dateTimeState.selectedDateTime
// Control visibility
dateTimeState.showDatePicker()
dateTimeState.hideDatePicker()
// Handle selections
dateTimeState.onDateSelected(LocalDate.now())
dateTimeState.onTimeSelected(LocalTime.now())
dateTimeState.onDateTimeSelected(LocalDateTime.now())
// Reset state
dateTimeState.reset()
}The library includes built-in validation helpers:
// Validate date
val dateValidation = DateTimeValidator.validateDate(
date = selectedDate,
minDate = LocalDate.now().minusDays(30),
maxDate = LocalDate.now().plusDays(30),
isRequired = true
)
if (!dateValidation.isValid) {
// Show error message
println(dateValidation.errorMessage)
}
// Validate time
val timeValidation = DateTimeValidator.validateTime(
time = selectedTime,
minTime = LocalTime(9, 0),
maxTime = LocalTime(17, 0),
isRequired = true
)
// Validate datetime
val dateTimeValidation = DateTimeValidator.validateDateTime(
dateTime = selectedDateTime,
minDateTime = LocalDateTime.now(),
maxDateTime = LocalDateTime.now().plusDays(7),
isRequired = true
)// Get current date/time
val currentDate = DateTimePickerUtils.getCurrentDate()
val currentTime = DateTimePickerUtils.getCurrentTime()
val currentDateTime = DateTimePickerUtils.getCurrentDateTime()
// Parse date/time strings
val parsedDate = DateTimePickerUtils.parseDate("25/12/2023", DateFormat.DD_MM_YYYY)
val parsedTime = DateTimePickerUtils.parseTime("14:30", TimeFormat.TWENTY_FOUR_HOUR)
// Validate date range
val isInRange = DateTimePickerUtils.isDateInRange(
date = selectedDate,
minDate = minDate,
maxDate = maxDate
)// Format dates
val formattedDate = localDate.toDisplayString(DateFormat.YYYY_MM_DD)
val apiFormat = localDate.toAPIFormat()
// Format times
val formattedTime = localTime.toDisplayString(TimeFormat.TWENTY_FOUR_HOUR)
// Format datetime
val formattedDateTime = localDateTime.toDisplayString(
DateFormat.DD_MM_YYYY,
TimeFormat.TWELVE_HOUR
)@Composable
fun ValidatedDateInput() {
var selectedDate by remember { mutableStateOf<LocalDate?>(null) }
var isError by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf<String?>(null) }
val validation = DateTimeValidator.validateDate(
date = selectedDate,
minDate = LocalDate.now(),
isRequired = true
)
LaunchedEffect(selectedDate) {
isError = !validation.isValid
errorMessage = validation.errorMessage
}
DateInputField(
label = "Select Future Date",
selectedDate = selectedDate,
isError = isError,
errorMessage = errorMessage,
onDateClick = { /* show picker */ }
)
}val arabicConfig = dateTimePickerConfig {
locale {
copy(
selectDate = "اختر التاريخ",
selectTime = "اختر الوقت",
cancel = "إلغاء",
select = "اختيار",
dateFormat = DateFormat.DD_MM_YYYY
)
}
}DateInputField(
label = "Date",
selectedDate = selectedDate,
trailingIcon = {
Icon(
painter = painterResource(Res.drawable.custom_calendar),
contentDescription = "Calendar",
tint = MaterialTheme.colorScheme.primary
)
},
onDateClick = { /* show picker */ }
)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Contributions are welcome! Please feel free to submit a Pull Request.
For support, please open an issue on GitHub or contact us at srabbijan@gmail.com.
A highly customizable and feature-rich date and time picker library for Kotlin Multiplatform Compose applications. This library provides beautiful, Material Design 3 compliant date and time selection components with extensive customization options.
rememberDateTimePickerState
Add the library to your commonMain dependencies:
dependencies {
implementation("io.github.srabbijan:kmpdatetimepicker:1.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
}##Preview https://youtube.com/shorts/GVtyaTCNjf8?feature=share
@Composable
fun MyScreen() {
val dateTimeState = rememberDateTimePickerState()
Column {
// Date Input Field
DateInputField(
label = "Select Date",
selectedDate = dateTimeState.selectedDate,
onDateClick = { dateTimeState.showDatePicker() }
)
// Date Picker Dialog
DateTimePicker(
label = "Select Date",
isVisible = dateTimeState.isDatePickerVisible,
onDateSelected = dateTimeState::onDateSelected,
onDismiss = dateTimeState::hideDatePicker
)
}
}@Composable
fun CustomizedDatePicker() {
val customConfig = dateTimePickerConfig {
colors {
copy(
primary = Color(0xFF6200EE),
background = Color.White,
border = Color(0xFFE0E0E0)
)
}
shapes {
copy(
container = RoundedCornerShape(12.dp),
dialog = RoundedCornerShape(20.dp)
)
}
locale {
copy(
selectDate = "Choose Date",
dateFormat = DateFormat.YYYY_MM_DD,
timeFormat = TimeFormat.TWENTY_FOUR_HOUR
)
}
}
DateInputField(
label = "Custom Date Picker",
selectedDate = selectedDate,
config = customConfig,
onDateClick = { /* show picker */ }
)
}A standalone date picker dialog.
DateTimePicker(
label = "Select Date",
isVisible = isVisible,
initialDate = LocalDate.now(),
minDate = LocalDate.now().minusDays(30),
maxDate = LocalDate.now().plusDays(30),
config = config,
onDateSelected = { date -> /* handle date */ },
onDismiss = { /* handle dismiss */ }
)A standalone time picker dialog.
DateTimeTimePicker(
label = "Select Time",
isVisible = isVisible,
initialTime = LocalTime.now(),
config = config,
onTimeSelected = { time -> /* handle time */ },
onDismiss = { /* handle dismiss */ }
)A combined date and time picker with tabs.
DateTimeFullPicker(
label = "Select Date & Time",
isVisible = isVisible,
initialDateTime = LocalDateTime.now(),
config = config,
onDateTimeSelected = { dateTime -> /* handle datetime */ },
onDismiss = { /* handle dismiss */ }
)DateInputField(
label = "Date",
selectedDate = selectedDate,
config = config,
enabled = true,
isError = false,
errorMessage = null,
leadingIcon = { /* custom icon */ },
trailingIcon = { /* custom icon */ },
onDateClick = { /* show picker */ }
)TimeInputField(
label = "Time",
selectedTime = selectedTime,
config = config,
enabled = true,
isError = false,
errorMessage = null,
leadingIcon = { /* custom icon */ },
trailingIcon = { /* custom icon */ },
onTimeClick = { /* show picker */ }
)DateTimeInputField(
label = "Date & Time",
selectedDateTime = selectedDateTime,
config = config,
enabled = true,
isError = false,
errorMessage = null,
leadingIcon = { /* custom icon */ },
trailingIcon = { /* custom icon */ },
onDateTimeClick = { /* show picker */ }
)The main configuration class that controls the appearance and behavior of all components.
data class DateTimePickerConfig(
val colors: DateTimePickerColors,
val shapes: DateTimePickerShapes,
val typography: DateTimePickerTypography,
val dimensions: DateTimePickerDimensions,
val locale: DateTimePickerLocale
)data class DateTimePickerColors(
val primary: Color,
val background: Color,
val surface: Color,
val onPrimary: Color,
val onBackground: Color,
val onSurface: Color,
val border: Color,
val error: Color,
val placeholder: Color,
val label: Color,
val selectedDay: Color,
val todayBorder: Color
)data class DateTimePickerShapes(
val container: Shape,
val dialog: Shape,
val button: Shape
)data class DateTimePickerTypography(
val title: TextStyle,
val label: TextStyle,
val body: TextStyle,
val button: TextStyle,
val error: TextStyle
)data class DateTimePickerDimensions(
val dialogWidth: Float,
val dialogPadding: Dp,
val fieldHeight: Dp,
val spacing: Dp,
val iconSize: Dp,
val borderWidth: Dp
)data class DateTimePickerLocale(
val selectDate: String,
val selectTime: String,
val selectDateTime: String,
val cancel: String,
val select: String,
val dateTab: String,
val timeTab: String,
val datePlaceholder: String,
val timePlaceholder: String,
val dateTimePlaceholder: String,
val dateFormat: DateFormat,
val timeFormat: TimeFormat
)The library comes with several predefined themes:
// Default theme
DateTimePickerThemes.Default
// Dark theme
DateTimePickerThemes.Dark
// Material 3 theme
DateTimePickerThemes.Material3
// Cupertino (iOS-style) theme
DateTimePickerThemes.CupertinoDateInputField(
label = "Select Date",
selectedDate = selectedDate,
config = DateTimePickerThemes.Dark,
onDateClick = { /* show picker */ }
)Use rememberDateTimePickerState for convenient state management:
@Composable
fun MyScreen() {
val dateTimeState = rememberDateTimePickerState(
initialDate = LocalDate.now(),
initialTime = LocalTime.now(),
initialDateTime = LocalDateTime.now()
)
// Access state
val selectedDate = dateTimeState.selectedDate
val selectedTime = dateTimeState.selectedTime
val selectedDateTime = dateTimeState.selectedDateTime
// Control visibility
dateTimeState.showDatePicker()
dateTimeState.hideDatePicker()
// Handle selections
dateTimeState.onDateSelected(LocalDate.now())
dateTimeState.onTimeSelected(LocalTime.now())
dateTimeState.onDateTimeSelected(LocalDateTime.now())
// Reset state
dateTimeState.reset()
}The library includes built-in validation helpers:
// Validate date
val dateValidation = DateTimeValidator.validateDate(
date = selectedDate,
minDate = LocalDate.now().minusDays(30),
maxDate = LocalDate.now().plusDays(30),
isRequired = true
)
if (!dateValidation.isValid) {
// Show error message
println(dateValidation.errorMessage)
}
// Validate time
val timeValidation = DateTimeValidator.validateTime(
time = selectedTime,
minTime = LocalTime(9, 0),
maxTime = LocalTime(17, 0),
isRequired = true
)
// Validate datetime
val dateTimeValidation = DateTimeValidator.validateDateTime(
dateTime = selectedDateTime,
minDateTime = LocalDateTime.now(),
maxDateTime = LocalDateTime.now().plusDays(7),
isRequired = true
)// Get current date/time
val currentDate = DateTimePickerUtils.getCurrentDate()
val currentTime = DateTimePickerUtils.getCurrentTime()
val currentDateTime = DateTimePickerUtils.getCurrentDateTime()
// Parse date/time strings
val parsedDate = DateTimePickerUtils.parseDate("25/12/2023", DateFormat.DD_MM_YYYY)
val parsedTime = DateTimePickerUtils.parseTime("14:30", TimeFormat.TWENTY_FOUR_HOUR)
// Validate date range
val isInRange = DateTimePickerUtils.isDateInRange(
date = selectedDate,
minDate = minDate,
maxDate = maxDate
)// Format dates
val formattedDate = localDate.toDisplayString(DateFormat.YYYY_MM_DD)
val apiFormat = localDate.toAPIFormat()
// Format times
val formattedTime = localTime.toDisplayString(TimeFormat.TWENTY_FOUR_HOUR)
// Format datetime
val formattedDateTime = localDateTime.toDisplayString(
DateFormat.DD_MM_YYYY,
TimeFormat.TWELVE_HOUR
)@Composable
fun ValidatedDateInput() {
var selectedDate by remember { mutableStateOf<LocalDate?>(null) }
var isError by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf<String?>(null) }
val validation = DateTimeValidator.validateDate(
date = selectedDate,
minDate = LocalDate.now(),
isRequired = true
)
LaunchedEffect(selectedDate) {
isError = !validation.isValid
errorMessage = validation.errorMessage
}
DateInputField(
label = "Select Future Date",
selectedDate = selectedDate,
isError = isError,
errorMessage = errorMessage,
onDateClick = { /* show picker */ }
)
}val arabicConfig = dateTimePickerConfig {
locale {
copy(
selectDate = "اختر التاريخ",
selectTime = "اختر الوقت",
cancel = "إلغاء",
select = "اختيار",
dateFormat = DateFormat.DD_MM_YYYY
)
}
}DateInputField(
label = "Date",
selectedDate = selectedDate,
trailingIcon = {
Icon(
painter = painterResource(Res.drawable.custom_calendar),
contentDescription = "Calendar",
tint = MaterialTheme.colorScheme.primary
)
},
onDateClick = { /* show picker */ }
)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Contributions are welcome! Please feel free to submit a Pull Request.
For support, please open an issue on GitHub or contact us at srabbijan@gmail.com.