# RangeCalendar **Category**: react **URL**: https://www.heroui.com/docs/react/migration/range-calendar **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/migration/(components)/range-calendar.mdx > Migration guide for RangeCalendar from HeroUI v2 to v3 *** Refer to the [v3 RangeCalendar documentation](/docs/react/components/range-calendar) for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2. ## Structure Changes In v2, `RangeCalendar` was a single component configured entirely through props: ```tsx import { RangeCalendar } from "@heroui/react"; import { today, getLocalTimeZone } from "@internationalized/date"; export default function App() { return ( ); } ``` In v3, RangeCalendar uses a compound component pattern with explicit subcomponents: ```tsx import { RangeCalendar } from "@heroui/react"; import { today, getLocalTimeZone } from "@internationalized/date"; export default function App() { return ( {(day) => {day}} {(date) => } ); } ``` ## Key Changes ### 1. Component Structure **v2:** Single `RangeCalendar` component with all layout handled internally **v3:** Compound components: `RangeCalendar.Header`, `RangeCalendar.Heading`, `RangeCalendar.NavButton`, `RangeCalendar.Grid`, `RangeCalendar.GridHeader`, `RangeCalendar.GridBody`, `RangeCalendar.HeaderCell`, `RangeCalendar.Cell`, `RangeCalendar.CellIndicator` ### 2. Year Picker **v2:** Built-in month/year pickers via `showMonthAndYearPickers` prop **v3:** Dedicated compound components: `RangeCalendar.YearPickerTrigger`, `RangeCalendar.YearPickerGrid`, `RangeCalendar.YearPickerGridBody`, `RangeCalendar.YearPickerCell` ### 3. Prop Changes | v2 Prop | v3 Equivalent | Notes | |---------|---------------|-------| | `value` | `value` | Same | | `defaultValue` | `defaultValue` | Same | | `onChange` | `onChange` | Same | | `focusedValue` | `focusedValue` | Same | | `onFocusChange` | `onFocusChange` | Same | | `minValue` | `minValue` | Same | | `maxValue` | `maxValue` | Same | | `isDateUnavailable` | `isDateUnavailable` | Same | | `allowsNonContiguousRanges` | `allowsNonContiguousRanges` | Same | | `isDisabled` | `isDisabled` | Same | | `isReadOnly` | `isReadOnly` | Same | | `isInvalid` | `isInvalid` | Same | | `pageBehavior` | `pageBehavior` | Same | | `visibleMonths` | `visibleDuration` | Changed to `{months: number}` object | | `showMonthAndYearPickers` | - | Use `RangeCalendar.YearPickerTrigger` and `RangeCalendar.YearPickerGrid` | | `onHeaderExpandedChange` | `onYearPickerOpenChange` | Renamed | | `color` | - | Removed (use Tailwind CSS) | | `calendarWidth` | - | Removed (use `className` or Tailwind CSS) | | `weekdayStyle` | - | Removed | | `firstDayOfWeek` | - | Use `I18nProvider` locale instead | | `topContent` | - | Place custom content inside `RangeCalendar` before the grid | | `bottomContent` | - | Place custom content inside `RangeCalendar` after the grid | | `errorMessage` | - | Removed (handle validation externally) | | `showHelper` | - | Removed | | `disableAnimation` | - | Removed | | `classNames` | - | Use `className` on individual compound components | ## Migration Examples ### Basic Range Selection ```tsx import { RangeCalendar } from "@heroui/react"; import { today, getLocalTimeZone } from "@internationalized/date"; ``` ```tsx import { RangeCalendar } from "@heroui/react"; import { today, getLocalTimeZone } from "@internationalized/date"; {(day) => {day}} {(date) => } ``` ### Controlled State ```tsx import { useState } from "react"; import { RangeCalendar } from "@heroui/react"; import { parseDate } from "@internationalized/date"; const [value, setValue] = useState({ start: parseDate("2024-03-01"), end: parseDate("2024-03-07"), }); ``` ```tsx import { useState } from "react"; import { RangeCalendar } from "@heroui/react"; import { parseDate } from "@internationalized/date"; const [value, setValue] = useState({ start: parseDate("2024-03-01"), end: parseDate("2024-03-07"), }); {(day) => {day}} {(date) => } ``` ### Month and Year Pickers ```tsx ``` ```tsx {(day) => {day}} {(date) => } {(year) => } ``` ### Multiple Months ```tsx ``` ```tsx
{(day) => {day}} {(date) => } {(day) => {day}} {(date) => }
```
### Unavailable Dates with Non-Contiguous Ranges ```tsx import { isWeekend } from "@internationalized/date"; import { useLocale } from "@react-aria/i18n"; const { locale } = useLocale(); isWeekend(date, locale)} allowsNonContiguousRanges /> ``` ```tsx import { isWeekend } from "@internationalized/date"; import { useLocale } from "@react-aria/i18n"; const { locale } = useLocale(); isWeekend(date, locale)} allowsNonContiguousRanges > {(day) => {day}} {(date) => } ``` ### Top and Bottom Content ```tsx Select your travel dates

} bottomContent={ } /> ```
```tsx

Select your travel dates

{(day) => {day}} {(date) => }
```
## Styling Changes ### v2: `classNames` Prop ```tsx ``` ### v3: Direct `className` Props ```tsx {(day) => {day}} {(date) => } ``` ## Component Anatomy The v3 RangeCalendar follows this structure: ``` RangeCalendar (Root) ├── [Custom top content] ├── RangeCalendar.Header │ ├── RangeCalendar.Heading (or RangeCalendar.YearPickerTrigger) │ ├── RangeCalendar.NavButton slot="previous" │ └── RangeCalendar.NavButton slot="next" ├── RangeCalendar.Grid (one per visible month) │ ├── RangeCalendar.GridHeader │ │ └── RangeCalendar.HeaderCell (render prop) │ └── RangeCalendar.GridBody │ └── RangeCalendar.Cell (render prop) │ └── RangeCalendar.CellIndicator (optional) ├── RangeCalendar.YearPickerGrid (optional) │ └── RangeCalendar.YearPickerGridBody │ └── RangeCalendar.YearPickerCell └── [Custom bottom content] ``` ## Summary 1. **Component Structure**: Single component → compound components with explicit layout control 2. **Year Picker**: `showMonthAndYearPickers` prop → dedicated `RangeCalendar.YearPickerTrigger` and `RangeCalendar.YearPickerGrid` components 3. **Multiple Months**: `visibleMonths={n}` → `visibleDuration={{months: n}}` with multiple `RangeCalendar.Grid` components using `offset` 4. **Color Removed**: Use Tailwind CSS classes instead 5. **Top/Bottom Content**: Props removed → place content directly as children inside `RangeCalendar` 6. **Cell Customization**: New `RangeCalendar.CellIndicator` and render prop support on `RangeCalendar.Cell` 7. **Styling**: `classNames` prop → `className` on individual compound components 8. **Removed Props**: `calendarWidth`, `weekdayStyle`, `showHelper`, `errorMessage`, `disableAnimation` — use Tailwind CSS or handle externally