Date picker (single, range, time)

Accessible date picker — typed ISO entry + calendar grid for single date / date range / date+time. Replaces native `<input type="date">` (inconsistent across browsers) and ad-hoc third-party widgets. Modeled after Duet (LocalTapiola), Polaris, Spectrum.

Component — Date picker

*tatus* v0.1.0 — Draft. Three modes: single / range / time.

R1 — Input cell

  • Text input accepting typed ISO YYYY-MM-DD (or locale-formatted, see R7).
  • Trailing calendar icon opens the popover.
  • Inline parse errors render below the cell ("Invalid date"); never silently auto-correct.

R2 — Calendar grid (popover)

  • 6×7 grid; days outside current month rendered with muted style.
  • Monthyear header with previousnext arrows + clickmonthname to open year/month quick-pick.
  • Today's date marked with outline ring (not filled — selection takes precedence).
  • Disabled dates rendered muted + not focusable; live region announces blocked attempt.

R3 — Range mode

  • Two paired inputs (start + end) sharing a single calendar popover.
  • Selecting start highlights tentative range while user picks end.
  • Preset shortcuts row above grid: Today, Yesterday, Last 7 days, Last 30 days, This month (configurable per product).

R4 — Time mode

  • Single mode: input includes time component YYYY-MM-DD HH:mm.
  • Popover adds hourminute scrolls (or 24-hour input + AMPM selector per R7 locale).
  • Seconds default off; togglable per instance.

R5 — Keyboard navigation

Key Action
←/→ Daybyday within grid
PgUp / PgDn Monthbymonth
Shift+PgUp / Shift+PgDn Yearbyyear
Home / End Start / end of week
Enter Select highlighted date
Esc Close popover; restore prior value

R6 — Screen-reader

  • Input: <input> with associated label + aria-describedby pointing at format hint.
  • Calendar popover: role="dialog" with aria-labelledby (month/year heading).
  • Grid: role="grid"; days role="gridcell"; selected aria-selected="true".
  • Liveregion: "Selected: {localeformatted date}".

R7 — i18n

  • Firstdayofweek per locale (Sunday for enUS; Monday for pt-BR; configurable).
  • Month / day names from locale data.
  • Input format per locale: enUS MM/DD/YYYY; ptBR DD/MM/YYYY; ISO always accepted alongside.
  • 12h / 24h time per locale.

R8 — Disabled / min / max

  • min and max props clamp the calendar; dates outside are disabled.
  • Per-date disable callback for arbitrary blackouts (e.g., weekends).

R9 — OUIA

Per specs/testing/ouia-test-hooks.kmd:

  • data-ouia-component-type="DatePicker"
  • data-ouia-safe="true" only when popover idle.

Não-escopo

  • Time-zone picker (separate spec if pursued).
  • Multidate select (cherrypick non-range) — separate variant if demand surfaces.
  • Recurring-date rules (RFC 5545) — out of v0.

Source: ../home/koder/dev/koder/meta/docs/stack/specs/components/date-picker.kmd