Date Input
The catnip-input-date custom element lets users type or pick a single date, date and time, or date range from a floating calendar panel. It uses the same integrated label and supporting-text patterns as Input, Number Input, and Chip Input. Shared field behaviour is summarised on Inputs overview.
Overview
catnip-input-date values are canonical date strings, not UTC timestamps. Single-date values must use YYYY-MM-DD. Date-time values use YYYY-MM-DDTHH:mm without a timezone suffix, so they represent the selected calendar date and time rather than a converted UTC instant. Use display-format only to change the visible text in the input.
Every type uses one combined trigger: leading calendar icon, a single-line text field, optional clear control, and a chevron. The trigger fills the available width; a value longer than the field scrolls inside it. Clicking the field, or pressing Arrow Down, opens the calendar; focusing it does not. Use slot="value" to replace the typed text, or slot="trigger" to replace the whole shell.
- Single date:
model-value/.modelValueis a string inYYYY-MM-DDformat. Calendar selection commits immediately whenshow-timeis off. - Date and time: Set
show-timeto draftYYYY-MM-DDTHH:mmin the panel. Reset / Cancel / Apply confirm the value. - Range: Set
mode="range"to bind{ start?: string; end?: string }. The trigger shows both endpoints separated by an em dash. Date-only range commits when the end date is selected. Date-time range uses the same Apply footer as single date-time. - Range presets: Set
show-presetson range mode for the sidebar (Today, Last 7 days, Custom range, and so on). Named presets show their label in the trigger and switch to their dates while the field has focus, so they can be read and edited; an edit makes the range custom. Custom ranges show the date string. Optionalperiod-presetssubsets, reorders, or relabels the built-ins. Range values may includepreset. - Panel orientation:
panel-orientation="horizontal"(default) pages one month, or two side-by-side months in range mode. Range horizontal panels switch to the stacked vertical layout below 800px.verticalalways stacks a scrollable month list. - Display format: Set
display-formatanddisplay-date-time-formatwith Day.js-style format tokens to change visible input text only. Emitted values stay canonical. - Forgiving typing: Besides the display format, the field accepts other separators (
.,/,-, spaces), digits without separators (27031990), missing leading zeros, and month names, and rewrites the date in the display format on blur. See Specs — Typed input. - Inline clear: Shown by default when the field has a value. Set
show-clear-buttontofalseto hide it. - Constraints: Use
min,max, anddisabled-datesto block invalid calendar cells. In range mode, usemax-range-daysto cap the inclusive number of calendar days between start and end. - Calendar: Month navigation, a clickable month/year header, weekday headers, current/selected/range states, and keyboard navigation for day movement. In range mode the header opens a year grid beside a month grid (stacked in the vertical layout). Single date still opens the year grid only.
Live example
Accessibility
- Label: Use the
labelprop orlabelslot;for/idwiring is handled automatically. - Field: The text field is a combobox with
aria-haspopup="dialog",aria-expanded, andaria-controlspointing at the panel while it is open. It describes its expected format, and named presets add their dates (or, while focused, the preset name) to the description. - Opening: A click opens the panel and leaves focus in the field for typing. Arrow Down (also Alt + Arrow Down) opens it and moves focus in, to the selected preset or the active day. Focusing the field alone never opens the panel.
- Panel: A
role="dialog"named after the field (for example "Start date, Choose date"). It renders right after the field, so reading order and Tab order follow it, and is shown in the top layer so it still paints above dialogs and clipped containers. While focus is inside it isaria-modaland Tab stays inside. - Closing: Escape, Tab from the field, picking a date (single date without time), Apply, Cancel, or a click outside. Focus returns to the field, except after a click outside. With Apply, Escape also discards the draft like Cancel. Without Cancel, a visually hidden Close button lets touch screen reader users dismiss the panel.
- Calendar: Each month is a
role="grid"table named by its month, with full weekday names and the APG date grid keys. The calendar has one Tab stop, on the active day. Unavailable days stay focusable and are announced as unavailable; days outsidemin/maxare disabled. A polite live region confirms range starts, completed ranges, and month changes. - Presets: The preset list is a listbox with one Tab stop; Arrow Up / Arrow Down, Home, and End move, Enter / Space pick. Selected rows use the checkmark appearance.
- Time: Panel time fields are labeled text inputs (
HH:mm), not native time pickers. Range times sit under each month and share the calendar column divider. - Invalid state:
intent="danger"setsaria-invalid="true"on the control;aria-describedbyincludes supporting text when present. - Forced colours: Selection, the range band, today, and focus stay visible in Windows contrast themes.