Components

Date Range Picker

Segmented date-range entry and an accessible range Calendar in one collision-aware popup.

DateRangePicker combines Date Range Field and Calendar. Users can type either endpoint or select a range from the popup.

Use Date Range Field when you do not need a calendar popup.

Date values come from @internationalized/date. Install it beside Akaza UI when application code creates or transforms dates: pnpm add akaza-ui @internationalized/date.

Anatomy

  • root: Generated picker root containing field and trigger.
  • field: Generated Date Range Field with all endpoint behavior.
  • #start-literal: Replaces start endpoint locale separators.
  • #separator: Replaces endpoint separator.
  • #end-literal: Replaces end endpoint locale separators.
  • #trigger: Calendar trigger content with open, close, and toggle actions.
  • content: Teleported, positioned role="dialog" popup.
  • #calendar: Replaces built-in Calendar while retaining popup infrastructure.
  • #previous, #heading, #next, #weekday, #day, #footer: Customize built-in Calendar content.
  • #close: Optional close-button content, rendered when slot or closeLabel exists.

Date Range Picker exposes one component with slots for its generated parts.

Usage

Selected: 2026-08-12 to 2026-08-18

Examples

Multiple months

Render adjacent months and navigate by the visible page. Add fixedWeeks when the popup should keep a stable six-week grid height between months.

<DateRangePicker
  v-model="range"
  :number-of-months="2"
  paged-navigation
  fixed-weeks
/>

Close behavior

Picker stays open after a complete selection by default so users can inspect or adjust both boundaries. Add closeOnSelect when a finished range should close immediately, or provide closeLabel for an explicit generated close button.

<DateRangePicker v-model="range" close-on-select />
<DateRangePicker v-model="range" close-label="Done" />

Constraints and unavailable dates

Date Range Field and Calendar receive the same boundaries, unavailable-date rule, non-contiguous setting, maximum length, disabled state, and read-only state.

<DateRangePicker
  v-model="range"
  :min-value="new CalendarDate(2026, 8, 1)"
  :max-value="new CalendarDate(2026, 10, 31)"
  :maximum-days="14"
  :is-date-unavailable="(date) => closedDates.has(date.toString())"
/>

Use isDateDisabled for Calendar-only selection rules. Use isDateUnavailable when typed endpoint and full-range validity must enforce the same rule.

Fixed endpoint

Fix the start or end while the other boundary remains editable through both segments and Calendar.

<DateRangePicker v-model="range" fixed-date="start" />

Controlled popup

Use v-model:open and the cancelable open-change event when application state owns dismissal.

<DateRangePicker
  v-model="range"
  v-model:open="open"
  @open-change="(next, details) => {
    if (!next && hasUnsavedDraft) details.cancel()
  }"
/>

Custom trigger and calendar parts

Slots change visuals without replacing ARIA, focus, positioning, collision handling, or selection behavior.

<DateRangePicker v-model="range">
  <template #trigger="{ isOpen }">
    <CalendarIcon :data-open="isOpen" />
  </template>
  <template #day="{ label, unavailable }">
    <span :class="{ 'line-through': unavailable }">{{ label }}</span>
  </template>
</DateRangePicker>

Use #calendar only when replacing the entire calendar is necessary. That slot receives current value and close while the picker retains popup behavior.

API Reference

Models

ModelTypeDefaultDescription
v-modelCalendarDateRange{}Shared typed and calendar-selected range.
v-model:openbooleanfalsePopup open state.
v-model:placeholderCalendarDateValueselected endpoint or todayFirst visible calendar month.

Props

Date Range Picker accepts Date Range Field props id, name, startName, endName, locale, dir, minValue, maxValue, isDateUnavailable, allowNonContiguousRanges, maximumDays, fixedDate, required, disabled, readOnly, invalid, selectOnFocus, autoAdvance, endpoint labels, and ARIA relationships.

