Skip to content
Component

Calendar

Dependency-free month-grid date picker. The header can stay simple or become an interactive month/year chooser.

Basic

The default header is a plain, non-clickable month label.

August 2026
SMTWTFS
  • Follows the ARIA APG date-grid pattern: Arrow keys move by day, Home/End jump to the start/end of the week, and Page Up/Down move a month - only one date is a Tab stop at a time.
  • The grid renders at a fixed 280px width regardless of viewport, which fits down to the smallest supported phone widths without its own responsive breakpoints.

Interactive month/year header

Set interactiveHeader to open a compact month and year chooser anchored inside the calendar. Years run from the current year back 100 years, respecting min/maxDate.

SMTWTFS

Min and max range

Days outside the allowed range are disabled.

August 2026
SMTWTFS

When to use

  • The date grid should always be visible - inline scheduling, a booking page, a dashboard filter that's used often.
  • As the anchored popup inside Date Picker, when a compact text-field trigger is what you actually want on the page.

When not to use

  • A single date field in a form where screen space matters - use Date Picker so the grid only appears on demand.
  • Time selection - pair it with Time Picker rather than extending Calendar itself.

Keyboard

KeyAction
Arrow keysMove focus by one day in that direction.
Home / EndJump to the start / end of the current week.
Page Up / Page DownMove one month back / forward.
Enter / SpaceSelects the focused date.

Mobile behavior

  • Fixed 280px grid width fits down to the smallest supported phone widths without a separate mobile layout.
  • Day cells meet a 44px touch target even though the grid itself is compact.

Accessibility notes

  • Follows the ARIA APG date-grid pattern with role="grid" and a roving tabindex - only the focused date is a Tab stop.
  • SSR-safe "today": the initial render uses a UTC-normalized date so server and client markup match, then corrects to the visitor's local today after mount if they differ - never a hydration mismatch.

Common mistakes

  • Passing a raw `new Date()` for `value`/`defaultValue` in a Server Component tree - use a UTC-normalized date (see the Basic example above) to avoid a timezone-dependent hydration mismatch.
  • Setting minDate after maxDate (or vice versa) - the grid will show every day disabled with no explicit empty-state messaging.

Known limitations

  • Single-month view only - no built-in multi-month or date-range selection.

Related components

Calendar props

value / onChangeNone
Date | null / (date: Date) => void

Controlled selected date.

defaultValueNone
Date | null

Uncontrolled initial date.

minDate / maxDateNone
Date

Dates outside this range render disabled.

interactiveHeaderfalse
boolean

Makes the month/year label open a compact chooser instead of a static label.

locale"en-US"
string

Locale used for month/weekday names.

CriterionStatusNote
Keyboard supportSupportedFull ARIA APG date-grid arrow/Home/End/PageUp/PageDown navigation.
Focus managementSupportedRoving tabindex keeps exactly one date in the tab order.
Screen reader labelsSupportedEach day cell announces its full date; selected/disabled state is exposed via aria-selected/aria-disabled.
Reduced motionSupportedprefers-reduced-motion: reduce zeroes all Fuji transition durations globally.
Reduced transparencySupportedprefers-reduced-transparency: reduce flattens Glass to opaque surfaces (portals included).
RTL layoutUntestedWeek/month grid direction under dir="rtl" hasn't been manually verified yet.

API reference

valueNone
Date | null

Controlled selected date.

defaultValuenull
Date | null

Uncontrolled initial date.

onChangeNone
(date: Date) => void

Fires when a day is selected.

minDateNone
Date

Earliest selectable date.

maxDateNone
Date

Latest selectable date.

locale"en-US"
string

BCP-47 locale for month and weekday names.

interactiveHeaderfalse
boolean

Make the header month/year an interactive chooser.

classNameNone
string

Additional classes applied to the component root.