2.4.12 `components/ui/DatePicker` primitive + wire into the issue date fields
Estimate: 18m · Depends on: 2.4.11
Build a presentational, accessible DatePicker in components/ui/ per 2.4.11, and replace the native <input type="date"> (currently Input-wrapped) in ALL THREE issue date surfaces — the create modal (2.3.3), the edit form (2.3.6), and the detail core-fields rail (2.4.2). A shared primitive, no per-surface re-implementation (the same way Combobox / TreeTable are shared).
Shape. An Input-styled trigger (selected date or placeholder + a Clear control) opening a Popover month grid. Value crosses as an ISO date string (YYYY-MM-DD) — exactly what the forms already hold — so the swap is drop-in: value + onChange(next: string | null) + disabled. Pure presentation: no queries, no Server-Action imports; the forms keep their existing commit paths (the edit form's submit, the detail rail's commit-on-close). Date math is UTC-safe (no off-by-one from local-tz parsing — the bug the ISO-string shape already guards).
A11y (load-bearing). The WAI-ARIA dialog + grid date-picker pattern (hand-rolled like Combobox / TreeTable): a labelled trigger button with aria-haspopup; a labelled dialog containing a grid of day buttons with roving focus + the 2.4.11 keyboard model; the selected day carries aria-current="date". Themed via --el-* only.
Scope guard. Single-date selection only. Date RANGES, relative presets ("in 3 days"), and time-of-day stay out of scope — no use case yet (no complexity for nothing).
Acceptance criteria
components/ui/DatePickermatchesdatepicker.mock.html(2.4.11): Input-styled trigger + Popover month grid, prev/next-month nav, selected/today states, a Clear control; value in/out is an ISOYYYY-MM-DDstring (or null).- Replaces the native date input in the create modal, edit form, AND detail core-fields rail — one shared primitive; the forms' existing commit / validation paths are unchanged.
- Full date-picker a11y: labelled trigger + dialog, a day
gridwith roving focus, arrows / PageUp-Down / Home-End / Enter / Esc keyboard; the selected day exposesaria-current="date"; a/tokens/date-pickerspecimen joins the STRICT shell-a11y sweep (axe-clean). - Colours via
--el-*only; UTC-safe date math (no local-tz off-by-one). - Component test (happy-dom): open → navigate months → select a day → clear; keyboard day-move + select; the specimen in the strict a11y sweep.
Context refs
design/work-items/datepicker.mock.html+design-notes.md(2.4.11) — the layout authoritycomponents/ui/Popover.tsx(anchored popover) +Input.tsx(trigger chrome) +Combobox.tsx/TreeTable.tsx(hand-rolled WAI-ARIA + roving-focus references)- The native date inputs to replace —
CreateIssueModal(2.3.3),EditIssueForm(2.3.6),CoreFieldsPanel(2.4.2): all hold an ISOYYYY-MM-DDstring today;lib/utils/datetime.tsformatDate tests/e2e/shell-a11y.spec.ts+ the/tokensroute convention;motir-core/CLAUDE.md—--el-*tokens