# Date Picker

**A calendar for picking a single date, several dates, or a range of dates.**

**Reference:** [View Source](https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Primitives/DatePicker) · [Zag.js Docs](https://zagjs.com/components/react/date-picker)

**DatePickerExamples.html**

```html
<ui:datePicker.root class="max-w-74">
    <ui:datePicker.label>Date</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader />
                    <ui:datePicker.tableBody />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
</ui:datePicker.root>

```

## Features

- Single, multiple, and range selection
- Day, month, and year views, switched from the calendar heading, or a picker for months or years only
- Dates can be typed into the input, in the format of the `locale`
- Keyboard navigation with the arrow keys, `Home`, `End`, `PageUp`, and `PageDown`
- Minimum and maximum dates, and a check for dates that are unavailable
- Range presets, like "last 7 days"
- Formats dates and localizes its labels for the site language
- Submits dates Extbase maps to a `DateTime`, whatever format the input shows
- Works with Field component for form integration
- Opens in a popup, or renders inline without one

## Anatomy

```html
<primitives:datePicker.root>
    <primitives:datePicker.label />
    <primitives:datePicker.control>
        <primitives:datePicker.input />
        <primitives:datePicker.clearTrigger />
        <primitives:datePicker.trigger />
    </primitives:datePicker.control>
    <primitives:datePicker.hiddenInput />
    <primitives:datePicker.positioner>
        <primitives:datePicker.content>
            <primitives:datePicker.view view="day">
                <primitives:datePicker.viewControl view="day">
                    <primitives:datePicker.prevTrigger view="day" />
                    <primitives:datePicker.viewTrigger view="day">
                        <primitives:datePicker.rangeText />
                    </primitives:datePicker.viewTrigger>
                    <primitives:datePicker.nextTrigger view="day" />
                </primitives:datePicker.viewControl>
                <primitives:datePicker.table view="day">
                    <primitives:datePicker.tableHeader />
                    <primitives:datePicker.tableBody />
                </primitives:datePicker.table>
            </primitives:datePicker.view>
            <primitives:datePicker.monthSelect />
            <primitives:datePicker.yearSelect />
            <primitives:datePicker.presetTrigger />
        </primitives:datePicker.content>
    </primitives:datePicker.positioner>
</primitives:datePicker.root>
```

The calendar has three views: `day`, `month`, and `year`. The `content` only holds what you put into it, so you render the views you need yourself, each in a `view` with its controls and its `table`. Every example on this page loops over the views; write them out one by one if the views differ. The `tableHeader` and `tableBody` belong to the `table` they sit in. Its cells, the weekday headings, and the options of `monthSelect` and `yearSelect` are not part of the markup you write: they depend on the locale and on the month shown, so the client builds them. Because of that, the grid of an `inline` date picker is empty until it hydrates: `showSkeleton="{true}"` on the `tableHeader` and the `tableBody` of the day view fills the gap with a placeholder (see [Inline](#inline)).

## Installation

```bash
typo3 ui:add date-picker
```

Or copy the files manually from GitHub (https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Registry/DatePicker) into your project.

Read more about installing [Components and Primitives](/docs/core-concepts/primitives.md).

## Examples

### Default Value

Pass `defaultValue` as an ISO date (`2025-06-15`), a `DateTimeInterface`, or a list of them. A Field inside a Form that is bound to an object takes the value of the property the field is named after.

**DatePickerExamples.html**

```html
<ui:datePicker.root class="max-w-74" defaultValue="2025-06-15">
    <ui:datePicker.label>Date</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input />
        <ui:datePicker.clearTrigger />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader />
                    <ui:datePicker.tableBody />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
</ui:datePicker.root>

```

### With Form Field

Use with the Field component for form validation.

**DatePickerExamples.html**

```html
<ui:field.root class="max-w-74" name="birthDate" required="{true}">
    <ui:datePicker.root>
        <ui:datePicker.label>Date of birth</ui:datePicker.label>
        <ui:datePicker.control>
            <ui:datePicker.input />
            <ui:datePicker.trigger />
        </ui:datePicker.control>
        <ui:datePicker.content>
            <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
                <ui:datePicker.view view="{view}">
                    <ui:datePicker.viewControl view="{view}">
                        <ui:datePicker.prevTrigger view="{view}" />
                        <ui:datePicker.viewTrigger view="{view}">
                            <ui:datePicker.rangeText />
                        </ui:datePicker.viewTrigger>
                        <ui:datePicker.nextTrigger view="{view}" />
                    </ui:datePicker.viewControl>
                    <ui:datePicker.table view="{view}">
                        <ui:datePicker.tableHeader />
                        <ui:datePicker.tableBody />
                    </ui:datePicker.table>
                </ui:datePicker.view>
            </f:for>
        </ui:datePicker.content>
    </ui:datePicker.root>
    <ui:field.errorText />
</ui:field.root>

```

### Range Selection

Set `selectionMode` to `DatePickerSelectionMode::Range` (an enum, so `selectionMode="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerSelectionMode::Range')}"`) and add an `input` for each end of the range with its `index`. The `presetTrigger` selects a range with one click. Its `value` is a case of the `DatePickerRangePreset` enum (`value="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerRangePreset::Last7Days')}"`): `ThisWeek`, `LastWeek`, `ThisMonth`, `LastMonth`, `ThisQuarter`, `LastQuarter`, `ThisYear`, `LastYear`, `Last3Days`, `Last7Days`, `Last14Days`, `Last30Days`, or `Last90Days`.

**DatePickerExamples.html**

```html
<ui:datePicker.root class="max-w-96" selectionMode="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerSelectionMode::Range')}">
    <ui:datePicker.label>Stay</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input index="0" />
        <span class="text-muted-foreground">–</span>
        <ui:datePicker.input index="1" />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader />
                    <ui:datePicker.tableBody />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
        <div class="mt-3 flex flex-wrap gap-2 border-t pt-3">
            <ui:datePicker.presetTrigger value="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerRangePreset::ThisWeek')}">This week</ui:datePicker.presetTrigger>
            <ui:datePicker.presetTrigger value="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerRangePreset::ThisMonth')}">This month</ui:datePicker.presetTrigger>
            <ui:datePicker.presetTrigger value="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerRangePreset::Last7Days')}">Last 7 days</ui:datePicker.presetTrigger>
        </div>
    </ui:datePicker.content>
</ui:datePicker.root>

```

### Multiple Selection

Set `selectionMode` to `DatePickerSelectionMode::Multiple` and limit the number of dates with `maxSelectedDates`. The input shows the first date only, so the example lists all of them below it, with an `onValueChange` callback it gives the `DatePicker` in its entry file (see [Unavailable Dates](#unavailable-dates)).

**DatePickerExamples.html**

```html
<ui:datePicker.root
    class="max-w-74"
    selectionMode="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerSelectionMode::Multiple')}"
    maxSelectedDates="3"
    autoMount="{false}"
    rootId="date-picker-multiple">
    <ui:datePicker.label>Dates (up to 3)</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input />
        <ui:datePicker.clearTrigger />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader />
                    <ui:datePicker.tableBody />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
    <p id="date-picker-multiple-dates" class="text-muted-foreground text-sm">No dates selected</p>
</ui:datePicker.root>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/DatePickerExamples/Multiple.entry.ts" />

```

**Multiple.entry.ts**

```ts
import { mount } from 'fluid-primitives';
import { DatePicker } from 'fluid-primitives/date-picker';

mount('ui:datePicker', 'date-picker-multiple', ({ props }) => {
    const datePicker = new DatePicker({
        ...props,
        // The input shows the first date only, so every selected date is listed below it.
        onValueChange: ({ valueAsString }) => {
            const datesEl = document.getElementById('date-picker-multiple-dates');
            if (datesEl) datesEl.textContent = valueAsString.join(', ') || 'No dates selected';
        },
    });
    datePicker.init();
    return datePicker;
});

```

### Multiple Months

`numOfMonths` shows several months of the day view next to each other. Render one `table` per month in the day view, with the `offset` of the month it shows (`0` for the first, `1` for the next). The example keeps the offsets in a `months` variable, so the same list sets `numOfMonths` and drives the loop. The month and year views always show a single table. The `ui` copy of `content` hides the days outside the visible month when `numOfMonths` is above `1`, so no day shows up in two neighbouring months.

**DatePickerExamples.html**

```html
<f:variable name="months" value="{0: 0, 1: 1}" />

<ui:datePicker.root class="max-w-96" numOfMonths="{months -> f:count()}" selectionMode="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerSelectionMode::Range')}">
    <ui:datePicker.label>Stay</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input index="0" />
        <span class="text-muted-foreground">–</span>
        <ui:datePicker.input index="1" />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <f:if condition="{view} == 'day'">
                    <f:then>
                        <div class="flex gap-4">
                            <f:for each="{months}" as="offset">
                                <ui:datePicker.table view="day" offset="{offset}">
                                    <ui:datePicker.tableHeader />
                                    <ui:datePicker.tableBody />
                                </ui:datePicker.table>
                            </f:for>
                        </div>
                    </f:then>
                    <f:else>
                        <ui:datePicker.table view="{view}">
                            <ui:datePicker.tableHeader />
                            <ui:datePicker.tableBody />
                        </ui:datePicker.table>
                    </f:else>
                </f:if>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
</ui:datePicker.root>

```

### Min/Max Constraints

Restrict the dates that can be selected with `min` and `max`, each an ISO date (`2025-06-15`) or a `DateTimeInterface`, like a date of your model. `defaultFocusedValue` takes the same.

**DatePickerExamples.html**

```html
<ui:datePicker.root
    class="max-w-74"
    min="{f:format.date(date: 'now', format: 'Y-m-d')}"
    max="{f:format.date(date: '+30 days', format: 'Y-m-d')}">
    <ui:datePicker.label>Appointment (within the next 30 days)</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader />
                    <ui:datePicker.tableBody />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
</ui:datePicker.root>

```

### Inline

Render the calendar in the page, without a popup, with `inline="{true}"`. It is always open and needs no `control`.

**DatePickerExamples.html**

```html
<ui:datePicker.root inline="{true}" class="w-fit">
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader showSkeleton="{view == 'day' ? true : false}" />
                    <ui:datePicker.tableBody showSkeleton="{view == 'day' ? true : false}" />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
</ui:datePicker.root>

```

### Unavailable Dates

`isDateUnavailable`, `format`, `parse`, `createCalendar`, and the `on...Change` callbacks are functions, so a template can't pass them. Create the `DatePicker` in your entry file instead and hand them to it with the other props. Here the weekends are unavailable.

**DatePickerExamples.html**

```html
<ui:datePicker.root class="max-w-74" autoMount="{false}" rootId="date-picker-unavailable-dates">
    <ui:datePicker.label>Delivery date</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'day', 1: 'month', 2: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader />
                    <ui:datePicker.tableBody />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
</ui:datePicker.root>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/DatePickerExamples/UnavailableDates.entry.ts" />

```

**UnavailableDates.entry.ts**

```ts
import { isWeekend } from '@internationalized/date';
import { mount } from 'fluid-primitives';
import { DatePicker } from 'fluid-primitives/date-picker';

mount('ui:datePicker', 'date-picker-unavailable-dates', ({ props }) => {
    const datePicker = new DatePicker({
        ...props,
        // A function can't travel from the template to the client, so it is passed here.
        isDateUnavailable: (date, locale) => isWeekend(date, locale),
    });
    datePicker.init();
    return datePicker;
});

```

### Month and Year Picker

Set `minView` to `DatePickerView::Month` to pick a month instead of a day, and `defaultView` to open on the month view. The picked month is its first day, so the `hiddenInput` submits the first of the month. Render only the views the calendar can reach: the day view is left out here. `format` and `parse` turn the input into `06/2025` and read it back. They are functions, so they come from the entry file as in [Unavailable Dates](#unavailable-dates), and `placeholder` tells people what to type.

**DatePickerExamples.html**

```html
<ui:datePicker.root
    class="max-w-74"
    defaultView="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerView::Month')}"
    minView="{f:constant(name: 'Jramke\FluidPrimitives\Enum\DatePickerView::Month')}"
    placeholder="mm/yyyy"
    autoMount="{false}"
    rootId="date-picker-month-year">
    <ui:datePicker.label>Card expires</ui:datePicker.label>
    <ui:datePicker.control>
        <ui:datePicker.input />
        <ui:datePicker.trigger />
    </ui:datePicker.control>
    <ui:datePicker.content>
        <f:for each="{0: 'month', 1: 'year'}" as="view">
            <ui:datePicker.view view="{view}">
                <ui:datePicker.viewControl view="{view}">
                    <ui:datePicker.prevTrigger view="{view}" />
                    <ui:datePicker.viewTrigger view="{view}">
                        <ui:datePicker.rangeText />
                    </ui:datePicker.viewTrigger>
                    <ui:datePicker.nextTrigger view="{view}" />
                </ui:datePicker.viewControl>
                <ui:datePicker.table view="{view}">
                    <ui:datePicker.tableHeader />
                    <ui:datePicker.tableBody />
                </ui:datePicker.table>
            </ui:datePicker.view>
        </f:for>
    </ui:datePicker.content>
</ui:datePicker.root>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/DatePickerExamples/MonthYear.entry.ts" />

```

**MonthYear.entry.ts**

```ts
import { CalendarDate } from '@internationalized/date';
import { mount } from 'fluid-primitives';
import { DatePicker } from 'fluid-primitives/date-picker';

mount('ui:datePicker', 'date-picker-month-year', ({ props }) => {
    const datePicker = new DatePicker({
        ...props,
        // The input shows `06/2025`, the hidden input still submits the first of the month (`2025-06-01`).
        format: date => `${String(date.month).padStart(2, '0')}/${date.year}`,
        parse: value => {
            const match = /^(\d{1,2})\/(\d{4})$/.exec(value);
            if (!match) return undefined;

            const month = Number(match[1]);
            return month >= 1 && month <= 12
                ? new CalendarDate(Number(match[2]), month, 1)
                : undefined;
        },
    });
    datePicker.init();
    return datePicker;
});

```

For a year picker, use `DatePickerView::Year` for `minView` and `defaultView`, render the `year` view only, and let `format` return `String(date.year)` and `parse` return `new CalendarDate(year, 1, 1)`.

### Dates in forms

The `hiddenInput` submits each selected date as the W3C date-time of its midnight (`2025-06-15T00:00:00+02:00`), whatever format the `locale` shows it in. The visible `input` has no `name` and is not submitted, and `ui:datePicker.root` renders the `hiddenInput` for you. A range or several dates submit one value per date under the same `name`, so end the name with `[]` (`dates[]`) for PHP to receive all of them. A date picker without a date submits an empty value.

That is the format Extbase maps to a `DateTime` property without any configuration. The offset is the one of the time zone PHP runs in, so the property holds the date that was picked: Extbase converts any other offset to that time zone, which can move the date to the day before or after. Extbase maps a request value to a `DateTime` only: it reads a `DateTimeImmutable` from the database, but has no type converter for one from a request. Type the property `DateTime`, or write a custom type converter for `DateTimeImmutable` if you need it. Outside Extbase, `new DateTimeImmutable($_POST['date'])` reads the value.

### Time zone

The calendar works in the time zone of the browser: it highlights today for the person looking at it, and the presets and `min`/`max` count from there. Zag falls back to UTC without a `timeZone`, which highlights the wrong day for a few hours of the day almost everywhere, so Fluid Primitives replaces that default. Set `timeZone` (`Europe/Berlin`) to use another one, like the time zone of a venue. The submitted dates carry the offset of the time zone PHP runs in, whatever `timeZone` is, so it never changes what is submitted.

### Localization

Dates are formatted for the language of the site, or for the `locale` you pass. Every label, from the buttons and the day cells to the month and year select and the placeholder of the input, is shipped via XLF in English and German and follows the current Site Language. They are the `datePicker.*` units of the language file. Some contain a `%placeholder%` that is filled in when the label renders, like the `%date%` of a day cell.

For per-template overrides, pass translated strings through the `translations` prop, by the id of the unit without `datePicker.`.

```html
<ui:datePicker.root
    translations="{
        clearTrigger: f:translate(key: 'LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:datePicker.clear'),
        dayCell: 'Pick %date%'
    }"
>
    ...
</ui:datePicker.root>
```

The client builds the labels Zag wants as functions of the date or the view from these texts. To change one of those from TypeScript, spread the translations your entry file receives and override it the way Zag takes it:

```ts
const datePicker = new DatePicker({
    ...props,
    translations: { ...props.translations, dayCell: state => `Pick ${state.valueText}` },
});
```

## API Reference

### datePicker.root

Provides shared date picker state and wraps all related parts. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `locale` | `string` | No | `-` | The locale (BCP 47 language tag) used to format and parse dates. Inherited from the site's language. |
| `timeZone` | `string` | No | `-` | The IANA time zone dates are evaluated in, e.g. `Europe/Berlin`. Defaults to the time zone of the browser. |
| `name` | `string` | No | `-` | The `name` attribute of the underlying input. Inherited from a surrounding field when available. |
| `disabled` | `boolean` | No | `-` | Whether the date picker is disabled. Inherited from a surrounding field when available. |
| `readOnly` | `boolean` | No | `-` | Whether the date picker is read-only. Inherited from a surrounding field when available. |
| `required` | `boolean` | No | `-` | Whether the date picker is required. Inherited from a surrounding field when available. |
| `invalid` | `boolean` | No | `-` | Whether the date picker is invalid. Inherited from a surrounding field when available. |
| `outsideDaySelectable` | `boolean` | No | `false` | Whether a day outside the visible month can be selected. |
| `min` | `DateTimeInterface\|string` | No | `-` | The minimum date that can be selected: an ISO date string (`2025-01-31`) or a `DateTimeInterface`. |
| `max` | `DateTimeInterface\|string` | No | `-` | The maximum date that can be selected: an ISO date string (`2025-01-31`) or a `DateTimeInterface`. |
| `closeOnSelect` | `boolean` | No | `true` | Whether the calendar should close after the date selection is complete. Ignored when `selectionMode` is `multiple`. |
| `openOnClick` | `boolean` | No | `false` | Whether to open the calendar when the input is clicked. |
| `defaultValue` | `DateTimeInterface\|string\|array` | No | `-` | The initial selected date(s) when rendered: an ISO date string (`2025-01-31`), a `DateTimeInterface`, or a list of them. Use when you don't need to control the selected date(s) of the date picker. Inherited from a surrounding field when available. |
| `defaultFocusedValue` | `DateTimeInterface\|string` | No | `-` | The initially focused date when rendered: an ISO date string or a `DateTimeInterface`. Use when you don't need to control the focused date of the date picker. |
| `numOfMonths` | `integer` | No | `-` | The number of months the day view shows next to each other. |
| `startOfWeek` | `integer` | No | `1` | The first day of the week. `0` is Sunday, `1` is Monday, and so on. |
| `fixedWeeks` | `boolean` | No | `-` | Whether the calendar should render with a fixed number of weeks (6), instead of 5 or 6 depending on the month. |
| `showWeekNumbers` | `boolean` | No | `-` | Whether to show the week number column in the day view. |
| `selectionMode` | `Enum\DatePickerSelectionMode` | No | `Single` | The selection mode of the calendar: `single`, `multiple`, or `range`. |
| `maxSelectedDates` | `integer` | No | `-` | The maximum number of dates that can be selected. Only applicable when `selectionMode` is `multiple`. |
| `placeholder` | `string` | No | `-` | The placeholder text of the input. Defaults to the date format of the `locale`, e.g. `dd.mm.yyyy`. |
| `defaultView` | `Enum\DatePickerView` | No | `Day` | The view the calendar starts in: `day`, `month`, or `year`. |
| `minView` | `Enum\DatePickerView` | No | `Day` | The smallest view of the calendar. `month` turns it into a month picker. |
| `maxView` | `Enum\DatePickerView` | No | `Year` | The largest view of the calendar. |
| `positioning` | `array` | No | `{     "placement": "bottom-start",     "gutter": 8 }` | The positioning options of the calendar content. |
| `defaultOpen` | `boolean` | No | `false` | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. |
| `inline` | `boolean` | No | `false` | Whether to render the calendar in the page, without a popup. It is always open and has no trigger. |
| `translations` | `array` | No | `-` | Localized date picker labels, by the id of the `datePicker.*` units of the language file. Use `f:translate` for per-template localization overrides when needed. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `rootId` | `string` | No | `-` | The root ID of the component, used for hydration and identification. |
| `ids` | `array` | No | `[]` | The IDs of of the component parts for composition. |
| `autoMount` | `boolean` | No | `true` | Whether the client initializes the component on its own. Set it to false to mount it yourself with `mount()` |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-root` | <uid> |
| `data-state` | "open" \| "closed" |
| `data-disabled` | Present when disabled |
| `data-readonly` | Present when read-only |
| `data-empty` | Present when the content is empty |

### datePicker.label

Labels an input. Renders a `<label>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `index` | `integer` | No | `0` | The index of the input this label is for, in range mode (`0` or `1`). |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-label` | <uid> |
| `data-state` | "open" \| "closed" |
| `data-index` | The index of the item |
| `data-disabled` | Present when disabled |
| `data-readonly` | Present when read-only |
| `data-invalid` | Present when invalid |

### datePicker.control

Groups the input and the triggers. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-control` | <uid> |
| `data-disabled` | Present when disabled |
| `data-placeholder-shown` | Present when placeholder is shown |
| `data-invalid` | Present when invalid |

### datePicker.input

Shows the selected date as text and lets people type one. Renders an `<input>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `index` | `integer` | No | `0` | The index of this input, in range mode (`0` or `1`). |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-input` | <uid> |
| `data-index` | The index of the item |
| `data-state` | "open" \| "closed" |
| `data-placeholder-shown` | Present when placeholder is shown |
| `data-invalid` | Present when invalid |

### datePicker.clearTrigger

Clears the selection. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### datePicker.trigger

Opens and closes the calendar. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-trigger` | <uid> |
| `data-placement` | The placement of the trigger |
| `data-side` | The side of the trigger that the trigger is positioned on |
| `data-state` | "open" \| "closed" |
| `data-placeholder-shown` | Present when placeholder is shown |

### datePicker.hiddenInput

Submits the selected dates as W3C date-times, one input per date. Renders `<input type="hidden">` elements.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

### datePicker.positioner

Positions the floating calendar. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-positioner` | <uid> |
| `data-nested` | Present when the positioner is nested within another {{widget}} |
| `data-has-nested` | Present when the positioner has nested {{widget}}s |

### datePicker.content

The calendar surface, positioned by `positioner`. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-content` | <uid> |
| `data-state` | "open" \| "closed" |
| `data-placement` | The placement of the content |
| `data-side` | The side of the trigger that the content is positioned on |
| `data-inline` | Present when the content is inline |
| `data-nested` | popover |
| `data-has-nested` | popover |

### datePicker.view

Wraps one view of the calendar: `day`, `month`, or `year`. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `view` | `string` | Yes | `-` | The view this element renders: `day`, `month`, or `year`. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-view` | <uid> |
| `data-view` | The view of the view |

### datePicker.viewControl

Groups the buttons that move through a view. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `view` | `string` | Yes | `-` | The view this element controls: `day`, `month`, or `year`. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-view-control` | <uid> |
| `data-view` | The view of the viewcontrol |

### datePicker.prevTrigger

Moves a view back: to the previous month, year, or decade. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `view` | `string` | Yes | `-` | The view this element navigates: `day`, `month`, or `year`. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-prev-trigger` | <uid> |
| `data-disabled` | Present when disabled |

### datePicker.nextTrigger

Moves a view forward: to the next month, year, or decade. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `view` | `string` | Yes | `-` | The view this element navigates: `day`, `month`, or `year`. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-next-trigger` | <uid> |
| `data-disabled` | Present when disabled |

### datePicker.viewTrigger

Switches to the next larger view. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `view` | `string` | Yes | `-` | The view this element switches away from: `day`, `month`, or `year`. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-view-trigger` | <uid> |
| `data-view` | The view of the viewtrigger |
| `data-disabled` | Present when disabled |

### datePicker.rangeText

Shows the range of dates a view displays, like "June 2025". Renders a `<span>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### datePicker.table

Wraps the grid of a view. Renders a `<table>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `view` | `string` | No | `'day'` | The view this table renders: `day`, `month`, or `year`. |
| `offset` | `integer` | No | `0` | Which month of the day view this table shows, counted from the first visible month: `0` for the first, `1` for the next. Only used with `numOfMonths` above `1`. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-table` | <uid> |
| `data-columns` |  |
| `data-view` | The view of the table |

### datePicker.tableHeader

Holds the weekday headings of the day view, built on the client. Renders a `<thead>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-table-header` | <uid> |
| `data-view` | The view of the tableheader |
| `data-disabled` | Present when disabled |

### datePicker.tableBody

Holds the days, months, or years of a view, built on the client. Renders a `<tbody>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-date-picker-table-body` | <uid> |
| `data-view` | The view of the tablebody |
| `data-disabled` | Present when disabled |

### datePicker.monthSelect

Jumps to a month, its options built on the client. Renders a `<select>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### datePicker.yearSelect

Jumps to a year, its options built on the client. Renders a `<select>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### datePicker.presetTrigger

Selects a predefined range of dates. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `Enum\DatePickerRangePreset` | Yes | `-` | The range the preset selects, like `DatePickerRangePreset::Last7Days`. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### Machine JavaScript API

| Name | Type | Description |
| --- | --- | --- |
| `focused` | `boolean` | Whether the input is focused |
| `open` | `boolean` | Whether the date picker is open |
| `disabled` | `boolean` | Whether the date picker is disabled |
| `invalid` | `boolean` | Whether the date picker is invalid |
| `readOnly` | `boolean` | Whether the date picker is read-only |
| `inline` | `boolean` | Whether the date picker is rendered inline |
| `numOfMonths` | `number` | The number of months to display |
| `showWeekNumbers` | `boolean` | Whether the week number column is shown in the day view |
| `selectionMode` | `SelectionMode` | The selection mode (single, multiple, or range) |
| `maxSelectedDates` | `number \| undefined` | The maximum number of dates that can be selected (only for multiple selection mode). |
| `isMaxSelected` | `boolean` | Whether the maximum number of selected dates has been reached. |
| `view` | `DateView` | The current view of the date picker |
| `getWeekNumber` | `(week: DateValue[]) => number` | Returns the ISO 8601 week number (1-53) for the given week (array of dates). |
| `getDaysInWeek` | `(week: number, from?: DateValue) => DateValue[]` | Returns an array of days in the week index counted from the provided start date, or the first visible date if not given. |
| `getOffset` | `(duration: DateDuration) => DateValueOffset` | Returns the offset of the month based on the provided number of months. |
| `getRangePresetValue` | `(value: DateRangePreset) => DateValue[]` | Returns the range of dates based on the provided date range preset. |
| `getMonthWeeks` | `(from?: DateValue) => DateValue[][]` | Returns the weeks of the month from the provided date. Represented as an array of arrays of dates. |
| `isUnavailable` | `(date: DateValue) => boolean` | Returns whether the provided date is available (or can be selected) |
| `weeks` | `DateValue[][]` | The weeks of the month. Represented as an array of arrays of dates. |
| `weekDays` | `WeekDay[]` | The days of the week. Represented as an array of strings. |
| `visibleRange` | `VisibleRange` | The visible range of dates. |
| `visibleRangeText` | `VisibleRangeText` | The human readable text for the visible range of dates. |
| `value` | `DateValue[]` | The selected date. |
| `valueAsDate` | `Date[]` | The selected date as a Date object. |
| `valueAsString` | `string[]` | The selected date as a string. |
| `focusedValue` | `DateValue` | The focused date. |
| `focusedValueAsDate` | `Date` | The focused date as a Date object. |
| `focusedValueAsString` | `string` | The focused date as a string. |
| `selectToday` | `VoidFunction` | Sets the selected date to today. |
| `setValue` | `(values: DateValue[]) => void` | Sets the selected date to the given date. |
| `setTime` | `(time: Time, index?: number) => void` | Sets the time for a specific date value. Converts CalendarDate to CalendarDateTime if needed. |
| `setFocusedValue` | `(value: DateValue) => void` | Sets the focused date to the given date. |
| `clearValue` | `(options?: { focus?: boolean }) => void` | Clears the selected date(s). |
| `setOpen` | `(open: boolean) => void` | Function to open or close the calendar. |
| `focusMonth` | `(month: number) => void` | Function to set the selected month. |
| `focusYear` | `(year: number) => void` | Function to set the selected year. |
| `getYears` | `() => Cell[]` | Returns the months of the year |
| `getYearsGrid` | `(props?: YearGridProps) => YearGridValue` | Returns the years of the decade based on the columns. Represented as an array of arrays of years. |
| `getDecade` | `() => Range<number \| undefined>` | Returns the start and end years of the decade. |
| `getMonths` | `(props?: MonthFormatOptions) => Cell[]` | Returns the months of the year |
| `getMonthsGrid` | `(props?: MonthGridProps) => MonthGridValue` | Returns the months of the year based on the columns. Represented as an array of arrays of months. |
| `format` | `(value: DateValue, opts?: Intl.DateTimeFormatOptions) => string` | Formats the given date value based on the provided options. |
| `setView` | `(view: DateView) => void` | Sets the view of the date picker. |
| `goToNext` | `VoidFunction` | Goes to the next month/year/decade. |
| `goToPrev` | `VoidFunction` | Goes to the previous month/year/decade. |
| `getDayTableCellState` | `(props: DayTableCellProps) => DayTableCellState` | Returns the state details for a given cell. |
| `getMonthTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given month cell. |
| `getYearTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given year cell. |
| `getRootState` | `() => RootState` | Returns the state of the root. |
| `getContentState` | `() => ContentState` | Returns the state of the content. |
| `getTriggerState` | `() => TriggerState` | Returns the state of the trigger. |
| `getInputState` | `() => InputState` | Returns the state of the input. |

### Accessibility

| Key | Description |
| --- | --- |
| `ArrowLeft`  | Moves focus to the previous day within the current week. |
| `ArrowRight`  | Moves focus to the next day within the current week. |
| `ArrowUp`  | Moves focus to the same day of the week in the previous week. |
| `ArrowDown`  | Moves focus to the same day of the week in the next week. |
| `Home`  | Moves focus to the first day of the current month. |
| `End`  | Moves focus to the last day of the current month. |
| `PageUp`  | Moves focus to the same day of the month in the previous month. |
| `PageDown`  | Moves focus to the same day of the month in the next month. |
| `Enter`  | Selects the focused date and closes the date picker. |
| `Esc`  | Closes the date picker without selecting any date. |
