DateRangePicker
Accessible, theme-aware date range picker for selecting a start and end date.
Supports partial ranges and predictable keyboard interaction.
Usage
Basic
import { DateRangePicker } from '@nofinite/nui';
<DateRangePicker
placeholder="Select date range"
onChange={(range) => console.log(range)}
/>;
Controlled
import { useState } from 'react';
import { DateRangePicker, DateRange } from '@nofinite/nui';
const [range, setRange] = useState<DateRange>({
from: undefined,
to: undefined,
});
<DateRangePicker value={range} onChange={setRange} />;
With constraints and form integration
<DateRangePicker
value={range}
onChange={setRange}
minDate="2020-01-01"
maxDate="2030-12-31"
locale="en-US"
nameFrom="startDate"
nameTo="endDate"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | { from?: string; to?: string } | — | Controlled range value. |
defaultValue | { from?: string; to?: string } | — | Initial value when uncontrolled. |
onChange | (r: { from?: string; to?: string }) => void | — | Called when the range changes. |
minDate | string | — | Minimum selectable date. |
maxDate | string | — | Maximum selectable date. |
placeholder | string | 'Pick range' | Trigger placeholder text. |
locale | string | 'en-US' | Locale for month and weekday labels. |
nameFrom | string | — | Hidden input name for start date. |
nameTo | string | — | Hidden input name for end date. |
id | string | — | ID for the trigger element. |
className | string | '' | Additional wrapper class names. |
Behavior Notes
-
Supports partial ranges (
fromonly ortoonly) in both controlled and uncontrolled modes. -
Drag-based selection is supported.
-
Calendar closes on:
- Range completion
- Outside click
- Escape key
-
minDateandmaxDateapply to both range boundaries. -
Date values are normalized to
YYYY-MM-DD.
Accessibility
- Trigger renders as a
<button>witharia-haspopup="dialog". - Calendar supports grid-based keyboard navigation.
- Arrow keys navigate days.
Enterconfirms selection.Escapecloses the calendar.- Focus is trapped while open.
Layout
- Trigger is inline-block.
- Calendar overlay is positioned relative to the trigger.
- Adapts to available width.
- Respects
prefers-reduced-motion.
<DateRangePicker className="w-full" />
Styling
No visual variants are exposed via props.
Styling is controlled using CSS variables and class selectors.
Common classes:
.ui-datepicker.ui-datepicker-calendar.ui-datepicker-day.ui-datepicker-day--selected.ui-datepicker-day--range
Best Practices
Do
- Use controlled mode for form-heavy workflows.
- Allow partial ranges where applicable.
- Set locale explicitly for international use.
Don’t
- Treat range selection as validation.
- Disable keyboard interaction.
- Nest inside scroll-locked containers.