UNPKG

2.64 kBJavaScriptView Raw
1import React from 'react';
2import PropTypes from 'prop-types';
3import classNames from 'classnames';
4import { mapToCssModules, tagPropType, toNumber } from './utils';
5
6const propTypes = {
7 /** Enable animation to bar */
8 animated: PropTypes.bool,
9 bar: PropTypes.bool,
10 barAriaLabelledBy: PropTypes.string,
11 barAriaValueText: PropTypes.string,
12 barClassName: PropTypes.string,
13 barStyle: PropTypes.object,
14 children: PropTypes.node,
15 /** Add custom class */
16 className: PropTypes.string,
17 /** Change underlying component's CSS base class name */
18 cssModule: PropTypes.object,
19 /** Add custom color to the placeholder */
20 color: PropTypes.string,
21 /** Maximum value of progress */
22 max: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
23 /** Minimum value of progress, defaults to zero */
24 min: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
25 multi: PropTypes.bool,
26 /** Add stripes to progress bar */
27 striped: PropTypes.bool,
28 style: PropTypes.object,
29 /** Set a custom element for this component */
30 tag: tagPropType,
31 /** Current value of progress */
32 value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
33};
34
35function Progress(props) {
36 const {
37 children,
38 className,
39 barClassName,
40 cssModule,
41 value = 0,
42 min = 0,
43 max = 100,
44 animated,
45 striped,
46 color,
47 bar,
48 multi,
49 tag: Tag = 'div',
50 style = {},
51 barStyle = {},
52 barAriaValueText,
53 barAriaLabelledBy,
54 ...attributes
55 } = props;
56
57 const percent = (toNumber(value) / toNumber(max)) * 100;
58
59 const progressClasses = mapToCssModules(
60 classNames(className, 'progress'),
61 cssModule,
62 );
63
64 const progressBarClasses = mapToCssModules(
65 classNames(
66 'progress-bar',
67 bar ? className || barClassName : barClassName,
68 animated ? 'progress-bar-animated' : null,
69 color ? `bg-${color}` : null,
70 striped || animated ? 'progress-bar-striped' : null,
71 ),
72 cssModule,
73 );
74
75 const progressBarProps = {
76 className: progressBarClasses,
77 style: {
78 ...(bar ? style : {}),
79 ...barStyle,
80 width: `${percent}%`,
81 },
82 role: 'progressbar',
83 'aria-valuenow': value,
84 'aria-valuemin': min,
85 'aria-valuemax': max,
86 'aria-valuetext': barAriaValueText,
87 'aria-labelledby': barAriaLabelledBy,
88 children: children,
89 };
90
91 if (bar) {
92 return <Tag {...attributes} {...progressBarProps} />;
93 }
94
95 return (
96 <Tag {...attributes} style={style} className={progressClasses}>
97 {multi ? children : <div {...progressBarProps} />}
98 </Tag>
99 );
100}
101
102Progress.propTypes = propTypes;
103
104export default Progress;