@equinor/eds-core-react
Version:
The React implementation of the Equinor Design System
115 lines (112 loc) • 3.67 kB
JavaScript
import { forwardRef, useState, useEffect } from 'react';
import styled, { keyframes, css } from 'styled-components';
import * as CircularProgress_tokens from './CircularProgress.tokens.js';
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
const indeterminate = keyframes(["100%{transform:rotate(360deg);}"]);
const Svg = styled.svg.withConfig({
displayName: "CircularProgress__Svg",
componentId: "sc-hib054-0"
})(["display:inline-block;", ";"], ({
$variant
}) => $variant === 'indeterminate' ? css(["animation:", " 1.4s linear infinite;"], indeterminate) : css(["transform:rotate(-90deg);"]));
const SrOnlyOutput = styled.output.withConfig({
displayName: "CircularProgress__SrOnlyOutput",
componentId: "sc-hib054-1"
})(["position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;"]);
const TrackCircle = styled.circle.withConfig({
displayName: "CircularProgress__TrackCircle",
componentId: "sc-hib054-2"
})([""]);
const ProgressCircle = styled.circle.withConfig({
displayName: "CircularProgress__ProgressCircle",
componentId: "sc-hib054-3"
})([""]);
const getToken = color => {
if (CircularProgress_tokens[color]) {
return CircularProgress_tokens[color];
}
return {
background: 'transparent',
entities: {
progress: {
background: color
}
}
};
};
const CircularProgress = /*#__PURE__*/forwardRef(function CircularProgress({
variant = 'indeterminate',
value = null,
size = 48,
color = 'primary',
...rest
}, ref) {
const thickness = 4;
const progress = Math.round(value);
const trackStyle = {};
const props = {
...rest,
ref,
$variant: variant
};
const token = getToken(color);
const [srProgress, setSrProgress] = useState(0);
const circumference = 2 * Math.PI * ((48 - thickness) / 2);
if (variant === 'determinate') {
trackStyle.stroke = circumference.toFixed(3);
trackStyle.strokeDashoffset = `${((100 - progress) / 100 * circumference).toFixed(3)}px`;
props['aria-valuenow'] = progress;
if (value !== undefined) {
props['aria-valuenow'] = progress;
props['aria-valuemin'] = 0;
props['aria-valuemax'] = 100;
}
}
useEffect(() => {
if (variant === 'indeterminate') return;
if (progress >= 25 && progress < 50) {
setSrProgress(25);
} else if (progress >= 50 && progress < 75) {
setSrProgress(50);
} else if (progress >= 75 && progress < 100) {
setSrProgress(75);
} else if (progress === 100) {
setSrProgress(100);
}
}, [progress, variant]);
const getProgressFormatted = () => {
return `Loading ${srProgress}%`;
};
return /*#__PURE__*/jsxs(Fragment, {
children: [/*#__PURE__*/jsxs(Svg, {
...props,
viewBox: "24 24 48 48",
role: "progressbar",
height: size,
width: size,
preserveAspectRatio: "xMidYMid meet",
children: [/*#__PURE__*/jsx(TrackCircle, {
style: trackStyle,
cx: 48,
cy: 48,
r: (48 - thickness) / 2,
fill: "none",
strokeWidth: thickness,
stroke: token.background
}), /*#__PURE__*/jsx(ProgressCircle, {
style: trackStyle,
cx: 48,
cy: 48,
r: (48 - thickness) / 2,
fill: "none",
strokeLinecap: "round",
strokeWidth: thickness,
strokeDasharray: variant === 'determinate' ? circumference : 48,
stroke: token.entities.progress.background
})]
}), variant === 'determinate' && /*#__PURE__*/jsx(SrOnlyOutput, {
children: getProgressFormatted()
})]
});
});
export { CircularProgress };