Calendar
The custom element is <hui-calendar>.
Overview
A role="grid" month view whose value is an ISO date. The pure date arithmetic lives in a shared module and Intl supplies the month and weekday names, so the host's locale is honoured.
Example
Source
<hui-calendar value="2024-02-15" aria-label="Date"></hui-calendar>The Go template that renders it:
<hui-calendar value="{{ .Value }}" min="{{ .Min }}" max="{{ .Max }}" locale="{{ .Locale }}"></hui-calendar>API
Attributes6
| Name | Type | Default | Description |
|---|---|---|---|
value | string | "" | The selected ISO date, YYYY-MM-DD. Reflects to the value attribute and moves the visible month to it. |
min | string | "" | Inclusive lower bound. Days before it are disabled. |
max | string | "" | Inclusive upper bound. Days after it are disabled. |
disabled-dates | string | "" | Whitespace- or comma-separated ISO dates to disable in addition to the range. |
week-start | number | 0 | First day of the week, 0 for Sunday. Reflects as a number. |
locale | string | "" | BCP 47 locale for the month, weekday and day labels; empty uses the host default. |
Properties6
| Name | Type | Default | Description |
|---|---|---|---|
value | string | '' | Reflects to the value attribute. |
min | string | '' | Reflects to the min attribute. |
max | string | '' | Reflects to the max attribute. |
disabled-dates | string | '' | Reflects to the disabled-dates attribute. |
week-start | number | 0 | Reflects to the week-start attribute. |
locale | string | '' | Reflects to the locale attribute. |
Events2
| Name | Description |
|---|---|
hui-select | Emitted when an enabled day is chosen, with detail.value the ISO date. It bubbles and is composed. |
change | Emitted after hui-select. It bubbles but is not composed. |
CSS custom properties5
| Name | Default | Description |
|---|---|---|
--hui-primary | oklch(0.496 0.265 301.924) | Background of the selected day. |
--hui-primary-foreground | oklch(0.977 0.014 308.299) | Text colour of the selected day. |
--hui-accent | oklch(0.96 0.003 325.6) | Background of a hovered day. |
--hui-input | oklch(0.62 0.019 323.02) | Border drawn around today when it is not selected. |
--hui-muted-foreground | oklch(0.542 0.034 322.5) | Colour of weekday headings, the arrows and disabled days. |
::part() hooks7
| Name | Description |
|---|---|
header | The row holding the previous and next controls and the month label. |
prev | The previous-month button. |
label | The aria-live="polite" month and year label. |
next | The next-month button. |
viewport | The clip box that contains the month slide animation. |
grid | The role="grid" table. |
day | A day button inside a role="gridcell". |
States
Bounded range
min and max bound what can be chosen. Dates outside them cannot be selected, and the month arrows stop at the ends.
Source
<hui-calendar value="2024-02-15" min="2024-02-10" max="2024-02-20"></hui-calendar>Disabled dates and week start
Single dates blocked with disabled-dates, and week-start="1" beginning the week on Monday.
Source
<hui-calendar value="2024-02-15" disabled-dates="2024-02-12 2024-02-13" week-start="1"></hui-calendar>Localised
locale changes the month and day names, and how the dates read, without changing the value the element submits.
Source
<hui-calendar value="2024-02-15" locale="de-DE" week-start="1"></hui-calendar>Server-side mechanics
The server renders <hui-calendar> with an ISO value and optional min, max, disabled-dates, locale and week-start. It is not form-associated and has no name, so it submits nothing; to submit a date, use <hui-date-picker> or copy the chosen value into a hidden input. The element owns only the grid and the date arithmetic, and reports a choice with hui-select and change. An hx-swap that replaces the calendar resets the visible month to the swapped-in value and drops keyboard focus, so re-render it only when the month should move.
Accessibility
- The table is a
role="grid"ofrole="gridcell"cells; each day button has a full spoken date as itsaria-labeland only the focused day carriestabindex="0". - Disabled days carry the native
disabledattribute, and arrow movement steps past them to the next enabled day. - The month label is
aria-live="polite", so a month change is announced. - The month slide is skipped under
prefers-reduced-motion: reduce.
Keyboard
| Keys | Action |
|---|---|
ArrowLeft, ArrowRight | Move the focus one day back or forward. |
ArrowUp, ArrowDown | Move the focus one week back or forward. |
PageUp, PageDown | Move the focus one month back or forward. |
Home, End | Move the focus to the first or last day of the focused week. |
Enter, Space | Select the focused day. |
Gotchas
- Unlike the form-associated molecules,
hui-calendar'schangebubbles but is not composed, so it does not cross a shadow boundary.