PropTypeDefaultDescription
isDateDisabled(date) => boolean-Calendar-only disabled-date rule.
calendarLabelstring"Choose date range"Trigger and popup accessible label.
closeLabelstring-Renders an explicit close button with this label.
closeOnSelectbooleanfalseCloses after both endpoints are selected.
weekStartsOn"sun" | "mon" | ...locale defaultExplicit first weekday.
weekdayFormat"narrow" | "short" | "long""narrow"Visible weekday format.
fixedWeeksbooleanfalseRenders six weeks per month for stable popup height.
numberOfMonthsnumber1Adjacent month grids.
pagedNavigationbooleanfalseMoves by numberOfMonths.
disableDaysOutsideCurrentViewbooleanfalseBlocks selecting outside days.
nextPage(placeholder) => CalendarDateValueadd month(s)Custom next page calculation.
prevPage(placeholder) => CalendarDateValuesubtract month(s)Custom previous page calculation.
side"top" | "right" | "bottom" | "left""bottom"Preferred popup side with collision flipping.
align"start" | "center" | "end""start"Popup alignment.
sideOffsetnumber6Trigger-to-popup gap in pixels.
teleportstring | false"body"Teleport target; false keeps popup beside root.
uiDateRangePickerUi-Classes and nested field/calendar UI maps.

Emits

EventPayloadDescription
update:modelValueCalendarDateRangeFires after accepted typed or calendar changes.
value-change(range, details)Fires before value changes. details.cancel() prevents update.
value-commit(range, details)Fires after accepted field or calendar commits.
update:openbooleanFires after accepted popup state changes.
open-change(open, details)Fires before popup changes. Cancelable.
update:placeholderCalendarDateValueFires after accepted visible-month changes.
placeholder-change(date, details)Fires before visible-month changes. Cancelable.

Open reasons include trigger, select, escape, outside-click, and programmatic. Value reasons match Date Range Field plus calendar.

Slots

SlotPropsDescription
start-literalvalueStart endpoint locale separator.
separator-Endpoint separator.
end-literalvalueEnd endpoint locale separator.
triggerisOpen, open, close, toggleCalendar trigger content. Actions are native event-handler safe.
calendarvalue, closeReplaces built-in Calendar.
previousdisabledBuilt-in Calendar previous control content.
headinglabel, monthsBuilt-in Calendar heading.
nextdisabledBuilt-in Calendar next control content.
weekdaydate, labelBuilt-in weekday content.
dayComplete CalendarDay stateBuilt-in day button content.
footervalue, placeholderOptional built-in Calendar footer.
closecloseExplicit close-button content.

Methods

MethodDescription
open(reasonOrEvent?, event?)Opens through cancelable lifecycle.
close(reasonOrEvent?, event?)Closes and restores trigger focus when appropriate.
toggle(reasonOrEvent?, event?)Toggles popup.
focusStart()Focuses first start segment.
focusEnd()Focuses first end segment.
clear(event?)Clears range through cancelable value flow.

UI Options

KeyDescription
rootPicker root.
fieldNested DateRangeFieldUi.
triggerCalendar popup trigger.
contentPositioned popup dialog.
calendarNested CalendarUi.
closeOptional close button.

Styling Hooks

UI keyCSS classData attrs / variables
rootakaza-date-range-pickerdata-akaza-state="open|closed", data-akaza-disabled, data-akaza-readonly, data-akaza-invalid
triggerakaza-date-range-picker-triggerdata-akaza-state="open|closed", data-akaza-disabled, aria-expanded, aria-controls
contentakaza-date-range-picker-contentdata-akaza-state="open", data-akaza-side, data-akaza-align, floating size/origin variables, --akaza-date-range-picker-duration
closeakaza-date-range-picker-close-

Nested field and calendar parts retain their own exact semantic classes and data attributes. Plain class applies to picker root. Use ui.content for teleported popup styling.

Keyboard and focus

Field segments follow Date Field's spinbutton keyboard pattern. Calendar uses roving day focus, arrow keys, week boundaries, month/year paging, and Enter/Space selection. Escape closes only the top dismissable layer and restores trigger focus. Outside pointer interaction closes the popup; touch activation uses native button behavior.