diff --git a/README.md b/README.md index b030243..73c45ec 100644 --- a/README.md +++ b/README.md @@ -20,24 +20,16 @@ Library is available on Maven Central repository. ``` Snapshots are available on [Sonatype’s snapshots repository](https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/boguszpawlowski/composecalendar/). -## Compose versions -| Compose Version | Compose Calendar Version | -|-------------------|----------------------------| -| 1.0.0 | 0.3.0 | -| 1.1.0 | 0.5.1 | -| 1.2.0 | 0.6.0 | -| 1.2.1 | 1.0.2 | -| 1.3.1 | 1.1.0 | - ## Supported features - Selection (single, multiple or a range of days) -- Every day as first day of week +- Chose day as first day of week - Showing/hiding adjacent months - Month and week headers - Customizable month container - Fully customizable day content - Horizontal swipe for changing a current month - Month / Week mode +- Min / Max Month (or Week) ## Basic Usage @@ -144,6 +136,10 @@ Apart from rendering your own components inside the calendar, you can modify it - `showAdjacentMonths` - whenever to render days from adjacent months. Defaults to `true`. - `firstDayOfWeek` - you can pass the `DayOfWeek` which you want you week to start with. It defaults to the first day of week of the `Locale.default()`. - `horizontalScrollEnabled` - a Boolean flag which enables month to be changed by a horizontal swipe. Defaults to `true`. +- `minMonth` - a `YearMonth` object representing the minimum month that can be shown in the calendar. By default there is no minimum month. +- `maxMonth` - a `YearMonth` object representing the maximum month that can be shown in the calendar. By default there is no maximum month. + +> :exclamation: You cannot set `minMonth` to be lower than `maxMonth` and vice versa. If you do so, the calendar state won't change. Apart from this, `Calendar` you can pass a `Modifier` object like in any other composable. @@ -213,6 +209,9 @@ Selection modes are represented by `SelectionMode` enum, with following values: - `Period` - selectable period - implemented by `start` and `end` dates. - selection will contain all dates between start and the end date. This implementation of SelectionState also allows for handling side-effects and vetoing the state change via `confirmSelectionChange` callback. +## Week Calendar +Apart from the default calendar, there is also a week calendar, which shows a single week at a time. It can be used in the same way as the default calendar, and has the same customization options. + ## KotlinX DateTime As the core of the library is built on `java.time` library, on Android it requires to use [core libary desugaring](https://developer.android.com/studio/write/java8-support) to be able to access it's API. As a result it's features may be unavailable to some project built around different date-time libraries (e.g. kotlinx-datetime). Although the project wont be migrating from `java.time`, as it's the best suited for it, there is a separate `kotlinx-datetime` artifact for those who need to use the library from a codebase based on it. It doesn't consist of a separate version of `ComposeCalendar` features, but offers a small bunch of utilities, that will enable you to create your own wrapper, as briefly presented in `KotlinDateTimeSample`. If the provided functionality, doesn't match your use-case, please submit an issue. diff --git a/library/api/library.api b/library/api/library.api index 7c47021..c1459db 100644 --- a/library/api/library.api +++ b/library/api/library.api @@ -76,8 +76,8 @@ public final class io/github/boguszpawlowski/composecalendar/WeekCalendarKt { public static final fun SelectableWeekCalendar (Landroidx/compose/ui/Modifier;Ljava/time/DayOfWeek;Ljava/time/LocalDate;ZZLio/github/boguszpawlowski/composecalendar/WeekCalendarState;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;II)V public static final fun StaticWeekCalendar (Landroidx/compose/ui/Modifier;Ljava/time/DayOfWeek;Ljava/time/LocalDate;ZLio/github/boguszpawlowski/composecalendar/WeekCalendarState;ZLkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;II)V public static final fun WeekCalendar (Lio/github/boguszpawlowski/composecalendar/WeekCalendarState;Landroidx/compose/ui/Modifier;Ljava/time/LocalDate;Ljava/time/DayOfWeek;ZZLkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;II)V - public static final fun rememberSelectableWeekCalendarState (Ljava/time/DayOfWeek;Lio/github/boguszpawlowski/composecalendar/week/Week;Ljava/util/List;Lio/github/boguszpawlowski/composecalendar/selection/SelectionMode;Lkotlin/jvm/functions/Function1;Lio/github/boguszpawlowski/composecalendar/header/WeekState;Lio/github/boguszpawlowski/composecalendar/selection/DynamicSelectionState;Landroidx/compose/runtime/Composer;II)Lio/github/boguszpawlowski/composecalendar/WeekCalendarState; - public static final fun rememberWeekCalendarState (Ljava/time/DayOfWeek;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/header/WeekState;Landroidx/compose/runtime/Composer;II)Lio/github/boguszpawlowski/composecalendar/WeekCalendarState; + public static final fun rememberSelectableWeekCalendarState (Ljava/time/DayOfWeek;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/week/Week;Ljava/util/List;Lio/github/boguszpawlowski/composecalendar/selection/SelectionMode;Lkotlin/jvm/functions/Function1;Lio/github/boguszpawlowski/composecalendar/header/WeekState;Lio/github/boguszpawlowski/composecalendar/selection/DynamicSelectionState;Landroidx/compose/runtime/Composer;II)Lio/github/boguszpawlowski/composecalendar/WeekCalendarState; + public static final fun rememberWeekCalendarState (Ljava/time/DayOfWeek;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/header/WeekState;Landroidx/compose/runtime/Composer;II)Lio/github/boguszpawlowski/composecalendar/WeekCalendarState; } public final class io/github/boguszpawlowski/composecalendar/WeekCalendarState { @@ -159,7 +159,11 @@ public final class io/github/boguszpawlowski/composecalendar/header/MonthStateKt public abstract interface class io/github/boguszpawlowski/composecalendar/header/WeekState { public static final field Companion Lio/github/boguszpawlowski/composecalendar/header/WeekState$Companion; public abstract fun getCurrentWeek ()Lio/github/boguszpawlowski/composecalendar/week/Week; + public abstract fun getMaxWeek ()Lio/github/boguszpawlowski/composecalendar/week/Week; + public abstract fun getMinWeek ()Lio/github/boguszpawlowski/composecalendar/week/Week; public abstract fun setCurrentWeek (Lio/github/boguszpawlowski/composecalendar/week/Week;)V + public abstract fun setMaxWeek (Lio/github/boguszpawlowski/composecalendar/week/Week;)V + public abstract fun setMinWeek (Lio/github/boguszpawlowski/composecalendar/week/Week;)V } public final class io/github/boguszpawlowski/composecalendar/header/WeekState$Companion { @@ -167,7 +171,7 @@ public final class io/github/boguszpawlowski/composecalendar/header/WeekState$Co } public final class io/github/boguszpawlowski/composecalendar/header/WeekStateKt { - public static final fun WeekState (Lio/github/boguszpawlowski/composecalendar/week/Week;)Lio/github/boguszpawlowski/composecalendar/header/WeekState; + public static final fun WeekState (Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/week/Week;)Lio/github/boguszpawlowski/composecalendar/header/WeekState; } public final class io/github/boguszpawlowski/composecalendar/selection/DynamicSelectionHandler { @@ -223,6 +227,7 @@ public final class io/github/boguszpawlowski/composecalendar/week/Week { public static final field $stable I public static final field Companion Lio/github/boguszpawlowski/composecalendar/week/Week$Companion; public fun (Ljava/util/List;)V + public final fun compareTo (Lio/github/boguszpawlowski/composecalendar/week/Week;)I public final fun component1 ()Ljava/util/List; public final fun copy (Ljava/util/List;)Lio/github/boguszpawlowski/composecalendar/week/Week; public static synthetic fun copy$default (Lio/github/boguszpawlowski/composecalendar/week/Week;Ljava/util/List;ILjava/lang/Object;)Lio/github/boguszpawlowski/composecalendar/week/Week; @@ -234,6 +239,7 @@ public final class io/github/boguszpawlowski/composecalendar/week/Week { public final fun getYearMonth ()Ljava/time/YearMonth; public fun hashCode ()I public final fun inc ()Lio/github/boguszpawlowski/composecalendar/week/Week; + public final fun minusWeeks (J)Lio/github/boguszpawlowski/composecalendar/week/Week; public final fun plusWeeks (J)Lio/github/boguszpawlowski/composecalendar/week/Week; public fun toString ()Ljava/lang/String; } @@ -243,3 +249,7 @@ public final class io/github/boguszpawlowski/composecalendar/week/Week$Companion public static synthetic fun now$default (Lio/github/boguszpawlowski/composecalendar/week/Week$Companion;Ljava/time/DayOfWeek;ILjava/lang/Object;)Lio/github/boguszpawlowski/composecalendar/week/Week; } +public final class io/github/boguszpawlowski/composecalendar/week/WeekKt { + public static final fun between (Ljava/time/temporal/ChronoUnit;Lio/github/boguszpawlowski/composecalendar/week/Week;Lio/github/boguszpawlowski/composecalendar/week/Week;)I +} + diff --git a/library/src/main/java/io/github/boguszpawlowski/composecalendar/Calendar.kt b/library/src/main/java/io/github/boguszpawlowski/composecalendar/Calendar.kt index 06c5b94..ba8c9b7 100644 --- a/library/src/main/java/io/github/boguszpawlowski/composecalendar/Calendar.kt +++ b/library/src/main/java/io/github/boguszpawlowski/composecalendar/Calendar.kt @@ -231,6 +231,8 @@ public fun Calendar( * @param initialSelection initial selection of the composable * @param initialSelectionMode initial mode of the selection * @param confirmSelectionChange callback for optional side-effects handling and vetoing the state change + * @param minMonth first month that can be shown + * @param maxMonth last month that can be shown */ @Composable public fun rememberSelectableCalendarState( @@ -258,6 +260,8 @@ public fun rememberSelectableCalendarState( * Helper function for providing a [CalendarState] implementation without a selection mechanism. * * @param initialMonth initially rendered month + * @param minMonth first month that can be shown + * @param maxMonth last month that can be shown */ @Composable public fun rememberCalendarState( diff --git a/library/src/main/java/io/github/boguszpawlowski/composecalendar/WeekCalendar.kt b/library/src/main/java/io/github/boguszpawlowski/composecalendar/WeekCalendar.kt index 6594f36..dcff06d 100644 --- a/library/src/main/java/io/github/boguszpawlowski/composecalendar/WeekCalendar.kt +++ b/library/src/main/java/io/github/boguszpawlowski/composecalendar/WeekCalendar.kt @@ -207,6 +207,8 @@ public fun WeekCalendar( * @param initialSelection initial selection of the composable * @param initialSelectionMode initial mode of the selection * @param confirmSelectionChange callback for optional side-effects handling and vetoing the state change + * @param minWeek first week that can be shown + * @param maxWeek last week that can be shown */ @Composable public fun rememberSelectableWeekCalendarState( @@ -237,6 +239,8 @@ public fun rememberSelectableWeekCalendarState( * * @param firstDayOfWeek first day of a week, defaults to current locale's * @param initialWeek initially rendered week + * @param minWeek first week that can be shown + * @param maxWeek last week that can be shown */ @Composable public fun rememberWeekCalendarState( diff --git a/library/src/main/java/io/github/boguszpawlowski/composecalendar/header/MonthState.kt b/library/src/main/java/io/github/boguszpawlowski/composecalendar/header/MonthState.kt index ff6daa7..def3131 100644 --- a/library/src/main/java/io/github/boguszpawlowski/composecalendar/header/MonthState.kt +++ b/library/src/main/java/io/github/boguszpawlowski/composecalendar/header/MonthState.kt @@ -48,9 +48,9 @@ private class MonthStateImpl( maxMonth: YearMonth, ) : MonthState { - private var _currentMonth by mutableStateOf(initialMonth) - private var _minMonth by mutableStateOf(minMonth) - private var _maxMonth by mutableStateOf(maxMonth) + private var _currentMonth by mutableStateOf(initialMonth) + private var _minMonth by mutableStateOf(minMonth) + private var _maxMonth by mutableStateOf(maxMonth) override var currentMonth: YearMonth get() = _currentMonth @@ -61,12 +61,14 @@ private class MonthStateImpl( override var minMonth: YearMonth get() = _minMonth set(value) { + if (value > _maxMonth) return _minMonth = value } override var maxMonth: YearMonth get() = _maxMonth set(value) { + if (value < _minMonth) return _maxMonth = value } } diff --git a/library/src/main/java/io/github/boguszpawlowski/composecalendar/week/WeekListState.kt b/library/src/main/java/io/github/boguszpawlowski/composecalendar/week/WeekListState.kt index 54dd82d..dfec788 100644 --- a/library/src/main/java/io/github/boguszpawlowski/composecalendar/week/WeekListState.kt +++ b/library/src/main/java/io/github/boguszpawlowski/composecalendar/week/WeekListState.kt @@ -66,6 +66,3 @@ internal class WeekListState( return result } } - -private operator fun Week.minus(other: Week) = - ChronoUnit.WEEKS.between(other.start, this.start) diff --git a/sample/src/main/java/io/github/boguszpawlowski/composecalendar/sample/MinMaxCalendarSample.kt b/sample/src/main/java/io/github/boguszpawlowski/composecalendar/sample/MinMaxCalendarSample.kt index f1d0e62..03128ea 100644 --- a/sample/src/main/java/io/github/boguszpawlowski/composecalendar/sample/MinMaxCalendarSample.kt +++ b/sample/src/main/java/io/github/boguszpawlowski/composecalendar/sample/MinMaxCalendarSample.kt @@ -57,7 +57,7 @@ fun MinMaxCalendarSample() { MinMaxControls(calendarState = calendarState) - Spacer(modifier = Modifier.height(20.dp)) + Spacer(modifier = Modifier.height(40.dp)) StaticWeekCalendar(calendarState = weekCalendarState) @@ -169,7 +169,7 @@ private fun MaxControls( private fun WeekMinMaxControls( calendarState: WeekCalendarState, ) { - val dateFormatter = remember { DateTimeFormatter.ofPattern("yyyy-MM") } + val dateFormatter = remember { DateTimeFormatter.ofPattern("yyyy-MM-dd") } Text( text = "Calendar Min Week", style = MaterialTheme.typography.h5, @@ -210,7 +210,9 @@ private fun WeekMinControls( textAlign = TextAlign.Center ) val minYearMonthText = remember(calendarState.weekState.minWeek) { - dateFormatter.format(calendarState.weekState.minWeek.start) + val start = dateFormatter.format(calendarState.weekState.minWeek.start) + val end = dateFormatter.format(calendarState.weekState.minWeek.end) + "$start - $end" } Text(text = minYearMonthText) Text( @@ -247,7 +249,9 @@ private fun WeekMaxControls( textAlign = TextAlign.Center ) val maxYearMonthText = remember(calendarState.weekState.maxWeek) { - dateFormatter.format(calendarState.weekState.maxWeek.start) + val start = dateFormatter.format(calendarState.weekState.maxWeek.start) + val end = dateFormatter.format(calendarState.weekState.maxWeek.end) + "$start - $end" } Text(text = maxYearMonthText) Text(