Skip to main content
Urbicon UI
source

DateRangePicker

Range selection in two clicks — start and end date in one calendar popover, closing itself once both are set. Shares the DatePicker surface: same sizes, variants, constraints, and locale handling.

Playground

Input Variant
Calendar Variant
<DateRangePicker
  label="Travel dates"
/>

01 Examples

Booking a stay

Two clicks on one dual calendar: the first sets the start, the second the end. closeOnSelect (the default) dismisses the popover once the range is complete, so the flow ends without a second gesture.
<DateRangePicker
  label="Check-in / check-out"
  bind:value={stay}
  placeholder="Pick your dates"
  clearable
/>

Bounded to a bookable window

minDate and maxDate fence the calendar; isDateDisabled handles the irregular gaps a fixed range cannot express — here every Sunday. A predicate that throws is caught and logged, and the date is then treated as allowed.
Next 90 days, Sundays excluded
<DateRangePicker
  label="Bookable period"
  bind:value={bookable}
  minDate={TODAY}
  maxDate={IN_90_DAYS}
  isDateDisabled={(d) => d.getDay() === 0}
  helper="Next 90 days, Sundays excluded"
/>

Reporting period in a form

name renders two hidden inputs — period_start and period_end — each carrying the serialised date, so a native submit never sends the locale-formatted display string. An empty range submits both halves as an empty string.
Submitted as period_start and period_end
<DateRangePicker
  label="Reporting period"
  name="period"
  bind:value={reportRange}
  required
  helper="Submitted as period_start and period_end"
/>

02 Customization

The trigger and the calendar are styled separately: inputVariant takes the Input ladder (outlined, filled, ghost, underline) and calendarVariant the Calendar one (default, bordered, ghost). size drives both.

Everything the calendar itself understands passes straight through — locale, weekStartsOn, showWeekNumbers, showOutsideDays, fixedWeeks. locale defaults to 'auto', which follows the active <I18nProvider>, so an app that already declares its language does not repeat it here.

For a single date use DatePicker; for the calendar surface without an input, see Calendar. See Customization for the general contract.

03 Accessibility

The trigger announces its popup

The text input carries aria-haspopup="dialog", aria-expanded, and — while open — aria-controls pointing at the calendar, so assistive tech reports both that a calendar exists and whether it is showing.

Keyboard

opens the calendar from the field. Enter closes it while open, and commits what has been typed while it is not. Esc closes the calendar; pressed again on a field with an uncommitted draft it discards that draft rather than the selection. Grid navigation inside the calendar follows the Calendar pattern.

Both embedded buttons are named

When clearable is set the field carries two controls, and each gets its own localized aria-label — "clear input" and "open calendar" — rather than sharing one ambiguous name. Both keep a visible focus-visible ring.

Typing is a first-class path

The range can be typed as well as clicked; parsing happens on blur or Enter, and a parse failure surfaces as the field's error. A picker that can only be operated by pointer excludes anyone who is faster on the keyboard.

Dismissal is separable from notification

closeOnEscape and closeOnClickOutside govern whether the popover closes; onEscape and onClickOutside only tell you it happened. Turning a notification into the close mechanism is the usual way a picker ends up impossible to dismiss by keyboard.

04 API Reference

35 props
35 props
Prop
Type
Default
Description

05 Types

Local type definitions used by this component.

12 types
Name
Kind
Category
Used by
Description

06 Installation

Import

import { DateRangePicker } from '@urbicon-ui/blocks';