UNPKG

mdc-react

Version:

Material Components for the web implemented in React

84 lines (74 loc) 4.08 kB
import { forwardRef } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { strings, cssClasses, sizeProps, Size } from './constants'; const CircularProgress = forwardRef(({ value = 0, size = Size.MEDIUM, indeterminate = false, closed = false, colorful = false, className, ...props }, ref) => { const classNames = classnames(cssClasses.ROOT, { [`${cssClasses.ROOT}--${size}`]: size, [cssClasses.INDETERMINATE]: indeterminate, [cssClasses.CLOSED]: closed }, className); const { viewBox, radius, strokeDasharray, strokeWidth, gapPatchStrokeWidth, indeterminateStrokeDashoffset } = sizeProps[size]; const progress = value > 1 ? (value / 100) : Number(value); const cx = viewBox / 2, cy = viewBox / 2; const strokeDashoffset = (2 * Math.PI * radius) * (1 - progress); return ( <div ref={ref} className={classNames} role="progressbar" aria-valuemin={0} aria-valuemax={1} aria-valuenow={progress} {...props} > {!indeterminate && <div className={cssClasses.DETERMINATE_CONTAINER}> <svg className={cssClasses.DETERMINATE_CIRCLE_GRAPHIC} viewBox={`0 0 ${viewBox} ${viewBox}`} xmlns={strings.XMLNS}> <circle className={cssClasses.DETERMINATE_TRACK} cx={cx} cy={cy} r={radius} strokeWidth={strokeWidth} /> <circle className={cssClasses.DETERMINATE_CIRCLE} cx={cx} cy={cy} r={radius} strokeWidth={strokeWidth} strokeDasharray={strokeDasharray} strokeDashoffset={strokeDashoffset} /> </svg> </div> } {indeterminate && <div className={cssClasses.INDETERMINATE_CONTAINER}> {(colorful ? [1, 2, 3, 4] : [0]).map(n => <div key={n} className={classnames(cssClasses.SPINNER_LAYER, { [`${cssClasses.PROGRESS_COLOR}-${n}`]: n })}> <div className={`${cssClasses.CIRCLE_CLIPPER} ${cssClasses.CIRCLE_LEFT}`}> <svg className={cssClasses.INDETERMINATE_CIRCLE_GRAPHIC} viewBox={`0 0 ${viewBox} ${viewBox}`} xmlns={strings.XMLNS}> <circle cx={cx} cy={cy} r={radius} strokeWidth={strokeWidth} strokeDasharray={strokeDasharray} strokeDashoffset={indeterminateStrokeDashoffset} /> </svg> </div><div className={cssClasses.GAP_PATCH}> <svg className={cssClasses.INDETERMINATE_CIRCLE_GRAPHIC} viewBox={`0 0 ${viewBox} ${viewBox}`} xmlns={strings.XMLNS}> <circle cx={cx} cy={cy} r={radius} strokeWidth={gapPatchStrokeWidth} strokeDasharray={strokeDasharray} strokeDashoffset={indeterminateStrokeDashoffset} /> </svg> </div><div className={`${cssClasses.CIRCLE_CLIPPER} ${cssClasses.CIRCLE_RIGHT}`}> <svg className={cssClasses.INDETERMINATE_CIRCLE_GRAPHIC} viewBox={`0 0 ${viewBox} ${viewBox}`} xmlns={strings.XMLNS}> <circle cx={cx} cy={cy} r={radius} strokeWidth={strokeWidth} strokeDasharray={strokeDasharray} strokeDashoffset={indeterminateStrokeDashoffset} /> </svg> </div> </div> )} </div> } </div> ); }); CircularProgress.displayName = 'MDCCircularProgress'; CircularProgress.propTypes = { value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), size: PropTypes.oneOf([Size.SMALL, Size.MEDIUM, Size.LARGE]), indeterminate: PropTypes.bool, closed: PropTypes.bool, colorful: PropTypes.bool }; CircularProgress.Size = Size; export default CircularProgress;