Let's get Material, Material-UI
Tags: react, materialui, css, beginners
Published: 2021-09-01 08:49:18

(9/27/21: This post is outdated after Material-UI (MUI) released [Version 5](https://mui.com/blog/mui-core-v5/))

Which CSS framework is the best for React and why is it Material-UI? Material-UI is a framework of React components with it's design based on [Google's Material Design](https://material.io/design). If you're familiar with React, you know how easy it is to work with components. When you need to style a container, button, text, etc. you just import the Material-UI component for that element and customize it with props. Let's go over setting it up for your project and some of the available components.

![React and Material-UI logos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txmsevpbeqzmgw240w5i.png)

#Installation
First install the source files via npm
```react
npm install @material-ui/core
```

Load the default Roboto font into your index.html
```react
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
```
![Index.html with Roboto](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ae89pyvsvntqpv7zl2e.png)

#Components
Go to the [Material-UI](https://material-ui.com/) site and search for the component you are using. Scroll down to the bottom of the page and click on **API** and you will see all the props and customization points.

First import the component into your project, *Typography* for example
```react
import Typography from '@material-ui/core/Typography'
```

Depending if you have content that needs to be wrapped in your component or not, you will wrap it with an open and closing component or you can call the component and have it self closing
```react
<Typography>
  Wrapped content
</Typography>

<TextField />
```

Customize the component using the **variant** prop
```react
<Typography variant='h1'>
  This is H1
</Typography>
<Typography variant='h2'>
  This is H2
</Typography>
```
![H1 and H2 variant](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4tbw8z94utsfqeijkkp.png)

#Grid
Material-UI gives us a 12 column grid system based on [flexbox](https://www.w3schools.com/css/css3_flexbox.asp).

Import the *Grid* component
```react
import Grid from '@material-ui/core/Grid'
```

Create a Grid container that will wrap around the the Grid items
```react
<Grid container>
  <Grid item>
    Item 1
  </Grid>
  <Grid item>
    Item 2
  </Grid>
  <Grid item>
    Item 3
  </Grid>
  <Grid item>
    Item 4
  </Grid>
</Grid>
```
![No spacing grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ihkbexpkgz62shv18wm3.png)
This will just lay these items next to each other, but we can pass in breakpoints and it will create spacing and make the grid responsive
```react
<Grid container>
  <Grid item xs={3}>
    Item 1
  </Grid>
  <Grid item xs={3}>
    Item 2
  </Grid>
  <Grid item xs={3}>
    Item 3
  </Grid>
  <Grid item xs={3}>
    Item 4
  </Grid>
</Grid>
```
![Spaced grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rm1u5xse72n0re20n3ri.png)

#Drawer
Navigation drawers can hold your links and other app functions. There are different drawer types:
 * Temporary - can toggle open or closed and sits on top of content
 * Persistent - can toggle open or closed and is on the same level as your content, this will re-adjust the size of your content
 * Permanent - are always visible and pinned to the left edge, they can't be closed

Import your *Drawer* component
```react
import Drawer from '@material-ui/core/Drawer'
```
Wrap your content in the opening and closing Drawer component then set the type with *variant*, we'll go with a *Temporary* drawer here. Then the side you want the Drawer to appear from we assign with *anchor*
```react
<Drawer variant='temporary' anchor='left'>
  Our Links
</Drawer>
```
We can toggle the Drawer open or close with *open* which takes in a boolean. I like to use useState and toggle with a button
```react
const [open, setOpen] = useState(false)
const toggleDrawer = () => { setOpen(open => !open) }

<Button onClick={toggleDrawer}>Toggle Drawer</Button>
<Drawer variant='temporary' anchor='left' open={open}>
  Our Links
</Drawer>
```
Drawers also have an *onClose* prop that takes in a callback function. This will be triggered when a user clicks on another part of the app while the Drawer is open. We can assign our toggleDrawer function to toggle our state and close the Drawer
```react
<Drawer variant='temporary' anchor='left' open={open} onClose={toggleDrawer}>
  Our Links
</Drawer>
```

#makeStyles Hook
Allows you to create CSS classes and add custom CSS

This has to be imported using destructuring
```react
import { makeStyles } from '@material-ui/core'
```
Assign a constant to *makeStyles* that takes in an object where we create a CSS class and add our custom CSS
```react
const useStyles = makeStyles({
   text: {
     fontSize: 50,
     backgroundColor: 'red'
   }
})
```
Assign another constant inside our component function to useStyles and invoke it then assign it to the component we want to style with *className*
```react
function App() {
  const classes = useStyles()

  return (
    <Typography className={classes.text}>
      Wrapped Content
    </Typography>
  );
}

export default App;
```
There are many more customization options, again check the **API** for what's available.

#Custom Themes
Material-UI has a default theme that has colors set and uses the Roboto font. You can find the settings on the default theme by searching **default theme** on the Material-UI site. We can change these settings with custom themes.

First import the needed functions into the root component of your app so the entire app has access to the custom theme
```react
import { createMuiTheme, ThemeProvider } from '@material-ui/core'
```
Assign a constant to *createMuiTheme* that takes in an object where we create our custom theme. Here we access the main color
```react
const theme = createMuiTheme({
  palette: {
    primary: {
      main: '#FEFEFE'
    }
  }
})
```
Wrap your entire app in the *ThemeProvider* then assign the custom theme we created using *theme*
```react
function App() {
  
  return (
    <ThemeProvider theme={theme}>
      <Typography color='primary'>
        Wrapped Content
      </Typography>
    </ThemeProvider>
  );
}

export default App;
```
We can change the font of the Typography component
```react
const theme = createMuiTheme({
  palette: {
    primary: {
      main: '#FEFEFE'
    }
  },
  typography: {
    fontFamily: 'Quicksand'
  }
})
```
Look in the default theme and find other settings you would like to customize



#Conclusion
As you can see Material-UI is very easy to use and customizable. The Grid component makes it very easy to create responsive apps. To dive deeper I recommend reading through the documentation on the Material-UI site. I will also link a great youtube tutorial I used to learn about Material-UI. Happy coding!

#Resources
[Material-UI](https://material-ui.com/)
[Material-UI Tutorial by The Net Ninja](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gjxLvV4VEkZ6H6H4yWuS58)