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.

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

September 2026
SMTWTFS

Locale

locale takes a BCP 47 tag and drives the month and weekday names, and each day's accessible name, through Intl.

September 2026
SMDMDFS

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.
  • Each day cell is named with its full date in the calendar's locale ("Saturday, March 14, 2026"). Today carries aria-current="date" and is marked with a dot as well as a color.
  • 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

classNameNone
string

Extra classes merged onto the calendar surface.

defaultValuenull
Date | null

Starting selection when uncontrolled.

interactiveHeaderfalse
boolean

Makes the header month/year label an interactive chooser. Defaults to false, which keeps the simple non-clickable header.

locale"en-US"
string

BCP 47 tag driving the weekday and month names, via `Intl`.

markedDateLabel"marked"
string

Text appended to a marked day's accessible name ("Monday, May 20, 2024, has tasks"). Default "marked". Describe what the mark means.

markedDatesNone
Date[] | ((date: Date) => boolean)

Days to mark with a small dot (e.g. days with tasks): a list of dates matched by calendar day, or a predicate per visible day. Marked days get `markedDateLabel` in their accessible name.

maxDateNone
Date

Latest selectable date; days after it render disabled. Compared by calendar day, like `minDate`.

minDateNone
Date

Earliest selectable date; days before it render disabled. Compared by calendar day, so `minDate={new Date()}` keeps today selectable.

onChangeNone
((date: Date) => void)

Called with the picked date.

todayNone
Date

The date treated as "today" (highlight, `aria-current="date"`). Defaults to the visitor's local date after mount (SSR uses a UTC placeholder); pass it for deterministic output or tests.

valueNone
Date | null

Controlled selection. Pair with `onChange`; omit for uncontrolled.

Coding agents read this reference, with its examples, from the version your project has installed, through the Fuji UI MCP server. Set up your agent