| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Calendar
A month on a plate. The month and year sit on two drums behind a window and roll when you page; the chosen day is a latched cap, a range is a groove cut between two caps, and events are lamps named in the line below.
Kit part · Calendars & date pickers · Inputs
A date field with its calendar card in a slot underneath: type a date in any common form for your locale, or press the key and the card slides out. Single dates and ranges; shown the Intl way, posted as ISO.
Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.
Aluminium
| Part | Rest | Focus | Card out | Error |
|---|---|---|---|---|
| Field | Session date | Session date | Session date | Session dateType a date like 28 Sept 2026. |
Graphite
| Part | Rest | Focus | Card out | Error |
|---|---|---|---|---|
| Field | Session date | Session date | Session date | Session dateType a date like 28 Sept 2026. |
| Name | Kind | Values | What it does |
|---|---|---|---|
| label | attribute | required | The printed label over the well; it names the field. |
| name | attribute | — | Adds a hidden input that posts the value as ISO: “2026-09-28”, or “start/end”. |
| value | attribute · property | ISO · "start/end" | The committed date. Shown in the field the locale’s way. |
| mode | attribute | "range" | Two dates. The card asks for the first day, then the last. |
| locale | attribute | BCP 47 · lang | How dates are shown and read, and the week’s first day in the card. |
| min · max | attribute | ISO dates | Passed to the calendar; typed dates outside get a hint naming the bounds. |
| disabled-weekdays · disabled-dates | attribute | "0 6" · ISO dates | Closed days, in the card and when typed. |
| hint | attribute | text | The hint under the well when all is well. |
| required | attribute | — | Marks the visible input required. |
| show() · close() | method | — | Slide the card out, or back into its slot. |
| change | event | bubbles | A date, or a whole range, was committed: typed or picked. |
| Enter | keyboard | in the field | Read what was typed. It accepts 28/09/2026, 28 Sept, Sep 28 2026, 2026-09-28 and the locale’s own ranges. |
| Alt+Down | keyboard | in the field | Open the card (plain Down works in an empty field). |
| Escape | keyboard | in the card | Close it and return to the calendar key. |
| Calendar keys | keyboard | in the card | Everything the calendar takes: arrows, Home/End, PageUp/PageDown, Enter. |
<tui-date-picker label="Session date" name="session" locale="en-GB"
value="2026-09-28" min="2026-09-01" disabled-weekdays="0"></tui-date-picker>
<!-- A range: posts "2026-10-05/2026-10-09". -->
<tui-date-picker label="Hold Studio B" name="hold" mode="range"></tui-date-picker>import '/kit/kit.mjs'; // defines <tui-date-picker> and <tui-calendar>
const picker = document.querySelector('tui-date-picker[name="session"]');
picker.addEventListener('change', () => price(picker.value)); // "2026-09-28"
picker.show(); // slide the card out from code
picker.close();Needs kit.css and kit.mjs. How to install the kit.
<label>. The calendar key has aria-haspopup="dialog" and aria-expanded; the card is a non-modal role="dialog" with a name.aria-invalid and rewrite the hint, which the field points to with aria-describedby, so the reason is read with the field.A custom element that writes a .tui-field (label, a recessed well holding the input and a small calendar key, a hint, a hidden ISO input) and a card holding a <tui-calendar>. Reading a typed date asks Intl for the locale’s order of day, month and year and for its month names (long and short, accents folded, English as a fallback), then checks the date is real; ranges are split on a dash or “to”, and missing months or years are borrowed from the other half, so Intl’s own range output (“10–14 Sept 2026”, “Sep 10 – 14, 2026”) reads back. The card slides out of the slot top first (a clip and a 10px drop over 200ms) and keeps an inner shadow on its top edge where the slot shades it.
The keyboard is never second-class: whatever a person types in their own format should just work.
5 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
A month on a plate. The month and year sit on two drums behind a window and roll when you page; the chosen day is a latched cap, a range is a groove cut between two caps, and events are lamps named in the line below.
Text entry in a recess, the label printed above it, and a hint that says how to fix an error.
One field with its one action in a shared well: subscribe, search, add.