Date Range Picker
Accessible, unstyled date range picker: start/end DateFields plus a popover RangeCalendar.
|
|
| Package |
@vizejs/ui/date-range-picker |
| Maturity |
stable |
| Own the source |
vize lib pull date-range-picker |
| Requires |
context, controllable-state, date-field, id, popover, range-calendar |
| Aliases |
range picker, booking dates, check-in check-out |
| Covers |
React Aria DateRangePicker, Reka UI DateRangePicker, WAI-ARIA APG date picker dialog |
Usage
import { DateRangePicker, DateRangePickerRoot, DateRangePickerCalendar, DateRangePickerContent, DateRangePickerField, DateRangePickerTrigger, DateRangePickerArrow, DateRangePickerGrid, DateRangePickerHeading, DateRangePickerMonthSelect, DateRangePickerNext, DateRangePickerPrev, DateRangePickerYearSelect } from "@vizejs/ui/date-range-picker";
Or copy the source into your project with vize lib pull date-range-picker (see Source Distribution).
API
DateRangePicker
Source: src/families/date-time/date-range-picker/date-range-picker-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id; nullish values use a deterministic fallback. |
modelValue |
DateRange | null |
undefined |
Controlled range; undefined selects uncontrolled mode and null clears. |
defaultValue |
DateRange | null |
null |
Initial uncontrolled range. |
open |
boolean |
undefined |
Controlled popover open state; undefined selects uncontrolled mode. |
defaultOpen |
boolean |
false |
Initial uncontrolled open state. |
modal |
boolean |
false |
Make outside content inert and contain focus while open. |
min |
PlainDate | null |
undefined |
Earliest selectable date, inclusive. |
max |
PlainDate | null |
undefined |
Latest selectable date, inclusive. |
isDateUnavailable |
DateMatcher |
undefined |
Predicate for dates that cannot be selected. |
locale |
string |
undefined |
BCP 47 locale for the field and calendar; defaults to the nearest LocaleProvider. |
dir |
"ltr" | "rtl" |
undefined |
Text direction; defaults to the nearest LocaleProvider. |
today |
PlainDate | null |
undefined |
Explicit current date for the calendar; the SSR-safe way to mark today. |
now |
DateTimeNow |
undefined |
Injectable clock evaluated during setup on server and client. |
timeZone |
string |
undefined |
IANA time zone used with now and host clocks. |
disabled |
boolean |
false |
Disable the field, trigger, and calendar. |
readOnly |
boolean |
false |
Lock the value while the calendar stays browsable. |
required |
boolean |
false |
Mark the field as required. |
startName |
string |
undefined |
Hidden input name that submits the ISO start date with forms. |
endName |
string |
undefined |
Hidden input name that submits the ISO end date with forms. |
allowNonContiguousRanges |
boolean |
false |
Allow committed ranges to span unavailable dates. |
closeOnSelect |
boolean |
true |
Close the popover after a calendar selection. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: DateRange | null] |
Fired when the picker requests a new controlled range. |
change |
[value: DateRange | null, previous: DateRange | null, nativeEvent: Event | null] |
Fired after a distinct committed range with the previous range and triggering event. |
update:open |
[value: boolean] |
Fired when the picker requests a new controlled open state. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
Slots
| Slot |
Slot props |
Description |
default |
DateRangePickerSlotState |
Picker composition: start/end DateRangePickerField, trigger, content, and DateRangePickerCalendar. |
Exposed
| Member |
Type |
Description |
value |
— |
|
open |
— |
|
disabled |
— |
|
readOnly |
— |
|
state |
— |
|
setValue |
— |
|
setOpen |
— |
|
DateRangePickerRoot
Source: src/families/date-time/date-range-picker/date-range-picker-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id; nullish values use a deterministic fallback. |
modelValue |
DateRange | null |
undefined |
Controlled range; undefined selects uncontrolled mode and null clears. |
defaultValue |
DateRange | null |
null |
Initial uncontrolled range. |
open |
boolean |
undefined |
Controlled popover open state; undefined selects uncontrolled mode. |
defaultOpen |
boolean |
false |
Initial uncontrolled open state. |
modal |
boolean |
false |
Make outside content inert and contain focus while open. |
min |
PlainDate | null |
undefined |
Earliest selectable date, inclusive. |
max |
PlainDate | null |
undefined |
Latest selectable date, inclusive. |
isDateUnavailable |
DateMatcher |
undefined |
Predicate for dates that cannot be selected. |
locale |
string |
undefined |
BCP 47 locale for the field and calendar; defaults to the nearest LocaleProvider. |
dir |
"ltr" | "rtl" |
undefined |
Text direction; defaults to the nearest LocaleProvider. |
today |
PlainDate | null |
undefined |
Explicit current date for the calendar; the SSR-safe way to mark today. |
now |
DateTimeNow |
undefined |
Injectable clock evaluated during setup on server and client. |
timeZone |
string |
undefined |
IANA time zone used with now and host clocks. |
disabled |
boolean |
false |
Disable the field, trigger, and calendar. |
readOnly |
boolean |
false |
Lock the value while the calendar stays browsable. |
required |
boolean |
false |
Mark the field as required. |
startName |
string |
undefined |
Hidden input name that submits the ISO start date with forms. |
endName |
string |
undefined |
Hidden input name that submits the ISO end date with forms. |
allowNonContiguousRanges |
boolean |
false |
Allow committed ranges to span unavailable dates. |
closeOnSelect |
boolean |
true |
Close the popover after a calendar selection. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: DateRange | null] |
Fired when the picker requests a new controlled range. |
change |
[value: DateRange | null, previous: DateRange | null, nativeEvent: Event | null] |
Fired after a distinct committed range with the previous range and triggering event. |
update:open |
[value: boolean] |
Fired when the picker requests a new controlled open state. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
Slots
| Slot |
Slot props |
Description |
default |
DateRangePickerSlotState |
Picker composition: start/end DateRangePickerField, trigger, content, and DateRangePickerCalendar. |
Exposed
| Member |
Type |
Description |
value |
DateRange | null |
Committed range, or null until both endpoints are known. |
open |
boolean |
Whether the calendar popover is open. |
disabled |
boolean |
Whether the picker is disabled. |
readOnly |
boolean |
Whether the value is locked while the calendar can still be browsed. |
state |
PickerOpenState |
Stable open-state token. |
setValue |
(value: DateRange | null) => boolean |
Request a range; returns whether it differs. |
setOpen |
(value: boolean) => boolean |
Request an open state; returns whether it differs. |
DateRangePickerCalendar
Source: src/families/date-time/date-range-picker/date-range-picker-calendar.vue
Props
| Prop |
Type |
Default |
Description |
numberOfMonths |
number |
1 |
Number of consecutive months rendered. |
pagedNavigation |
boolean |
false |
Move month controls by numberOfMonths. |
fixedWeeks |
boolean |
false |
Always render six week rows per month. |
weekStartsOn |
Weekday |
undefined |
First day of week (0 = Sunday); defaults to the locale preference. |
weekdayFormat |
CalendarWeekdayFormat |
"short" |
Weekday column label width. |
calendar |
string |
undefined |
Intl calendar used for display labels only. |
numberingSystem |
string |
undefined |
Intl numbering system for labels. |
ariaLabel |
string |
undefined |
Accessible name for the calendar group. |
Slots
| Slot |
Slot props |
Description |
default |
CalendarSlotState |
Range calendar composition; defaults to a header plus one grid per month. |
DateRangePickerContent
Source: src/families/date-time/date-range-picker/date-range-picker-content.vue
Props
| Prop |
Type |
Default |
Description |
placement |
Placement |
"bottom-start" |
Preferred placement before collision handling. |
initialFocus |
() => HTMLElement | null | undefined |
undefined |
Initial focus target; defaults to the roving calendar day. |
ariaLabel |
string |
undefined |
Accessible dialog name. |
ariaLabelledby |
string |
undefined |
Ids that label the dialog. |
Slots
| Slot |
Slot props |
Description |
default |
Record<string, never> |
Popover body, typically DateRangePickerCalendar. |
DateRangePickerField
Source: src/families/date-time/date-range-picker/date-range-picker-field.vue
Props
| Prop |
Type |
Default |
Description |
boundary (required) |
DateRangeBoundary |
undefined (required) |
Range endpoint this field edits. |
placeholderValue |
PlainDate | null |
undefined |
Date whose segments seed arrow-key stepping from empty; defaults to the picker today or host date. |
placeholders |
FieldSegmentPlaceholders |
{ year: "yyyy", month: "mm", day: "dd" } |
Placeholder text for empty segments. |
emptyText |
string |
"Empty" |
Text announced for empty segments. |
ariaLabel |
string |
undefined |
Accessible name for the segment group. |
ariaLabelledby |
string |
undefined |
Ids that label the segment group. |
ariaDescribedby |
string |
undefined |
Ids that describe the group and every segment. |
ariaErrormessage |
string |
undefined |
Id of the validation message used while invalid. |
ariaInvalid |
boolean |
false |
Force the invalid state. |
Slots
| Slot |
Slot props |
Description |
default |
DateFieldSlotState |
Extra content after the segments, typically the picker trigger after the end field. Receives field state. |
segment |
FieldSegmentState |
Segment content. Receives the segment state; defaults to its text. |
Exposed
| Member |
Type |
Description |
focus |
— |
|
DateRangePickerTrigger
Source: src/families/overlays/popover/popover-trigger.vue
Props
| Prop |
Type |
Default |
Description |
type |
"button" | "reset" | "submit" |
"button" |
Native button submission behavior. |
disabled |
boolean |
false |
Remove the trigger from activation and sequential keyboard focus. |
ariaLabel |
string |
undefined |
Accessible name when no visible label supplies one. |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before the trigger toggles the popover. Call preventDefault() to keep state unchanged. |
Slots
| Slot |
Slot props |
Description |
default |
PopoverSlotState |
Trigger contents. Receives the current Popover state and trigger availability. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
focus |
— |
|
DateRangePickerArrow
Source: src/families/overlays/popover/popover-arrow.vue
Slots
| Slot |
Slot props |
Description |
default |
PopoverArrowSlotState |
Decorative arrow contents. Receives coordinates for optional custom drawing. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
x |
— |
|
y |
— |
|
DateRangePickerGrid
Source: src/families/date-time/calendar/calendar-grid.vue
Props
| Prop |
Type |
Default |
Description |
monthIndex |
number |
0 |
Zero-based index of the visible month this grid renders. |
showWeekNumbers |
boolean |
false |
Render a leading row header with the ISO 8601 week number of each row. |
weekNumberLabel |
string |
"Wk" |
Visible week-number column header. |
weekNumberHeader |
string |
"Week" |
Full week-number column header used as abbr. |
Slots
| Slot |
Slot props |
Description |
weekday |
CalendarWeekdaySlotState |
Weekday column header content. Receives the weekday, its labels, and column index. |
weekNumber |
CalendarWeekNumberSlotState |
Week-number row header content. Receives the ISO week and the row's days. |
day |
CalendarDayState |
Day button content. Receives the complete day state; defaults to the localized day number. |
DateRangePickerHeading
Source: src/families/date-time/calendar/calendar-heading.vue
Slots
| Slot |
Slot props |
Description |
default |
CalendarHeadingSlotState |
Heading content. Receives the localized heading and visible months. |
DateRangePickerMonthSelect
Source: src/families/date-time/calendar/calendar-month-select.vue
Props
| Prop |
Type |
Default |
Description |
ariaLabel |
string |
"Month" |
Accessible name of the native select. |
Events
| Event |
Payload |
Description |
change |
[month: number, nativeEvent: Event] |
Fired after the user picks a month, with the ISO month number. |
DateRangePickerNext
Source: src/families/date-time/calendar/calendar-next.vue
Props
| Prop |
Type |
Default |
Description |
unit |
CalendarNavigationUnit |
"month" |
Whether the control pages by month (or numberOfMonths when paged) or by year. |
ariaLabel |
string |
undefined |
Accessible name; defaults to "Next month" or "Next year". |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before navigation. Call preventDefault() to keep the view unchanged. |
Slots
| Slot |
Slot props |
Description |
default |
CalendarNavigationSlotState |
Control content. Receives the unit and whether navigation is possible. |
DateRangePickerPrev
Source: src/families/date-time/calendar/calendar-prev.vue
Props
| Prop |
Type |
Default |
Description |
unit |
CalendarNavigationUnit |
"month" |
Whether the control pages by month (or numberOfMonths when paged) or by year. |
ariaLabel |
string |
undefined |
Accessible name; defaults to "Previous month" or "Previous year". |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before navigation. Call preventDefault() to keep the view unchanged. |
Slots
| Slot |
Slot props |
Description |
default |
CalendarNavigationSlotState |
Control content. Receives the unit and whether navigation is possible. |
DateRangePickerYearSelect
Source: src/families/date-time/calendar/calendar-year-select.vue
Props
| Prop |
Type |
Default |
Description |
from |
number |
undefined |
First listed year; defaults to the min year or ten years before the view. |
to |
number |
undefined |
Last listed year; defaults to the max year or ten years after the view. |
ariaLabel |
string |
"Year" |
Accessible name of the native select. |
Events
| Event |
Payload |
Description |
change |
[year: number, nativeEvent: Event] |
Fired after the user picks a year. |
Behavior
Normative state x input -> outcome table for the DateRangePicker compound
(@vizejs/ui/date-range-picker): date-range-picker-root.vue,
date-range-picker-field.vue (one per boundary),
date-range-picker-content.vue, and date-range-picker-calendar.vue, with
DateRangePickerTrigger re-exporting PopoverTrigger. Popover, field, and
range-calendar rules follow their own contracts. Every row is proven by the
named test.
| # |
State |
Input |
Outcome |
Proven by |
| Q1 |
closed |
trigger / two day activations |
the popover opens focused on today, the range commits in order, the popover closes, and both fields plus startName/endName inputs update |
renders start and end fields and commits a two-click calendar range |
| Q2 |
complete range |
clear one field / type it back |
clearing an endpoint commits null but keeps the other draft; typing it back commits an ordered range even when entered reversed |
editing one field keeps a draft endpoint until both are known and orders the range |
| Q3 |
imperative |
expose / disabled |
setValue updates both fields and the open calendar; setValue(null) empties them; disabled pickers disable the trigger |
exposes imperative range and open control and respects disabled |
| Q4 |
SSR/hydration |
closed and open requests |
byte-identical markup in both states; an open range picker hydrates silently |
renders byte-identical closed and open range picker markup across SSR requests, hydrates an open range picker without mismatches |
Root data: data-vize-ui="date-range-picker", data-state, data-start,
data-end, data-disabled, data-readonly. Each field root carries
data-boundary.