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).

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: built in ​

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.

Accessibility: your part ​

  • The calendar has no label. Put it under a heading or in a labeled region that says what the date is for.
  • When min or max is set, tell people the allowed dates.

When to use

  • A month that stays on screen: a booking surface, a filter by date, an availability view.
  • Picking dates where the weekday or the week around them matters.

Do

  • Set min and max to the dates people can pick.

When not to use

  • A date entered in a form: hy-date-picker. The calendar alone submits nothing.
  • A date far from today, such as a birth date: hy-date-field.
  • A time of day: hy-date-field type="time".

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 | undefined—Earliest selectable date (ISO YYYY-MM-DD). Out-of-range days are disabled.
maxmaxstring | undefined—Latest selectable date (ISO YYYY-MM-DD). Out-of-range days are disabled.
localelocalestring | undefined—Explicit locale override. Falls back to <html lang> then navigator.language.
rangerangebooleanfalseEnable two-endpoint range selection.
loadingTextloading-textstring'Loading calendar'Text announced while the calendar loads. Use for internationalization.
previousMonthLabelprevious-month-labelstring'Previous month'Accessible label for the previous-month button. Use for internationalization.
nextMonthLabelnext-month-labelstring'Next month'Accessible label for the next-month button. Use for internationalization.

Events ​

EventDetailDescription
input—Fires on each selection step (range anchor, navigation commit).
change—Fires 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 ​

The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.

PropertyDefaultDescription
--hy-calendar-cell-size—Edge length of a day cell
--hy-calendar-gap-layout-2xsvar(--hy-gap-layout-2xs)Gap between day cells
--hy-calendar-radius-form-mdvar(--hy-radius-form-md)Corner radius of a day cell
--hy-calendar-radius-overlay-floating-mdvar(--hy-radius-overlay-floating-md)Corner radius of the calendar surface
--hy-calendar-background-brand-on-restvar(--hy-background-brand-on-rest)Selected day fill — the on token (C6)
--hy-calendar-background-brand-soft-restvar(--hy-background-brand-soft-rest)In-range day background
--hy-calendar-foreground-brand-restvar(--hy-foreground-brand-rest)Foreground of in-range and today day cells.
--hy-calendar-background-surface-basevar(--hy-background-surface-base)Calendar surface background.
--hy-calendar-padding-form-mdvar(--hy-padding-form-md)Padding of the calendar surface.
--hy-calendar-foreground-default-restvar(--hy-foreground-default-rest)Foreground of an in-month day cell.
--hy-calendar-foreground-subtle-restvar(--hy-foreground-subtle-rest)Foreground of out-of-month day cells and weekday headers.
--hy-calendar-background-neutral-hovervar(--hy-background-neutral-hover)Hovered day background.
--hy-calendar-foreground-brand-on-restvar(--hy-foreground-brand-on-rest)Selected day text on the on fill
--hy-calendar-border-brand-restvar(--hy-border-brand-rest)Border of the today marker.
--hy-calendar-motion-transition-hover-durationvar(--hy-motion-transition-hover-duration)Hover transition duration.
--hy-calendar-motion-transition-hover-easingvar(--hy-motion-transition-hover-easing)Hover transition easing.

Built with Lit. Documented with VitePress.