7.2 Styling of React Components

# Animations - React Transition Group

When we are dynamically adding or removing elements from the DOM, like with the GitHub Profiles example from last week, we can present a better user experience by adding a small animation to the state transition.

The easiest way to accomplish this is by using a wrapping component that manages this logic. The react-transition-group (opens new window) project works really well for this.

It works by applying particular CSS classes to the child components (the ones we want to animate) at preset times during the component life cycle. After reading the docs linked above, lets apply it to our code example from last week.

# Before

function CardList(props) {
  const cards = props.profiles.map((profile) => (
    <ProfileCard
      key={profile.id}
      profile={profile}
      handleRemove={props.handleRemoveProfile}
    />
  ));
  return { cards };
}
1
2
3
4
5
6
7
8
9
10

# After

import { CSSTransitionGroup } from 'react-transition-group';

function CardList(props) {
  const cards = props.profiles.map((profile) => (
    <ProfileCard
      key={profile.id}
      profile={profile}
      handleRemove={props.handleRemoveProfile}
    />
  ));
  return (
    <CSSTransitionGroup
      component="div"
      className="CardList"
      transitionName="fade"
      transitionAppear={true}
      transitionAppearTimeout={200}
      transitionEnterTimeout={250}
      transitionLeaveTimeout={225}
    >
      {cards}
    </CSSTransitionGroup>
  );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# The CSS to actually make it work

/* CSSTransitionGroup Classes  */
/* For the initial page load */
.fade-appear {
  opacity: 0.01;
}
.fade-appear.fade-appear-active {
  opacity: 1;
  transition: all 200ms;
}

/* As elements are added to the DOM */
.fade-enter {
  opacity: 0.01;
  transform: scale(1, 0);
  overflow: hidden;
}
.fade-enter.fade-enter-active {
  opacity: 1;
  transform: scale(1, 1);
  transition: opacity 250ms ease-in, transform 195ms ease-out;
}

/* As elements are removed from the DOM */
.fade-leave {
  opacity: 1;
  height: 180px;
  will-change: height;
}
.fade-leave.fade-leave-active {
  opacity: 0.01;
  height: 2px;
  color: transparent;
  background-color: hsl(0, 85%, 40%);
  border-top: 2px solid hsl(0, 85%, 40%);
  border-radius: 0;
  transition: opacity 250ms ease-out, background-color 195ms linear,
    height 195ms ease-out, color 100ms linear, border-top 150ms linear, border-radius
      150ms linear;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# Animations - Framer Motion

Framer Motion (opens new window)

# ReactStrap

Bootstrap v4 for React (opens new window)

# MUI

Material Design for React (opens new window)

To add MUI to your project, we need to import it to our node_modules.

yarn add @mui/material @emotion/react @emotion/styled
1

OR there is a alternate way of styling components. To use it, install this instead. Until we start building custom themes it won't really matter. Start with the first option, above.

yarn add @mui/material @mui/styled-engine-sc styled-components
1

# Material Icon Fonts

Next we should be importing the Material-Icons fonts to our project. To do this we actually want to edit the index.js file inside the public folder of our React app.

Inside the head, add this link tag.

<link
  rel="stylestyle"
  href="https://fonts.googleapis.com/css/?family=Material+Icons"
/>
<!-- and to use the Roboto font, also add -->
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
1
2
3
4
5
6
7
8
9

Then you will have all the Material icons available in your app.

Tip

You can follow this same approach to add ANY Google Font to your app.

To search for the icon you want to use, you can visit this page (opens new window) or within the MUI site (opens new window).

To actually use one in a React component we just have to use the correct className plus the correct text.

<i className="material-icons">favorite</i>
1

The Material Icons font uses ligatures (combinations of letters) to determine which icon glyph to display. The text inside the <i> element is the ligature. The correct spelling is key to this working. You can use any inline element you want, like <span>, if you don't want to use the <i> element.

The icons have different variations - base, rounded, sharp, or outlined. To use a variant, change the className. The one used above shows the base set. Here are the other three you will need.

<i className="material-icons-round">favorite</i>
<i className="material-icons-sharp">favorite</i>
<i className="material-icons-outlined">favorite</i>
1
2
3

TIP

If you are going to use the Material Icons inside the MUI Components then you will also have to install:

yarn add @mui/icons-material
1

# MUI Components

After you install the @mui/material package into your project then you can use any of their components instead of the base JSX that looks like html.

Original example return value from a component.

import './my-thing-button.css';

export default function MyThing(props){
return (
  <p>
    <button className="myTextClass">Text</button>
    <button className="myContainedClass">Contained</button>
    <button className="myOutlinedClass">Outlined</button>
  </p>
);
1
2
3
4
5
6
7
8
9
10

We can import any of the MUI components that we want to use. It will have default CSS and often have variations that we can show with the variant attribute.

Updated to use MUI.

import Button from '@mui/material/Button';

export default function MyThing(props) {
  return (
    <p>
      <Button variant="text">Text</Button>
      <Button variant="contained">Contained</Button>
      <Button variant="outlined">Outlined</Button>
    </p>
  );
}
1
2
3
4
5
6
7
8
9
10
11

Here is the Full List of Components from MUI (opens new window).

# Video course on MUI

Here is a great course about Material-UI on YouTube (opens new window) by The Net Ninja.

This course was released in March 2021 so, it is very up to date. However, in September 2021 they upgraded from Material-UI to MUI.

In the video he is showing version 4.x of Material UI. MUI is version 5.x.

The biggest difference for the tutorial is the name of the folders for the imports.

Instead of imports that look like this:

import Button from '@material-ui/core/Button';
1

You will need to use imports that look like this:

import Button from '@mui/material/Button';
1

The new imports almost all start with @mui/material instead of @material-ui/core. The yarn add commands have changed too, but we have already done that...

# MUI Themes

MUI comes with a default theme with various style settings You can create you own theme to override these defaults and create your own style system.

...more to come about themes in Week 9...

# CSS Baseline / Reset / Normalize

If you have ever used a CSS Reset or Normalize, you understand how it can make consistency across browsers much easier. MUI has one too.

Just add it to your index.js or app.js file.

import CssBaseline from `@mui/material/CssBaseline`;

function App(){
  return (
    <div class="container">
      <CssBaseline />
      <Header/>
      <NavBar/>
      <Main/>
    </div>
  );
}
1
2
3
4
5
6
7
8
9
10
11
12

Just place it as the first element in your app. It does not wrap other elements.

React MUI Video coming soon...

Last Updated: : 10/21/2021, 11:00:05 PM