Skip to content

Commit 30e83e5

Browse files
layershifterharel
authored andcommitted
style(Progress): refactor, update typings and remove propTypes (Semantic-Org#1269)
1 parent 88e09d9 commit 30e83e5

File tree

3 files changed

+181
-161
lines changed

3 files changed

+181
-161
lines changed

src/modules/Progress/Progress.js

Lines changed: 167 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import _ from 'lodash'
21
import cx from 'classnames'
3-
import React, { PropTypes } from 'react'
2+
import _ from 'lodash'
3+
import React, { Component, PropTypes } from 'react'
44

55
import {
66
customPropTypes,
@@ -12,173 +12,192 @@ import {
1212
useValueAndKey,
1313
} from '../../lib'
1414

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,
2022

21-
const isAutoSuccess = autoSuccess && (percent >= 100 || value >= total)
23+
/** A progress bar can show activity. */
24+
active: PropTypes.bool,
2225

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']),
2728

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,
3431

35-
_percent = _.clamp(_percent, 0, 100)
32+
/** Primary content. */
33+
children: PropTypes.node,
3634

37-
if (!_.isUndefined(precision)) {
38-
_percent = _.round(_percent, precision)
39-
}
35+
/** Additional classes. */
36+
className: PropTypes.string,
4037

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),
4740

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,
7543

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,
8646

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,
9049

91-
/** A progress bar can show activity. */
92-
active: PropTypes.bool,
50+
/** A progress bar can have its colors inverted. */
51+
inverted: PropTypes.bool,
9352

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+
]),
9664

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+
]),
9973

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+
]),
10299

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+
]),
105111

106-
/** Additional classes. */
107-
className: PropTypes.string,
112+
/** A progress bar can show a warning state. */
113+
warning: PropTypes.bool,
114+
}
108115

109-
/** A progress bar be disabled. */
110-
disabled: PropTypes.bool,
116+
static _meta = {
117+
name: 'Progress',
118+
type: META.TYPES.MODULE,
119+
}
111120

112-
/** A progress bar can show a error state. */
113-
error: PropTypes.bool,
121+
calculatePercent = () => {
122+
const { percent, total, value } = this.props
114123

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+
}
117127

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)
120131

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
179138

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+
}
182201
}
183202

184203
export default Progress

0 commit comments

Comments
 (0)