Material-UI pickers

Upgrading to v3#

Version v3 for @material-ui/pickers is coming with a whole bunch of breaking changes. This is a guide of how-to update :)

⬇️ Install#

First of all, you need to install the new package, because the project is transferred to mui-org! Please also note, that v3 of @material-ui/pickers relies on v4 of @material-ui/core

npm i @material-ui/pickers @material-ui/core@latest

yarn add @material-ui/pickers @material-ui/core@latest

Note: It's also required to upgrade your @material-ui/core version to @next

🌚 Imports#

There are a lot of changes in imports. From now on, we are not providing keyboard prop on the pickers. Keyboard mode comes with separate components like <KeyboardDatePicker />. Thus you are assured that keyboard-specific logic will be correctly tree-shaken.

- import { DatePicker } from '@material-ui/pickers'
+ import { KeyboardDatePicker } from '@material-ui/pickers'

- <DatePicker keyboard />
+ <KeyboardDatePicker />

Also there are no more wrapper-specific components, like InlineDatePicker. Use variant prop instead.

- import { InlineDatePicker } from '@material-ui/pickers'
+ import { DatePicker } from '@material-ui/pickers'

- <InlineDatePicker />
+ <DatePicker variant="inline" />

To override the default material-ui's <TextField /> variant use

<DatePicker variant="inline" inputVariant="outlined" />

💪 State management#

We have done a lot of work to make state-management of pickers more obvious in v3 and simplify the form integration experience. From now on, there is no hidden internal state under the hood. Your components are truly controlled.

That means that now onChange will be called on each particular day-click or keystroke. So if you are doing some heavy operations in onChange (e.g. xhr requests, dom mutations or redirects) - please move them to onAccept. This callback will be fired only when the user actually accepts the date.

+ onChange={setDate} // stateLogic
+ onAccept={requestSomeDataFromServer} // async action
- onChange={(newDate) => {
-   setDate(newDate)
-   requestSomeDataFromServer(newDate)
- }}

⌨ Keyboard mode#

Previously, keyboard mode was a bit painful, especially from form integration perspective. That's why we recreated it from scratch. Now onChange prop for <Keyboard(Date|Time)Picker /> has different signature from the pure pickers:

type KeybordOnChange = (date: MaterialUiPickersDate | null, value: string | undefined) => void;

It is even possible to control keyboard pickers by pure string. ⚠️ value prop will work as well ⚠️

function KeyboardString() {
  const [value, setValue] = useState('01/01/2019');

  return (
      onChange={(_, newValue) => setValue(newValue)}

Also we completely replaced react-text-mask with rifm. That saved us several KBs of bundle size, and improved performance

🎉 And now no more need in mask prop 🎉#

Mask will be generated and applied automatically from the format passed. So please, make sure that your formats are easy to input from keyboard. And it is still possible to fully customize mask, checkout this example.

- mask={[/d/, /d/, "/", /d/, /d/, "/", /d/, /d/, /d/, /d/]}

🚪 Controlling open/close state#

ref approach to customize open/close state was replaced with open props and onClose, onOpen callbacks. Check out the new example

🛡 Typescript#

We are working hard to make this library perfectly Typescript compatible. And from v3 and on, date type in such props like onChange, value will automatically be inferred from the @date-io package you used. So less any from our side :)

🙈 Misc#

  • Improved accessibility by making the toolbar button actually focusable <button />
  • Rename moment property of MuiPickersUtilsProvider to libInstance
  • Rename onlyCalendar prop to disableToolbar
  • Remove withUtils HOC, and provide useUtils hook
  • Remove BasePicker HOC, and provide usePickerState and useKeyboardPickerState hooks
  • Remove openToYearSelection prop in favor of openTo
  • Remove exported MuiPickersContextConsumer in favor of useUtils hook
  • When using views prop - DatePicker by default will open to the the first item of views.
  • Order of views will now follow the order in the passed views array.