DatePicker
Accessible React date picker with an in-calendar Hijri (Umm al-Qura) and Gregorian toggle, min and max bounds, and Arabic support. Value is always a Date.
DatePicker selects a single date, with an in-calendar Gregorian/Hijri toggle. The value is always Date | null; the Hijri view is display only.
When to use
Use DatePicker for a single date such as a birth date, an appointment, or a document issue date. Saudi services often need both calendars: enable the Hijri view and showSecondaryCalendar so each day shows its counterpart.
Bound the range with minValue and maxValue to prevent invalid dates. For a start and end, use DateRangePicker.
Examples
Props
Props declared by DatePicker. Native attributes of the underlying element pass through.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "md" | "lg" | ||
variant | "default" | "filled-lighter" | "filled-darker" | ||
value | Date | Currently selected date (controlled). Local Y/M/D. | |
defaultValue | Date | Initial value when uncontrolled. | |
onChange | (value: Date | null) => void | Fires whenever the user picks a day. null when cleared. | |
minValue | Date | Earliest pickable date (inclusive). | |
maxValue | Date | Latest pickable date (inclusive). | |
label | react.ReactNode | Visible label above the trigger. | |
helperText | react.ReactNode | Hint shown below the trigger. Hidden while an error message is showing. | |
errorMessage | react.ReactNode | Message shown below the trigger when error is true. | |
error | boolean | Marks the field invalid - sets aria-invalid and error styling. | |
required | boolean | Marks the field required - adds the asterisk + aria-required. | |
disabled | boolean | Disables the trigger entirely. | |
readOnly | boolean | Read-only: value is shown but not editable (segments + calendar locked). | |
id | string | Caller-supplied id for the field. | |
className | string | Forwarded to the Group (the trigger row), matching Input/Select. | |
aria-label | string | ||
aria-labelledby | string | ||
calendar | CalendarSystem | Calendar system (controlled). Omit to let the user toggle freely with the in-popover switch. | |
defaultCalendar | CalendarSystem | Initial calendar system when uncontrolled. Defaults to 'gregorian'. | |
onCalendarChange | (calendar: CalendarSystem) => void | Fires whenever the calendar system toggles. | |
showCalendarToggle | boolean | Show the Gregorian↔Hijri toggle inside the popover. Defaults to true,
but is forced off when calendar is controlled - a toggle that ignores
its click is a worse footgun than no toggle. | |
calendarLabels | CalendarLabels | Override the toggle labels. Defaults are locale-aware (English / Arabic). | |
showSecondaryCalendar | boolean | When true, each day cell also shows the other calendar's day number
as small secondary text (e.g., Hijri active → Gregorian day shown small
underneath). Helps users cross-reference dates between calendar systems
without round-tripping the toggle. Defaults to false. |
Accessibility
The calendar follows the grid pattern from React Aria. Arrow keys move between days, Page Up and Page Down change the month, and Escape closes the popover. The field label, helper text, and error are wired like TextInput, and the calendar toggle has an accessible name.
Dates are announced in the active calendar system, so Hijri users hear Hijri dates.