Skip to content

Latest commit

 

History

History
426 lines (324 loc) · 12.5 KB

migration-v3.md

File metadata and controls

426 lines (324 loc) · 12.5 KB

Migration From v3 to v4

Yeah, v4 alpha has been released!

Looking for the v3 docs? Find them here.

This document is a work in progress. Have you upgraded your site and run into something that's not covered here? Add your changes on GitHub

Introduction

This is a reference for upgrading your site from Material-UI v3 to v4. While there's a lot covered here, you probably won't need to do everything for your site. We'll do our best to keep things easy to follow, and as sequential as possible so you can quickly get rocking on v4!

Why you should migrate

This documentation page covers the how of migrating from v3 to v4. The why is covered in the release blog post: Work in progress, on Medium.

Updating Your Dependencies

The very first thing you will need to do is update your dependencies.

Update Material-UI version

You need to update your package.json to use the latest version of Material-UI.

"dependencies": {
  "@material-ui/core": "^4.0.0-alpha.0"
}

Or run

npm install @material-ui/core@next

or

yarn add @material-ui/core@next

Update React version

The minimum required version of React was increased from react@^16.3.0 to react@^16.8.0. This allows us to rely on Hooks.

Handling Breaking Changes

Core

  • Every component forward their ref. This is implemented by using React.forwardRef(). This affects the internal component tree and display name and therefore might break shallow or snapshot tests. innerRef will no longer return a ref to the instance (or nothing if the inner component is a function component) but a ref to its root component. The corresponding API docs list the root component.

Styles

  • ⚠️ Material-UI depends on JSS v10. JSS v10 is not backward compatible with v9. Make sure JSS v9 is not installed in your environment. Removing react-jss from your package.json can help.

  • Isolation of the styling solution of the core components in a dedicated package. Remove the MuiThemeProvider component:

    -import { MuiThemeProvider } from '@material-ui/core/styles';
    +import { ThemeProvider } from '@material-ui/styles';
  • Remove the first option argument of withTheme(). The first argument was a placeholder for a potential future option. We have never found a need for it. It's time to remove this argument. It matches the emotion and styled-components API.

    -const DeepChild = withTheme()(DeepChildRaw);
    +const DeepChild = withTheme(DeepChildRaw);
  • Scope the keyframes API. You should apply the following changes in your codebase. It helps isolating the animation logic:

    rippleVisible: {
      opacity: 0.3,
  • animation: 'mui-ripple-enter 100ms cubic-bezier(0.4, 0, 0.2, 1)',

  • animation: $mui-ripple-enter 100ms cubic-bezier(0.4, 0, 0.2, 1), }, '@keyframes mui-ripple-enter': { '0%': { opacity: 0.1, }, '100%': { opacity: 0.3, }, },

### Theme

- The `theme.palette.augmentColor()` method no longer performs a side effect on its input color.
To use it correctly, you have to use the returned value.

