Migration from v5 to v6
This guide describes the changes needed to migrate the Date and Time Pickers from v5 to v6.
Start using the alpha release
In package.json, change the version of the date pickers package to next.
-"@mui/x-date-pickers": "latest",
+"@mui/x-date-pickers": "next",
Using next ensures that it will always use the latest v6 alpha release, but you can also use a fixed version, like 6.0.0-alpha.0.
Since v6 is a major release, it contains some changes that affect the public API. These changes were done for consistency, improve stability and make room for new features. Below are described the steps you need to take to migrate from v5 to v6.
Run codemods
The preset-safe codemod will automatically adjust the bulk of your code to account for breaking changes in v6. You can run v6.0.0/pickers/preset-safe targeting only Date and Time Pickers or v6.0.0/preset-safe to target Data Grid as well.
It should be only applied once per folder.
// Date and Time Pickers specific
npx @mui/x-codemod v6.0.0/pickers/preset-safe <path>
// Target Data Grid as well
npx @mui/x-codemod v6.0.0/preset-safe <path>
Breaking changes that are handled by this codemod are denoted by a ✅ emoji in the table of contents on the right side of the screen.
If you have already applied the v6.0.0/pickers/preset-safe (or v6.0.0/preset-safe) codemod, then you should not need to take any further action on these items.
All other changes must be handled manually.
Picker components rewrite
Update format of the value prop
Previously, it was possible to provide any format that your date management library was able to parse.
For instance, you could pass value={new Date()} when using AdapterDayjs.
This behavior brought a lot of confusion.
In v6, the format expected by the value prop is the same as for any other prop holding a date.
Here is the syntax to initialize a date picker at the current date for each adapter:
// Date-fns
<DatePicker value={new Date()} />;
// Dayjs
import dayjs from 'dayjs';
<DatePicker value={dayjs()} />;
// Moment
import moment from 'moment';
<DatePicker value={moment()} />;
// Luxon
import { DateTime } from 'luxon';
<DatePicker value={DateTime.now()} />;
Drop clock in desktop mode
In desktop mode, the DateTimePicker and TimePicker components will not display the clock.
This is the first step towards moving to a better implementation.
The behavior on mobile mode is still the same.
If you were relying on Clock Picker in desktop mode for tests—make sure to check testing caveats to choose the best replacement for it.
You can manually re-enable the clock using the new viewRenderers prop.
The code below enables the Clock UI on all the DesktopTimePicker and DesktopDateTimePicker in your application.
Take a look at the default props via theme documentation for more information.
const theme = createTheme({
components: {
MuiDesktopNextTimePicker: {
defaultProps: {
viewRenderers: {
hours: renderTimeViewClock,
minutes: renderTimeViewClock,
seconds: renderTimeViewClock,
},
},
},
MuiDesktopNextDateTimePicker: {
defaultProps: {
viewRenderers: {
hours: renderTimeViewClock,
minutes: renderTimeViewClock,
seconds: renderTimeViewClock,
},
},
},
},
});
Date library and adapters
✅ Do not import adapter from @date-io
In v5, it was possible to import adapters either from @date-io or @mui/x-date-pickers which were the same.
In v6, the adapters are extended by @mui/x-date-pickers to support fields components.
Which means adapters can not be imported from @date-io anymore. They need to be imported from @mui/x-date-pickers or @mui/x-date-pickers-pro. Otherwise, some methods will be missing.
If you do not find the adapter you were using—there probably was a reason for it, but you can raise an issue expressing interest in it.
-import AdapterJalaali from '@date-io/jalaali';
+import { AdapterMomentJalaali } from '@mui/x-date-pickers/AdapterMomentJalaali';
Increase Luxon minimal version
The v6 AdapterLuxon now requires luxon version 3.0.2 or higher in order to work.
Take a look at the Upgrading Luxon guide if you are using an older version.
View components
✅ Rename components
The view components allowing to pick a time, a date or parts of a date without an input have been renamed to better fit their usage:
-<CalendarPicker {...props} />
+<DateCalendar {...props} />
-<DayPicker {...props} />
+<DayCalendar {...props} />
-<CalendarPickerSkeleton {...props} />
+<DayCalendarSkeleton {...props} />
-<MonthPicker {...props} />
+<MonthCalendar {...props} />
-<YearPicker {...props} />
+<YearCalendar {...props} />
-<ClockPicker {...props} />
+<TimeClock {...props} />
Component names in the theme have changed as well:
-MuiCalendarPicker: {
+MuiDateCalendar: {
-MuiDayPicker: {
+MuiDayCalendar: {
-MuiCalendarPickerSkeleton: {
+MuiDayCalendarSkeleton: {
-MuiMonthPicker: {
+MuiMonthCalendar: {
-MuiYearPicker: {
+MuiYearCalendar: {
-MuiClockPicker: {
+MuiTimeClock: {
✅ Rename date prop to value
The date prop has been renamed value on MonthCalendar, YearCalendar, TimeClock, and DateCalendar (components renamed in previous section):
-<MonthPicker date={dayjs()} />
+<MonthCalendar value={dayjs()} />
-<YearPicker date={dayjs()} />
+<YearCalendar value={dayjs()} />
-<ClockPicker date={dayjs()} />
+<TimeClock value={dayjs()} />
-<CalendarPicker date={dayjs()} />
+<DateCalendar value={dayjs()} />
Use the 12h/24h format from the locale as the default value of the ampm prop on TimeClock
The default value of the ampm prop changed from false to utils.is12HourCycleInCurrentLocale().
It means that the TimeClock component will use a 12h time format for locales where the time is usually displayed with a 12h format.
If you want to keep the previous behavior, you just have to set the ampm prop to false (components renamed in previous section):
- <ClockPicker />
+ <TimeClock ampm={false} />
Localization
✅ Rename localization props
The props used to set the text displayed in the pickers have been replaced by keys inside the localeText prop:
| Removed prop | Property in the new localText prop |
|---|---|
endText |
end |
getClockLabelText |
clockLabelText |
getHoursClockNumberText |
hoursClockNumberText |
getMinutesClockNumberText |
minutesClockNumberText |
getSecondsClockNumberText |
secondsClockNumberText |
getViewSwitchingButtonText |
calendarViewSwitchingButtonAriaLabel |
leftArrowButtonText |
openPreviousView (or previousMonth when the button changes the visible month) |
rightArrowButtonText |
openNextView (or nextMonth when the button changes the visible month) |
startText |
start |
For instance if you want to replace the startText / endText
<DateRangePicker
- startText="From"
- endText="To"
+ localeText={{
+ start: 'From',
+ end: 'To',
+ }}
/>
✅ Rename locale prop on LocalizationProvider
The locale prop of the LocalizationProvider component have been renamed adapterLocale:
<LocalizationProvider
dateAdapter={AdapterDayjs}
- locale="fr"
+ adapterLocale="fr"
>
{children}
</LocalizationProvider
Component slots (custom sub-components)
Toolbar (ToolbarComponent)
The
ToolbarComponenthas been replaced by aToolbarcomponent slot. You can find more information about this pattern in the MUI Base documentation:// Same on all other pickers <DatePicker - ToolbarComponent: MyToolbar, + components={{ Toolbar: MyToolbar }} />The
toolbarPlaceholderandtoolbarFormatprops have been moved to thetoolbarcomponent props slot:// Same on all other pickers <DatePicker - toolbarPlaceholder="__" - toolbarFormat="DD / MM / YYYY" + componentsProps={{ + toolbar: { + toolbarPlaceholder: "__", + toolbarFormat: "DD / MM / YYYY", + } + }} />The
toolbarTitleprop has been moved to the localization object:// Same on all other pickers <DatePicker - toolbarTitle="Title" + localeText={{ toolbarTitle: "Title" }} />The toolbar related translation keys have been renamed to better fit their usage:
// Same on all other pickers <DatePicker localeText={{ - datePickerDefaultToolbarTitle: 'Date Picker', + datePickerToolbarTitle: 'Date Picker', - timePickerDefaultToolbarTitle: 'Time Picker', + timePickerToolbarTitle: 'Time Picker', - dateTimePickerDefaultToolbarTitle: 'Date Time Picker', + dateTimePickerToolbarTitle: 'Date Time Picker', - dateRangePickerDefaultToolbarTitle: 'Date Range Picker', + dateRangePickerToolbarTitle: 'Date Range Picker', }} />The
onChange/openViewprops on the toolbar have been renamed toonViewChange/view.const CustomToolbarComponent = props => ( <div> - <button onChange={() => props.onChange('day')}>Show day view</button> + <button onClick={() => props.onViewChange('day')}>Show day view</button> - <div>Current view: {props.openView}</div> + <div>Current view: {props.view}</div> </div> ) <DatePicker - ToolbarComponent={CustomToolbarComponent} + components={{ + Toolbar: CustomToolbarComponent + }} />The
currentlySelectingRangeEnd/setCurrentlySelectingRangeEndprops on the Date Range Picker toolbar have been renamed torangePosition/onRangePositionChange.const CustomToolbarComponent = props => ( <div> - <button onChange={() => props.setCurrentlySelectingRangeEnd('end')}>Edit end date</button> + <button onClick={() => props.onRangePositionChange('end')}>Edit end date</button> - <div>Is editing end date: {props.currentlySelectingRangeEnd === 'end'}</div> + <div>Is editing end date: {props.rangePosition === 'end'}</div> </div> ) <DateRangePicker - ToolbarComponent={CustomToolbarComponent} + components={{ + Toolbar: CustomToolbarComponent + }} />
Tabs
The
hideTabsandtimeIconprops have been moved totabscomponent props. ThedateRangeIconprop has been renamed todateIconand moved totabscomponent props.// Same on all other Date Time picker variations <DateTimePicker - hideTabs={false} - dateRangeIcon={<LightModeIcon />} - timeIcon={<AcUnitIcon />} + componentsProps={{ + tabs: { + hidden: false, + dateIcon: <LightModeIcon />, + timeIcon: <AcUnitIcon />, + } + }} />The
onChangeprop onDateTimePickerTabscomponent has been renamed toonViewChangeto better fit its usage:<DateTimePickerTabs - onChange={() => {}} + onViewChange={() => {}} />const CustomTabsComponent = props => ( <div> - <button onClick={() => props.onChange('day')}>Show day view</button> + <button onClick={() => props.onViewChange('day')}>Show day view</button> </div> ) <DateTimePicker components={{ Tabs: CustomTabsComponent }} />
Action bar
The
actionprop of theactionBarslot is no longer supporting a callback. Instead, you can pass a callback at the slot level<DatePicker componentsProps={{ - actionBar: { - actions: (variant) => (variant === 'desktop' ? [] : ['clear']), - }, + actionBar: ({ wrapperVariant }) => ({ + actions: wrapperVariant === 'desktop' ? [] : ['clear'], + }), }} />
Day (renderDay)
The
renderDayprop has been replaced by aDaycomponent slot on all date, date time and date range pickers:<DatePicker - renderDay={(_, dayProps) => <CustomDay {...dayProps} />} + components={{ Day: CustomDay }} />The
selectedDaysprop have been removed from theDaycomponent. If you need to access it, you can control the value and pass it to the slot usingcomponentsProps:function CustomDay({ selectedDay, ...other }) { // do something with 'selectedDay' return <PickersDay {...other} />; } function App() { const [value, setValue] = React.useState(null); return ( <DatePicker value={value} onChange={(newValue) => setValue(newValue)} components={{ Day: CustomDay }} componentsProps={{ day: { selectedDay: value }, }} /> ); }
Popper (PopperProps)
The
PopperPropsprop has been replaced by apoppercomponent props on all responsive and desktop pickers:<DatePicker - PopperProps={{ onClick: handleClick }} + componentsProps={{ popper: { onClick: handleClick }}} />
Desktop transition (TransitionComponent)
The
TransitionComponentprop has been replaced by aDesktopTransitioncomponent slot on all responsive and desktop pickers:<DatePicker - TransitionComponent={Fade} + components={{ DesktopTransition: Fade }} />
Dialog (DialogProps)
The
DialogPropsprop has been replaced by adialogcomponent props on all responsive and mobile pickers:<DatePicker - DialogProps={{ backgroundColor: 'red' }} + componentsProps={{ dialog: { backgroundColor: 'red }}} />
Desktop paper (PaperProps)
The
PaperPropsprop has been replaced by adesktopPapercomponent props on all responsive and desktop pickers:<DatePicker - PaperProps={{ backgroundColor: 'red' }} + componentsProps={{ desktopPaper: { backgroundColor: 'red }}} />
Desktop TrapFocus (TrapFocusProp)
The
TrapFocusPropsprop has been replaced by adesktopTrapFocuscomponent props on all responsive and desktop pickers:<DatePicker - TrapFocusProps={{ isEnabled: () => false }} + componentsProps={{ desktopTrapFocus: { isEnabled: () => false }}} />
Paper Content
The
PaperContent/paperContentcomponent slot and component props slot have been removed.You can use the new
Layoutcomponent slot. The main difference is that you now receive the various parts of the UI instead of a singlechildrenprop:+import { usePickerLayout } from '@mui/x-date-pickers/PickersLayout'; function MyCustomLayout (props) { - const { children } = props; - - return ( - <React.Fragment> - {children} - <div>Custom component</div> - </React.Fragment> - ); + const { toolbar, tabs, content, actionBar} = usePickerLayout(props); + + return ( + <PickersLayoutRoot> + {toolbar} + {content} + {actionBar} + <div>Custom component</div> + </PickersLayoutRoot> + ); } function App() { return ( <DatePicker components={{ - PaperContent: MyCustomLayout, + Layout: MyCustomLayout, }} /> ); }
Left arrow button
- The component slot
LeftArrowButtonhas been renamedPreviousIconButtonon all pickers:
<DatePicker
components={{
- LeftArrowButton: CustomButton,
+ PreviousIconButton: CustomButton,
}}
componentsProps={{
- leftArrowButton: {},
+ previousIconButton: {},
}}
/>
Right arrow button
The component slot
RightArrowButtonhas been renamedNextIconButtonon all pickers:<DatePicker components={{ - RightArrowButton: CustomButton, + NextIconButton: CustomButton, }} componentsProps={{ - rightArrowButton: {}, + nextIconButton: {}, }} />
Rename remaining private components
The four components prefixed with Private are now stable.
These components were renamed:
PrivatePickersMonth->MuiPickersMonthPrivatePickersSlideTransition->MuiPickersSlideTransitionPrivatePickersToolbarText->MuiPickersToolbarTextPrivatePickersYear->MuiPickersYear
Manual style overriding will need to use updated classes:
-.PrivatePickersMonth-root {
+.MuiPickersMonth-root {
-.PrivatePickersSlideTransition-root {
+.MuiPickersSlideTransition-root {
-.PrivatePickersToolbarText-root {
+.MuiPickersToolbarText-root {
-.PrivatePickersYear-root {
+.MuiPickersYear-root {
Component name changes are also reflected in themeAugmentation:
const theme = createTheme({
components: {
- PrivatePickersMonth: {
+ MuiPickersMonth: {
// overrides
},
- PrivatePickersSlideTransition: {
+ MuiPickersSlideTransition: {
// overrides
},
- PrivatePickersToolbarText: {
+ MuiPickersToolbarText: {
// overrides
},
- PrivatePickersYear: {
+ MuiPickersYear: {
// overrides
},
},
});