Categories
Material UI

Material UI — Progress Bars

Spread the love

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add progress bars with Material UI.

Linear Progress Bar

We can use the LinearProgress component to add a horizontal progress bar.

For example, we can write:

import React from "react";
import LinearProgress from "@material-ui/core/LinearProgress";

export default function App() {
  return (
    <div>
      <LinearProgress />
    </div>
  );
}

We just add it and it’ll show an animated progress bar.

To change the style, we can set the color property:

import React from "react";
import LinearProgress from "@material-ui/core/LinearProgress";

export default function App() {
  return (
    <div>
      <LinearProgress color="secondary" />
    </div>
  );
}

Now it’ll be pink.

Determinate Progress Bar

If we want to show a progress bar until something is done, we can set the value prop to control the progress.

We also need the variant prop set to determinate to set determinate progress.

For example, we can write:

import React from "react";
import LinearProgress from "@material-ui/core/LinearProgress";

export default function App() {
  const [progress, setProgress] = React.useState(0);

  React.useEffect(() => {
    const timer = setInterval(() => {
      setProgress(oldProgress => {
        if (oldProgress === 100) {
          return 0;
        }
        return Math.min(oldProgress + 15, 100);
      });
    }, 500);

  return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <div>
      <LinearProgress variant="determinate" value={progress} />
    </div>
  );
}

to add a prigress state. which is a number we use to determine the progress.

The value ranges from 0 to 100.

The value is updated with the useEffect progress, which calls setProgress to update the progress.

If it’s less than 100, we keep adding 100 to it.

Otherwise, we set it to 100.

Then we get a progress bar that keeps moving back and forth.

Linear Buffer

We can set the variant to buffer to add a dotted line and a lighter line to the bar.

For example, we can write:

import React from "react";
import LinearProgress from "@material-ui/core/LinearProgress";

export default function App() {
  const [progress, setProgress] = React.useState(0);

  React.useEffect(() => {
    const timer = setInterval(() => {
      setProgress(oldProgress => {
        if (oldProgress === 100) {
          return 0;
        }
        return Math.min(oldProgress + 15, 100);
      });
    }, 500);

  return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <div>
      <LinearProgress
        variant="buffer"
        value={progress}
        valueBuffer={progress * 1.1}
      />
    </div>
  );
}

to show a light bar to the right of the actual progress bar.

The rest of the unfilled space is filled with a dotted line.

Non-Standard Ranges

We can make the range non-standard by creating our own function to normalize the number to 100.

For example, we can write:

import React from "react";
import LinearProgress from "@material-ui/core/LinearProgress";

const MIN = 100;
const MAX = 200;
const normalize = value => ((value - MIN) * 100) / (MAX - MIN);

export default function App() {
  const [progress, setProgress] = React.useState(MIN);

  React.useEffect(() => {
    const timer = setInterval(() => {
      setProgress(oldProgress => {
        if (oldProgress === MAX) {
          return 0;
        }
        return Math.min(oldProgress + 15, MAX);
      });
    }, 500);

  return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <div>
      <LinearProgress variant="determinate" value={normalize(progress)} />
    </div>
  );
}

We set the MIN and MAX constants to the values we want.

Then we define the normalize function to convert that to a range between 0 and 100.

And then we can do the same thing as the other determinate progress bars.

The only thing different is the value prop still has a value between 0 and 100 because we called the normalize function to convert to such.

Customized Progress

We can style the progress with the withStyles higher-order component.

For example, we can write:

import React from "react";
import LinearProgress from "@material-ui/core/LinearProgress";
import { withStyles } from "@material-ui/core/styles";

const BorderLinearProgress = withStyles(theme => ({
  root: {
    height: 10,
    borderRadius: 5
  },
  colorPrimary: {
    backgroundColor:
      theme.palette.grey[theme.palette.type === "light" ? 200 : 700]
  },
  bar: {
    borderRadius: 5,
    backgroundColor: "green"
  }
}))(LinearProgress);

export default function App() {
  const [progress, setProgress] = React.useState(0);

  React.useEffect(() => {
    const timer = setInterval(() => {
      setProgress(oldProgress => {
        if (oldProgress === 100) {
          return 0;
        }
        return Math.min(oldProgress + 15, 100);
      });
    }, 500);

  return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <div>
      <BorderLinearProgress variant="determinate" value={progress} />
    </div>
  );
}

We used the withStyles higher-order component to change the color of the progress bar with the backgroundColor property of the bar class.

colorPrimary has the color of the unfilled part.

The height andborderRadius are also changed.

Conclusion

We can make a linear progress bar and use it either to show a progress bar forever or just use it to display the progress.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *