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
Please select a date range
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:
| Value | Mobile rendering |
|---|---|
modal (default) | Fullscreen Dialog with a 2-step flow: tap to set start → tap to set end. Range highlights between selections. |
native | Two 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
| Prop | Type | Default | Description |
|---|---|---|---|
value | DateRange | - | Controlled selected range ({ start, end }) |
defaultValue | DateRange | - | Default selected range (uncontrolled) |
onChange | (range: DateRange) => void | - | Callback when range changes |
placeholder | string | - | Placeholder text |
variant | 'outlined' | 'filled' | 'outlined' | Visual variant |
size | 'sm' | 'md' | 'lg' | 'md' | Size |
locale | string | 'ko-KR' | Locale for day/month labels |
dateFormat | string | 'yyyy.MM.dd' | Date format string |
minDate | Date | - | Minimum selectable date |
maxDate | Date | - | Maximum selectable date |
disabled | boolean | false | Disabled state |
error | boolean | false | Error state |
errorMessage | string | - | Error message |
label | string | - | Label displayed above the input |
required | boolean | false | Whether the field is required (shows red asterisk) |
presets | Array<{ label: string; range: DateRange }> | - | Preset ranges shown in sidebar |
mobileVariant | 'modal' | 'native' | 'modal' | Mobile rendering: 2-step fullscreen flow or stacked native inputs |
className | string | - | Additional CSS class |
style | CSSProperties | - | Inline styles |