@mongez/react-components
Version:
Beautiful and simple ready React Components for quick production.
99 lines (98 loc) • 2.72 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import { useState, useRef, useEffect } from "react";
import classes from "./Progress.module.scss.js";
function Progress({
loading: incomingLoading = true,
value: incomingProgress,
height = 5,
glow = 20,
zIndex = 1000,
color = "#21a6e9",
glowColor = "#21a6e9",
}) {
// create a progress state to show the progress of the loading
const [progress, setProgress] = useState(0);
const progressRef = useRef();
const isControlled = incomingProgress !== undefined;
const [loading, setLoading] = useState(incomingLoading);
const hide = () => {
if (!progressRef.current) return;
progressRef.current.style.display = "none";
};
const show = () => {
if (!progressRef.current) return;
progressRef.current.style.display = "block";
};
const set = (value) => {
if (!progressRef.current) return;
progressRef.current.style.width = `${value}%`;
setProgress(value);
};
useEffect(() => {
if (isControlled) return;
if (!loading) return;
// create an interval to be updated every 100ms
const interval = setInterval(() => {
show();
// update the progress state by 10
let newProgress = progress + 10;
setProgress(newProgress);
// update the progress bar width
set(newProgress);
}, 100);
// clear the interval when the progress state is 100
if (progress === 100) {
// update the progress bar width
set(100);
clearInterval(interval);
}
// return a function to clear the interval when the component is unmounted
return () => {
clearInterval(interval);
};
}, [progress, loading, isControlled]);
useEffect(() => {
if (incomingProgress === undefined) return;
if (incomingProgress >= 100) {
set(100);
setTimeout(() => {
hide();
}, 700);
return;
} else if (incomingProgress === 0) {
hide();
return;
} else {
show();
setTimeout(() => {
set(incomingProgress);
}, 0);
}
}, [incomingProgress]);
useEffect(() => {
setLoading(incomingLoading);
if (!incomingLoading && incomingLoading !== loading) {
set(100);
setTimeout(() => {
hide();
}, 500);
}
}, [incomingLoading, loading]);
return jsx("div", {
className: classes.root,
children: jsx("div", {
className: classes.progressWrapper,
children: jsx("div", {
ref: progressRef,
style: {
zIndex,
boxShadow: `0 0 ${glow}px ${glowColor}`,
height: `${height}px`,
backgroundColor: color,
},
className: classes.progress,
}),
}),
});
}
export { Progress as default };