Building complex user interfaces is never easy. For this reason, sometimes it makes sense using CSS frameworks that can help us not wasting our time reinventing the wheel.
In this article, I show how to use Material UI components building a React-based application useful to display some football data. In particular, the Italian highest league, Serie A.
Introduction
Creating the project and install necessary dependencies
To easily get started with create-react-app
I run the following:
npx create-react-app serie-a-almanac --template typescript
cd serie-a-almanac
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
To install Material UI and Material UI Icons:
npm install @material-ui/core @material-ui/icons
Finally, I need to import the font in the <head></head>
of index.html
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
Defining the basic architecture of the application
Before rushing into the code, I always try to define the basic design of my application. In this phase, I try to imagine my application as more layers.
This is enough to get started.
The project structure
This last preparation phase is, in my opinion, the most important. It's important to me find the best way to arrange components into folders and subfolders.
This is how I arranged the code generated by create-react-app
...
/src
/components
/App
App.css
App.test.tsx
App.tsx
/images
logo.svg
index.css
index.tsx
react-app-env.d.ts
serviceWorker.ts
setupTests.ts
package.json
...
Building the main container, App.tsx
This container is responsible for displaying the header bar and the content corresponding to the URL the user navigates.
The AppBar
import React from 'react';
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import {
AppBar,
Toolbar,
Typography,
IconButton,
} from '@material-ui/core';
import MenuIcon from '@material-ui/icons/Menu';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
},
}),
);
const App: React.FC = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
Football Almanac
</Typography>
</Toolbar>
</AppBar>
</div>
);
}
export default App;
The
CSS-in-JS
solution unlocks many great features (theme nesting, dynamic styles, self-support, etc.) so I decided to give it a chance, at least while working with Material UI.
The Drawer
Change the App.tsx
file as follows
import { Drawer } from '@material-ui/core';
......
return (
<div>
<div className={classes.root}>
...
</div>
<Drawer open={true}>
Hello Drawer!
</Drawer>
</div>
);
Et voila'!
To make this component working properly I need to manage its open|close
state.
......
const [isOpen, setIsOpen] = useState(false);
const toggleDrawer = (open: boolean) => (
event: React.KeyboardEvent | React.MouseEvent,
) => {
if (
event.type === 'keydown' &&
((event as React.KeyboardEvent).key === 'Tab' ||
(event as React.KeyboardEvent).key === 'Shift')
) {
return;
}
setIsOpen(open);
};
return (
<div>
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu" onClick={toggleDrawer(true)}>
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
Football Almanac
</Typography>
</Toolbar>
</AppBar>
</div>
<Drawer open={isOpen} onClose={toggleDrawer(false)}>
Hello Drawer!
</Drawer>
</div>
);
What's next
In the next step I will create the drawer and I will add some client side navigation with React Router DOM.
Top comments (1)
Thanks