26Date field
A themed date picker over a native <input type="date">. The input keeps its type, so the value stays a valid ISO date, form submission is unchanged, and a script failure returns the platform picker.
Use it for
- Publish scheduling, cohort start dates, deadlines
- Anywhere a single date is the answer
Not for
- A date RANGE — use two fields with a real relationship between them
- A date the reader must not change — that is text
- Times — a date picker that also picks minutes is two controls in one
Themed picker
data-ns-calendar replaces the native popup with the system's own. Click the field or press Down/Enter; arrows move by day, PageUp/Down by month, Esc closes and returns focus.
markup
<div class="ns-datefield" data-ns-calendar><input class="ns-input" type="date" value="2026-09-14" aria-label="Publish date"></div>Native fallback
Without data-ns-calendar — and this is also exactly what the reader gets if the script never loads, which is why the input keeps type="date".
markup
<div class="ns-datefield"><input class="ns-input" type="date" aria-label="Publish date"></div>In a field
Scheduled posts go live at 09:00 in the site timezone.
markup
<div class="ns-field">
<label class="ns-field__label" for="d-pub">Publish date</label>
<div class="ns-datefield"><input class="ns-input" id="d-pub" type="date" value="2026-09-14"></div>
<p class="ns-field__help">Scheduled posts go live at 09:00 in the site timezone.</p>
</div>Accessibility contract
- Month and weekday names come from Intl, never a hard-coded array — that array is wrong in most of the world, and silently so. The first day of the week follows the locale too
- A roving tabindex, not aria-activedescendant: exactly one day is tabbable and arrows move real focus, so the focused cell is announced with no live region
- A real <table> with <th scope="col">, so the day/column relationship is announced rather than implied by position
- Esc closes and returns focus to the field, from anywhere inside
- Today is a ring and selected is a fill — two different claims, so they coexist on the same cell without either winning