UNPKG

orcs-design-system

Version:
130 lines (128 loc) 5.5 kB
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 } } };