Elements

Date Pickers

Calendar dates, ranges, and times with native fallbacks and full localization.


Setup

Date picker styles are included in Manifest CSS or a standalone stylesheet, both referencing theme variables.

Date picker functionality is included in manifest.js with all core plugins, or it can be selectively loaded.

<!-- Manifest CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mnfst@latest/lib/manifest.min.css" />

<!-- Manifest JS -->
<script src="https://cdn.jsdelivr.net/npm/mnfst@latest/lib/manifest.min.js"></script>

Field

Native Input

The simplest date field is a native <input type="date">, displaying the browser's built-in picker when pressed. No plugin required.


<input type="date">

Picker Field

For full control over content, format, and styling, add x-date to an input. The plugin renders a themed calendar dropdown under the field and writes the selection back as a localized display value.


<input x-date placeholder="Select a date">

Triggers aren't input-specific — a <button x-date> opens the same dropdown, with its authored text serving as the placeholder until the selection replaces it. Triggers with element children (icons, custom layout) keep their content untouched; display the value yourself with x-model or $date().


<button x-date>Pick a date</button>

Keep the authored type="date" for graceful degradation: until the plugin loads (or if JavaScript is disabled), the browser's native picker serves as the fallback, and its min/max attributes carry over.

<input x-date type="date" min="2026-01-01" max="2026-12-31">

Default Value

Seed the field with a value attribute in ISO format (YYYY-MM-DD) — the same value a native date input would carry.

<input x-date value="2026-06-15">

For two-way reactive binding, use x-model instead. When both are present, x-model wins. The model holds the ISO value; the field displays the localized format.


<div x-data="{ when: '' }">
    <input x-date x-model="when" placeholder="Select a date">
    <span x-text="when"></span>
</div>

Form Participation

Add a name attribute to submit with a <form>. The plugin synthesizes a paired hidden input carrying the ISO value and keeps it in sync. The visible field holds the human-readable format while the form receives the machine-readable one.

<form>
    <input x-date name="event_date" placeholder="Event date">
    <button type="submit">Save</button>
</form>

Time Fields

The input's authored type declares what the field picks. type="time" makes a standalone time picker — a dropdown of hour and minute columns (plus AM/PM in 12-hour locales). type="datetime-local" combines the calendar with a time row.


<!-- Time only -->
<input x-date type="time" placeholder="Pick a time">

<!-- Date + time -->
<input x-date type="datetime-local" placeholder="Pick date & time">

Time-only values are HH:mm strings; datetime values are YYYY-MM-DDTHH:mm. The x-date.time modifier on a plain input is equivalent to type="datetime-local".


Calendar

To author a calendar directly — without a field — place x-date on a container. The wrapper element determines its presentation: <div> renders in the page flow, <menu popover> anchors as a dropdown, and <dialog popover> opens as a modal.


<!-- Inline -->
<div x-date x-model="picked"></div>

<!-- Dropdown -->
<button popovertarget="cal-menu">Choose date</button>
<menu id="cal-menu" popover x-date></menu>

<!-- Dialog -->
<button popovertarget="cal-dialog">Choose date</button>
<dialog id="cal-dialog" popover x-date></dialog>

Clicking the calendar heading jumps to month and year views for fast long-range navigation, the same way native pickers do.


Selection Modes

Range

The x-date.range modifier selects a start and end date. Hovering previews the span before the second click commits it. The model value is a { start, end } object; the form/string value is start/end.


<div x-data="{ stay: { start: '', end: '' } }">
    <input x-date.range x-model="stay" placeholder="Select a range">
</div>

For travel-booking layouts, pair ranges with a multi-month calendar — the months config key (1–4) lays months side by side:


<div x-date.range="{ months: 2 }"></div>

Multiple

The x-date.multiple modifier toggles any number of individual dates. The model value is an array of ISO strings; the form value is comma-separated.


<div x-data="{ dates: [] }">
    <div x-date.multiple x-model="dates"></div>
</div>

Configuration

Pass an object as the directive's value for reactive configuration. All keys are optional and re-evaluate like any Alpine expression.

Key Type Description
months number (1–4) Calendar months displayed side by side. Default 1.
firstDay string | number First weekday override — a name ('monday') or index (0 = Sunday). Defaults to the locale's.
min / max ISO string Selectable bounds. Also read from the input's native min/max attributes.
disabled array | function Unselectable dates — ISO strings, { from, to } spans, or a (date) => boolean predicate.
presets array Quick-pick chips shown in the footer (see below).
now / clear boolean Set false to hide the Today/Now or Clear action. Both default true.

