| | --- |
| | sidebar_position: 5 |
| | --- |
| |
|
| | # Upgrading to v9 |
| |
|
| | This release includes significant updates related to accessibility, styles, internationalization, and performance. See the [changelog](./changelog.mdx) for the full list of changes. |
| |
|
| | ## Upgrading from v7 |
| |
|
| | If you are upgrading from v7, this guide is still valid. First, read the [migration guide from v7 to v8](../versioned_docs/version-8.10.1/upgrading.mdx), then follow the steps below. |
| |
|
| | ## Checklist |
| |
|
| | ### 1. Upgrade to the Latest Version |
| |
|
| | ```bash npm2yarn |
| | npm install react-day-picker@latest |
| | ``` |
| |
|
| | If you are not using `date-fns` directly in your code (e.g., when using a [different locale](./localization/changing-locale.mdx)), remove it from your dependencies: |
| |
|
| | ```bash npm2yarn |
| | npm remove date-fns |
| | ``` |
| |
|
| | ### 2. Update Your Custom Styles |
| |
|
| | The default design has changed slightly. You may need to adjust DayPicker to match your design. See the [styling docs](./docs/styling.mdx) for more information. |
| |
|
| | ### 3. Add the `onSelect` Prop When Using `selected` |
| |
|
| | The `selected` prop is now controlled. Add an `onSelect` prop to handle the selected state and keep it in sync with your component. |
| |
|
| | ```diff |
| | + const [selected, setSelected] = useState<Date | undefined>(undefined) |
| | <DayPicker |
| | mode="single" |
| | selected={selected} // controlled prop |
| | + onSelect={setSelected} // update the selected date |
| | /> |
| | ``` |
| |
|
| | ### 4. Update Class Names |
| |
|
| | Class names for UI elements have been updated for clarity and consistency. If you use custom styles via the `classNames` or `styles` prop, update them accordingly. |
| |
|
| | For example, `day_disabled` is now `disabled`: |
| |
|
| | ```diff |
| | <DayPicker |
| | classNames={{ |
| | - day_disabled: 'day-disabled', |
| | + disabled: 'day-disabled', // applies `.day_disabled` to disabled days |
| | }} |
| | /> |
| | ``` |
| | |
| | Additionally, the `day` element is now `day_button`, and the `cell` element is now `day`: |
| |
|
| | ```diff |
| | <DayPicker |
| | classNames={{ |
| | - cell: 'day-cell', |
| | + day: 'day-cell', |
| | - day: 'day-button', |
| | + day_button: 'day-button', |
| | }} |
| | /> |
| | ``` |
| |
|
| | See the full list of updated class names in the [`DeprecatedUI`](./api/type-aliases/DeprecatedUI.md) type. |
| |
|
| | <details> |
| | <summary>**List of Updated Class Names**</summary> |
| |
|
| | | Old Name | New Name | |
| | | --------------------- | ---------------------------------------------------------- | |
| | | `button` | `button_previous`, `button_next` | |
| | | `button_reset` | `button_previous`, `button_next` | |
| | | `caption` | `month_caption` | |
| | | `caption_between` | Removed | |
| | | `caption_dropdowns` | `dropdowns` | |
| | | `caption_end` | Removed | |
| | | `caption_start` | Removed | |
| | | `cell` | `day` – ⚠️ The previous `day` element is now `day_button`. | |
| | | `day_disabled` | `disabled` | |
| | | `day_hidden` | `hidden` | |
| | | `day_outside` | `outside` | |
| | | `day_range_end` | `range_end` | |
| | | `day_range_middle` | `range_middle` | |
| | | `day_range_start` | `range_start` | |
| | | `day_selected` | `selected` | |
| | | `day_today` | `today` | |
| | | `dropdown_icon` | `chevron` | |
| | | `dropdown_month` | `months_dropdown` | |
| | | `dropdown_year` | `years_dropdown` | |
| | | `head` | Removed | |
| | | `head_cell` | `weekday` | |
| | | `head_row` | `weekdays` | |
| | | `multiple_months` | Removed. Use `data-multiple-months` data attribute. | |
| | | `nav_button` | `button_previous`, `button_next` | |
| | | `nav_button_next` | `button_next` | |
| | | `nav_button_previous` | `button_previous` | |
| | | `nav_icon` | `chevron`, `button_next`, `button_previous` | |
| | | `row` | `week` | |
| | | `table` | `month_grid` | |
| | | `tbody` | `weeks` | |
| | | `tfoot` | `footer` | |
| | | `vhidden` | Removed | |
| | | `weeknumber` | `week_number` | |
| | | `with_weeknumber` | Removed. Use `data-week-numbers` data attribute. | |
| |
|
| | </details> |
| |
|
| | ### 5. Replace `fromDate` and `toDate` |
| |
|
| | Replace `fromDate` and `toDate` with the `hidden`, `startMonth`, and `endMonth` props. |
| |
|
| | #### Example: Replace `fromDate` |
| |
|
| | ```diff |
| | <DayPicker |
| | - fromDate={new Date(2010, 11, 03)} |
| | + startMonth={new Date(2010, 11)} |
| | + hidden={[{ before: new Date(2010, 11, 03) }]} |
| | /> |
| | ``` |
| |
|
| | #### Example: Replace `toDate` |
| |
|
| | ```diff |
| | <DayPicker |
| | - toDate={new Date(2010, 11, 03)} |
| | + endMonth={new Date(2010, 11)} |
| | + hidden={[{ after: new Date(2010, 11, 03) }]} |
| | /> |
| | ``` |
| |
|
| | ### 6. Update Tests and Translations |
| |
|
| | DayPicker's ARIA labels have been updated for clarity. Update your tests and translations accordingly. |
| |
|
| | #### Updated ARIA Labels |
| |
|
| | | Label | Old Label | New Label | |
| | | ------------------------------------------------------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------- | |
| | | [`labelDayButton`](./api/functions/labelDayButton)<br/>_ex_ ~`labelDay`~ | `21st November (Monday)` | `Monday, November 21st, 2024`<br/>`Monday, November 21st, 2024, selected`<br/>`Today, November 21st, 2024` | |
| | | [`labelPrevious`](./api/functions/labelPrevious) | `Go to previous month` | `Go to the Previous Month` | |
| | | [`labelNext`](./api/functions/labelNext) | `Go to next month` | `Go to the Next Month` | |
| | | [`labelWeekNumber`](./api/functions/labelWeekNumber.md) | `Week nr. ##` | `Week ##` | |
| |
|
| | Update test selectors as needed: |
| |
|
| | ```diff |
| | - screen.getByRole('button', 'Go to next month') |
| | + screen.getByRole('button', 'Go to the Next Month') |
| | ``` |
| |
|
| | #### `labelDay` Changes |
| |
|
| | The `labelDay` function has been renamed to `labelDayButton`. It now includes the year and communicates the selected and today status. See [Translating DayPicker](./guides/translation.mdx) for more information. |
| |
|
| | ### 7. Update Formatters to Return a String |
| |
|
| | Formatters now return a `string` instead of a `ReactNode`. Update your code accordingly. |
| |
|
| | ```diff |
| | <DayPicker |
| | formatters={{ |
| | - formatCaption: (month) => <strong>{format(month, "LLLL y")}</strong> // ❌ returned an element |
| | + formatCaption: (month) => format(month, "LLLL y") // ✅ return a string |
| | }} |
| | /> |
| | ``` |
| |
|
| | If you need to return a `ReactElement`, use a [custom component](./guides/custom-components.mdx): |
| |
|
| | ```tsx |
| | <DayPicker |
| | formatters={{ |
| | formatCaption: (month) => format(month, "LLLL y"), // ✅ return a string |
| | }} |
| | components={{ |
| | Caption: ({ children }) => <strong>{children}</strong>, // ✅ return a ReactElement |
| | }} |
| | /> |
| | ``` |
| |
|
| | ### 8. Update Custom Components |
| |
|
| | If you use the `components` prop, update your code as some components have changed. See the [custom components guide](./guides/custom-components.mdx) for details. |
| |
|
| | ```diff |
| | <DayPicker |
| | components={{ |
| | - IconRight: MyRightIcon, |
| | - IconLeft: MyLeftIcon, |
| | + Chevron: (props) => { |
| | + if (props.orientation === "left") { |
| | + return <ChevronLeftIcon {...props} /> |
| | + } |
| | + return <ChevronRightIcon {...props} /> |
| | + }, |
| | }} |
| | /> |
| | ``` |
| |
|
| | <details> |
| | <summary>**List of Updated Components**</summary> |
| |
|
| | | Component | Changes | |
| | | -------------- | --------------------------------------------------------------------------- | |
| | | `Caption` | Renamed to [`MonthCaption`](./api/functions/MonthCaption.md). | |
| | | `Day` | Now renders a [`DayButton`](./api/functions/DayButton.md). | |
| | | `DayContent` | Removed. Use [`formatDay`](./api/functions/formatDay.md) to change content. | |
| | | `Head` | Removed. | |
| | | `HeadRow` | Renamed to [`Weekdays`](./api/functions/Weekdays.md). | |
| | | `IconDropdown` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md). | |
| | | `IconLeft` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md). | |
| | | `IconRight` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md). | |
| | | `Row` | Renamed to [`Week`](./api/functions/Week.md). | |
| |
|
| | </details> |
| |
|
| | ### Deprecations |
| |
|
| | Deprecated props and types will be removed in the next major version. Update your code to avoid breaking changes. |
| |
|
| | #### Deprecated Props |
| |
|
| | | Deprecated Prop | Replacement | Notes | |
| | | --------------- | ------------ | ------------------------------------------------ | |
| | | ~`fromMonth`~ | `startMonth` | Renamed. The start month for the navigation. | |
| | | ~`toMonth`~ | `endMonth` | Renamed. The end month for the navigation. | |
| | | ~`fromYear`~ | `startMonth` | Pass the first month of the year to `startMonth` | |
| | | ~`toYear`~ | `endMonth` | Pass the last month of the year to `endMonth`. | |
| |
|
| | #### Example |
| |
|
| | ```diff |
| | <DayPicker |
| | - fromYear={2010} |
| | + startMonth={new Date(2010, 0)} // January 2010 |
| | - toYear={2021} |
| | + endMonth={new Date(2021, 11)} // December 2021 |
| | /> |
| | ``` |
| |
|
| | #### Deprecated Types |
| |
|
| | If you use TypeScript, some types have been deprecated for clarity and shorter names. |
| |
|
| | ```diff |
| | - import type { DayPickerDefaultProps } from 'react-day-picker' |
| | + import type { PropsBase } from 'react-day-picker' |
| | ``` |
| |
|
| | See the source of [types/deprecated.ts](https://github.com/gpbl/react-day-picker/blob/next/src/types/deprecated.ts) for more details. |
| |
|
| | <details> |
| | <summary>**List of Deprecated Types**</summary> |
| |
|
| | | Deprecated Type | Deprecation Reason | |
| | | ------------------------------ | ------------------------------------------------------------------------------------------------------------- | |
| | | ~`Caption`~ | Renamed to [`MonthCaption`](./api/functions/MonthCaption.md). | |
| | | ~`HeadRow`~ | Removed. | |
| | | ~`Row`~ | Renamed to [`Week`](./api/functions/Week.md). | |
| | | ~`DayPickerSingleProps`~ | Renamed to [`PropsSingle`](./api/interfaces/PropsSingle.md). | |
| | | ~`DayPickerMultipleProps`~ | Renamed to [`PropsMulti`](./api/interfaces/PropsMulti.md). | |
| | | ~`DayPickerRangeProps`~ | Renamed to [`PropsRange`](./api/interfaces/PropsRange.md). | |
| | | ~`DayPickerDefaultProps`~ | Renamed to [`PropsBase`](./api/interfaces/PropsBase.md). | |
| | | ~`DaySelectionMode`~ | Renamed to [`Mode`](./api/type-aliases/Mode.md). | |
| | | ~`Modifier`~ | Will be removed. Use `string` instead. | |
| | | ~`InternaModifier`~ | Split into [`DayFlag`](./api/enumerations/DayFlag) and [`SelectionState`](./api/enumerations/SelectionState). | |
| | | ~`SelectSingleEventHandler`~ | Will be removed. Use [`PropsSingle["onSelect]`](./api/interfaces/PropsSingle.md) instead. | |
| | | ~`SelectMultipleEventHandler`~ | Will be removed. Use [`PropsMulti["onSelect]`](./api/interfaces/PropsMulti.md) instead. | |
| | | ~`SelectRangeEventHandler`~ | Will be removed. Use [`PropsRange["onSelect]`](./api/interfaces/PropsRange.md) instead. | |
| | | ~`DayPickerProviderProps`~ | Not used anymore. | |
| | | ~`useNavigation`~ | Included in [`useDayPicker`](./api/functions/useDayPicker.md). | |
| | | ~`useDayRender`~ | Removed. Customize day rendering with the `htmlAttributes` prop in a custom `Day` component. | |
| | | ~`ContextProvidersProps`~ | Not used anymore. | |
| | | ~`DayLabel`~ | Use `typeof labelDay` instead. | |
| | | ~`NavButtonLabel`~ | Use `typeof labelNext` or `typeof labelPrevious` instead. | |
| | | ~`WeekdayLabel`~ | Use `typeof labelWeekday` instead. | |
| | | ~`WeekNumberLabel`~ | Use `typeof labelWeekNumber` instead. | |
| | | ~`DayClickEventHandler`~ | Use `DayMouseEventHandler` instead. | |
| | | ~`DayFocusEventHandler`~ | Will be removed. Use `DayEventHandler<React.FocusEvent \| React.KeyboardEvent>` instead. | |
| | | ~`DayKeyboardEventHandler`~ | Will be removed. Use `DayEventHandler<React.KeyboardEvent>` instead. | |
| | | ~`DayMouseEventHandler`~ | Will be removed. Use `DayEventHandler<React.MouseEvent>` instead. | |
| | | ~`DayPointerEventHandler`~ | Will be removed. Use `DayEventHandler<React.PointerEvent>` instead. | |
| | | ~`DayTouchEventHandler`~ | Will be removed. Use `DayEventHandler<React.TouchEvent>` instead. | |
| | |
| | </details> |
| | |