Skip to content

style(Progress): refactor, update typings and remove propTypes #1269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
315 changes: 167 additions & 148 deletions src/modules/Progress/Progress.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash'
import cx from 'classnames'
import React, { PropTypes } from 'react'
import _ from 'lodash'
import React, { Component, PropTypes } from 'react'

import {
customPropTypes,
Expand All @@ -12,173 +12,192 @@ import {
useValueAndKey,
} from '../../lib'

function Progress(props) {
const {
active, attached, autoSuccess, color, children, className, disabled, error, indicating,
inverted, label, percent, precision, progress, size, success, total, value, warning,
} = props
/**
* A progress bar shows the progression of a task.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment for docs.

*/
class Progress extends Component {
static propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

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

const showProgress = progress
|| label
|| !_.isUndefined(precision)
|| !(_.every([total, value], _.isUndefined))
/** A progress bar can attach to and show the progress of an element (i.e. Card or Segment). */
attached: PropTypes.oneOf(['top', 'bottom']),

let _percent
if (!_.isUndefined(percent)) {
_percent = percent
} else if (!_.isUndefined(total) && !_.isUndefined(value)) {
_percent = value / total * 100
}
/** Whether success state should automatically trigger when progress completes. */
autoSuccess: PropTypes.bool,

_percent = _.clamp(_percent, 0, 100)
/** Primary content. */
children: PropTypes.node,

if (!_.isUndefined(precision)) {
_percent = _.round(_percent, precision)
}
/** Additional classes. */
className: PropTypes.string,

let progressText
if (label === 'percent' || label === true || _.isUndefined(label)) {
progressText = `${_percent}%`
} else if (label === 'ratio') {
progressText = `${value}/${total}`
}
/** A progress bar can have different colors. */
color: PropTypes.oneOf(SUI.COLORS),

const classes = cx(
'ui',
size,
color,
useKeyOnly(active || indicating, 'active'),
useKeyOnly(isAutoSuccess || success, 'success'),
useKeyOnly(warning, 'warning'),
useKeyOnly(error, 'error'),
useKeyOnly(disabled, 'disabled'),
useKeyOnly(indicating, 'indicating'),
useKeyOnly(inverted, 'inverted'),
useValueAndKey(attached, 'attached'),
className,
'progress'
)
const rest = getUnhandledProps(Progress, props)
const ElementType = getElementType(Progress, props)

return (
<ElementType {...rest} className={classes}>
<div className='bar' style={{ width: `${_percent}%` }}>
{showProgress && <div className='progress'>{progressText}</div>}
</div>
{children && <div className='label'>{children}</div>}
</ElementType>
)
}
/** A progress bar be disabled. */
disabled: PropTypes.bool,

Progress._meta = {
name: 'Progress',
type: META.TYPES.MODULE,
props: {
attached: ['top', 'bottom'],
color: SUI.COLORS,
label: ['ratio', 'percent'],
size: _.without(SUI.SIZES, 'mini', 'huge', 'massive'),
},
}
/** A progress bar can show a error state. */
error: PropTypes.bool,

Progress.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,
/** An indicating progress bar visually indicates the current level of progress of a task. */
indicating: PropTypes.bool,

/** A progress bar can show activity. */
active: PropTypes.bool,
/** A progress bar can have its colors inverted. */
inverted: PropTypes.bool,

/** A progress bar can attach to and show the progress of an element (i.e. Card or Segment). */
attached: PropTypes.oneOf(Progress._meta.props.attached),
/** Can be set to either to display progress as percent or ratio. */
label: customPropTypes.every([
customPropTypes.some([
customPropTypes.demand(['percent']),
customPropTypes.demand(['total', 'value']),
]),
PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(['ratio', 'percent']),
]),
]),

/** Whether success state should automatically trigger when progress completes. */
autoSuccess: PropTypes.bool,
/** Current percent complete. */
percent: customPropTypes.every([
customPropTypes.disallow(['total', 'value']),
PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]),
]),

/** A progress bar can have different colors. */
color: PropTypes.oneOf(Progress._meta.props.color),
/** Decimal point precision for calculated progress. */
precision: PropTypes.number,

/** A progress bar can contain a text value indicating current progress. */
progress: PropTypes.bool,

