UNPKG

box-ui-elements-mlh

Version:
138 lines (117 loc) 2.89 kB
/** * @flow * @file Progress Bar component * @author Box */ import React, { PureComponent } from 'react'; import './ProgressBar.scss'; type Props = { percent: number, }; type State = { percent: number, }; class ProgressBar extends PureComponent<Props, State> { props: Props; state: State; timeout: TimeoutID; interval: IntervalID; static defaultProps = { percent: 0 }; /** * [constructor] * * @return {ProgressBar} */ constructor(props: Props) { super(props); const { percent }: State = props; this.state = { percent }; } /** * Clears any timeouts and intervals * * @return {void} */ clearTimeoutAndInterval() { clearInterval(this.interval); clearTimeout(this.timeout); } /** * Starts progress on mount */ componentDidMount() { this.startProgress(); } /** * Updates state from new props * * @return {void} */ componentDidUpdate(prevProps: Props): void { const { percent }: Props = this.props; if (prevProps.percent !== percent) { this.clearTimeoutAndInterval(); this.setState({ percent }, this.startProgress); } } /** * Clears time out * * @return {void} */ componentWillUnmount() { this.clearTimeoutAndInterval(); } /** * Increaments the progress or resets it * depending upon the edge conditions. * * @return {void} */ startProgress = () => { const { percent }: State = this.state; if (percent === 0) { this.interval = setInterval(this.incrementProgress, 100); } else if (percent === 100) { // Timeout helps transition of hiding the bar to finish this.timeout = setTimeout(this.resetProgress, 600); } }; /** * Increaments the progress very slowly * * @return {void} */ incrementProgress = () => { const { percent } = this.state; this.setState({ percent: percent + 2 / (percent || 1), }); }; /** * Resets the progress to 0 * * @return {void} */ resetProgress = () => { this.setState(ProgressBar.defaultProps); }; /** * Renders the progress bar * * @return {void} */ render() { const { percent }: State = this.state; const containerStyle = { opacity: percent > 0 && percent < 100 ? 1 : 0, transitionDelay: percent > 0 && percent < 100 ? '0' : '0.4s', }; return ( <div className="be-progress-container" style={containerStyle}> <div className="be-progress" style={{ width: `${percent}%` }} /> </div> ); } } export default ProgressBar;