Calendar
Purpose and Scope
The Calendar documentation covers a date-selection component that appears in the ARIA, base, and Radix documentation families. Across those families, the reader-facing goal is consistent: install a project-local calendar source file, wire it to date state, and then compose it into richer flows such as date pickers, range selection, presets, booked-date displays, and date-time pickers. The page is not just a visual catalog entry. It also explains which upstream date library shapes the public contract, what dependencies are required, and which edge cases matter when the selected day appears offset by timezone behavior.
Sources: apps/v4/content/docs/components/aria/calendar.mdx, apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
The most important distinction is the implementation family. The ARIA version is based on React Aria and uses date values from the internationalized date package, while the base and Radix pages are built on React DayPicker and use JavaScript Date values. In shadcn/ui terms, the component is still copied into the application as editable code, so the family determines the starting implementation and dependency set rather than a closed package boundary. When documenting or upgrading a project, first identify which family generated the local component.
Sources: apps/v4/content/docs/components/aria/calendar.mdx, apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
Relevant Source Files
- apps/v4/content/docs/components/aria/calendar.mdx - Defines the ARIA Calendar page, including installation, React Aria links, usage with CalendarDate, date-picker guidance, international calendars, range calendar examples, caption dropdowns, presets, time picker, booked dates, custom cell sizing, and RTL notes.
- apps/v4/content/docs/changelog/2025-06-calendar.mdx - Records the June 2025 Calendar upgrade to the latest React DayPicker and points users to the upgrade guide for the major component refresh.
- apps/v4/content/docs/components/base/calendar.mdx - Defines the base Calendar page, including React DayPicker dependencies, Date-based usage, Persian calendar import replacement, timezone handling, range selection, and examples.
- apps/v4/content/docs/components/radix/calendar.mdx - Mirrors the Radix Calendar page with React DayPicker usage, dependency installation, Persian calendar support, timezone guidance, and example variants.
- apps/v4/content/docs/changelog/2024-08-npx-shadcn-init.mdx - Provides CLI distribution context for installing components with npx shadcn add, component-owned dependencies, framework support, aliases, registries, and monorepo improvements.
- apps/v4/content/docs/changelog/2025-04-shadcn-2-5.mdx - Provides registry installation context for resolve-anywhere behavior, multi-pass import resolution, and files placed outside fixed structures.
Installation and Dependency Model
All three Calendar pages present the same primary installation command: add the calendar through the shadcn CLI. That path is the normal workflow because it installs source code into the consuming application and allows the registry item to bring along its needed dependencies. The manual path is still documented for teams that want to understand or reproduce the generated output. In that flow, readers install the upstream packages, ensure the Button component exists, copy the component source into the local components directory, and adjust imports to match the project aliases.
Sources: apps/v4/content/docs/components/aria/calendar.mdx, apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx, apps/v4/content/docs/changelog/2024-08-npx-shadcn-init.mdx
The dependency names are an immediate signal for which API shape to expect. The ARIA Calendar installs React Aria Components and the internationalized date package, then demonstrates state using a nullable CalendarDate initialized from the local time zone. The base and Radix Calendar pages install React DayPicker plus date-fns, then demonstrate state using Date or undefined. The Button requirement appears in every manual path because Calendar’s navigation controls reuse the local shadcn/ui Button implementation. That keeps visual styling consistent with the rest of the project’s component library.
Sources: apps/v4/content/docs/components/aria/calendar.mdx, apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
npx shadcn@latest add calendarnpm install react-aria-components @internationalized/datenpm install react-day-picker date-fnsSystem-to-Code Mapping
The ARIA page maps to a React Aria component contract. Its usage imports getLocalTimeZone, today, and CalendarDate from the internationalized date package, then renders Calendar with value and onChange. That makes it a good fit for projects already using React Aria primitives or international calendar systems. The page explicitly points readers to React Aria’s Calendar documentation for deeper API details and introduces I18nProvider for Persian, Islamic, Buddhist, and other non-Gregorian calendar systems. In this family, a range calendar is represented by a RangeCalendar component rather than a mode flag.
Sources: apps/v4/content/docs/components/aria/calendar.mdx
The base and Radix pages map to React DayPicker. Their usage imports Calendar from the local UI directory, stores a Date in React state, and passes mode, selected, and onSelect props. Range selection is activated with mode set to range, and month or year dropdowns are exposed through captionLayout. These pages also include an About section that states the component is built on top of React DayPicker. For users, that means DayPicker’s selection modes, modifiers, caption behavior, and date-fns integration are the relevant upstream concepts to understand.
Sources: apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
Usage Patterns and Variants
A minimal Calendar example is intentionally small: hold date state, render Calendar, and add a border and rounded corners through className. The docs then expand from that base into common product patterns. Date Picker guidance tells readers to use Calendar as the calendar panel inside a date-picker composition rather than treating the component as a complete popover input. The examples list also includes basic calendars, range calendars, month and year selectors, presets, date-and-time pickers, booked dates, and responsive custom cell sizes. These examples establish Calendar as a composable primitive, not a one-off widget.
Sources: apps/v4/content/docs/components/aria/calendar.mdx, apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
import { Calendar } from "@/components/ui/calendar"
const [date, setDate] = React.useState<Date | undefined>(new Date())
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
className="rounded-lg border"
/>
)Cell sizing is handled through a CSS custom property on the Calendar element. The ARIA page shows both responsive spacing-token values and fixed rem values using the same property. That detail is useful when a design needs larger touch targets, dense layouts, or different desktop and mobile sizes without forking the component. The examples also preserve the standard className styling model, so teams can add borders, radius, and size variables where they render Calendar rather than editing the component for every layout adjustment.
Sources: apps/v4/content/docs/components/aria/calendar.mdx
<Calendar
value={date}
onChange={setDate}
className="rounded-lg border [--cell-size:--spacing(11)] md:[--cell-size:--spacing(12)]"
/>Internationalization, RTL, and Timezone Edge Cases
International calendar support differs by family. The ARIA page directs readers to React Aria’s I18nProvider when using Persian, Islamic, Buddhist, or similar calendar systems. The base and Radix pages instead document a source edit for Persian, Hijri, or Jalali usage: replace the DayPicker import from the default React DayPicker entry point with the Persian entry point. This is a practical example of shadcn/ui’s open-code model. Because the component lives in the application, teams can change imports and behavior directly when upstream libraries expose specialized builds.
Sources: apps/v4/content/docs/components/aria/calendar.mdx, apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
Timezone behavior receives a dedicated note in the DayPicker-based pages. The Calendar accepts a timeZone prop so displayed and selected dates match the user’s local timezone. The docs call out a common symptom: selecting one day but seeing the previous day highlighted. The recommended pattern is to detect the timezone on the client with Intl.DateTimeFormat inside an effect, then pass it to Calendar. Detecting during render can create hydration mismatches because server and client environments may report different timezones.
Sources: apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
export function CalendarWithTimezone() {
const [date, setDate] = React.useState<Date | undefined>(undefined)
const [timeZone, setTimeZone] = React.useState<string | undefined>(undefined)
React.useEffect(() => {
setTimeZone(Intl.DateTimeFormat().resolvedOptions().timeZone)
}, [])
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
timeZone={timeZone}
/>
)
}RTL support is treated as a framework-level configuration rather than a Calendar-only toggle. The ARIA page points readers to the general RTL configuration guide and also links international calendar guidance near that section. That separation is important because text direction affects more than date cells: navigation buttons, layout flow, focus order expectations, and surrounding form controls all need to agree. Calendar should therefore be validated in the full page or form context where it appears, especially when paired with date pickers or localized labels.
Sources: apps/v4/content/docs/components/aria/calendar.mdx
Upgrade and Registry Context
The June 2025 changelog says Calendar was upgraded to the latest React DayPicker and describes the change as a major upgrade with many new features and improvements, plus more than thirty calendar blocks. For teams with an existing copied component, that is a signal to compare local modifications before replacing the file. Because shadcn/ui distributes editable code, an upgrade may involve merging upstream component changes with project-specific styling, import paths, timezone behavior, or date-picker composition instead of simply bumping a package version.
Sources: apps/v4/content/docs/changelog/2025-06-calendar.mdx
The broader CLI and registry changelogs explain why Calendar installation can work across varied project structures. The rewritten CLI supports adding components, dependencies, themes, hooks, utils, remote registry items, framework detection, alias updates, and monorepo workflows. Later, resolve-anywhere behavior allows registries to place files outside a fixed structure and perform multi-pass import resolution. For Calendar, that context matters when imports point through project aliases or when the Button dependency and Calendar source need to land in locations customized by components.json or registry metadata.
Sources: apps/v4/content/docs/changelog/2024-08-npx-shadcn-init.mdx, apps/v4/content/docs/changelog/2025-04-shadcn-2-5.mdx
Compact API Reference
| Family | Upstream library | Date state shape | Single selection props | Range selection | International calendar note |
|---|---|---|---|---|---|
| ARIA | React Aria Components plus internationalized date utilities | CalendarDate or null | value and onChange | RangeCalendar component | Use I18nProvider for locales such as Persian, Islamic, or Buddhist |
| base | React DayPicker plus date-fns | Date or undefined | mode, selected, and onSelect | mode set to range | Replace the DayPicker import with react-day-picker/persian for Persian, Hijri, or Jalali usage |
| Radix | React DayPicker plus date-fns | Date or undefined | mode, selected, and onSelect | mode set to range | Replace the DayPicker import with react-day-picker/persian for Persian, Hijri, or Jalali usage |
Use captionLayout set to dropdown when the design needs month and year selectors. Use className for border, radius, and layout-specific styling. Use the CSS variable for cell size when the visual density needs to change without rewriting the component. Use timeZone on DayPicker-based calendars when local selection must be stable across server rendering and client hydration. For the ARIA family, use React Aria’s API reference for deeper prop coverage; for the base and Radix families, use React DayPicker’s documentation to understand selection modes and caption behavior.
Sources: apps/v4/content/docs/components/aria/calendar.mdx, apps/v4/content/docs/components/base/calendar.mdx, apps/v4/content/docs/components/radix/calendar.mdx
Next Steps
Start by choosing the component family already used in the project, then add Calendar with the CLI and verify the generated imports. If the component will appear inside an input workflow, read the matching Date Picker page for the same family before inventing a custom popover pattern. If the app is localized, validate the calendar system, locale provider, RTL behavior, and timezone handling together. If upgrading an older installation after the June 2025 refresh, compare local edits carefully and retest range selection, presets, date pickers, and booked-date examples.