Skip to content

DatePicker

Segmented date input with a calendar popover; backed by React Aria + @internationalized/date for locale-aware formatting and full keyboard control.

  • stable
  • since v0.1.0
  • 1.9 kB
  • forms
  • date

Each date segment is its own labelled spinbutton; popover is a labelled dialog with a roving-tabindex calendar grid.

Preview
Open
tsx
import { DatePicker } from "@arshad-shah/cynosure-react";
import { parseDate } from "@internationalized/date";
<DatePicker label="Start date" defaultValue={parseDate("2026-04-17")} />

Values are @internationalized/date DateValues — pair the picker with parseDate / today(getLocalTimeZone()) from @internationalized/date.

outline (default), filled, and ghost tint the segmented track — the same vocabulary as the other form controls; the raised segment tiles stay constant.

Preview
Open
tsx

sm, md (default), and lg.

Preview
Open
tsx

Disabled, read-only, invalid, and empty.

Preview
Open
tsx

Constrain the selectable range with minValue and maxValue. The calendar disables out-of-range cells and the segments reject out-of-range entries.

Preview
Open
tsx

granularity switches between day-only and time-aware segments (hour, minute, second).

Preview
Open
tsx
PropTypeDefaultDescription
label
ReactNode
Visible label, also used as the picker's accessible name when a string.
size
"sm"|"md"|"lg"
Accepted for API parity with other form controls; visual effect is minor in the segmented design.
variant
"outline"|"filled"|"ghost"
"outline"
Tints the segmented track: `outline` (light well + hairline border), `filled` (deeper solid tint), `ghost` (transparent; tiles flat at rest).
invalid
boolean
Renders the invalid state.
className
string
style
CSSProperties
value
DateValue|null
Controlled date value.
defaultValue
DateValue|null
Uncontrolled initial value.
onChange
((value: DateValue | null) => void)
Fires with the next value when the user picks a date or clears the input.
  • Each segment (year/month/day, plus time when applicable) is a labelled spinbutton — arrow keys nudge the value, type-ahead works for two-digit entry.
  • The calendar popover is a labelled dialog with a roving-tabindex grid for date navigation.
  • invalid toggles aria-invalid on the input group; the calendar respects minValue / maxValue and skips disabled cells.
  • Pass aria-label (or a string label prop) so the field has an accessible name in both states.
  • Use value + onChange for controlled state; pass null to clear.
  • Combine with FormField + FormMessage to surface “required date” validation.
  • Wrap in LocaleProvider to switch the segment order and the calendar’s first-day-of-week.