Range Calendar
Installation
Usage
Bind an object with start and end DateValue properties. An incomplete selection has an undefined end. The default view uses the same Header, Month, Cell and Day parts you can compose yourself.
Use CalendarDate from @internationalized/date for date-only values, or parseDate for ISO date strings. Bind placeholder to control the visible month. An explicit locale and placeholder keep server and client formatting predictable. Avoid converting a date-only selection through a UTC JavaScript Date to store it. Save each endpoint with value.start?.toString() and value.end?.toString().
Examples
Across months
numberOfMonths controls the visible months. pagedNavigation advances a page at a time. This example has no range-length limit. Optional minDays and maxDays count both endpoints; an out-of-range second selection becomes a new start date.
Composition and accessibility
Root exposes a children snippet with months and weekdays. Keep the default Month, or compose Grid, GridHead, GridBody, GridRow, HeadCell, Cell and Day to restyle individual regions. Month also accepts a day(date) snippet. Header, Heading, PrevButton, NextButton, MonthSelect and YearSelect can be omitted, reordered or replaced with another documented composition.
Styled parts forward native attributes and expose bind:ref for their underlying element. Arrow keys move between days, Page Up and Page Down change the visible month, and Enter or Space selects. Focus and selection are distinct. Disabled dates cannot be selected; readonly calendars remain navigable. The today indicator and unavailable strike-through provide cues beyond color.
The standalone calendar does not create a form field. Add a named hidden input when it participates in a form, or use the corresponding date picker for editable fields and form serialization. The calendar grid stays still during navigation; only state feedback changes.
Bounds and custom composition
Choose two to seven days within September. This composition omits navigation buttons because dates outside the month are unavailable.
API reference
RangeCalendar.Root
| Prop | Type | Default |
|---|---|---|
children | Snippet<[RangeCalendarRootSnippetProps]> | undefined | — |
id | string | undefined | — |
placeholder Bindable | DateValue | undefined The placeholder date, used to control the view of the calendar when no value is present. | — |
style | string | StyleProperties | null | undefined | — |
disabled | boolean | undefined Whether or not the calendar is disabled. | — |
value Bindable | DateRange | undefined The value of the selected date range. | — |
readonly | boolean | undefined Whether the calendar is readonly. When true, the user will be able to focus and navigate the calendar, but will not be able to select dates. | — |
ref Bindable | HTMLElement | null | undefined | null |
onValueChange | OnChangeFn<DateRange> | undefined A callback function called when the value changes. | — |
onPlaceholderChange | OnChangeFn<DateValue> | undefined A callback function called when the placeholder value changes. | — |
preventDeselect | boolean | undefined Whether or not users can deselect a date once selected without selecting another date. | — |
minValue | DateValue | undefined The minimum date that can be selected in the calendar. | — |
maxValue | DateValue | undefined The maximum date that can be selected in the calendar. | — |
pagedNavigation | boolean | undefined Applicable only when `numberOfMonths` is greater than 1. | — |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined The day of the week to start the calendar on, which must be a number between 0 and 6, where 0 is Sunday and 6 is Saturday. | — |
weekdayFormat | "long" | "short" | "narrow" | undefined How the string representation of the weekdays provided via the `weekdays` state store should be formatted. | 'short' |
isDateDisabled | DateMatcher | undefined A function that receives a date and returns `true` or `false` to indicate whether the date is disabled. | — |
isDateUnavailable | DateMatcher | undefined Dates matching the provided matchers are marked as "unavailable." Unlike disabled dates, users can still focus and select unavailable dates. However, selecting an unavailable date renders the date picker as invalid. | — |
fixedWeeks | boolean | undefined Display 6 weeks per month, regardless the month's number of weeks. This is useful for displaying a consistent calendar, where the size of the calendar doesn't change month to month. | true |
numberOfMonths | number | undefined Determines the number of months to display on the calendar simultaneously. For navigation between months, refer to the `pagedNavigation` prop. | — |
calendarLabel | string | undefined This label is exclusively used for accessibility, remaining hidden from the page. It's read by screen readers when the calendar is opened. The current month and year are automatically appended to the label, so you only need to provide the base label. | — |
locale | string | undefined The default locale setting. | 'en-US' |
disableDaysOutsideMonth | boolean | undefined Whether to disable the selection of days outside the current month. By default, days outside the current month are rendered to fill the calendar grid, but they are not selectable. Setting this prop to `true` will disable this behavior. | — |
maxDays | number | undefined The maximum number of days that can be selected in a range. | — |
monthFormat | "numeric" | "long" | "short" | "narrow" | "2-digit" | ((month: number) => string) | undefined The format of the month names in the calendar. | — |
yearFormat | "numeric" | "2-digit" | ((year: number) => string) | undefined The format of the year names in the calendar. | — |
onStartValueChange | OnChangeFn<DateValue | undefined> | undefined A callback function called when the start value changes. This doesn't necessarily mean the `value` has updated and should be used to apply cosmetic changes to the calendar when only part of the value is changed/completed. | — |
onEndValueChange | OnChangeFn<DateValue | undefined> | undefined A callback function called when the end value changes. This doesn't necessarily mean the `value` has updated and should be used to apply cosmetic changes to the calendar when only part of the value is changed/completed. | — |
minDays | number | undefined The minimum number of days that can be selected in a range. | — |
excludeDisabled | boolean | undefined Whether to automatically reset the range if any date within the selected range becomes disabled. When true, the entire range will be cleared if a disabled date is found between the start and end dates. | — |
RangeCalendar.Grid
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.GridBody
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.GridHead
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.GridRow
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.HeadCell
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.Header
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.Heading
| Prop | Type | Default |
|---|---|---|
child | Snippet<[CalendarHeadingSnippetProps & { props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[CalendarHeadingSnippetProps]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.MonthSelect
| Prop | Type | Default |
|---|---|---|
monthFormat | "numeric" | "long" | "short" | "narrow" | "2-digit" | ((month: number) => string) | undefined How the month names should be formatted in the select options. | — |
months | number[] | undefined An array of month numbers (1-12) to display in the select. This allows for flexible month selection, such as showing only specific months or seasons. | — |
child | Snippet<[CalendarMonthSelectSnippetProps & { props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[CalendarMonthSelectSnippetProps]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.NextButton
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.PrevButton
| Prop | Type | Default |
|---|---|---|
child | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.YearSelect
| Prop | Type | Default |
|---|---|---|
yearFormat | "numeric" | "2-digit" | ((year: number) => string) | undefined How the year should be formatted in the select options. | — |
years | number[] | undefined An array of years to display in the select. This allows for complete control over which years appear, such as showing only years with data or excluding certain periods. | — |
child | Snippet<[CalendarYearSelectSnippetProps & { props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[CalendarYearSelectSnippetProps]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.Cell
| Prop | Type | Default |
|---|---|---|
date Required | CalendarDate | CalendarDateTime | ZonedDateTime The date value of the cell. | — |
month Required | CalendarDate | CalendarDateTime | ZonedDateTime The month DateValue that this cell is being rendered in. | — |
child | Snippet<[CalendarCellSnippetProps & { props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[CalendarCellSnippetProps]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.Day
| Prop | Type | Default |
|---|---|---|
child | Snippet<[CalendarDaySnippetProps & { props: Record<string, unknown>; }]> | undefined | — |
children | Snippet<[CalendarDaySnippetProps]> | undefined | — |
style | string | StyleProperties | null | undefined | — |
ref Bindable | HTMLElement | null | undefined | null |
id | string | undefined | — |
RangeCalendar.Month
| Prop | Type | Default |
|---|---|---|
class | string | undefined | — |
month Required | { value: DateValue; weeks: DateValue[][]; dates: DateValue[]; } | — |
weekdays Required | string[] | — |
locale | string | undefined | 'en-US' |
showHeading | boolean | undefined | false |
day | Snippet<[date: DateValue]> | undefined | — |
pnpm dlx @mielui/svelte add range-calendar