Key Points To Make React Progress Bar
I am using two Material UI components called LinearProgress & CircularProgress to create the Linear Progress Bar & Circular Progress bar .
For formatting the seconds to show the remaining time on the timer, I am using Moment JS.
To run the timer and progress bar, we require three values –
- initial Time (Duration of the timer)
- timeLeft
- progressBarPrecentage
NOTE – You can also replace TIMER and show PERCENTAGE in the PROGRESS BAR by using “progressBarPercentage” variable used in the source code.
Find below the Source code with Output for both the Progress Bar Types.
How to make React Circular ProgressBar
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
import { Box, CircularProgress, Typography } from "@mui/material"; import moment from "moment"; import { useState, useRef, useEffect } from "react"; const CircularProgressBar = (props) => { const initialTime = 10; // in seconds const [timeLeft, setTimeLeft] = useState(initialTime); const [progressBarPercent, setProgressBarPercent] = useState(0); const timerId = useRef(); useEffect(() => { if (initialTime) { timerId.current = window.setInterval(() => { setTimeLeft((prevProgress) => prevProgress - 1); }, 1000); return () => { clearInterval(timerId.current); }; } }, []); useEffect(() => { if (initialTime) { if (progressBarPercent < 100) { let updateProgressPercent = Math.round( ((initialTime - (timeLeft - 1)) / initialTime) * 100 ); setProgressBarPercent(updateProgressPercent); } if (timeLeft === 0 && timerId.current) { clearInterval(timerId.current); return; } } }, [timeLeft]); return ( <Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", boxShadow: "0px 2px 10px rgba(0, 0, 0, 0.15)", width: "100%", padding: "20px" }} > <Box sx={{ position: "relative", display: "inline-flex" }}> <CircularProgress variant="determinate" size="20rem" value={progressBarPercent} sx={{ color: progressBarPercent > 90 ? `red` : "blue" }} /> <Box sx={{ top: 0, left: 0, bottom: 0, right: 0, position: "absolute", display: "flex", alignItems: "center", justifyContent: "center" }} > <Typography sx={{ fontWeight: 400, fontSize: "25px" }}> Time left: </Typography> <Typography sx={{ fontWeight: 700, fontSize: "25px", ml: 1 }}> {moment .utc(1000 * timeLeft) .format( `${timeLeft > 3600 ? "HH[h]:mm[m]:ss[s]" : "mm[m]:ss[s]"} ` )} </Typography> </Box> </Box> </Box> ); }; export default CircularProgressBar; |
OUTPUT OF REACT CIRCULAR PROGRESS BAR
How to make a Linear Progress Bar with Timer
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
import { Box, LinearProgress, linearProgressClasses, Typography } from "@mui/material"; import moment from "moment"; import { useState, useRef, useEffect } from "react"; const SubmitTimeProgressBar = (props) => { const initialTime = 10; // in seconds const [timeLeft, setTimeLeft] = useState(initialTime); const [progressBarPercent, setProgressBarPercent] = useState(0); const timerId = useRef(); useEffect(() => { if (initialTime) { timerId.current = window.setInterval(() => { setTimeLeft((prevProgress) => prevProgress - 1); }, 1000); return () => { clearInterval(timerId.current); }; } }, []); useEffect(() => { if (initialTime) { if (progressBarPercent < 100) { let updateProgressPercent = Math.round( ((initialTime - (timeLeft - 1)) / initialTime) * 100 ); setProgressBarPercent(updateProgressPercent); } if (timeLeft === 0 && timerId.current) { clearInterval(timerId.current); return; } } }, [timeLeft]); return ( <Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", background: "#FFFFFF", boxShadow: "0px 2px 10px rgba(0, 0, 0, 0.15)", width: "100%", padding: "20px" }} > <Box sx={{ width: "50%" }}> <LinearProgress variant="determinate" value={progressBarPercent} sx={{ borderRadius: "20px", background: "rgba(132, 162, 233, 0.4)", padding: "15px", [`& .${linearProgressClasses.bar1Determinate}`]: { backgroundColor: progressBarPercent > 90 ? `red` : "blue" } }} /> </Box> <Box sx={{ ml: 1, display: "flex" }}> <Typography sx={{ fontWeight: 400, fontSize: "25px" }}> Time left: </Typography> <Typography sx={{ fontWeight: 700, fontSize: "25px", ml: 1 }}> {moment .utc(1000 * timeLeft) .format( `${timeLeft > 3600 ? "HH[h]:mm[m]:ss[s]" : "mm[m]:ss[s]"} ` )} </Typography> </Box> </Box> ); }; export default SubmitTimeProgressBar; |
OUTPUT OF LINEAR PROGRESS BAR REACT