Date Picker
ProA calendar surface plus two ready pickers, single date and range, over Radix Popover with native Date math and no date dependency. Selection is a solid ink fill; the in-range days take a soft grey.
Installation#
Usage#
The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.
Have a license? Unlock it here
Calendar#
The Calendar is the standalone grid the pickers wrap. Use it directly when you need an always-open calendar. The caption cycles day → month → year views; arrow keys move the focused day, PageUp/PageDown move a month, Home/End jump to the week edges.
Range selection#
Set mode="range" to select a { from, to } span. The first click sets the start, the second closes the range; hovering previews the span. Show multiple months with numberOfMonths.
Presets#
Pass presets to render a quick-pick rail. Use presets (boolean) for the built-in set, or pass your own array. The single-date set ships getDatePresets(); the range set ships getDateRangePresets() with eleven common spans (Today, Last 7 days, This month, Last year, …).
Range with presets#
The combination most analytics surfaces want: a two-month range picker with the full preset rail.
Sizes#
Constraints#
Bound the range with min / max, or disable arbitrary days with isDateDisabled. Disabled days are inert and struck through.
Density#
Like the rest of Koala, the calendar honors density: compact (the default, or whatever the nearest DensityProvider sets) keeps 32px cells and a 32px trigger for dense application UI; comfortable opens them to 36px.
Inside a Field#
Drop a picker inside a Field and it auto-wires the label, hint, id, and error/disabled state, with no manual props.
API reference#
Calendar
The standalone month grid the pickers wrap, a <div> with a roving-tabindex role="grid". Takes className on its root, merged last, as every export here does.
| Prop | Type | Default | Description |
|---|---|---|---|
| mode | "single" | "range" | "single" | Pick one Date, or a DateRange of { from, to }. |
| selected | Date | DateRange | - | Controlled selection: a Date in single mode, a DateRange in range mode. |
| defaultSelected | Date | DateRange | - | Initial selection when uncontrolled. |
| onSelect | (value: Date | DateRange | undefined) => void | - | Called with the new selection; a range is { from } until its second click. |
| month | Date | - | Controlled displayed month. |
| defaultMonth | Date | - | Initial month when uncontrolled; otherwise the selection's month, or today's. |
| onMonthChange | (month: Date) => void | - | Called when the displayed month changes. |
| min | Date | - | Earliest selectable day, inclusive. |
| max | Date | - | Latest selectable day, inclusive. |
| isDateDisabled | (date: Date) => boolean | - | Disable arbitrary days, such as weekends. Disabled days are inert and struck through. |
| weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 1 | First column of the week, 0 for Sunday; Monday by default. |
| locale | string | - | BCP-47 locale for month and weekday labels. Defaults to the visitor's; server and hydrating renders use en-US, then the visitor's takes over. |
| numberOfMonths | number | 1 | Month grids shown side by side. The caption switches to month and year views only with one. |
| density | "comfortable" | "compact" | "compact" | Cell size: 36 or 32px. Falls back to the nearest DensityProvider. |
| Data attribute | Description |
|---|---|
| data-selected | On a day button: the selected day or a range endpoint. On a month or year cell: the displayed one. |
| data-today | On today's day button; set after hydration, never on the server. |
| data-outside | On a day from the neighbouring month. |
| data-disabled | On a day outside min/max or matched by isDateDisabled. |
| data-current | On the month or year cell that holds today. |
DatePicker
A trigger that opens a Calendar in a Radix Popover, for one date; it closes on pick. Reads Field context for its id, description, disabled and error state.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | Date | - | Controlled date. |
| defaultValue | Date | - | Initial date when uncontrolled. |
| onChange | (date: Date | undefined) => void | - | Called on pick, preset or clear. |
| placeholder | string | "Pick a date" | Trigger label while no date is set. |
| size | "sm" | "md" | "lg" | "sm" | Trigger height: 32, 36 or 40px. Unset, it follows density (sm compact, md comfortable), or the size a Form imposes. |
| block | boolean | false | Stretch the trigger to its container's width. |
| clearable | boolean | false | Show a clear button in the trigger once a value is set. |
| presets | boolean | DatePreset[] | - | A quick-pick rail: true for the built-in set, or your own { label, value } items. |
| format | (date: Date) => string | - | Format each date in the trigger label. Defaults to the locale's medium date. |
| min | Date | - | Earliest selectable day, inclusive. |
| max | Date | - | Latest selectable day, inclusive. |
| isDateDisabled | (date: Date) => boolean | - | Disable arbitrary days, such as weekends. Disabled days are inert and struck through. |
| weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 1 | First column of the week, 0 for Sunday; Monday by default. |
| locale | string | - | BCP-47 locale for month and weekday labels. Defaults to the visitor's; server and hydrating renders use en-US, then the visitor's takes over. |
| numberOfMonths | number | 1 | Month grids shown side by side. |
| density | "comfortable" | "compact" | "compact" | Calendar cell size (36 or 32px) and the trigger's default size. Falls back to the nearest DensityProvider. |
| align | "start" | "center" | "end" | "start" | Popover alignment against the trigger; it opens 8px below. |
| disabled | boolean | - | Disable the trigger. Inside a Field, read from the field. |
| hasError | boolean | - | Mark the trigger invalid (aria-invalid, destructive border). Inside a Field, read from the field. |
| id | string | - | The trigger's id. Inside a Field, read from the field so its label points here. |
| triggerClassName | string | - | Extra classes for the trigger; className lands on the trigger too. |
| Data attribute | Description |
|---|---|
| data-state | On the trigger: "open" or "closed". |
| data-placeholder | On the trigger while no value is set. |
| data-active | On the preset that matches the current value. |
| CSS variable | Description |
|---|---|
| --surface | Read by the trigger as its fill (falls back to --background); the popover sets it to var(--popover). |
DateRangePicker
The same picker for a DateRange; it closes once both ends are set or a preset is chosen. Reads Field context like DatePicker.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | DateRange | - | Controlled range, { from, to }. |
| defaultValue | DateRange | - | Initial range when uncontrolled. |
| onChange | (range: DateRange | undefined) => void | - | Called on each click, preset or clear. |
| placeholder | string | "Pick a date range" | Trigger label while no start is set. |
| size | "sm" | "md" | "lg" | "sm" | Trigger height: 32, 36 or 40px. Unset, it follows density (sm compact, md comfortable), or the size a Form imposes. |
| block | boolean | false | Stretch the trigger to its container's width. |
| clearable | boolean | false | Show a clear button in the trigger once a value is set. |
| presets | boolean | DateRangePreset[] | - | A quick-pick rail: true for the built-in set, or your own { label, value } items. |
| format | (date: Date) => string | - | Format each date in the trigger label. Defaults to the locale's medium date. |
| min | Date | - | Earliest selectable day, inclusive. |
| max | Date | - | Latest selectable day, inclusive. |
| isDateDisabled | (date: Date) => boolean | - | Disable arbitrary days, such as weekends. Disabled days are inert and struck through. |
| weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 1 | First column of the week, 0 for Sunday; Monday by default. |
| locale | string | - | BCP-47 locale for month and weekday labels. Defaults to the visitor's; server and hydrating renders use en-US, then the visitor's takes over. |
| numberOfMonths | number | 2 | Month grids shown side by side. |
| density | "comfortable" | "compact" | "compact" | Calendar cell size (36 or 32px) and the trigger's default size. Falls back to the nearest DensityProvider. |
| align | "start" | "center" | "end" | "start" | Popover alignment against the trigger; it opens 8px below. |
| disabled | boolean | - | Disable the trigger. Inside a Field, read from the field. |
| hasError | boolean | - | Mark the trigger invalid (aria-invalid, destructive border). Inside a Field, read from the field. |
| id | string | - | The trigger's id. Inside a Field, read from the field so its label points here. |
| triggerClassName | string | - | Extra classes for the trigger; className lands on the trigger too. |
| Data attribute | Description |
|---|---|
| data-state | On the trigger: "open" or "closed". |
| data-placeholder | On the trigger while no value is set. |
| data-active | On the preset that matches the current value. |
| CSS variable | Description |
|---|---|
| --surface | Read by the trigger as its fill (falls back to --background); the popover sets it to var(--popover). |
getDatePresets
Returns the built-in single-date set: Today, Yesterday, Tomorrow, In a week, In two weeks, In a month.
| Prop | Type | Default | Description |
|---|---|---|---|
| now | Date | new Date() | The day the presets are relative to. |
getDateRangePresets
Returns the built-in eleven ranges, from Today and Last 7 days to This month and Last year.
| Prop | Type | Default | Description |
|---|---|---|---|
| now | Date | new Date() | The day the presets are relative to. |
| weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 1 | Where This week and Last week begin. |