<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# DatePicker

A labeled date field. With a mouse or trackpad it is a text box you can type the date into (in the locale's numbers, or ISO; a two-digit year is the one within 50 years of today) with a button that opens a `Calendar` in a popover; on a touch screen it is the phone's own date picker (`<input type="date">`). Either way the value is an ISO date (`"2026-10-11"`) and the form submits it under `name`, as a native date input does.

```tsx
import { DatePicker } from "@/components/ouro/calendar/date-picker";
```

## Example

```tsx
<DatePicker label="Delivery date" name="delivery" min="2026-10-11" required error={errors?.delivery} />
<DatePicker label="Birthday" value={birthday} onValueChange={setBirthday} locale="en-GB" />
```

## Use instead when

- Use `Calendar` instead for a calendar always on the page or for a range of dates, and `TextField type="time"` for a time.

## Props

Type: `DatePickerProps`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `chooseDateLabel` | `string` | `"Choose date"` | The name of the button that opens the calendar, as visually hidden text and not an `aria-label`, so a test's `getByLabel("Date")` finds the text box alone. Translate it with your app. |
| `className` | `string` |  | Layout only: margins, width, grid placement (`mt-4`, `col-span-2`). Appearance classes warn in development; style fields in your theme. |
| `closeLabel` | `string` | `"Close"` | The label of the calendar's close button, which only screen readers and the keyboard reach. Translate it with your app. |
| `defaultValue` | `string` |  | The date at first, as an ISO date, when you do not control `value`. |
| `description` | `ReactNode` |  | Supporting text under the label, read after the label through `aria-describedby`. |
| `disabled` | `boolean` |  | Disables the field and its calendar button, and fades it. |
| `error` | `ReadonlyErrorMessages` |  | What is wrong, from your server action or client check. The message (or several, as a list) shows under the field, which gets `aria-invalid`. A message is text or a React node (one with a link); an empty string or array means valid. |
| `hideLabel` | `boolean` |  | Hides the label visually; screen readers still read it as the field's name. |
| `invalidDateMessage` | `string` | `"Enter a valid date."` | The browser's message for typed text that is not a date, or a date `isDateDisabled` names. Translate it with your app. |
| `isDateDisabled` | `((date: string) => boolean)` |  | Marks single days unavailable: `isDateDisabled={(date) => booked.has(date)}`. It gets each day as an ISO date. Such a day, typed or picked in the phone's own picker, is invalid. |
| `label` (required) | `string` |  | What the date is for, shown above the field and read as its name. Required: every control needs a name. To hide it visually, keep it and add `hideLabel`. |
| `locale` | `string` | `"en-US"` | The BCP 47 locale for the calendar and the typed format: `"en-GB"` reads 11/10/2026 as 11 October and starts weeks on Monday. Pass your app's locale; the default is the same on the server and in the browser. Phones show their own picker in the phone's language. |
| `max` | `string` |  | The latest date allowed, as an ISO date. Later days are unavailable in the calendar, and a typed one is invalid. |
| `min` | `string` |  | The earliest date allowed, as an ISO date. Earlier days are unavailable in the calendar, and a typed one is invalid. |
| `name` | `string` |  | The form field name. The form submits the ISO date (`2026-10-11`) under it, or an empty string. |
| `nextMonthLabel` | `string` | `"Next month"` | The calendar's next month button's label. Translate it with your app. |
| `onValueChange` | `((value: string) => void)` |  | Called with the ISO date when the user picks or types an allowed date, and with `""` when the field no longer holds one. A date before `min`, after `max` or named by `isDateDisabled`, typed or chosen in the phone's own picker, is not a value: it reports `""`, and the field shows why and blocks the submit. |
| `outOfRangeMessage` | `string` | `"Enter a date in the allowed range."` | The browser's message for a typed date before `min` or after `max`. Translate it with your app. |
| `placeholder` | `string` |  | An example of what to type, shown while the field is empty: `"MM/DD/YYYY"`. It is not a label. |
| `previousMonthLabel` | `string` | `"Previous month"` | The calendar's previous month button's label. Translate it with your app. |
| `readOnly` | `boolean` |  | The field shows its date but cannot be changed; its calendar button is disabled. |
| `ref` | `Ref<HTMLInputElement>` |  | The input element. |
| `required` | `boolean` |  | A date must be given: the field gets `required` and `aria-required`, and the label a marker. |
| `value` | `string` |  | The date as an ISO date (`"2026-10-11"`), or `""` for none. Pass it with `onValueChange` to control the field. |

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `dateFormat`: Not a prop. The locale sets the format: `<DatePicker locale="en-GB">`.
- `errorMessage`: Not a prop. Ouro UI uses `error`: `<DatePicker error="Required.">`.
- `format`: Not a prop. The locale sets the format: `<DatePicker locale="en-GB">`.
- `helperText`: Not a prop. Ouro UI uses `description`: `<DatePicker description="...">`.
- `invalid`: Not a prop. `error` marks the field invalid: `<DatePicker error="What is wrong">`.
- `isDisabled`: Not a prop. Ouro UI uses `disabled`: `<DatePicker disabled>`.
- `isInvalid`: Not a prop. `error` marks the field invalid: `<DatePicker error="What is wrong">`.
- `isRequired`: Not a prop. Ouro UI uses `required`: `<DatePicker required>`.
- `maxDate`: Not a prop. Ouro UI uses `max`: `<DatePicker max="2026-12-31">`.
- `minDate`: Not a prop. Ouro UI uses `min`: `<DatePicker min="2026-10-11">`.
- `onChange`: Not a prop. Ouro UI uses `onValueChange`, which gets the ISO date: `<DatePicker onValueChange={setDate}>`.
- `selected`: Not a prop. Ouro UI uses `value`: `<DatePicker value={date} onValueChange={setDate}>`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`).

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

## Types

### `ErrorMessage`

One error message: text, or a React element for a message that carries a link or other markup.

```ts
type ErrorMessage = string | ReactElement;
```

### `ReadonlyErrorMessages`

A read-only message view accepted by fields and Form; mutable input arrays remain valid.

```ts
type ReadonlyErrorMessages = ErrorMessage | readonly ErrorMessage[];
```
