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
npm install react-day-picker@latest
yarn add react-day-picker@latest
pnpm 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
npm remove date-fns
yarn remove date-fns
pnpm 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 |
---|---|---|
labelDayButton ex labelDay | 21st November (Monday) | Monday, November 21st, 2024 Monday, November 21st, 2024, selected Today, 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. |