A typed DD/MM/YYYY field with a calendar popover, min/max and a date-of-birth preset.
DateField accepts typing (DD/MM/YYYY, day first) or picking from Calendar. preset="dob" opens on a sensible year with a year dropdown, for dates decades back.
Installation
npx shadcn@latest add KezLahd/rime/date-fieldAlso installs: base, field, icon, text-input.
Usage
import { DateField } from "@/components/ui";
<Field label="Due date"><DateField value={due} onChange={setDue} /></Field>Examples
Open
October 2026
Default
API
Generated from the component's TypeScript types and JSDoc (scripts/gen-ui-registry.mjs), so it always matches the source.
DateField
| Prop | Type | Default | Description |
|---|---|---|---|
| valueRequired | IsoDate | null | ||
| onChangeRequired | (value: IsoDate | null) => void | null when cleared or when the typed text is not a usable date. | |
| isDateDisabled | (date: IsoDate) => boolean | ||
| min | IsoDate | ||
| max | IsoDate | ||
| defaultMonth | IsoDate | Month the calendar opens on when empty. For a date of birth, pass ~40 years ago (or use preset="dob"). | |
| preset | "dob" | dob: a date of birth, set up as a sign-up form does it. Month and Year dropdowns in the calendar, years 1920 to this year, no future dates, and an empty field opens 40 years back. Any prop passed explicitly wins over the preset. | |
| captionLayout | "label" | "dropdown" | The calendar's caption. dropdown gives Month ▾ and Year ▾ quick pickers; see Calendar. | |
| fromYear | number | Year span of the Year picker (dropdown caption only). | |
| toYear | number | ||
| invalid | boolean | ||
| disabled | boolean | ||
| required | boolean | ||
| id | string | ||
| name | string | ||
| placeholder | string | "DD/MM/YYYY" | |
| aria-label | string | ||
| className | string | ||
| inline | boolean | false | Show the calendar open, in place under the field: no portal, no focus move, no outside-click listener. For docs and thumbnails. |
Calendar
| Prop | Type | Default | Description |
|---|---|---|---|
| isDateDisabled | (date: IsoDate) => boolean | Days that cannot be picked. Still focusable, so keyboard users can pass over them. | |
| min | IsoDate | ||
| max | IsoDate | ||
| defaultMonth | IsoDate | Month shown first when there is no value. Defaults to today's month. | |
| autoFocus | boolean | Moves focus into the grid on mount (used by DateField's popup). | |
| numberOfMonths | 1 | 2 | 1 | 2 | 1 | Months side by side. Navigation moves them together. |
| captionLayout | "label" | "dropdown" | "label" | "dropdown" | "label" | label: the month and year as a heading, with month and year arrows. dropdown: Month ▾ and Year ▾ buttons that open quick pickers, for dates years away such as a date of birth (a sign-up form). Month arrows stay. Two-month calendars always use labels. |
| fromYear | number | First and last years the Year picker lists (dropdown only). Default to min's and max's years, else 100 years back and 10 on. They also bound the arrows and keyboard paging, so the grid never shows a year the picker lacks. | |
| toYear | number | ||
| className | string | ||
| valueRequired | IsoDate | null | never | ||
| onChangeRequired | (value: IsoDate) => void | never | ||
| range | never | DateRange | Range mode. After a start is picked, hovering or arrowing previews the range. | |
| onRangeChange | never | (range: DateRange) => void |
Theme tokens
Per-component tokens are undeclared by default, so the default shown is the fallback the CSS uses. Set one at :root (or in theme.css) to restyle every instance. Live values are read from this page, so they follow the Rime Studio.
| Token | Default | Live value |
|---|---|---|
| --field-focus-border | rgba(var(--rgb-brand), 0.7) / var(--focus-color) | … |
| --field-focus-ring | var(--focus-halo) | … |
System tokens it reads
| Token | Default | Live value |
|---|---|---|
| --brand | tokens.css | … |
| --brand-gradient | tokens.css | … |
| --danger-ink | tokens.css | … |
| --dur | tokens.css | … |
| --dur-fast | tokens.css | … |
| --ease | tokens.css | … |
| --ease-out | tokens.css | … |
| --focus-color | tokens.css | … |
| --focus-halo | tokens.css | … |
| --focus-ring | tokens.css | … |
| --font-body | tokens.css | … |
| --glow-sm | tokens.css | … |
| --ink-body | tokens.css | … |
| --ink-brand | tokens.css | … |
| --ink-disabled | tokens.css | … |
| --ink-heading | tokens.css | … |
| --ink-inverse | tokens.css | … |
| --ink-muted | tokens.css | … |
| --line | tokens.css | … |
| --line-brand | tokens.css | … |
| --line-brand-strong | tokens.css | … |
| --r-xl | tokens.css | … |
| --r-xs | tokens.css | … |
| --rgb-brand | tokens.css | … |
| --rgb-brand-deep | tokens.css | … |
| --shadow-float | tokens.css | … |
| --surface-solid | tokens.css | … |
| --text-micro | tokens.css | … |
| --wash-active | tokens.css | … |
| --wash-hover | tokens.css | … |
| --wash-strong | tokens.css | … |
| --wash-subtle | tokens.css | … |
| --z-popover | tokens.css | … |
Accessibility
- The calendar is a grid with arrow-key navigation; Esc returns focus to the field.
Do and don't
Do
- Always let people type a date of birth; never force a calendar for it.
Don't
- Don't mix date orders within one product.
For AI agents
This page as markdown, rendered from the same registry entry. Point an agent at it (or add .md to this page's URL), or at /llms.txt for the index.
Open date-field.md