Date field with a calendar popover. Typing and picking both work, in the user's locale.
import { DatePicker } from "@rdloom/react";
export default function DatePickerBasicExample() {
return (
<DatePicker className="w-64" label="Due date" />
);
}Installation
npx rdloom add date-pickerCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/date-picker.jsonWorks, but without upgrade tracking.
Usage
import { DatePicker } from "@rdloom/react";
<DatePicker className="w-64" label="Due date" />With time
import { DatePicker } from "@rdloom/react";
export default function DatePickerWithTimeExample() {
return (
<DatePicker className="w-72" label="Meeting" granularity="minute" />
);
}Min max
import { getLocalTimeZone, today } from "@internationalized/date";
import { DatePicker } from "@rdloom/react";
export default function DatePickerMinMaxExample() {
const now = today(getLocalTimeZone());
return (
<DatePicker className="w-64" label="Delivery" description="Within the next 2 weeks" minValue={now} maxValue={now.add({ weeks: 2 })} />
);
}Invalid
import { Button, DatePicker } from "@rdloom/react";
export default function DatePickerInvalidExample() {
return (
<form className="flex flex-col items-start gap-3" onSubmit={(e) => e.preventDefault()}>
{/* Submit it empty to see the error. */}
<DatePicker className="w-64" label="Start date" isRequired />
<Button type="submit">Save</Button>
</form>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
labelrequiredVisible label. | string | none |
descriptionHelp text under the field. | string | none |
errorMessageShown when the field is invalid. | string | none |
sizeField height and font size. | "sm" | "md" | "lg" | "md" |
granularitySmallest editable unit. hour/minute add time segments. | "day" | "hour" | "minute" | "day" |
valueControlled value. | DateValue | null | none |
defaultValueInitial value when uncontrolled. | DateValue | none |
minValueEarliest allowed date. | DateValue | none |
maxValueLatest allowed date. | DateValue | none |
isDisabledPrevents editing and dims the field. | boolean | false |
isInvalidMarks the value invalid and shows errorMessage. | boolean | false |
isRequiredRequires a date for form submission. | boolean | false |
onChangeCalled when the date changes. | (value: DateValue | null) => void | none |
Accessibility
Role group, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
- Tab moves between date segments
- Up/Down arrows change the focused segment
- Typing numbers fills segments
- Alt+Down opens the calendar, Esc closes it
Screen readers announce
- The group is announced with its label; each segment with its name and value (month, 3) or as empty
- Up/Down arrows announce each new value
- The calendar button is announced as Calendar
- After picking a date in the calendar, the new date is announced and focus is back in the field
What your code must do
- Label names the group and each segment
- Segment order follows the user's locale
Guidelines
Use it when
- Entering a single date, like a due date or birthday
Avoid it when
- A start and end date: use DateRangePicker
Don't
- A plain text input with a format hint like DD/MM/YYYY
- Forcing calendar clicks for far-away dates like birthdays
- Passing isInvalid for required or format checks (even isInvalid={false}): any defined value takes over validity and hides the built-in errors. Use isRequired and validate; pass isInvalid only for errors the app finds itself, such as from the server
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-surface-default--rd-color-surface-raised--rd-color-border-default--rd-color-border-strong--rd-color-text-default--rd-color-text-muted--rd-color-feedback-danger--rd-color-focus-ring--rd-radius-control--rd-radius-overlay