Skip to content
EspañolEnglish
All components (204)

Date range

Dates and time · DateRangePicker

What it is and when to use it

Two dates that go together: "from September 1 to 30". Each end is typed in parts, just like in DatePicker, and the calendar shows two months at once so you can choose a period that crosses a month boundary without going back and forth.

When to use it

  • Periods: that of a report, a vacation, a fiscal year, a promotion.
  • months={1} when there is no room for two months (a narrow column, a side panel).
  • minValue and maxValue to bound it: whatever is outside appears dimmed in the calendar.

When not to

  • A single date: DatePicker.
  • A panel filter with shortcuts ("today", "last seven days", "this month") in addition to the custom range: QuickRange.
  • The range in view, without a field: Calendar with range.

Keyboard: each segment of the two dates is a Tab stop, and Left Arrow and Right Arrow also move from one to another within each date; Up Arrow and Down Arrow increase and decrease the one with focus, or you type the number. The calendar opens with its button. In the calendar: arrow keys move by days and weeks, Page Up and Page Down change the month (with Shift, the year), Home and End go to the first and last day of the month, and Enter or Space select the start first and then the end.

Accessibility: the label is required and names the whole group; the help text and the error are read as its description. The dash between the two dates is decoration (aria-hidden). The button is called "Open calendar" and the month buttons "Previous month" and "Next month".

Fine-tuning: CSS variables of the box, shared by all fields: --amset-field-height, -padding, -font, -label, -description, -radius, -background and -border. Those of the date field: --amset-date-target (height of each segment, 24 px; 44 with a finger), --amset-date-button (the calendar button) and --amset-date-icon. And those of the panel calendar: --amset-calendar-day (side of each day: 28, 32 or 40 px depending on the size, and it shrinks on a narrow screen), --amset-calendar-slot, --amset-calendar-padding, --amset-calendar-font and --amset-calendar-nav (the month buttons). If it does not fit on one line, the second date drops below the first instead of overflowing the box.

Context: it goes inside LocaleProvider (or AmsetProvider).

What it looks like

Within the 2026 fiscal year

<DateRangePicker
  label="Report period"
  defaultValue={{ start: { year: 2026, month: 9, day: 1 }, end: { year: 2026, month: 9, day: 30 } }}
  minValue={{ year: 2026, month: 1, day: 1 }}
  maxValue={{ year: 2026, month: 12, day: 31 }}
  hint="Within the 2026 fiscal year"
/>

Props

Import it with import { DateRangePicker } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
labelrequiredstring—
classNamestring—
defaultOpenbooleanThe calendar starts open. The test bench uses it to photograph the panel.
defaultValue{ readonly start: T; readonly end: T; } | nullThe range at the start, without controlling it from outside.
disabledboolean—
endNamestring—
errorstring—
firstDayOfWeekFirstDayOfWeekWhich day the week starts on. Without this, the language decides.
hintstring—
invalidboolean—
isDateUnavailable(date: PlainDate) => booleanDays that cannot be chosen even if they fall within the limits.
maxValuePlainDateThe last day that can be chosen.
minValuePlainDateThe first day that can be chosen.
months2 | 1How many months are visible at once. Two is comfortable for choosing a range; if they do not fit, they go one below the other.
offsetnumber—
onChange(value: DateRange) => voidIt is only announced with BOTH ends set: half a range is not a value.
onOpenChange(open: boolean) => void—
openbooleanThe calendar open or closed, controlled from outside.
placeholderValuePlainDateThe reference day: the value an empty segment starts with when touched with an arrow. By default TODAY.
placementPlacement—
readOnlyboolean—
requiredboolean—
shouldCloseOnSelectbooleanClose the calendar when the interval is completed. By default yes: with both ends set, there is nothing left to choose.
shouldForceLeadingZerosbooleanLeading zeros in the day and month. On by default.
size"sm" | "md" | "lg"—
startNamestringWhat name each end travels under in a plain old form.
validationBehavior"aria" | "native"`aria` (the default) announces the state without the browser interrupting submission with its bubble; `native` also adds its own validation.
value{ readonly start: T; readonly end: T; } | nullThe chosen range, controlled from outside.
variantFieldVariant—

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: