Upgrading to v9
This release includes significant updates related to accessibility, styles, internationalization, and performance. See the changelog 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, then follow the steps below.
Checklist
1. Upgrade to the Latest Version
- npm
- Yarn
- pnpm
- Bun
npm install react-day-picker@latest
yarn add react-day-picker@latest
pnpm add react-day-picker@latest
bun add react-day-picker@latest
If you are not using date-fns directly in your code (e.g., when using a different locale), remove it from your dependencies:
- npm
- Yarn
- pnpm
- Bun
npm remove date-fns
yarn remove date-fns
pnpm remove date-fns
bun 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 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.
+ 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:
<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:
<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 type.
List of Updated Class Names
| 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. |
5. Replace fromDate and toDate
Replace fromDate and toDate with the hidden, startMonth, and endMonth props.
Example: Replace fromDate
<DayPicker
- fromDate={new Date(2010, 11, 03)}
+ startMonth={new Date(2010, 11)}
+ hidden={[{ before: new Date(2010, 11, 03) }]}
/>
Example: Replace toDate
<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 |
|---|---|---|
labelDayButtonex labelDay | 21st November (Monday) | Monday, November 21st, 2024Monday, November 21st, 2024, selectedToday, November 21st, 2024 |
labelPrevious | Go to previous month | Go to the Previous Month |
labelNext | Go to next month | Go to the Next Month |
labelWeekNumber | Week nr. ## | Week ## |
Update test selectors as needed:
- 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 for more information.
7. Update Formatters to Return a String
Formatters now return a string instead of a ReactNode. Update your code accordingly.
<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:
<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 for details.
<DayPicker
components={{
- IconRight: MyRightIcon,
- IconLeft: MyLeftIcon,
+ Chevron: (props) => {
+ if (props.orientation === "left") {
+ return <ChevronLeftIcon {...props} />;
+ }
+ return <ChevronRightIcon {...props} />;
+ },
}}
/>
List of Updated Components
| Component | Changes |
|---|---|
Caption | Renamed to MonthCaption. |
Day | Now renders a DayButton. |
DayContent | Removed. Use formatDay to change content. |
Head | Removed. |
HeadRow | Renamed to Weekdays. |
IconDropdown | Removed. The icon is rendered by Chevron. |
IconLeft | Removed. The icon is rendered by Chevron. |
IconRight | Removed. The icon is rendered by Chevron. |
Row | Renamed to Week. |
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
<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.
- import type { DayPickerDefaultProps } from 'react-day-picker';
+ import type { PropsBase } from 'react-day-picker';
See the source of types/deprecated.ts for more details.
List of Deprecated Types
| Deprecated Type | Deprecation Reason |
|---|---|
Caption | Renamed to MonthCaption. |
HeadRow | Removed. |
Row | Renamed to Week. |
DayPickerSingleProps | Renamed to PropsSingle. |
DayPickerMultipleProps | Renamed to PropsMulti. |
DayPickerRangeProps | Renamed to PropsRange. |
DayPickerDefaultProps | Renamed to PropsBase. |
DaySelectionMode | Renamed to Mode. |
Modifier | Will be removed. Use string instead. |
InternaModifier | Split into DayFlag and SelectionState. |
SelectSingleEventHandler | Will be removed. Use PropsSingle["onSelect] instead. |
SelectMultipleEventHandler | Will be removed. Use PropsMulti["onSelect] instead. |
SelectRangeEventHandler | Will be removed. Use PropsRange["onSelect] instead. |
DayPickerProviderProps | Not used anymore. |
useNavigation | Included in useDayPicker. |
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. |