1
- import _ from 'lodash'
2
1
import cx from 'classnames'
3
- import React , { PropTypes } from 'react'
2
+ import _ from 'lodash'
3
+ import React , { Component , PropTypes } from 'react'
4
4
5
5
import {
6
6
customPropTypes ,
@@ -12,173 +12,192 @@ import {
12
12
useValueAndKey ,
13
13
} from '../../lib'
14
14
15
- function Progress ( props ) {
16
- const {
17
- active, attached, autoSuccess, color, children, className, disabled, error, indicating,
18
- inverted, label, percent, precision, progress, size, success, total, value, warning,
19
- } = props
15
+ /**
16
+ * A progress bar shows the progression of a task.
17
+ */
18
+ class Progress extends Component {
19
+ static propTypes = {
20
+ /** An element type to render as (string or function). */
21
+ as : customPropTypes . as ,
20
22
21
- const isAutoSuccess = autoSuccess && ( percent >= 100 || value >= total )
23
+ /** A progress bar can show activity. */
24
+ active : PropTypes . bool ,
22
25
23
- const showProgress = progress
24
- || label
25
- || ! _ . isUndefined ( precision )
26
- || ! ( _ . every ( [ total , value ] , _ . isUndefined ) )
26
+ /** A progress bar can attach to and show the progress of an element (i.e. Card or Segment). */
27
+ attached : PropTypes . oneOf ( [ 'top' , 'bottom' ] ) ,
27
28
28
- let _percent
29
- if ( ! _ . isUndefined ( percent ) ) {
30
- _percent = percent
31
- } else if ( ! _ . isUndefined ( total ) && ! _ . isUndefined ( value ) ) {
32
- _percent = value / total * 100
33
- }
29
+ /** Whether success state should automatically trigger when progress completes. */
30
+ autoSuccess : PropTypes . bool ,
34
31
35
- _percent = _ . clamp ( _percent , 0 , 100 )
32
+ /** Primary content. */
33
+ children : PropTypes . node ,
36
34
37
- if ( ! _ . isUndefined ( precision ) ) {
38
- _percent = _ . round ( _percent , precision )
39
- }
35
+ /** Additional classes. */
36
+ className : PropTypes . string ,
40
37
41
- let progressText
42
- if ( label === 'percent' || label === true || _ . isUndefined ( label ) ) {
43
- progressText = `${ _percent } %`
44
- } else if ( label === 'ratio' ) {
45
- progressText = `${ value } /${ total } `
46
- }
38
+ /** A progress bar can have different colors. */
39
+ color : PropTypes . oneOf ( SUI . COLORS ) ,
47
40
48
- const classes = cx (
49
- 'ui' ,
50
- size ,
51
- color ,
52
- useKeyOnly ( active || indicating , 'active' ) ,
53
- useKeyOnly ( isAutoSuccess || success , 'success' ) ,
54
- useKeyOnly ( warning , 'warning' ) ,
55
- useKeyOnly ( error , 'error' ) ,
56
- useKeyOnly ( disabled , 'disabled' ) ,
57
- useKeyOnly ( indicating , 'indicating' ) ,
58
- useKeyOnly ( inverted , 'inverted' ) ,
59
- useValueAndKey ( attached , 'attached' ) ,
60
- className ,
61
- 'progress'
62
- )
63
- const rest = getUnhandledProps ( Progress , props )
64
- const ElementType = getElementType ( Progress , props )
65
-
66
- return (
67
- < ElementType { ...rest } className = { classes } >
68
- < div className = 'bar' style = { { width : `${ _percent } %` } } >
69
- { showProgress && < div className = 'progress' > { progressText } </ div > }
70
- </ div >
71
- { children && < div className = 'label' > { children } </ div > }
72
- </ ElementType >
73
- )
74
- }
41
+ /** A progress bar be disabled. */
42
+ disabled : PropTypes . bool ,
75
43
76
- Progress . _meta = {
77
- name : 'Progress' ,
78
- type : META . TYPES . MODULE ,
79
- props : {
80
- attached : [ 'top' , 'bottom' ] ,
81
- color : SUI . COLORS ,
82
- label : [ 'ratio' , 'percent' ] ,
83
- size : _ . without ( SUI . SIZES , 'mini' , 'huge' , 'massive' ) ,
84
- } ,
85
- }
44
+ /** A progress bar can show a error state. */
45
+ error : PropTypes . bool ,
86
46
87
- Progress . propTypes = {
88
- /** An element type to render as (string or function). */
89
- as : customPropTypes . as ,
47
+ /** An indicating progress bar visually indicates the current level of progress of a task. */
48
+ indicating : PropTypes . bool ,
90
49
91
- /** A progress bar can show activity . */
92
- active : PropTypes . bool ,
50
+ /** A progress bar can have its colors inverted . */
51
+ inverted : PropTypes . bool ,
93
52
94
- /** A progress bar can attach to and show the progress of an element (i.e. Card or Segment). */
95
- attached : PropTypes . oneOf ( Progress . _meta . props . attached ) ,
53
+ /** Can be set to either to display progress as percent or ratio. */
54
+ label : customPropTypes . every ( [
55
+ customPropTypes . some ( [
56
+ customPropTypes . demand ( [ 'percent' ] ) ,
57
+ customPropTypes . demand ( [ 'total' , 'value' ] ) ,
58
+ ] ) ,
59
+ PropTypes . oneOfType ( [
60
+ PropTypes . bool ,
61
+ PropTypes . oneOf ( [ 'ratio' , 'percent' ] ) ,
62
+ ] ) ,
63
+ ] ) ,
96
64
97
- /** Whether success state should automatically trigger when progress completes. */
98
- autoSuccess : PropTypes . bool ,
65
+ /** Current percent complete. */
66
+ percent : customPropTypes . every ( [
67
+ customPropTypes . disallow ( [ 'total' , 'value' ] ) ,
68
+ PropTypes . oneOfType ( [
69
+ PropTypes . number ,
70
+ PropTypes . string ,
71
+ ] ) ,
72
+ ] ) ,
99
73
100
- /** A progress bar can have different colors. */
101
- color : PropTypes . oneOf ( Progress . _meta . props . color ) ,
74
+ /** Decimal point precision for calculated progress. */
75
+ precision : PropTypes . number ,
76
+
77
+ /** A progress bar can contain a text value indicating current progress. */
78
+ progress : PropTypes . bool ,
79
+
80
+ /** A progress bar can vary in size. */
81
+ size : PropTypes . oneOf ( _ . without ( SUI . SIZES , 'mini' , 'huge' , 'massive' ) ) ,
82
+
83
+ /** A progress bar can show a success state. */
84
+ success : PropTypes . bool ,
85
+
86
+ /**
87
+ * For use with value.
88
+ * Together, these will calculate the percent.
89
+ * Mutually excludes percent.
90
+ */
91
+ total : customPropTypes . every ( [
92
+ customPropTypes . demand ( [ 'value' ] ) ,
93
+ customPropTypes . disallow ( [ 'percent' ] ) ,
94
+ PropTypes . oneOfType ( [
95
+ PropTypes . number ,
96
+ PropTypes . string ,
97
+ ] ) ,
98
+ ] ) ,
102
99
103
- /** Primary content. */
104
- children : PropTypes . node ,
100
+ /**
101
+ * For use with total. Together, these will calculate the percent. Mutually excludes percent.
102
+ */
103
+ value : customPropTypes . every ( [
104
+ customPropTypes . demand ( [ 'total' ] ) ,
105
+ customPropTypes . disallow ( [ 'percent' ] ) ,
106
+ PropTypes . oneOfType ( [
107
+ PropTypes . number ,
108
+ PropTypes . string ,
109
+ ] ) ,
110
+ ] ) ,
105
111
106
- /** Additional classes. */
107
- className : PropTypes . string ,
112
+ /** A progress bar can show a warning state. */
113
+ warning : PropTypes . bool ,
114
+ }
108
115
109
- /** A progress bar be disabled. */
110
- disabled : PropTypes . bool ,
116
+ static _meta = {
117
+ name : 'Progress' ,
118
+ type : META . TYPES . MODULE ,
119
+ }
111
120
112
- /** A progress bar can show a error state. */
113
- error : PropTypes . bool ,
121
+ calculatePercent = ( ) => {
122
+ const { percent , total , value } = this . props
114
123
115
- /** An indicating progress bar visually indicates the current level of progress of a task. */
116
- indicating : PropTypes . bool ,
124
+ if ( ! _ . isUndefined ( percent ) ) return percent
125
+ if ( ! _ . isUndefined ( total ) && ! _ . isUndefined ( value ) ) return value / total * 100
126
+ }
117
127
118
- /** A progress bar can have its colors inverted. */
119
- inverted : PropTypes . bool ,
128
+ getPercent = ( ) => {
129
+ const { precision } = this . props
130
+ const percent = _ . clamp ( this . calculatePercent ( ) , 0 , 100 )
120
131
121
- /** Can be set to either to display progress as percent or ratio. */
122
- label : customPropTypes . every ( [
123
- customPropTypes . some ( [
124
- customPropTypes . demand ( [ 'percent' ] ) ,
125
- customPropTypes . demand ( [ 'total' , 'value' ] ) ,
126
- ] ) ,
127
- PropTypes . oneOfType ( [
128
- PropTypes . bool ,
129
- PropTypes . oneOf ( Progress . _meta . props . label ) ,
130
- ] ) ,
131
- ] ) ,
132
-
133
- /** Current percent complete. */
134
- percent : customPropTypes . every ( [
135
- customPropTypes . disallow ( [ 'total' , 'value' ] ) ,
136
- PropTypes . oneOfType ( [
137
- PropTypes . string ,
138
- PropTypes . number ,
139
- ] ) ,
140
- ] ) ,
141
-
142
- /** A progress bar can contain a text value indicating current progress. */
143
- progress : PropTypes . bool ,
144
-
145
- /** Decimal point precision for calculated progress. */
146
- precision : PropTypes . number ,
147
-
148
- /** A progress bar can vary in size. */
149
- size : PropTypes . oneOf ( Progress . _meta . props . size ) ,
150
-
151
- /** A progress bar can show a success state. */
152
- success : PropTypes . bool ,
153
-
154
- /**
155
- * For use with value.
156
- * Together, these will calculate the percent.
157
- * Mutually excludes percent.
158
- */
159
- total : customPropTypes . every ( [
160
- customPropTypes . demand ( [ 'value' ] ) ,
161
- customPropTypes . disallow ( [ 'percent' ] ) ,
162
- PropTypes . oneOfType ( [
163
- PropTypes . string ,
164
- PropTypes . number ,
165
- ] ) ,
166
- ] ) ,
167
-
168
- /**
169
- * For use with total. Together, these will calculate the percent. Mutually excludes percent.
170
- */
171
- value : customPropTypes . every ( [
172
- customPropTypes . demand ( [ 'total' ] ) ,
173
- customPropTypes . disallow ( [ 'percent' ] ) ,
174
- PropTypes . oneOfType ( [
175
- PropTypes . string ,
176
- PropTypes . number ,
177
- ] ) ,
178
- ] ) ,
132
+ if ( _ . isUndefined ( precision ) ) return percent
133
+ return _ . round ( percent , precision )
134
+ }
135
+
136
+ isAutoSuccess = ( ) => {
137
+ const { autoSuccess, percent, total, value } = this . props
179
138
180
- /** A progress bar can show a warning state. */
181
- warning : PropTypes . bool ,
139
+ return autoSuccess && ( percent >= 100 || value >= total )
140
+ }
141
+
142
+ showProgress = ( ) => {
143
+ const { label, precision, progress, total, value } = this . props
144
+
145
+ if ( label || progress || ! _ . isUndefined ( precision ) ) return true
146
+ return ! ( _ . every ( [ total , value ] , _ . isUndefined ) )
147
+ }
148
+
149
+ render ( ) {
150
+ const {
151
+ active,
152
+ attached,
153
+ children,
154
+ className,
155
+ color,
156
+ disabled,
157
+ error,
158
+ indicating,
159
+ inverted,
160
+ label,
161
+ size,
162
+ success,
163
+ total,
164
+ value,
165
+ warning,
166
+ } = this . props
167
+
168
+ const classes = cx (
169
+ 'ui' ,
170
+ color ,
171
+ size ,
172
+ useKeyOnly ( active || indicating , 'active' ) ,
173
+ useKeyOnly ( disabled , 'disabled' ) ,
174
+ useKeyOnly ( error , 'error' ) ,
175
+ useKeyOnly ( indicating , 'indicating' ) ,
176
+ useKeyOnly ( inverted , 'inverted' ) ,
177
+ useKeyOnly ( success || this . isAutoSuccess ( ) , 'success' ) ,
178
+ useKeyOnly ( warning , 'warning' ) ,
179
+ useValueAndKey ( attached , 'attached' ) ,
180
+ 'progress' ,
181
+ className ,
182
+ )
183
+ const rest = getUnhandledProps ( Progress , this . props )
184
+ const ElementType = getElementType ( Progress , this . props )
185
+
186
+ const percent = this . getPercent ( )
187
+
188
+ return (
189
+ < ElementType { ...rest } className = { classes } >
190
+ < div className = 'bar' style = { { width : `${ percent } %` } } >
191
+ { this . showProgress ( ) && (
192
+ < div className = 'progress' >
193
+ { label !== 'ratio' ? `${ percent } %` : `${ value } /${ total } ` }
194
+ </ div >
195
+ ) }
196
+ </ div >
197
+ { children && < div className = 'label' > { children } </ div > }
198
+ </ ElementType >
199
+ )
200
+ }
182
201
}
183
202
184
203
export default Progress
0 commit comments