docs/pages/blog/material-ui-v4-is-out.md
React components for faster and simpler web development. Build your own design system, or start with Material Design.
MaterialĀ UI v4 has finally arrived. We are so excited about this release, as it defines better foundations for the UI components. Thank you to everyone, especially to the team, and to everyone who's contributed code, issue triage, and support. Thank you.
āØāØāØ See the 4.0.0 Release Note on GitHub. āØāØāØ
<p class="blog-description">https://material-ui.com/</p>MaterialĀ UI v1 was released one year ago. Version 4 is our most important major release since then. For those unfamiliar with the history of the project, we didn't release a v2, and v3 only introduced a slight browsers support change.
This release happens within our fixed frequency release strategy. We try to release a major at least every 12 months and at most every 6 months. The migration from v0 to v1 was painful, it almost felt like using two different UI libraries. We've done our best to minimize the time needed to migrate from v3 to v4. To help ease the transition, you can follow this migration guide š. It shouldn't take more than a few hours.
This release is influenced by two major factors. First, following the Developer Survey we ran in March, we have analyzed the results and used them to change our priorities for the coming year. Secondly, we needed to be up to date with the latest best practices in the React community and with the Material Design Specification.
The Material Design team at Google has made the customization of their design system framework a core feature: Material Theming. It's an important dimension of the library for us. Since the release of v1, we have been improving the component customization demos, release after release. We demonstrate a wide range of different designs:
<p class="blog-description"><a href="https://v4.mui.com/components/text-fields/#customized-inputs">live demo</a></p> <p class="blog-description"><a href="https://v4.mui.com/components/tabs/#customized-tabs">live demo</a></p> <p class="blog-description"><a href="https://mui-treasury.com/primitive/button">live demo</a></p>After listening to v3 customization experiences of hundreds of developers, we realized that we could do better. We have found 4 classes of common problems.
<head> element. However, styled components and other popular styling solutions inject the style just before it, losing specificity. To solve the problem, we have introduced a new prop: injectFirst.import { StylesProvider } from '@mui/styles';
<StylesProvider injectFirst>
{/* Your component tree.
Styled components can override MaterialĀ UI's styles. */}
</StylesProvider>;
.fHmkjM. This design decision helps the isolation of the style of each component, however, it makes the overrides harder. We introduced a classes API in v1 to target all our elements as an attempt to mitigate this problem.
We have observed the use of this API for months and have seen many people struggling with it. It can be challenging to apply the class name on the right element and requires boilerplate as well.
As an attempt to further improve the situation, we have changed the class name generation to output global class names, while keeping the classes API working as before š
.ā ļø Using global class names provide more power but comes with responsibility. We encourage patterns that increase your custom style isolation.
:focus, :hover, :active. Sometimes, MaterialĀ UI can't use a pseudo-class as the state doesn't exist in the platform, for example the selected state of a menu item. MaterialĀ UI implements support of eight different custom pseudo-classes. It's important to understand that you need to increase the specificity when using a pseudo-class. For instance:.MenuItem {
color: black;
}
/* We increase the specificity */
.MenuItem.Mui-selected {
color: blue;
}
const useStyles = makeStyles({
// style rule
foo: (props) => ({
backgroundColor: props.backgroundColor,
}),
bar: {
// CSS property
color: (props) => props.color,
},
});
function MyComponent() {
// Simulated props for the purpose of the example
const props = {
backgroundColor: 'black',
color: 'white',
};
// Pass the props as the first argument of useStyles()
const classes = useStyles(props);
return <div className={`${classes.foo} ${classes.bar}`} />;
}
Documentation was reported as the 3rd most critical pain point in the Developer Survey. We have fixed some of the reported issues and aim to continuously improve going forward.
i18n. Developers come to MaterialĀ UI's documentation from all around the world. We want to include as many people as possible ššš. We have completed the effort started in v3 by working on the Algolia search support, Google search indexing, Table Of Contents and Side Nav infrastructure.
We would like to thank Danica Shen, Dominik Engel, and Jairon Alves Lima for their heroic work on the šØš³, š©šŖ and š§š· translations, while not forgetting the other 348 (and growing) translators.
Best practices. We are now recommending the use of the hooks API over the classes API wherever possible. We have migrated a large portion of the demos to showcase a single approach.
A better UX. We have changed the menu organization to group all the components under a single navigation item. We have changed the background color to white to increase the text contrast and readability.
You may be afraid that using MaterialĀ UI's components will bloat and slow down your website/application. Would you be better off writing your own components? Well, it's our mission to make this cost as minimal as possible š.
import {
Table
TableBody,
TableCell,
TableHead,
TableRow,
Paper,
} from '@mui/material';
MaterialĀ UI v4 depends on React ā„16.8.0. This is the first version of React that supports the new Hooks API.
ref prop to access the underlying DOM node of a React element. You might want to focus an element, compute the position of an element, and so on. You should never need to access a MaterialĀ UI component's instance methods, they are considered private. The components expose an action when it's really needed. For instance, you might want to update the tab indicator position when it goes out of sync with the tab item position. To ease this use case, Sebastian has lead an effort to implement React.forwardRef(). In practice, this means that you can retrieve a reference to the DOM node like you would do with a built-in component (button, div, etc.):import { Button } from '@mui/material';
function MyButton() {
const myRef = React.useRef();
return <Button ref={myRef}>;
}
Hooks migration. While there is no plan to remove classes from React, the React Team encourages new code to be written with the hooks API. Josh has led an effort to rewrite the vast majority of our components with the hooks API. The change has a couple of advantages.
Not all the platforms we support can use the class API natively, so we transpile the syntax with Babel. Functions are supported everywhere, they require fewer line of code. We have observed a -2% gzipped bundle reduction by removing the need to transpile classes.
It reduces the noise in the React Dev Tools āļø, since we could reduce the number of intermediary elements from 5 to 2 in the most common cases. We have found the hooks API easier to work with: to write, to read, and to change. This is a net positive for everyone's productivity. Developers read our source to find inspiration, so we should do our best to promote the best patterns.
<p class="blog-description">React Dev Tools output for one Typography element in production (<a href="https://github.com/mui/material-ui/pull/15023">this POC</a> might further improve the situation).</p>Concurrent mode. React has shared its release timeline for the important features coming into React. Concurrent mode should be released within the next few months. Concurrent Mode lets React apps be more responsive by rendering component trees without blocking the main thread. We have worked on getting ready for it. Most of the work was related to fixing the <React.StrictMode> warnings. You should soon be able to leverage it š„.
Shallow tests. We have removed the majority of our internal shallow tests to rely on full mount tests.
Most of our users are interested in the good looking functional aspect of our components, rather than in a strict application of the Material Design guidelines. However, we think that it's important for us to keep up to date with the guidelines. The specification received it's most significant update since Google made it the design language for its apps in 2014, at Google I/O 2018.
The Material Design "v2" announcement caught us by surprise when we released MaterialĀ UI v1. We have worked on upgrading our components since then. In v4, we have updated the styles of the Tab, Snackbar, Checkboxes, Radios, Switches, List, Dialog, and other components āØ.
<p class="blog-description">Dense Outlined text field</p> <p class="blog-description">Dense Filled text field</p>There are so many new things, we can't be exhaustive. Aside from what we have already announced, you will find:
An application example of the Box component.
An example of the new spacing helper API.
import * as React from 'react';
import { makeStyles } from '@mui/material/styles';
const useStyles = makeStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
export default function Hook() {
const classes = useStyles();
return <button className={classes.root}>Hook</button>;
}
ā ļø Be aware of the difference between @mui/styles and @mui/material/styles. The latter contains the default theme.
Together, we have accomplished most of the objectives we defined a year ago in the v1 release blog post. We're proud of everyone who contributed. We're going to try to execute these new objectives with the same regularity:
Let us know the components you want! š
system in the core. We have received great feedback on the new system package. Going forward, we will try to move it to the core components. Ideally, you should be able to use dynamic color & variants from your theme as well as have access to all the props:import { Button } from '@mui/material';
<Button mt={{ xs: 2, md: 3 }}>Hello worlds</Button>;
How are we going to sustain this ambitious roadmap? We will follow the Bootstrap model. We are working on a Premium theme store.
We have built partnerships with the best theme authors of the ecosystem. Within a few weeks, you should find a collection of the best MaterialĀ UI templates and themes š.
Finally, one last thank you to everyone who's contributed to MaterialĀ UI v4. I'm so excited about this release! It's just the beginning. We will keep working hard on delivering the best possible React UI framework components.
<hr />You can find the same post on Medium.