Create a Material React app
How to use create-react-app with Material web components.
Getting started
Material is a beautiful and open source design system, by Google. There are some unofficial and popular packages implementing Material with React but now there is an official one: Material Components for React (MDC React)
Create React App (CRA) is the official React development tool and let you
Set up a modern web app by running one command.
Let’s create a webapp that uses both Material and React, plus TypeScript.
Create a react app with TypeScript template.
npx create-react-app material-react-app --template typescript
cd material-react-app
yarn start
If everything went well your browser will open and you can start coding and see changes live thanks to awesome livereload.
CRA creates also a git repo, I am going to push it on GitHub. Of course, you are going to use a different repo name and URL. For instance
git remote add origin git@github.com:fibo/material-react-app.git
git push -u origin master
We are going to add Sass, since it is used by Material for theme customization and it is also supported by CRA. Launch commands
yarn add node-sass
git mv src/App.css src/App.scss
Then update style import in your src/App.tsx
-import './App.css';
+import './App.scss';
Finally, add a .env file with the following content
SASS_PATH=node_modules
Create a Layout
Let’s start adding a dismissible drawer as well as other few components to create a basic layout with a top navigation bar.
The navigation drawer slides in from the left and contains the navigation destinations for your app.
Install dependencies
yarn add @material/react-drawer @material/react-material-icon @material/react-top-app-bar @material/react-list
Include Material icons by adding the following to public/index.html file
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
Replace the content of src/App.scss with the following code
@import '@material/react-drawer/index.scss';
@import '@material/react-top-app-bar/index.scss';
@import '@material/react-list/index.scss';
@import '@material/react-material-icon/index.scss';
.drawer-container {
display: flex;
flex-direction: row;
height: 100vh;
overflow: hidden;
}
.drawer-app-content {
flex: auto;
overflow: auto;
}
Replace the content of src/App.tsx with the following code
import React, { useState } from 'react';
import TopAppBar, {
TopAppBarFixedAdjust,
TopAppBarIcon,
TopAppBarRow,
TopAppBarSection,
TopAppBarTitle
} from '@material/react-top-app-bar';
import Drawer, {
DrawerAppContent,
DrawerContent,
DrawerHeader,
DrawerTitle
} from '@material/react-drawer';
import MaterialIcon from '@material/react-material-icon';
import List, {
ListItem,
ListItemGraphic,
ListItemText
} from '@material/react-list';
import './App.scss';
export default function App () {
const [drawerIsOpen, setDrawerIsOpen] = useState(false)
return (
<div className='drawer-container'>
<TopAppBar>
<TopAppBarRow>
<TopAppBarSection align='start'>
<TopAppBarIcon navIcon tabIndex={0}>
<MaterialIcon
hasRipple
icon='menu'
onClick={() => setDrawerIsOpen(!drawerIsOpen)}
/>
</TopAppBarIcon>
<TopAppBarTitle>Inbox</TopAppBarTitle>
</TopAppBarSection>
</TopAppBarRow>
</TopAppBar>
<TopAppBarFixedAdjust className='top-app-bar-fix-adjust'>
<Drawer dismissible open={drawerIsOpen}>
<DrawerHeader>
<DrawerTitle tag='h2'>
jane.smith@gmail.com
</DrawerTitle>
</DrawerHeader>
<DrawerContent>
<List>
<ListItem>
<ListItemGraphic graphic={<MaterialIcon icon='folder'/>} />
<ListItemText primaryText='Mail' />
</ListItem>
</List>
</DrawerContent>
</Drawer>
<DrawerAppContent className='drawer-app-content'>
Your inbox content
</DrawerAppContent>
</TopAppBarFixedAdjust>
</div>
)
}
Deploy
For sure this section can vary a lot according to your needs. I am going to show, as an example, how I deployed on GitHub Pages.
You need to tell CRA your webapp base URL setting PUBLIC_URL
environment variable.
It is also achieved setting your package.json homepage
attribute. Since I use a custom dommain for my GitHub Pages I added to my package.json file
"homepage": "https://g14n.info/material-react-app",
NOTA BENE: Do not worry about http or https, even the domain does not matter, CRA in will use the slug of the URL, in my case material-react-app
, to set relative URLs to bundles, somthing like <script src="/material-react-app/static/js/2.a71d9b2e.chunk.js"></script>
Install gh-pages package to deploy easily.
yarn add gh-pages
Add a deploy
script to your package.json
"scripts": {
"build": "react-scripts build",
+ "deploy": "gh-pages -d build",
"eject": "react-scripts eject",
+ "predeploy": "yarn build",
"start": "react-scripts start",
"test": "react-scripts test"
},
From now on, to deploy just launch yarn deploy
.
Organize repository
At this point you may want to reorganize your repository. You may notice that there is already a README.md generated by CRA, I am going to edit it to add proper content.
Also, I usually like to have a src/components/ folder, as well as src/reducers, src/pages. Of course this is up to you and/or your team.