UNPKG

monday-ui-react-core

Version:

Official monday.com UI resources for application development in React.js

181 lines (169 loc) • 4.87 kB
import React, { useMemo, forwardRef } from "react"; import PropTypes from "prop-types"; import cx from "classnames"; import { baseClassName, PROGRESS_BAR_STYLES } from "./LinearProgressBarConstants"; import { calculatePercentage } from "./LinearProgressBarHelpers"; import Bar from "./Bar/Bar"; import PercentageLabel from "../PercentageLabel/PercentageLabel"; import { SIZES } from "../../../constants/sizes"; import "./LinearProgressBar.scss"; const LinearProgressBar = forwardRef( ( { min, max, value, valueSecondary, animated, barStyle, className, size, indicateProgress, multi, multiValues, ariaLabel }, ref ) => { const wrapperClassName = useMemo(() => { const base = `${baseClassName}--wrapper`; return cx(base, { [`${base}__${size}`]: size }, className); }, [size, className]); const valuePercentage = useMemo(() => { if (multi) { const firstValue = multiValues && multiValues.length && multiValues[0].value; if (firstValue === null || firstValue === undefined) return 0; return calculatePercentage(firstValue, min, max); } if (value === null || value === undefined) return 0; return calculatePercentage(value, min, max); }, [value, min, max, multi, multiValues]); const renderMultiBars = useMemo(() => { if (!multi) return null; return ( <> {[...multiValues].reverse().map(({ value: baseValue, color }, i) => ( <Bar barStyle="none" value={baseValue} animated={animated} baseClass={baseClassName} color={color} min={min} max={max} /* eslint-disable-next-line react/no-array-index-key */ key={`${baseClassName}_${color}_${i}`} /> ))} </> ); }, [min, max, animated, multiValues, multi]); const renderPercentage = indicateProgress ? ( <PercentageLabel forElement="linear-progress-bar" className={`${baseClassName}__label`} value={valuePercentage} /> ) : null; const renderBaseBars = !multi ? ( <> <Bar barLabelName={ariaLabel} barStyle={barStyle} id="linear-progress-bar" value={valueSecondary} animated={animated} baseClass={`${baseClassName}__secondary`} min={min} max={max} /> <Bar barStyle={barStyle} value={value} animated={animated} baseClass={baseClassName} min={min} max={max} /> </> ) : null; return ( <div className={wrapperClassName} ref={ref}> <div className={`${baseClassName}__container`}> {renderBaseBars} {renderMultiBars} </div> {renderPercentage} </div> ); } ); LinearProgressBar.styles = PROGRESS_BAR_STYLES; LinearProgressBar.sizes = SIZES; LinearProgressBar.propTypes = { /** * Determine the progress bar style (Supported options exposed through `LinearProgressBar.styles`). */ barStyle: PropTypes.oneOf(Object.values(PROGRESS_BAR_STYLES)), /** * The progress bar starting value. */ min: PropTypes.number, /** * The progress bar ending value. */ max: PropTypes.number, /** * The progress bar current value. */ value: PropTypes.number, /** * The progress bar secondary value. */ valueSecondary: PropTypes.number, /** * If set to *true*, animations are used. */ animated: PropTypes.bool, /** * Set external styling to the progress bar. */ className: PropTypes.string, /** * Determine the progress bar height (Supported options exposed through `LinearProgressBar.sizes`) */ size: PropTypes.oneOf(Object.values(SIZES)), /** * Show progress bar progression in percentages */ indicateProgress: PropTypes.bool, /** * Use multiple bars. * ***Note:*** `value`, `valueSecondary` & `barStyle` won't be used */ multi: PropTypes.bool, /** * Array of bar value objects { * `value` - The progress value, * `color` - hex [`#000000` ~ `#ffffff`] of the current bar * } */ multiValues: PropTypes.arrayOf( PropTypes.shape({ /** * The progress bar current value. */ value: PropTypes.number.isRequired, /** * The bar color in hex - #000000 ~ #ffffff */ color: PropTypes.string.isRequired }).isRequired ), /** ARIA description for the progress bar */ ariaLabel: PropTypes.string }; LinearProgressBar.defaultProps = { barStyle: PROGRESS_BAR_STYLES.PRIMARY, size: SIZES.SMALL, className: "", multi: false, indicateProgress: false, valueSecondary: 0, value: 0, min: 0, max: 100, animated: true, multiValues: [], ariaLabel: "" }; export default LinearProgressBar;