/** A progress bar can vary in size. */
size: PropTypes.oneOf(_.without(SUI.SIZES, 'mini', 'huge', 'massive')),

/** A progress bar can show a success state. */
success: PropTypes.bool,

/**
* For use with value.
* Together, these will calculate the percent.
* Mutually excludes percent.
*/
total: customPropTypes.every([
customPropTypes.demand(['value']),
customPropTypes.disallow(['percent']),
PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]),
]),

/** Primary content. */
children: PropTypes.node,
/**
* For use with total. Together, these will calculate the percent. Mutually excludes percent.
*/
value: customPropTypes.every([
customPropTypes.demand(['total']),
customPropTypes.disallow(['percent']),
PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]),
]),

/** Additional classes. */
className: PropTypes.string,
/** A progress bar can show a warning state. */
warning: PropTypes.bool,
}

/** A progress bar be disabled. */
disabled: PropTypes.bool,
static _meta = {
name: 'Progress',
type: META.TYPES.MODULE,
}

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

/** An indicating progress bar visually indicates the current level of progress of a task. */
indicating: PropTypes.bool,
if (!_.isUndefined(percent)) return percent
if (!_.isUndefined(total) && !_.isUndefined(value)) return value / total * 100
}

/** A progress bar can have its colors inverted. */
inverted: PropTypes.bool,
getPercent = () => {
const { precision } = this.props
const percent = _.clamp(this.calculatePercent(), 0, 100)

/** Can be set to either to display progress as percent or ratio. */
label: customPropTypes.every([
customPropTypes.some([
customPropTypes.demand(['percent']),
customPropTypes.demand(['total', 'value']),
]),
PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(Progress._meta.props.label),
]),
]),

/** Current percent complete. */
percent: customPropTypes.every([
customPropTypes.disallow(['total', 'value']),
PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
]),

/** A progress bar can contain a text value indicating current progress. */
progress: PropTypes.bool,

/** Decimal point precision for calculated progress. */
precision: PropTypes.number,

/** A progress bar can vary in size. */
size: PropTypes.oneOf(Progress._meta.props.size),

/** A progress bar can show a success state. */
success: PropTypes.bool,

/**
* For use with value.
* Together, these will calculate the percent.
* Mutually excludes percent.
*/
total: customPropTypes.every([
customPropTypes.demand(['value']),
customPropTypes.disallow(['percent']),
PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
]),

/**
* For use with total. Together, these will calculate the percent. Mutually excludes percent.
*/
value: customPropTypes.every([
customPropTypes.demand(['total']),
customPropTypes.disallow(['percent']),
PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
]),
if (_.isUndefined(precision)) return percent
return _.round(percent, precision)
}

isAutoSuccess = () => {
const { autoSuccess, percent, total, value } = this.props

/** A progress bar can show a warning state. */
warning: PropTypes.bool,
return autoSuccess && (percent >= 100 || value >= total)
}

showProgress = () => {
const { label, precision, progress, total, value } = this.props

if (label || progress || !_.isUndefined(precision)) return true
return !(_.every([total, value], _.isUndefined))
}

render() {
const {
active,
attached,
children,
className,
color,
disabled,
error,
indicating,
inverted,
label,
size,
success,
total,
value,
warning,
} = this.props

const classes = cx(
'ui',
color,
size,
useKeyOnly(active || indicating, 'active'),
useKeyOnly(disabled, 'disabled'),
useKeyOnly(error, 'error'),
useKeyOnly(indicating, 'indicating'),
useKeyOnly(inverted, 'inverted'),
useKeyOnly(success || this.isAutoSuccess(), 'success'),
useKeyOnly(warning, 'warning'),
useValueAndKey(attached, 'attached'),
'progress',
className,
)
const rest = getUnhandledProps(Progress, this.props)
const ElementType = getElementType(Progress, this.props)

const percent = this.getPercent()

return (
<ElementType {...rest} className={classes}>
<div className='bar' style={{ width: `${percent}%` }}>
{this.showProgress() && (
<div className='progress'>
{ label !== 'ratio' ? `${percent}%` : `${value}/${total}` }
</div>
)}
</div>
{children && <div className='label'>{children}</div>}
</ElementType>
)
}
}

export default Progress
Loading