Skip to content

DateRangePicker

Anatomy

+------------------------------------------------+
| Label |
| +--------------------------------------------+ |
| | MM/DD/YYYY – MM/DD/YYYY [📅] | |
| +--------------------------------------------+ |
| Helper text |
+------------------------------------------------+

Examples

Basic

<DateRangePicker label="Trip dates" />

Controlled

import { parseDate, type DateValue } from '@internationalized/date';
import type { RangeValue } from 'react-aria-components';
const [range, setRange] = useState<RangeValue<DateValue> | null>({
start: parseDate('2026-05-25'),
end: parseDate('2026-06-01'),
});
<DateRangePicker label="Trip dates" value={range} onChange={setRange} />

Blackout dates

const blocked = new Set(['2026-05-30', '2026-05-31']);
<DateRangePicker
label="Pickup window"
isDateUnavailable={(d) => blocked.has(d.toString())}
/>

When to use

  • Any flow that needs two related dates: trip, billing window, reservation, vacation, leave request.

When to use <DatePicker> instead

  • One date, not a range.

Tokens

See the tokens block in this spec’s frontmatter.

Install: @helixui/core

import { DateRangePicker } from '@helixui/core'

status: stable · since: 0.1.0

Tags: date, range, picker, calendar, popover, departure, return

Props

NameTypeDefaultDescription
labelstringundefinedField label rendered above the trigger row.
descriptionstringundefinedHelper text rendered below the trigger row.
errorMessagestringundefinedValidation error rendered when the field is invalid.
tone'brand' | 'neutral' | 'danger'brandTone for the focus ring and selected days.
size'sm' | 'md' | 'lg'mdTouch target size, matching every other helixui input.
valueRangeValue<DateValue> | nullundefinedControlled selected range.
defaultValueRangeValue<DateValue>undefinedUncontrolled initial range.
onChange(value: RangeValue<DateValue> | null) => voidundefinedFires when the user picks a complete range.
minValueDateValueundefinedEarliest selectable date.
maxValueDateValueundefinedLatest selectable date.
isDateUnavailable(date: DateValue) => booleanundefinedMark specific dates as unselectable (blackout dates).
isDisabledbooleanfalseDisable the entire picker.
isReadOnlybooleanfalseShow as non-editable.

Tokens used

color.bg.surface.default, color.bg.action.brand.default, color.bg.action.brand.subtle, color.border.subtle, color.border.action.brand, color.text.primary, color.text.muted, color.text.action.brand, color.text.action.brand.on, radius.md, spacing.1

Accessibility

Role: combobox

Keyboard

KeyAction
TabMove between start / end segments and the trigger.
ArrowUpIncrement focused segment.
ArrowDownDecrement focused segment.
EnterOpen the popover; on the grid, anchor or commit the range.
ArrowKeysInside the grid — move by day; PageUp/PageDown by month.

Notes

  • Each segment is independently focusable.
  • The trigger is a labeled button; opens a dialog with a range-aware calendar.
  • Days inside the active range announce as aria-selected.