orcs-design-system
Version:
TeamForm's Design System, aka: ORCS
130 lines (128 loc) • 5.5 kB
JavaScript
import React, { useRef, useEffect, useState } from "react";
import PropTypes from "prop-types";
import styled, { css, keyframes, ThemeProvider } from "styled-components";
import { space, layout } from "styled-system";
import { themeGet } from "@styled-system/theme-get";
import { jsx as _jsx } from "react/jsx-runtime";
const expandWidth = keyframes(["0%{width:0;}"]);
const Background = styled.div.withConfig({
displayName: "ProgressBar__Background",
componentId: "sc-q9qaaf-0"
})(["", " ", " position:relative;background:", ";height:16px;border-radius:8px;width:", ";"], space, layout, props => themeGet("colors.greyLighter")(props), props => props.containerWidth ? props.containerWidth + "%" : "100%");
const Fill = styled.div.withConfig({
displayName: "ProgressBar__Fill",
componentId: "sc-q9qaaf-1"
})(["width:", ";position:absolute;left:3px;top:3px;height:10px;border-radius:5px;animation:", " 1000ms ease-in-out 1;transition:", ";", ";"], props => {
if (props.fillWidth && props.containerWidthPx) {
const sixPxInPercentage = 6 / props.containerWidthPx * 100;
const minPixelValue = 1; // Minimum pixel value for visibility
const minPercentageValue = minPixelValue / props.containerWidthPx * 100;
const calculatedWidth = `calc(${props.fillWidth}% - ${sixPxInPercentage}%)`;
return `max(${calculatedWidth}, ${minPercentageValue}%)`;
}
return "0";
}, expandWidth, props => themeGet("transition.transitionDefault")(props), props => props.gradient ? css(["background:linear-gradient( to right,", " 0%,", " 50%,", " 100% );"], themeGet("colors.danger")(props), themeGet("colors.warning")(props), themeGet("colors.success")(props)) : css(["background:", ";"], themeGet("colors.primary")(props)));
/**
* Progress bar is not intended to be used for loading (that's what the Loading component is for). The intended use is for indicating progress through steps or progress towards a goal.
*
* A percentage width of the container (grey background) can be specified using the containerWidth prop, in most cases this should be 100. If not set the container is rendered without a CSS width property.
*
* A percentage width of the fill (coloured element) can be specified using the fillWidth prop. On page load the fill will animate from 0 to set value, and on change of the fillWidth prop value the fill will automatically animate to the new width value.
*/
export default function ProgressBar(_ref) {
let {
containerWidth = "100%",
fillWidth,
gradient,
theme,
ariaLabel = "Progress",
...props
} = _ref;
const backgroundRef = useRef(null);
const [containerWidthPx, setContainerWidthPx] = useState(0);
useEffect(() => {
if (backgroundRef.current) {
setContainerWidthPx(backgroundRef.current.offsetWidth);
}
}, [containerWidth]);
const component = /*#__PURE__*/_jsx(Background, {
ref: backgroundRef,
containerWidth: containerWidth,
...props,
"aria-label": ariaLabel,
"aria-valuenow": fillWidth,
"aria-valuemin": "0",
"aria-valuemax": "100",
children: /*#__PURE__*/_jsx(Fill, {
containerWidthPx: containerWidthPx,
gradient: gradient,
fillWidth: fillWidth
})
});
return theme ? /*#__PURE__*/_jsx(ThemeProvider, {
theme: theme,
children: component
}) : component;
}
ProgressBar.propTypes = {
/** Sets the percentage width of the parent container */
containerWidth: PropTypes.number,
/** Sets the percentage width of the fill */
fillWidth: PropTypes.number,
/** Changes fill to have a gradient */
gradient: PropTypes.bool,
/** Specifies the system design theme. */
theme: PropTypes.object,
/** Specifies the aria-label for the progress bar */
ariaLabel: PropTypes.string
};
ProgressBar.__docgenInfo = {
"description": "Progress bar is not intended to be used for loading (that's what the Loading component is for). The intended use is for indicating progress through steps or progress towards a goal.\n\nA percentage width of the container (grey background) can be specified using the containerWidth prop, in most cases this should be 100. If not set the container is rendered without a CSS width property.\n\nA percentage width of the fill (coloured element) can be specified using the fillWidth prop. On page load the fill will animate from 0 to set value, and on change of the fillWidth prop value the fill will automatically animate to the new width value.",
"methods": [],
"displayName": "ProgressBar",
"props": {
"containerWidth": {
"defaultValue": {
"value": "\"100%\"",
"computed": false
},
"description": "Sets the percentage width of the parent container",
"type": {
"name": "number"
},
"required": false
},
"ariaLabel": {
"defaultValue": {
"value": "\"Progress\"",
"computed": false
},
"description": "Specifies the aria-label for the progress bar",
"type": {
"name": "string"
},
"required": false
},
"fillWidth": {
"description": "Sets the percentage width of the fill",
"type": {
"name": "number"
},
"required": false
},
"gradient": {
"description": "Changes fill to have a gradient",
"type": {
"name": "bool"
},
"required": false
},
"theme": {
"description": "Specifies the system design theme.",
"type": {
"name": "object"
},
"required": false
}
}
};