Skip to content

HyCalendar

Usage examples on this page are written for Lit / plain HTML (<hy-calendar>). The same component ships as HyCalendar in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A presentational, keyboard-accessible month grid built on the Temporal API. Pure date engine — no input, no popover. Embeddable standalone (booking surfaces, inline filters) and composed by hy-date-picker.

Selection is single by default; set range for two-endpoint selection. The value is an ISO YYYY-MM-DD (single) or an ISO 8601 interval start/end (range), per DATETIME_COMPONENTS_PLAN.md §3.

Temporal-free first paint

The grid is computed from Temporal, which is awaited via ensureTemporal() on first connect. Before it resolves (and during SSR) the component renders a lightweight loading shell — it never reads Temporal in the constructor or first render, so it passes the @lit-labs/ssr smoke test and behaves on the Safari/no-Temporal path.

Accessibility

role="grid" with a roving tabindex over day buttons; Arrow keys move by day, PageUp/PageDown by month (Shift by year), Home/End to week edges. Today carries aria-current="date"; selected days carry aria-selected. Month changes are announced via a polite live region.

Examples

Single date

html
<hy-calendar value="2026-03-07"></hy-calendar>

Range

html
<hy-calendar range value="2026-03-07/2026-03-12"></hy-calendar>

API

Properties

PropertyAttributeTypeDefaultDescription
valuevaluestring''Selected value — ISO YYYY-MM-DD (single) or ISO interval start/end (range).
minminstring | undefinedEarliest selectable date (ISO YYYY-MM-DD). Out-of-range days are disabled.
maxmaxstring | undefinedLatest selectable date (ISO YYYY-MM-DD). Out-of-range days are disabled.
localelocalestring | undefinedExplicit locale override. Falls back to <html lang> then navigator.language.
rangerangebooleanfalseEnable two-endpoint range selection.

Events

EventDetailDescription
inputFires on each selection step (range anchor, navigation commit).
changeFires once a selection is committed (single click; range second click).

CSS Parts

PartDescription
baseThe calendar wrapper
headerThe month navigation header
nav-prevPrevious-month button
nav-nextNext-month button
headingThe month/year heading
gridThe day grid
weekdayA weekday column header
dayA day button
live-regionScreen-reader announcement region

CSS Custom Properties

PropertyDescription
--hy-calendar-cell-sizeEdge length of a day cell
--hy-calendar-gapGap between day cells
--hy-calendar-radiusCorner radius of a day cell
--hy-calendar-surface-radiusCorner radius of the calendar surface
--hy-calendar-day-selected-backgroundSelected day background
--hy-calendar-day-range-backgroundIn-range day background
--hy-calendar-day-highlight-foregroundForeground of in-range and today day cells. Default: var(--hy-foreground-brand-rest).
--hy-calendar-backgroundCalendar surface background. Default: var(--hy-background-surface-base).
--hy-calendar-paddingPadding of the calendar surface. Default: var(--hy-padding-form-md).
--hy-calendar-day-foregroundForeground of an in-month day cell. Default: var(--hy-foreground-default-rest).
--hy-calendar-muted-foregroundForeground of out-of-month day cells and weekday headers. Default: var(--hy-foreground-subtle-rest).
--hy-calendar-day-hover-backgroundHovered day background. Default: var(--hy-background-neutral-hover).
--hy-calendar-day-selected-foregroundSelected day foreground. Default: var(--hy-foreground-on-brand-rest).
--hy-calendar-today-borderBorder of the today marker. Default: var(--hy-border-brand-rest).
--hy-calendar-hover-durationHover transition duration. Default: var(--hy-motion-transition-hover-duration).
--hy-calendar-hover-easingHover transition easing. Default: var(--hy-motion-transition-hover-easing).

Built with Lit. Documented with VitePress.