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 calendar
npm install react-aria-components @internationalized/date
npm install react-day-picker date-fns

System-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

FamilyUpstream libraryDate state shapeSingle selection propsRange selectionInternational calendar note
ARIAReact Aria Components plus internationalized date utilitiesCalendarDate or nullvalue and onChangeRangeCalendar componentUse I18nProvider for locales such as Persian, Islamic, or Buddhist
baseReact DayPicker plus date-fnsDate or undefinedmode, selected, and onSelectmode set to rangeReplace the DayPicker import with react-day-picker/persian for Persian, Hijri, or Jalali usage
RadixReact DayPicker plus date-fnsDate or undefinedmode, selected, and onSelectmode set to rangeReplace 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.