UNPKG

@re-flex/ui

Version:
50 lines (49 loc) 2.67 kB
import { css, styled, useTheme } from "@re-flex/styles"; import clsx from "clsx"; import React from "react"; import ProgressbarBase from "./ProgressbarBase"; const Progressbar = styled(ProgressbarBase)(({ theme: { prefix, palette, transitions } }) => ({ display: "inline-block", "&.indeterminate svg circle": { animation: `${prefix}-circular-progressbar-dash var(--progressbar-circular-duration) var(--progressbar-timing-function) infinite`, strokeDasharray: "80px, 200px", strokeDashoffset: "0px", }, "&.determinate svg circle": { transition: "all var(--progressbar-circular-duration) var(--progressbar-timing-function)", }, svg: { display: "block", circle: { color: "var(--progressbar-color)" } }, [`@keyframes ${prefix}-circular-progressbar-rotate`]: { "0%": { transformOrigin: '"50% 50%"', transform: "rotate(0deg)" }, "100%": { transform: "rotate(360deg)" }, }, [`@keyframes ${prefix}-circular-progressbar-dash`]: { "0%": { strokeDasharray: "1px, 200px", strokeDashoffset: "0px" }, "50%": { strokeDasharray: "100px, 200px", strokeDashoffset: "-15px" }, "100%": { strokeDasharray: "100px, 200px", strokeDashoffset: "-125px" }, }, })); const CircularProgressbar = ({ className, children, size = 32, thickness = 6, indeterminate = false, value = 0, ...rest }) => { const theme = useTheme(); size = typeof size === "string" ? theme.sizes?.[size] * theme.space - 4 || 1.25 : size; const circleClassName = indeterminate ? "indeterminate" : "determinate"; const circleStyle = {}; const rootProps = {}; if (indeterminate === false) { const circumference = 2 * Math.PI * ((size - thickness) / 2); circleStyle.strokeDasharray = circumference.toFixed(3); rootProps["aria-valuenow"] = Math.round(value); circleStyle.strokeDashoffset = `${(((100 - value) / 100) * circumference).toFixed(3)}px`; } return (React.createElement(Progressbar, { role: "progressbar", className: [`${theme.prefix}-progressbar circular`, circleClassName] .filter(Boolean) .join(" ") }, indeterminate === false && React.createElement("progress", { ...rest, value: value }), React.createElement("svg", { viewBox: `${size / 2} ${size / 2} ${size} ${size}`, width: size, height: size }, React.createElement("circle", { className: clsx(circleClassName, css(circleStyle)), cx: size, cy: size, r: (size - thickness) / 2, fill: "none", strokeWidth: thickness, stroke: theme.palette.primary.main })))); }; export default CircularProgressbar;