# Calendar _(no submodules)_ - calendar.test-fixtures — Wave-3h local test fixture… - [calendar.test-fixtures](./calendar.test-fixtures.md) — Wave-3h local test fixture that augments the chassis test i18n instance with the `react-ui.calendar.*` keyset. The chas… - [calendar.variants](./calendar.variants.md) — `calendarVariants` is the cva config that powers the outer wrapper of ``. The recipe is intentionally minimal… - calendar.test-fixtures — Wave-3h local test fixture… - [calendar.test-fixtures](./calendar.test-fixtures.md) — Wave-3h local test fixture that augments the chassis test i18n instance with the `react-ui.calendar.*` keyset. The chas… - [calendar.variants](./calendar.variants.md) — `calendarVariants` is the cva config that powers the outer wrapper of ``. The recipe is intentionally minimal… - calendar.test-fixtures — Wave-3h local test fixture… - [calendar.test-fixtures](./calendar.test-fixtures.md) — Wave-3h local test fixture that augments the chassis test i18n instance with the `react-ui.calendar.*` keyset. The chas… - [calendar.variants](./calendar.variants.md) — `calendarVariants` is the cva config that powers the outer wrapper of ``. The recipe is intentionally minimal… - calendar.test-fixtures — Wave-3h local test fixture… - [calendar.test-fixtures](./calendar.test-fixtures.md) — Wave-3h local test fixture that augments the chassis test i18n instance with the `react-ui.calendar.*` keyset. The chas… - [calendar.variants](./calendar.variants.md) — `calendarVariants` is the cva config that powers the outer wrapper of ``. The recipe is intentionally minimal… - [calendar.test-fixtures](./calendar.test-fixtures.md) — Wave-3h local test fixture that augments the chassis test i18n instance with the `react-ui.calendar.*` keyset. The chas… - [calendar.variants](./calendar.variants.md) — `calendarVariants` is the cva config that powers the outer wrapper of ``. The recipe is intentionally minimal… ## Purpose `` is the chassis date-grid primitive — a thin wrapper over `react-day-picker` (v9) that adds the chassis cva recipe, theme-aware lucide chevrons for previous/next-month navigation, locale-driven `aria-label` overrides, and a labelled outer wrapper. The chassis derives the active locale from `useTranslation()` so date formatting and accessible labels stay in lock-step with the rest of the app surface. The chassis exposes the upstream surface verbatim through `Omit` — every supported `mode` (`single`, `multiple`, `range`), the `selected` / `onSelect` controlled API, `numberOfMonths`, `showOutsideDays`, `weekStartsOn`, `disabled`, `fromMonth`/`toMonth`, the `modifiers` system, and the rest of the upstream API documented at . Two upstream props are intercepted: `className` (so it merges with the chassis recipe via `cn()`) and `locale` (so the chassis can drive it from `useI18n()` rather than the consumer wiring it manually). For the rare case where a single calendar must diverge from the active app locale, pass a `localeOverride` (a `Partial` per the upstream API). ## Features - Wraps `react-day-picker` v9 with zero additional state — fully controlled or uncontrolled per the upstream API. - Three modes — `single` / `multiple` / `range` — selected via the upstream `mode` prop. - Locale-aware: the chassis reads the active locale from `useTranslation()` so the calendar stays in sync with the app surface. - `aria-label` on the outer wrapper resolves through the active i18n via `labelKey` (defaults to `react-ui.calendar.label`). - Previous / next month navigation buttons get translated `aria-label`s via `previousMonthKey` / `nextMonthKey`. - Lucide-iconography for navigation chevrons (`ChevronLeftIcon` / `ChevronRightIcon`) wired into `react-day-picker`'s `components.Chevron` slot. - Forwards refs to the outer wrapper `
`. - All other upstream props pass through unchanged. ## Usage: Basic Example ```tsx import { Calendar } from "@suaveplan/react-ui"; import { useState } from "react"; export function ScheduleCalendar() { const [date, setDate] = useState(new Date()); return ; } ``` ## Usage: Advanced Example ```tsx import { Calendar } from "@suaveplan/react-ui"; import type { DateRange } from "react-day-picker"; import { useState } from "react"; export function BookingCalendar() { const [range, setRange] = useState(); const today = new Date(); return ( ); } ``` ## API Reference ### `` `forwardRef` — renders an outer wrapper `
` containing the `` instance. #### `CalendarProps` | Prop | Type | Default | Description | |---|---|---|---| | `mode` | `"single" \| "multiple" \| "range"` | `undefined` | Selection mode — drives the `selected` / `onSelect` shape per the upstream API. | | `labelKey` | `TranslationKey` | `"react-ui.calendar.label"` | `aria-label` for the outer wrapper. | | `previousMonthKey` | `TranslationKey` | `"react-ui.calendar.previousMonth"` | `aria-label` for the previous-month navigation button. | | `nextMonthKey` | `TranslationKey` | `"react-ui.calendar.nextMonth"` | `aria-label` for the next-month navigation button. | | `localeOverride` | `Partial` | `undefined` | Override the date-fns locale for this calendar instance. When unset, `react-day-picker` falls back to its bundled `enUS`. | | _every other_ `DayPickerProps` field | _upstream_ | _upstream_ | Forwarded as-is. See . | ## Implementation Notes - The chassis intentionally does NOT expose the upstream `locale` prop directly — `localeOverride` is a renamed escape hatch that documents the chassis's intent to drive locale from `useTranslation()` by default. - `react-day-picker` ships its own classnames for the grid, day buttons, and navigation chrome via its internal `classNames` map. The chassis only scopes the OUTER container — overriding the inner classnames belongs in a theme variant override. - Keyboard navigation (arrow keys, Home/End, Enter/Space, PageUp/Down) is supplied entirely by `react-day-picker` — the chassis does not wrap or intercept it. - The chevron icons are passed via `components.Chevron` rather than `classNames` so the chassis can swap them for theme-provided lucide / radix icons in a future Wave 5d theme-icon-pack pass. - `react-day-picker` renders its day grid as either a `` (default) or a `[role="grid"]` element depending on the upstream version — the chassis does not assume one or the other in tests, hitting both via the `grid` selector. - When migrating from a previous `` consumer (e.g. an upstream shadcn block), the only required change is to drop the `locale` prop — the chassis derives it automatically. - Per the brief reconciliation note: the chassis casts the unreachable `?? "default"` fallback for `(i18n as { readonly locale: string }).locale` is NOT needed here because the locale is read indirectly via `useTranslation()` rather than from `i18n.locale`.