```diff
-const background = { main: color };
-theme.palette.augmentColor(background);
+const background = theme.palette.augmentColor({ main: color });

console.log({ background });
  • You can safely remove the next variant from the theme creation:

    typography: {
      useNextVariants: true,
    },

Typography

  • [Typography] Remove the deprecated typography variants. You can upgrade by performing the following replacements:

    • display4 => h1
    • display3 => h2
    • display2 => h3
    • display1 => h4
    • headline => h5
    • title => h6
    • subheading => subtitle1
    • body2 => body1
    • body1 (default) => body2 (default)
  • [Typography] Remove the opinionated display: block default typography style. You can use the new display?: 'initial' | 'inline' | 'block'; property.

  • [Typography] Rename the headlineMapping property to variantMapping to better align with its purpose.

    -<Typography headlineMapping={headlineMapping}>
    +<Typography variantMapping={variantMapping}>
  • [Typography] Change the default variant from body2 to body1. A font size of 16px is a better default than 14px. Bootstrap, material.io or even our documentation use 16px as a default font size. 14px like Ant Design is understandable as Chinese users have a different alphabet. We document 12px as the default font size for Japanese.

  • [Typography] Remove the default color from the typography variants. The color should inherit most of the time. It's the default behavior of the web.

  • [Typography] Rename color="default" to color="initial" following the logic of #13028. The usage of default should be avoided, it lakes semantic.

Button

  • [Button] Remove the deprecated button variants (flat, raised and fab):

    -<Button variant="raised" />
    +<Button variant="contained" />
    -<Button variant="flat" />
    +<Button variant="text" />
    -import Button from '@material-ui/core/Button';
    -<Button variant="fab" />
    +import Fab from '@material-ui/core/Fab';
    +<Fab />

TextField

  • [InputLabel] You should be able to override all the styles of the FormLabel component using the CSS API of the InputLabel component. The FormLabelClasses property has been removed.

    <InputLabel
    - FormLabelClasses={{ asterisk: 'bar' } }
    + classes={{ asterisk: 'bar' } }
    >
      Foo
    </InputLabel>
  • [InputBase] Change the default box sizing model. It uses the following CSS now:

    box-sizing: border-box;

    It solves issues with the fullWidth prop.

  • [InputBase] Remove the inputType class from InputBase.

Layout

  • [Grid] In order to support arbitrary spacing values and to remove the need to mentally county by 8, we are changing the spacing API:

      /**
       * Defines the space between the type `item` component.
       * It can only be used on a type `container` component.
       */
    -  spacing: PropTypes.oneOf([0, 8, 16, 24, 32, 40]),
    +  spacing: PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),

    Going forward, you can use the theme to implement a custom Grid spacing transformation function.

Table

  • [TableCell] Remove the deprecated numeric property.

    -<TableCell numeric>{row.calories}</TableCell>
    +<TableCell align="right">{row.calories}</TableCell>
  • [TableRow] Remove the fixed height CSS property. The cell height is computed by the browser using the padding and line-height.

  • [TableCell] Move the dense mode to a different property:

    -<TableCell padding="dense" />
    +<TableCell size="small" />
  • [TablePagination] The component no longer tries to fix invalid (page, count, rowsPerPage) property combinations. It raises a warning instead.

Tabs

  • [Tab] Remove the labelContainer, label and labelWrapped class keys for simplicity. This has allowed us to removed 2 intermediary DOM elements. You should be able to move the custom styles to the root class key.

    capture d ecran 2019-02-23 a 15 46 48

Menu

  • [MenuItem] Remove the fixed height of the MenuItem. The padding and line-height are used by the browser to compute the height.

List

  • [List] Rework the list components to match the specification:

    • The usage of the ListItemAvatar component is required when using an avatar
    • The usage of the ListItemIcon component is required when using a left checkbox
    • The edge property should be set on the icon buttons.

Paper

  • [Paper] Reduce the default elevation. Change the default Paper elevation to match the Card and the Expansion Panel:

    -<Paper />
    +<Paper elevation={2} />

Dialog

  • [DialogActions] Rename the disableActionSpacing prop disableSpacing.

  • [DialogActions] Rename the action CSS class spacing.

  • [DialogContentText] Use typography variant body1 instead of subtitle1.

  • [Dialog] The child needs to be able to hold a ref.

    class Component extends React.Component {
      render() {
        return <div />
      }
    }
    -const MyComponent = props => <div {...props} />
    +const MyComponent = React.forwardRef((props, ref) => <div ref={ref} {...props} />);
    <Dialog><Component /></Dialog>
    <Dialog><MyComponent /></Dialog>
    <Dialog><div /></Dialog>

Card

  • [CardActions] Rename the disableActionSpacing prop disableSpacing.
  • [CardActions] Remove the disableActionSpacing CSS class.
  • [CardActions] Rename the action CSS class spacing.

ClickAwayListener

  • [ClickAwayListener] Hide react-event-listener.

ExpansionPanel

  • [ExpansionPanelActions] Rename the action CSS class spacing.

Switch

  • [Switch] Refactor the implementation to make it easier to override the styles. Rename the class names to match the specification wording:

    -icon
    -bar
    +thumb
    +track

Divider

  • [Divider] Remove the deprecated inset prop.

    -<Divider inset />
    +<Divider variant="inset" />

Snackbar

  • [Snackbar] Match the new specification.

    • Change the dimensions
    • Change the default transition to from Slide to Grow.

SvgIcon

  • [SvgIcon] Rename nativeColor -> htmlColor. React solved the same problem with the for HTML attribute, they have decided to call the prop htmlFor. This change follows the same reasoning.

    -<AddIcon nativeColor="#fff" />
    +<AddIcon htmlColor="#fff" />

Node

UMD

  • This change eases the use of Material-UI with a CDN:

    const {
      Button,
      TextField,
    -} = window['material-ui'];
    +} = MaterialUI;

    It's consistent with the other React projects:

    • material-ui => MaterialUI
    • react-dom => ReactDOM
    • prop-types => PropTypes

Modal

  • [Modal] The child needs to be able to hold a ref.

    class Component extends React.Component {
      render() {
        return <div />
      }
    }
    -const MyComponent = props => <div {...props} />
    +const MyComponent = React.forwardRef((props, ref) => <div ref={ref} {...props} />);
    <Modal><Component /></Modal>
    <Modal><MyComponent /></Modal>
    <Modal><div /></Modal>
  • [Modal] Remove the classes customization API for the Modal component. (-74% bundle size reduction when used standalone)

  • [Modal] event.defaultPrevented is now ignored. The new logic closes the Modal even if event.preventDefault() is called on the key down escape event. event.preventDefault() is meant to stop default behaviors like clicking a checkbox to check it, hitting a button to submit a form, and hitting left arrow to move the cursor in a text input etc. Only special HTML elements have these default behaviors. People should use event.stopPropagation() if they don't want to trigger a onClose event on the modal.

Portal

  • [Portal] The child needs to be able to hold a ref when disablePortal is used.

    class Component extends React.Component {
      render() {
        return <div />
      }
    }
    -const MyComponent = props => <div {...props} />
    +const MyComponent = React.forwardRef((props, ref) => <div ref={ref} {...props} />);
    <Portal><Component /></Portal>
    <Portal><MyComponent /></Portal>
    <Portal><div /></Portal>

Slide

  • [Slide] The child needs to be able to hold a ref.

    class Component extends React.Component {
      render() {
        return <div />
      }
    }
    -const MyComponent = props => <div {...props} />
    +const MyComponent = React.forwardRef((props, ref) => <div ref={ref} {...props} />);
    <Slide><Component /></Slide>
    <Slide><MyComponent /></Slide>
    <Slide><div /></Slide>

Tooltip

  • [Tooltip] The child needs to be able to hold a ref.

    class Component extends React.Component {
      render() {
        return <div />
      }
    }
    -const MyComponent = props => <div {...props} />
    +const MyComponent = React.forwardRef((props, ref) => <div ref={ref} {...props} />);
    <Tooltip><Component /></Tooltip>
    <Tooltip><MyComponent /></Tooltip>
    <Tooltip><div /></Tooltip>