react-all-progressbar
Version:
This is a simple NPM Package for progress bars and progress circles.
186 lines (180 loc) • 4.75 kB
JavaScript
import React, { useState, useEffect } from "react";
import "./ProgressCircles.css";
function Progress({
type,
progressValue,
outerBackgroundColor,
innerBackgroundColor,
width,
height,
borderRadius,
circleWidth,
circleSize,
textPercentage,
textColor,
textSize,
textFontFamily,
textFontWeight,
}) {
// For Progress Bars
if (progressValue > 100) {
progressValue = 100;
}
if (progressValue < 0) {
progressValue = -progressValue;
}
if (width < 0) {
width = -width;
}
if (height < 0) {
height = -height;
}
if (borderRadius < 0) {
borderRadius = -borderRadius;
}
// For Progress Circles
if (circleWidth < 0) {
circleWidth = -circleWidth;
}
if (circleSize < 0) {
circleSize = -circleSize;
}
if (circleSize > 35) {
circleSize = 35;
}
if (circleWidth > 10) {
circleWidth = 10;
}
let percent, r, circumference;
let [offset, setOffset] = useState(0);
function setValues() {
percent = document
.querySelector(".radial-progress")
.getAttribute("data-percentage")
.valueOf();
r = document.querySelector("circle.complete").getAttribute("r");
circumference = 2 * Math.PI * r;
offset = circumference - (percent * circumference) / 100;
setOffset(offset);
}
useEffect(() => {
if (type === "circle") {
setValues(); //eslint-disable-next-line
}
});
return (
<div className="progress-body">
{type === "circle" ? (
<svg
className="radial-progress"
data-percentage={progressValue}
viewBox="0 0 80 80"
>
<circle
className="incomplete"
cx="40"
cy="40"
r={circleSize}
style={{
stroke: outerBackgroundColor,
strokeWidth: circleWidth,
strokeDashoffset: circleSize * Math.PI * 2,
}}
></circle>
<circle
className="complete"
cx="40"
cy="40"
r={circleSize}
stroke={innerBackgroundColor}
style={{
strokeDashoffset: offset,
strokeWidth: circleWidth,
strokeDasharray: circleSize * Math.PI * 2,
}}
></circle>
{textPercentage ? (
<text
className="percentage"
x="50%"
y="57%"
transform="matrix(0, 1, -1, 0, 80, 0)"
style={{
fill: textColor,
textAnchor: "middle",
fontSize: textSize,
fontFamily: textFontFamily,
fontWeight: textFontWeight,
}}
>
{progressValue}%
</text>
) : (
""
)}
</svg>
) : type === "bar" ? (
<div style={{ display: "flex", alignItems: "center" }}>
<div
className="progress-bar"
style={{
background: outerBackgroundColor,
width: `${width}px`,
height: `${height}px`,
borderRadius: `${borderRadius}px`,
margin: `10px`,
}}
>
<div
className="progress-internal"
style={{
background: innerBackgroundColor,
width: `${progressValue}%`,
height: `${height}px`,
borderRadius: `${borderRadius}px`,
transition: "width 1.25s ease-in-out",
}}
></div>
</div>
{textPercentage ? (
<div
className="progress-percentage"
style={{
display: "flex",
marginLeft: "10px",
alignItems: "center",
color: textColor,
fontSize: textSize,
fontFamily: textFontFamily,
fontWeight: textFontWeight,
}}
>
{progressValue}%
</div>
) : (
""
)}
</div>
) : (
"Please select a type: circle or bar"
)}
</div>
);
}
Progress.defaultProps = {
type: "bar",
progressValue: 33,
outerBackgroundColor: "#003566",
innerBackgroundColor: "#ffd60a",
width: 200,
height: 10,
borderRadius: 10,
circleWidth: 10,
circleSize: 35,
textPercentage: true,
textColor: "#000",
textSize: "1.5rem",
textFontFamily: "Arial",
textFontWeight: "bold",
};
export default Progress;