
Flexible calendar views enable event display with monthly, bi-weekly, 3-day, and schedule options. Features cross-platform compatibility, customizable styling, and date handling using a specific date-time library.
Compose Calendar Event is a Compose Multiplatform package that provides flexible calendar views to display events.
It supports all platforms (Android, iOS, Desktop, Web) using only kotlinx.datetime for date handling.
kotlinx.datetime. implementation("io.github.the-best-is-best:compose-calendar-event:2.2.0")Compose Calendar Event is available on mavenCentral().
enum class CalendarType {
MONTHLY, ThreeDays, SCHEDULED
}
@Composable
internal fun App() = AppTheme {
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
CalendarScreen()
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalendarScreen() {
val selectedMonth = Clock.System.todayIn(TimeZone.currentSystemDefault())
var calendarType by remember { mutableStateOf(CalendarType.MONTHLY) } // Track calendar type
val data = listOf(
ComposeCalendarEvent(
id = 1,
"Event #100232",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 2, 14, 1, 15),
end = LocalDateTime(2025, 2, 14, 2, 45)
),
ComposeCalendarEvent(
id = 2,
"Event 1",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 2, 15, 1, 45),
end = LocalDateTime(2025, 2, 15, 3, 15)
),
ComposeCalendarEvent(
id = 3,
"Event 1 2",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 2, 15, 7, 10),
end = LocalDateTime(2025, 2, 15, 11, 10)
),
ComposeCalendarEvent(
id = 4,
"Event 3",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 3, 26, 3, 45),
end = LocalDateTime(2025, 3, 26, 7, 15)
),
ComposeCalendarEvent(
id = 5,
"Event 3 1",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 3, 28, 3, 45),
end = LocalDateTime(2025, 3, 28, 7, 15)
),
ComposeCalendarEvent(
id = 6,
"Event 3 2",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 3, 21, 3, 45),
end = LocalDateTime(2025, 3, 21, 7, 15)
)
)
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "Calendar") },
actions = {
var expanded by remember { mutableStateOf(false) } // For dropdown menu
Box {
IconButton(onClick = { expanded = true }) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Change Calendar Type"
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
DropdownMenuItem(
text = { Text("Monthly View") },
onClick = {
calendarType = CalendarType.MONTHLY
expanded = false
}
)
DropdownMenuItem(
text = { Text("3 Days View") },
onClick = {
calendarType = CalendarType.ThreeDays
expanded = false
}
)
DropdownMenuItem(
text = { Text("Scheduled View") },
onClick = {
calendarType = CalendarType.SCHEDULED
expanded = false
}
)
}
}
}
)
}
) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) {
when (calendarType) {
CalendarType.MONTHLY -> MyMonthlyCalendar(data, selectedMonth)
CalendarType.ThreeDays -> MyWeeklyView(data, selectedMonth)
CalendarType.SCHEDULED -> MyScheduledCalendar(data)
}
}
}
}
@Composable
fun MyMonthlyCalendar(
data: List<ComposeCalendarEvent>,
selectedMonth: LocalDate,
) {
var _selectedMonth by remember { mutableStateOf(selectedMonth) }
CalendarView(
isTwoWeeksSupport = true,
selectedDate = _selectedMonth,
currentDayTextColor = Color.White,
currentDayColor = Color.Blue,
events = data,
onMonthChanged = { newMonth ->
_selectedMonth = newMonth
},
onDateSelected = { newDate ->
_selectedMonth = newDate
},
onEventClick = {
println("event clicked is $it")
},
firstDayOfWeek = DayOfWeek.MONDAY,
displayItem = {
Card(
modifier = Modifier.fillMaxWidth(),
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp),
colors = androidx.compose.material3.CardDefaults.cardColors(
containerColor = it.color
)
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Change Calendar Type",
tint = it.textColor
)
Spacer(Modifier.width(10.dp))
Column(modifier = Modifier.padding(12.dp)) {
Text(
text = it.name,
color = it.textColor,
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "${it.start.hour}:${it.start.minute} - ${it.end.hour}:${it.end.minute}",
color = it.textColor.copy(alpha = 0.8f),
style = MaterialTheme.typography.bodySmall
)
}
}
}
}
)
}
@Composable
fun MyWeeklyView(
data: List<ComposeCalendarEvent>,
selectedMonth: LocalDate
) {
var _selectedMonth by remember { mutableStateOf(selectedMonth) }
ThreeDaysCalendar(
events = data,
currentDate = _selectedMonth,
currentDayTextColor = Color.White,
currentDayColor = Color.Blue,
onDateSelected = {
_selectedMonth = it
},
onEventClick = {
println("event clicked is $it")
}
)
}
@Composable
fun MyScheduledCalendar(
data: List<ComposeCalendarEvent>
) {
ScheduleView(
events = data,
displayItem = {
Card(
modifier = Modifier.fillMaxWidth(),
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp),
colors = androidx.compose.material3.CardDefaults.cardColors(
containerColor = it.color
)
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Change Calendar Type",
tint = it.textColor
)
Spacer(Modifier.width(10.dp))
Column(modifier = Modifier.padding(12.dp)) {
Text(
text = it.name,
color = it.textColor,
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "${it.start.hour}:${it.start.minute} - ${it.end.hour}:${it.end.minute}",
color = it.textColor.copy(alpha = 0.8f),
style = MaterialTheme.typography.bodySmall
)
}
}
}
},
onEventClick = {
println("event clicked is $it")
}
)
}Contributions are welcome! Feel free to open an Issue or submit a Pull Request.
Compose Calendar Event is a Compose Multiplatform package that provides flexible calendar views to display events.
It supports all platforms (Android, iOS, Desktop, Web) using only kotlinx.datetime for date handling.
kotlinx.datetime. implementation("io.github.the-best-is-best:compose-calendar-event:2.2.0")Compose Calendar Event is available on mavenCentral().
enum class CalendarType {
MONTHLY, ThreeDays, SCHEDULED
}
@Composable
internal fun App() = AppTheme {
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
CalendarScreen()
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalendarScreen() {
val selectedMonth = Clock.System.todayIn(TimeZone.currentSystemDefault())
var calendarType by remember { mutableStateOf(CalendarType.MONTHLY) } // Track calendar type
val data = listOf(
ComposeCalendarEvent(
id = 1,
"Event #100232",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 2, 14, 1, 15),
end = LocalDateTime(2025, 2, 14, 2, 45)
),
ComposeCalendarEvent(
id = 2,
"Event 1",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 2, 15, 1, 45),
end = LocalDateTime(2025, 2, 15, 3, 15)
),
ComposeCalendarEvent(
id = 3,
"Event 1 2",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 2, 15, 7, 10),
end = LocalDateTime(2025, 2, 15, 11, 10)
),
ComposeCalendarEvent(
id = 4,
"Event 3",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 3, 26, 3, 45),
end = LocalDateTime(2025, 3, 26, 7, 15)
),
ComposeCalendarEvent(
id = 5,
"Event 3 1",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 3, 28, 3, 45),
end = LocalDateTime(2025, 3, 28, 7, 15)
),
ComposeCalendarEvent(
id = 6,
"Event 3 2",
color = Color(0xFF1CB0F9),
textColor = Color.White,
start = LocalDateTime(2025, 3, 21, 3, 45),
end = LocalDateTime(2025, 3, 21, 7, 15)
)
)
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "Calendar") },
actions = {
var expanded by remember { mutableStateOf(false) } // For dropdown menu
Box {
IconButton(onClick = { expanded = true }) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Change Calendar Type"
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
DropdownMenuItem(
text = { Text("Monthly View") },
onClick = {
calendarType = CalendarType.MONTHLY
expanded = false
}
)
DropdownMenuItem(
text = { Text("3 Days View") },
onClick = {
calendarType = CalendarType.ThreeDays
expanded = false
}
)
DropdownMenuItem(
text = { Text("Scheduled View") },
onClick = {
calendarType = CalendarType.SCHEDULED
expanded = false
}
)
}
}
}
)
}
) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) {
when (calendarType) {
CalendarType.MONTHLY -> MyMonthlyCalendar(data, selectedMonth)
CalendarType.ThreeDays -> MyWeeklyView(data, selectedMonth)
CalendarType.SCHEDULED -> MyScheduledCalendar(data)
}
}
}
}
@Composable
fun MyMonthlyCalendar(
data: List<ComposeCalendarEvent>,
selectedMonth: LocalDate,
) {
var _selectedMonth by remember { mutableStateOf(selectedMonth) }
CalendarView(
isTwoWeeksSupport = true,
selectedDate = _selectedMonth,
currentDayTextColor = Color.White,
currentDayColor = Color.Blue,
events = data,
onMonthChanged = { newMonth ->
_selectedMonth = newMonth
},
onDateSelected = { newDate ->
_selectedMonth = newDate
},
onEventClick = {
println("event clicked is $it")
},
firstDayOfWeek = DayOfWeek.MONDAY,
displayItem = {
Card(
modifier = Modifier.fillMaxWidth(),
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp),
colors = androidx.compose.material3.CardDefaults.cardColors(
containerColor = it.color
)
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Change Calendar Type",
tint = it.textColor
)
Spacer(Modifier.width(10.dp))
Column(modifier = Modifier.padding(12.dp)) {
Text(
text = it.name,
color = it.textColor,
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "${it.start.hour}:${it.start.minute} - ${it.end.hour}:${it.end.minute}",
color = it.textColor.copy(alpha = 0.8f),
style = MaterialTheme.typography.bodySmall
)
}
}
}
}
)
}
@Composable
fun MyWeeklyView(
data: List<ComposeCalendarEvent>,
selectedMonth: LocalDate
) {
var _selectedMonth by remember { mutableStateOf(selectedMonth) }
ThreeDaysCalendar(
events = data,
currentDate = _selectedMonth,
currentDayTextColor = Color.White,
currentDayColor = Color.Blue,
onDateSelected = {
_selectedMonth = it
},
onEventClick = {
println("event clicked is $it")
}
)
}
@Composable
fun MyScheduledCalendar(
data: List<ComposeCalendarEvent>
) {
ScheduleView(
events = data,
displayItem = {
Card(
modifier = Modifier.fillMaxWidth(),
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp),
colors = androidx.compose.material3.CardDefaults.cardColors(
containerColor = it.color
)
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "Change Calendar Type",
tint = it.textColor
)
Spacer(Modifier.width(10.dp))
Column(modifier = Modifier.padding(12.dp)) {
Text(
text = it.name,
color = it.textColor,
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "${it.start.hour}:${it.start.minute} - ${it.end.hour}:${it.end.minute}",
color = it.textColor.copy(alpha = 0.8f),
style = MaterialTheme.typography.bodySmall
)
}
}
}
},
onEventClick = {
println("event clicked is $it")
}
)
}Contributions are welcome! Feel free to open an Issue or submit a Pull Request.