Quickly set up a theme in Material-UI and access it in your components

Add a customisable Material-UI theme to your React app

Photo by Toa Heftiba on Unsplash

There are a million tutorials on Create React App, but few walk through adding the minimal code needed to get started with the Material-UI theme.

We’re going to skip the React basics and focus on:

  • Installing Material-UI
  • Adding the default theme to your app
  • Customising the default theme
  • Accessing the theme in your components

Let’s get started!

Install React with Create React App

Open up your terminal and navigate to the folder you’d like the app to live in.

Run the following commands, replacing material-ui-baseline with your project name:

npx create-react-app material-ui-baseline
cd material-ui-baseline
npm start

Install Material-UI

In your terminal, inside the project root folder run:

// with npm
npm install @material-ui/core
// with yarn
yarn add @material-ui/core

Head to public/index.html and add the Roboto font to your <head>:

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />

If you’re planning on using the Material-UI icons at all, also add the Google Web Font link:

<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />

From your terminal, while in the root folder, install the icon package:

// with npm
npm install @material-ui/icons
// with yarn
yarn add @material-ui/icons

Remove the stock stuff

Open up App.js and remove everything, replacing it with the following code:

import React from 'react'const App = () => (
<div>
<p>A bare bones application!</p>
</div>
)
export default App

Delete App.css now that we’re not using it in App.js.

Delete the index.css file and remove its import from index.js.

import './index.css';

Setup ThemeProvider and CssBaseline in App.js

Firstly, we want to define a theme object using createMuiTheme, which we will later pass into our ThemeProvider.

Add a new file in your src folder and name it theme.js.

This is where we’ll add our custom options to overwrite the material defaults.

Import createMuiTheme, setting up a basic theme:

import { createMuiTheme }  from '@material-ui/core/styles'const theme = createMuiTheme({
palette: {
primary: { 500: '#467fcf' },
},
})
export default theme

Your custom there can be extended to cover whatever variables you’d like, for some inspiration here is a full list of the default values.

Back in App.js we’re going to import our new theme, ThemeProvider and the CssBaseline.

Then, to make sure that all of our application has access to the theme variables, we’ll wrap our code in the ThemeProvider, using our custom theme as a prop.

We also call CssBaseline inside the ThemeProvider:

import React from 'react'
import { ThemeProvider } from '@material-ui/core/styles'
import CssBaseline from '@material-ui/core/CssBaseline'
import theme from './theme'
const App = () => (
<ThemeProvider theme={theme}>
<CssBaseline />
<div>
<p>A bare bones application!</p>
</div>
</ThemeProvider>
)
export default App

Accessing our theme

Now that we have a theme available to us, we can access it in any of our components. Let’s add a new component to try it out!

Add a new folder in src called components and let’s create a new file called item.jsx, adding the following code:

import React from 'react'const Item = () => {
return (
<p>I'm an Item!</p>
)
}
export default Item

Importing the component into our App.js and popping it into the component:

import Item from './components/item'const App = () => (
<ThemeProvider theme={theme}>
<CssBaseline />
<Item />
</ThemeProvider>
)

Define our style hook

Let’s flesh out the Item component, making a basic card, but this time with Material-UI to do the heavy lifting!

Firstly, we’re going to import makeStyles from the material style library:

import { makeStyles } from '@material-ui/styles'

Using it to define a useStyles hook, outside of our component:

const useStyles = makeStyles(theme => ({
root: {
margin: theme.spacing(3),
width: 345,
},
media: {
height: 140,
},
title: {
color: theme.palette.primary.main
}
}))

Quite a lot is happening in a small amount of code:

  • We pass our theme, which we defined earlier, into the makeStyles function
  • We define style objects (root, media, and title), which we can access later
  • We access default and custom variables using our theme (theme.spacing is a default value)

Note: when defining styles we write a style object, similar to adding an inline style to a React elementstyle={{ height: '100px' }}

Finally, inside of our component, we can call our style hook, allowing us to apply the styles as a className:

const classes = useStyles()

Building with Material-UI

Let’s throw together some Material-UI components and apply the styles.

Inside our return statement, delete the placeholder sentence and add a Card:

<Card className={classes.root}>
</Card>

To apply our style, we simply add a className, accessing the part of the style object we’d like to assign. In this case our classes.root style.

Within our Card, we’re going to add an action area (comes with a nice click animation by default) with a content area and a header image:

<CardActionArea>
<CardMedia
className={classes.media}
image="https://images.unsplash.com/photo-1540573133985-87b6da6d54a9?ixlib=rb-1.2.1&auto=format&fit=crop&w=1955&q=80"
title="Surprised monkey"
/>
<CardContent>
/* text to follow */
</CardContent>
</CardActionArea>

Inside of our content area, we’ll add some text:

<Typography gutterBottom variant="h5" component="h2" className={classes.title}>
OMG it's a Monkey!
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
Monkey is a common name that may refer to groups or species of mammal. The term is applied descriptively to groups of primates
</Typography>

Notice that we can choose a variant of the Typography component, accessing either our own defined class using className or through default color attributes.

Below our CardActionArea, we’ll add a button, wrapped in the CardAction component:

<CardActions>
<Button size="small" color="primary" href="https://unsplash.com/photos/Z05GiksmqYU">
See it on Unsplash
</Button>
</CardActions>

Your card should now look like this:

Our new styled Material-UI component

I’ve included Item component code below:

As you can see, we can quickly build using the Material-UI blocks as a baseline and apply our custom styles over the top very easily.

The full code is available on Github.

Cheers

Kits

Front end developer at Bright Analytics, London, working mainly with React @kit_son

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store