Skip to content

Repository files navigation

KMP Calendar

A Kotlin Multiplatform calendar component for Compose Multiplatform, with four switchable views (daily, weekly, monthly, yearly) and a generic animated bar chart.

Maven Central License

Platforms

Target Supported Notes
Android Yes minSdk 24, compileSdk 36
JVM / Desktop Yes Compose for Desktop
iOS No Not currently configured

All UI lives in commonMain, so adding further Compose Multiplatform targets requires no changes to the component code.

Installation

// build.gradle.kts
dependencies {
    implementation("io.github.gauravvvvvvvvvv:kmp-calendar:1.0.1")
}

For a Kotlin Multiplatform module, add it to commonMain:

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("io.github.gauravvvvvvvvvv:kmp-calendar:1.0.1")
        }
    }
}

kotlinx-datetime is exposed as an api dependency, so LocalDate and DayOfWeek are available to consumers without declaring it separately.

Built against Kotlin 2.0.21 and Compose Multiplatform 1.6.11.

Quick start

import androidx.compose.runtime.*
import com.gaurav.calendar.*
import kotlinx.datetime.*

@Composable
fun CalendarScreen() {
    var viewType by remember { mutableStateOf(CalendarViewType.DAILY) }
    var selectedDate by remember {
        mutableStateOf(
            Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
        )
    }
    var currentMonth by remember { mutableStateOf(selectedDate) }
    var currentYear by remember { mutableStateOf(selectedDate.year) }

    KMPCalendar(
        viewType = viewType,
        selectedDate = selectedDate,
        currentMonth = currentMonth,
        currentYear = currentYear,
        onDateSelected = { selectedDate = it },
        onMonthChanged = { currentMonth = it },
        onYearChanged = { currentYear = it },
        onViewTypeChanged = { viewType = it }
    )
}

KMPCalendar is fully state-hoisted — it holds no internal date state. You own selectedDate, currentMonth, currentYear and viewType, which makes the component straightforward to drive from a ViewModel or restore from saved state.

The four views

CalendarViewType selects which view renders. Each view has its own header control that can switch view type via onViewTypeChanged.

View What it shows Which callback fires
DAILY Full month grid, single day selection onDateSelected
WEEKLY Month grid with the selected 7-day range highlighted onDateSelected
MONTHLY 12-month grid for picking a month onDateSelected with day 1 of the chosen month
YEARLY Multi-year grid for picking a year onYearChanged

Note that in MONTHLY view a selection is reported through onDateSelected as the first day of the chosen month, not as a separate month callback.

Configuration

KMPCalendar(
    // ...
    config = CalendarConfig(
        weekStartDay = DayOfWeek.MONDAY,
        yearRange = 2024..2030,
        showTodayIndicator = true,
        enablePastDates = true,
        enableFutureDates = true
    )
)
Property Type Default Purpose
weekStartDay DayOfWeek SUNDAY First column of the week
yearRange IntRange 2020..2035 Years offered in the yearly view
colors CalendarColors CalendarColors() Colour overrides
showTodayIndicator Boolean true Highlight today's date
enablePastDates Boolean true Allow selecting dates before today
enableFutureDates Boolean false Allow selecting dates after today

enableFutureDates defaults to false, so out of the box the calendar behaves as a date-of-record picker. Set it to true for scheduling use cases.

Colours

CalendarColors defaults every field to Color.Unspecified, which means "use the ambient MaterialTheme". Override only what you need:

import androidx.compose.ui.graphics.Color

CalendarConfig(
    colors = CalendarColors(
        selectedColor = Color(0xFF3B82F6),
        todayColor = Color(0xFF10B981),
        weekRangeColor = Color(0xFF3B82F6).copy(alpha = 0.2f),
        disabledColor = Color.Gray
    )
)
Field Applies to
selectedColor Background of the selected date
todayColor Background of today, when not selected
weekRangeColor The highlighted 7-day range in WEEKLY view
disabledColor Dates excluded by enablePastDates / enableFutureDates

Because the fallback is the Material theme rather than hardcoded values, the calendar picks up light/dark theming automatically if you pass no colours at all.

Bar chart

The library also ships KMPBarChart, a generic animated bar chart. It is independent of the calendar and can be used on its own — the type parameter lets you attach any domain object to a bar and get it back in the click callback.

import com.gaurav.calendar.charts.*

data class Sale(val id: Int, val region: String)

@Composable
fun SalesChart() {
    val bars = listOf(
        BarData(data = Sale(1, "North"), percentage = 82, label = "Mon"),
        BarData(data = Sale(2, "South"), percentage = 45, label = "Tue"),
        BarData(data = Sale(3, "East"), percentage = 18, label = "Wed"),
        BarData(data = Sale(4, "West"), percentage = 67, label = "Thu")
    )

    KMPBarChart(
        data = bars,
        config = BarChartConfig(animationDuration = 700),
        initialSelectedLabel = "Mon",
        onBarClick = { bar -> println("tapped ${bar.data?.region}") }
    )
}

BarData<T> takes data: T? (optional payload), percentage: Int (0–100, drives bar height) and label: String.

Bars are colour-coded by magnitude via the public getBarColor(percentage) function:

Percentage Colour
0–25 Red
26–50 Orange
51–75 Green
76–100 Blue

BarChartConfig options:

Property Type Default
showValues Boolean true
animateHeight Boolean true
barWidth Dp 24.dp
barSlotWidth Dp 64.dp
chartHeight Dp 192.dp
animationDuration Int 500

When there are more bars than fit the width, the chart scrolls horizontally rather than compressing the bars.

API surface

Package com.gaurav.calendar:

  • KMPCalendar — the unified entry point
  • CalendarViewTypeDAILY, WEEKLY, MONTHLY, YEARLY
  • CalendarConfig, CalendarColors
  • DailyCalendarView, WeeklyCalendarView, MonthlyCalendarView, YearlyCalendarView — the individual views, usable directly if you don't want the unified wrapper
  • CalendarViewHeader

Package com.gaurav.calendar.charts:

  • KMPBarChart, BarData, BarChartConfig, getBarColor

Building locally

The project builds with JDK 17–21. Newer JDKs are not parseable by Gradle 8.13.

./gradlew build
./gradlew :library:publishToMavenLocal

License

Apache License 2.0 — see LICENSE.

About

A Kotlin Multiplatform calendar component.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages