Date Picker
DatePicker pairs a Button trigger with a Popover that holds a Calendar. The trigger shows the current selection (or a placeholder) and opens the calendar on click — use it in forms, filters, and toolbars where a full inline calendar would take up too much room.
<DatePicker value={value} onChange={setValue} outline className="w-56" />Usage
DatePicker ships from the @cladd-ui/react/calendar subpath — the calendar bundle is split out so apps that don't use it don't pay for react-day-picker. Because of that split, react-day-picker is an optional peer dependency that cladd does not install for you — add it explicitly:
npm install react-day-pickerimport { DatePicker, type DateRange } from '@cladd-ui/react/calendar';
const [value, setValue] = useState<Date | undefined>();
<DatePicker value={value} onChange={setValue} />;The component is controlled — pass value plus an onChange handler. In the default single mode value is a Date and onChange receives Date | undefined. The popover open state is internal by default; pass open / onOpenChange to drive it yourself.
Examples
Sizes
The trigger follows the shared size scale from 2xs to 2xl, the same one used by Button, Select, and the rest of the size-aware controls. The default is md. The calendar inside the popover sizes independently via calendarSize (default lg).
<DatePicker
value={value}
onChange={setValue}
size="md"
outline
className="w-56"
/>Colors
Use color to set the accent on both the trigger and the calendar selection. Any of the eleven accent colors works; when unset it inherits the theme accent.
<DatePicker
value={value}
onChange={setValue}
color="brand"
className="w-56"
/>Range
Set mode="range" to select a start and end date. The value is a DateRange ({ from?: Date; to?: Date }, re-exported from react-day-picker), and calendarProps forwards options to the embedded Calendar — here numberOfMonths: 2 shows two months side by side.
<DatePicker
mode="range"
value={value}
onChange={setValue}
placeholder="Select range"
calendarProps={{ numberOfMonths: 2 }}
outline
className="w-64"
/>Multiple
Set mode="multiple" to collect several individual dates. The value is a Date[], and the trigger lists the picked dates once more than one is selected.
<DatePicker
mode="multiple"
value={value}
onChange={setValue}
placeholder="Select dates"
outline
className="w-72"
/>Custom format
Pass format to control the trigger label. It receives the current value for the active mode and returns a ReactNode — here an Intl.DateTimeFormat long date. Without it the trigger falls back to toLocaleDateString.
<DatePicker
value={value}
onChange={setValue}
format={(date) =>
new Intl.DateTimeFormat('en-US', { dateStyle: 'long' }).format(date)
}
outline
className="w-64"
/>Rounded
Set rounded for a pill-shaped trigger — forwarded straight to Button.rounded.
<DatePicker
value={value}
onChange={setValue}
rounded
outline
className="w-56"
/>Playground
size, color, and the boolean toggles compose freely. Default to md; reach for lg when the picker is a primary field in a form.
<DatePicker
value={value}
onChange={setValue}
size="md"
color="brand"
rounded={false}
outline
className="w-56"
/>API Reference
DatePickerProps is a discriminated union over mode. The default 'single' mode takes value: Date, onChange: (value: Date | undefined) => void, a format: (value: Date) => ReactNode, and closeOnSelect (default true). 'multiple' switches value to Date[] with a matching onChange/format, and 'range' uses a DateRange ({ from?: Date; to?: Date }, re-exported from react-day-picker) with onChange: (value: DateRange | undefined) => void. The base props below — sizing, color, popover position, and so on — apply to every mode. calendarProps forwards straight through to the embedded Calendar (including numberOfMonths, disabled, startMonth, and endMonth).
| Name: Type | Default | Description |
|---|---|---|
| calendarProps: Omit<Partial<PropsBase>, 'mode' | 'required'> & { size?: CalendarSize; controlSize?: ButtonSize; color?: Color; } | — | Extra props forwarded to the underlying Calendar (e.g. numberOfMonths, disabled, startMonth, endMonth). |
| calendarSize: CalendarSize | 'lg' | Calendar size inside the popover. Default 'lg'. |
| className: string | — | Extra classes for the trigger button. |
| closeOnSelect: boolean | true | Close the popover after a pick. Default true. |
| color: Color | — | Accent color token. Drives the trigger and the calendar. Default: theme accent. |
| contentClassName: string | — | Extra classes for the trigger's inner content row. |
| disabled: boolean | — | Dim the trigger and block opening. |
| dropdownIcon: boolean | true | Show the chevron indicator on the right of the trigger. Default true. |
| format: (value: Date) => ReactNode | toLocaleDateString | Format the selected date into the trigger label. Default toLocaleDateString. |
| icon: ReactNode | — | Icon node in the trigger. Defaults to a calendar glyph; pass null to hide. |
| iconClassName: string | — | Extra classes for the icon wrapper. |
| mode: 'single' | 'single' | Selection mode. Default 'single'. |
| onChange: (value: Date | undefined) => void | — | Fires when the selected date changes. |
| onOpenChange: (open: boolean) => void | — | Fires whenever the popover open state changes. |
| open: boolean | — | Controlled popover open state. Pair with onOpenChange. |
| outline: boolean | — | Trigger surface outline ring. Forwarded to Button.outline. |
| placeholder: ReactNode | 'Select date' | Shown in the trigger when nothing is selected. Default 'Select date'. |
| popoverClassName: string | 'w-auto' | Extra classes for the popover surface. Default 'w-auto'. |
| popoverColor: Color | color | Accent color for the popover. Defaults to color. |
| popoverOffset: PopoverOffset | ['-50%', 4] | Popover spacing from the trigger. Default ['-50%', 4]. |
| popoverPosition: PopoverPosition | 'bottom-end' | Popover anchor side + alignment. Default 'bottom-end'. |
| popoverSurfaceLevel: number | string | — | Surface level for the popover. |
| readOnly: boolean | — | Show the value but block opening the popover. |
| rounded: boolean | — | Pill-style trigger. Forwarded to Button.rounded. |
| size: ButtonSize | 'md' | Trigger button size. Forwarded to Button.size. Default 'md'. |
| value: Date | — | Selected date. |