<div x-date="{
    min: '2026-06-01',
    max: '2026-06-30',
    disabled: ['2026-06-13', { from: '2026-06-20', to: '2026-06-22' }]
}"></div>

Presets

Each preset is a labeled value matching the selection mode: { label, value } for single dates, { label, start, end } for ranges, { label, dates } for multiples. Because the config is a live expression, preset values can be computed.


<div x-date.range="{
    presets: [
        { label: 'This weekend', start: '2026-06-13', end: '2026-06-14' },
        { label: 'Next week', start: '2026-06-15', end: '2026-06-21' }
    ]
}"></div>

Keyboard

The day grid is fully keyboard-operable with a single tab stop (the selection, or today).

Key Action
Previous / next day
Previous / next week
PageUp PageDown Previous / next month
Home Start of week
Enter / Space Select the focused day
Escape Close the dropdown

Localization

Calendars localize themselves from the active locale: month and weekday names, first day of the week, date display formats, and the 12/24-hour clock all come from Intl. Switching locale re-renders every calendar, with no configuration needed.

The few built-in UI strings are overridable through the universal _ui block — namespaced under date — in any local data file your project loads. Override only the keys you want; anything omitted stays in English.

{
    "data": {
        "content": {
            "en": "/data/content.en.yaml",
            "fr": "/data/content.fr.yaml"
        }
    }
}
Key Default Used for
today Today Footer jump-to-today action
now Now Time picker's current-time action
clear Clear Footer / time picker clear action
previousMonth Previous month Header arrow label (assistive tech)
nextMonth Next month Header arrow label (assistive tech)
time Time Date+time row label

Because overrides are namespaced per element, one shared _ui block can localize other Manifest elements too (i.e. _ui.colorpicker).


Magic Method

Use the $date(id) magic method to read or change a picker from anywhere on the page. The id is the field's or calendar's element id. Used on its own it returns the primary value as a string.

<input id="event" x-date placeholder="Choose…">
<span x-text="$date('event').iso"></span>
<span x-text="$date('event').formatted"></span>
Property Returns
$date(id) Primary value string — ISO date, start/end, comma list, or HH:mm per mode.
$date(id).iso Same as the primary value.
$date(id).formatted Localized display string.
$date(id).date The selected Date object (single mode).
$date(id).range { start, end } ISO strings (range mode).
$date(id).start / .end Range endpoints individually.
$date(id).dates Array of ISO strings (multiple mode).
$date(id).time HH:mm string when a time is set.
$date(id).mode 'single', 'range', or 'multiple'.
Action Effect
$date(id).setDate(iso) Select a date programmatically.
$date(id).setTime('HH:mm') Set the time of day.
$date(id).clear() Clear the selection.
$date(id).open() / .close() Open or close a field's dropdown.

Styles

Theme

The default calendar uses the following theme variables:

Variable Purpose
--color-popover-surface Calendar background
--color-content-stark Day numbers and primary text
--color-content-subtle Weekday labels, muted text, disabled days
--color-brand-surface / --color-brand-inverse Selected day fill and text
--color-field-surface Hover states and preset chips
--color-line Borders, dividers, and the today ring
--radius Calendar, day, and field corner radius
--spacing-field-height Header and control heights
--transition Hover and focus transitions
--icon-previous / --icon-next Header navigation chevrons (SVG masks)

Tailwind CSS

If using Tailwind, individual fields and calendars can be customized with utility classes.

<input x-date class="max-w-48 rounded-full" placeholder="Compact">
<div x-date class="border border-line shadow-lg"></div>

Customization

Modify base styles with custom CSS targeting [x-date] (or the .date-picker marker class the plugin stamps on every calendar root, which also covers modified directives like x-date.range). The generated markup is semantic HTML, so the inner parts are plain element selectors:

Selector Part
header Month navigation — arrows and heading button
section One calendar month (multi-month layouts)
[role=grid] abbr Weekday labels
[role=grid] button Day cells
[role=listbox] button Month / year jump cells
fieldset Time-of-day row (date+time)
.time-options Hour / minute / AM-PM columns
footer Today, presets, and Clear actions

Day and cell states are attributes and plain classes: [aria-selected=true] (selected), [aria-current=date] (today), :disabled, .outside (adjacent-month days), and .range-start / .range-end / .in-range for range spans.

/* Rounder selected days */
[x-date] [role=grid] button[aria-selected=true],
.date-picker [role=grid] button[aria-selected=true] {
    border-radius: 50%;
}

/* Tone down the range band */
.date-picker [role=grid] button.in-range {
    background: color-mix(in oklch, var(--color-brand-surface) 15%, transparent);
}
: