@wix/design-system
Version:
@wix/design-system
67 lines • 4.13 kB
JavaScript
import React, { useLayoutEffect, useRef, useState } from 'react';
import { CircleLoaderCheck, CircleLoaderCheckSmall, FormFieldError, FormFieldErrorSmall, } from '@wix/wix-ui-icons-common/system';
import { StatusCompleteFilled, StatusAlertFilled, } from '@wix/wix-ui-icons-common';
import Tooltip from '../Tooltip';
import { st, classes } from './CircularProgressBar.st.css.js';
import { dataHooks, Size, sizesMap } from './constants';
import { CircularProgressBarCore } from './CircularProgressBarCore';
import { ProgressLabel } from './CircularProgressBarCore/ProgressLabel';
import { useIcons } from '../WixDesignSystemIconThemeProvider';
// This is a workaround for tokens to work with JS based solution, it has drawbacks:
// 1. it's not reactive (if token changes, UI won't update)
// 2. it's checking for css vars loaded on body only
const extractSizeFromCSSVariable = (variableName, element, fallback) => {
const cssValue = getComputedStyle(element)
.getPropertyValue(variableName)
.trim();
if (cssValue) {
const numericValue = parseFloat(cssValue);
return !isNaN(numericValue) ? numericValue : fallback;
}
return fallback;
};
const CircularProgressBar = ({ size = 'medium', skin = 'standard', labelPlacement = 'bottom', label, value, dataHook, error, errorMessage, className, light, ...restProps }) => {
const icons = useIcons('CircularProgressBar', {
StatusCompleteFilled,
CircleLoaderCheckSmall,
CircleLoaderCheck,
StatusAlertFilled,
FormFieldErrorSmall,
FormFieldError,
});
const sizeToSuccessIcon = {
[Size.tiny]: icons.StatusCompleteFilled,
[Size.small]: icons.CircleLoaderCheckSmall,
[Size.medium]: icons.CircleLoaderCheck,
[Size.large]: icons.CircleLoaderCheck,
};
const sizeToErrorIcon = {
[Size.tiny]: React.createElement(icons.StatusAlertFilled, null),
[Size.small]: React.createElement(icons.FormFieldErrorSmall, null),
[Size.medium]: React.createElement(icons.FormFieldError, null),
[Size.large]: React.createElement(icons.FormFieldError, null),
};
const [dynamicSizesMap, setDynamicSizesMap] = useState(sizesMap);
const rootRef = useRef(null);
useLayoutEffect(() => {
const newSizesMap = {
tiny: extractSizeFromCSSVariable('--wds-circular-progress-bar-size-tiny', rootRef.current, sizesMap.tiny),
small: extractSizeFromCSSVariable('--wds-circular-progress-bar-size-small', rootRef.current, sizesMap.small),
medium: extractSizeFromCSSVariable('--wds-circular-progress-bar-size-medium', rootRef.current, sizesMap.medium),
large: extractSizeFromCSSVariable('--wds-circular-progress-bar-size-large', rootRef.current, sizesMap.large),
};
setDynamicSizesMap(newSizesMap);
}, []);
const renderSuccessIcon = size => {
const IconToRender = sizeToSuccessIcon[size];
return React.createElement(IconToRender, null);
};
const renderProgressLabel = () => (React.createElement(ProgressLabel, { size: size, value: value, "data-skin": skin, label: label }));
const renderProgressBar = () => {
return (React.createElement(CircularProgressBarCore, { className: st(classes.progressBar, { light, size, skin }), ...restProps, value: value, label: label, error: error, errorMessage: errorMessage, labelPlacement: labelPlacement, "data-hook": dataHooks.circularProgressBar, size: dynamicSizesMap[size], "data-size": size, "data-skin": skin, successIcon: renderSuccessIcon(size), errorIcon: sizeToErrorIcon[size], renderProgressLabel: renderProgressLabel }));
};
return (React.createElement("div", { ref: rootRef, "data-hook": dataHook, className: st(classes.root, className) }, error && errorMessage ? (React.createElement(Tooltip, { className: classes.tooltip, content: errorMessage, dataHook: dataHooks.tooltip }, renderProgressBar())) : (renderProgressBar())));
};
CircularProgressBar.displayName = 'CircularProgressBar';
export default CircularProgressBar;
//# sourceMappingURL=CircularProgressBar.js.map