Skip to main content

DateRangePicker

A date input for selecting a range of dates. Displays two side-by-side calendars and supports preset ranges.

Basic Usage

With Label

Variants

Error State

Disabled

With Presets

<DateRangePicker
presets={[
{
label: 'Last 7 days',
range: {
start: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
end: new Date(),
},
},
{
label: 'Last 30 days',
range: {
start: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
end: new Date(),
},
},
]}
/>

Mobile variant

A side-by-side dual calendar doesn't fit small viewports. mobileVariant picks between two strategies:

ValueMobile rendering
modal (default)Fullscreen Dialog with a 2-step flow: tap to set start → tap to set end. Range highlights between selections.
nativeTwo stacked native <input type="date"> (start + end) — uses the OS spinner.
<DateRangePicker mobileVariant="native" label="Period" />

The 2-step modal flow feels native to mobile users (think Airbnb / Google Flights) and avoids the cramped dual-calendar layout entirely.

Mobile considerations

  • 2-step flow uses the same Calendar component as desktop, but resets to the start step each open to avoid stale state.
  • Day cells meet 44×44px tap target on mobile.
  • Preset list (when provided) renders as a horizontal scrollable chip row above the calendar on mobile.

Props

PropTypeDefaultDescription
valueDateRange-Controlled selected range ({ start, end })
defaultValueDateRange-Default selected range (uncontrolled)
onChange(range: DateRange) => void-Callback when range changes
placeholderstring-Placeholder text
variant'outlined' | 'filled''outlined'Visual variant
size'sm' | 'md' | 'lg''md'Size
localestring'ko-KR'Locale for day/month labels
dateFormatstring'yyyy.MM.dd'Date format string
minDateDate-Minimum selectable date
maxDateDate-Maximum selectable date
disabledbooleanfalseDisabled state
errorbooleanfalseError state
errorMessagestring-Error message
labelstring-Label displayed above the input
requiredbooleanfalseWhether the field is required (shows red asterisk)
presetsArray<{ label: string; range: DateRange }>-Preset ranges shown in sidebar
mobileVariant'modal' | 'native''modal'Mobile rendering: 2-step fullscreen flow or stacked native inputs
classNamestring-Additional CSS class
styleCSSProperties-Inline styles