1- import React from 'react' ;
1+ import React , { cloneElement } from 'react' ;
22import PropTypes from 'prop-types' ;
3+ import classNames from 'classnames' ;
4+ import { map } from 'react-bootstrap/ElementChildren' ;
35import { omit } from 'ramda' ;
4- import RBProgressBar from 'react-bootstrap/ProgressBar' ;
6+
57import { bootstrapColors } from '../../private/BootstrapColors' ;
68
7- /**
8- * A component for creating progress bars just with CSS. Control the current
9- * progress with a callback and the `value` prop.
9+ /*
10+ * Bulk of this file is vendored from react-bootstrap/src/ProgressBar, but we
11+ * add the ability to style the bar which is needed for setting colors more
12+ * freely.
1013 */
14+ const ROUND_PRECISION = 1000 ;
15+
16+ function getPercentage ( now , min , max ) {
17+ const percentage = ( ( now - min ) / ( max - min ) ) * 100 ;
18+ return Math . round ( percentage * ROUND_PRECISION ) / ROUND_PRECISION ;
19+ }
20+
21+ function renderProgressBar (
22+ {
23+ min,
24+ now,
25+ max,
26+ label,
27+ visuallyHidden,
28+ striped,
29+ animated,
30+ className,
31+ style,
32+ variant,
33+ barStyle,
34+ ...props
35+ } ,
36+ ref
37+ ) {
38+ return (
39+ < div
40+ ref = { ref }
41+ { ...props }
42+ role = "progressbar"
43+ className = { classNames ( className , `progress-bar` , {
44+ [ `bg-${ variant } ` ] : variant ,
45+ [ `progress-bar-animated` ] : animated ,
46+ [ `progress-bar-striped` ] : animated || striped
47+ } ) }
48+ style = { { width : `${ getPercentage ( now , min , max ) } %` , ...style , ...barStyle } }
49+ aria-valuenow = { now }
50+ aria-valuemin = { min }
51+ aria-valuemax = { max }
52+ >
53+ { visuallyHidden ? (
54+ < span className = "visually-hidden" > { label } </ span >
55+ ) : (
56+ label
57+ ) }
58+ </ div >
59+ ) ;
60+ }
61+
62+ const ProgressBar = React . forwardRef ( ( { isChild, ...props } , ref ) => {
63+ if ( isChild ) {
64+ return renderProgressBar ( props , ref ) ;
65+ }
66+
67+ const {
68+ min,
69+ now,
70+ max,
71+ label,
72+ visuallyHidden,
73+ striped,
74+ animated,
75+ variant,
76+ className,
77+ children,
78+ barStyle,
79+ ...wrapperProps
80+ } = props ;
81+
82+ return (
83+ < div
84+ ref = { ref }
85+ { ...wrapperProps }
86+ className = { classNames ( className , 'progress' ) }
87+ >
88+ { children
89+ ? map ( children , child => cloneElement ( child , { isChild : true } ) )
90+ : renderProgressBar (
91+ {
92+ min,
93+ now,
94+ max,
95+ label,
96+ visuallyHidden,
97+ striped,
98+ animated,
99+ variant,
100+ barStyle
101+ } ,
102+ ref
103+ ) }
104+ </ div >
105+ ) ;
106+ } ) ;
107+
108+ ProgressBar . defaultProps = {
109+ min : 0 ,
110+ max : 100 ,
111+ animated : false ,
112+ isChild : false ,
113+ visuallyHidden : false ,
114+ striped : false
115+ } ;
116+
11117const Progress = props => {
12118 const {
13119 children,
@@ -22,7 +128,7 @@ const Progress = props => {
22128 } = props ;
23129 const isBootstrapColor = bootstrapColors . has ( color ) ;
24130 return (
25- < RBProgressBar
131+ < ProgressBar
26132 className = { class_name || className }
27133 { ...omit ( [ 'setProps' ] , otherProps ) }
28134 data-dash-is-loading = {
@@ -32,9 +138,10 @@ const Progress = props => {
32138 isChild = { bar }
33139 variant = { isBootstrapColor ? color : null }
34140 visuallyHidden = { hide_label }
141+ barStyle = { isBootstrapColor ? { } : { backgroundColor : color } }
35142 >
36143 { children }
37- </ RBProgressBar >
144+ </ ProgressBar >
38145 ) ;
39146} ;
40147
0 commit comments