Content & Data
Calendar Grid
Calendar Grid is a composed month-view calendar with single-date or range selection and grid keyboard navigation.
Single-date or range month view — composed from Calendar Day
betaReact AvailableFigma PartialDocs Partial
- React last updated
- 2026-07-12
- Documentation last updated
- 2026-06-01
- Accessibility target
- WCAG 2.2 AA (target)
- Version
- 0.5.0-beta
Known open questions
- Month/year drill-up and range selection are implemented on Calendar Grid.
- Six-week grid with outside-month days visible is an initial policy — not fully verified in Figma Month Grid.
Live preview
Single-date month grid with roving tabindex and arrow-key navigation.
Current month
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Arrow keys move focus; Enter or Space selects. Page Up/Page Down change months. Initial policy uses Monday week start and en-GB formatting — localization deferred.
Range mode
Two-click range selection with a live hover/keyboard preview before the end is committed.
Pick a start, then an end date
Mon
Tue
Wed
Thu
Fri
Sat
Sun
First click sets the start date. Hover or arrow-key to preview the range before committing an end with a second click or Enter. Clicking inside a completed range starts a new one.
Purpose
A month-view calendar grid for selecting one date or a date range, composed from Calendar Day cells with month navigation.
Anatomy
Calendar Grid composes Calendar Day: header + previous/next month buttons + weekday row + week rows. Clicking the header drills up to a month grid, then a year grid, for fast month/year navigation.
Variants and states
single-date · range
When to use
Inline month or range selection, or as the calendar surface inside Date Picker.
When not to use
Multi-date (non-contiguous) selection or scheduling views with events — not confirmed in Figma.
Accessibility
role="grid" with weekday column headers, roving tabindex on day buttons, and arrow-key navigation.
Keyboard behavior
Arrow keys move by day; Home/End move within week; Page Up/Page Down change month; Enter/Space selects focused day. Roving tabindex keeps one day in tab order. The month and year drill-up grids use the same roving-tabindex model with arrow keys, Home/End, and Enter/Space over their own cells.
Common mistakes
Using Calendar Day outside a grid without providing collection keyboard semantics.
Properties
Composes Calendar Day building blocks in a 7×6 grid with month heading and previous/next controls.
How does Calendar Grid work with a keyboard?
The grid uses role="grid" with roving tabindex on day buttons and explicit arrow/Home/End/Page Up/Page Down handling.
How does focus move between months?
Page Up/Page Down and month buttons update the visible month while preserving the focused weekday where possible through date clamping.
How are outside-month dates handled?
Outside-month days remain visible and selectable unless disabled. They use muted styling.
What week-start and locale assumptions are used?
Initial batch uses en-GB formatting and Monday week start. Stored values remain locale-neutral YYYY-MM-DD strings.
How does range selection work?
Set mode="range" and use rangeValue/defaultRangeValue/onRangeValueChange ({ start, end }) instead of value. First click sets start; second click commits end (swapped into chronological order if picked backwards); clicking inside a completed range starts fresh. Hovering or moving keyboard focus after start is set shows a live provisional preview of the range before it's committed.
Tokens used
semantic/surface/defaultsemantic/border/defaultsemantic/text/primarycomponent/radius/container
Component API
| Prop | Type | Default | Description |
|---|---|---|---|
| mode | "single" | "range" | — | Selection mode. Defaults to single-date; range mode uses separate range props below. |
| value | YYYY-MM-DD | — | Controlled selected date (single mode). |
| defaultValue | YYYY-MM-DD | — | Initial selected date (single mode). |
| onValueChange | (date) => void | — | Selection callback (single mode). |
| rangeValue | { start, end } | — | Controlled range value (range mode). |
| defaultRangeValue | { start, end } | — | Initial range value (range mode). |
| onRangeValueChange | (range) => void | — | Range selection callback (range mode). |
| visibleMonth | { year, month } | — | Controlled visible month. |
| defaultVisibleMonth | { year, month } | — | Initial visible month. |
React example
Copy React example
import { CalendarGrid } from "@/components/ui/CalendarGrid";
export function Example() {
return <CalendarGrid defaultValue="2026-07-14" />;
}