Skip to content

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, typed value, optional clear control, and a chevron. The trigger fills the available width so the value can stay on one line; if the container is too narrow (typical for date-time ranges), the value wraps and the field grows in height. Use slot="value" to replace the typed text, or slot="trigger" to replace the whole shell.

  • Single date: model-value / .modelValue is a string in YYYY-MM-DD format. Calendar selection commits immediately when show-time is off.
  • Date and time: Set show-time to draft YYYY-MM-DDTHH:mm in 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-presets on range mode for the sidebar (Today, Last 7 days, Custom range, and so on). Named presets show their label in the trigger; custom ranges show the date string. Optional period-presets subsets, reorders, or relabels the built-ins. Range values may include preset.
  • 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. vertical always stacks a scrollable month list.
  • Display format: Set display-format and display-date-time-format with Day.js-style format tokens to change visible input text only. Emitted values stay canonical.
  • Inline clear: Shown by default when the field has a value. Set show-clear-button to false to hide it.
  • Constraints: Use min, max, and disabled-dates to block invalid calendar cells. In range mode, use max-range-days to 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 label prop or label slot; for / id wiring is handled automatically.
  • Trigger: The native text control exposes aria-haspopup="grid", aria-expanded, and panel linkage while open. It uses the available width and wraps instead of truncating.
  • 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.
  • Calendar: Arrow keys move by day/week, Home / End move within the week, PageUp / PageDown change month, Shift + PageUp / Shift + PageDown change year, Enter / Space select, and Escape closes.
  • Presets: The range preset list is a listbox; selected rows use the checkmark appearance.
  • Invalid state: intent="danger" sets aria-invalid="true" on the control; aria-describedby includes supporting text when present.

Catnip Design System by Signicat