crazy4groovy
7/8/2017 - 1:43 AM

Simple progress bar for ReactJs

Simple progress bar for ReactJs

import { object } from 'prop-types';
import React from 'react';

const _ = {
  setState: () => {},
};

export default class Component extends React.Component {
  static propTypes = { style: object };
  static defaultProps = { style: {} };

  state = {
    className: '',
    show: false,
  };

  componentWillMount() {
    _.setState = this.setState.bind(this);
  }

  render() {
    const { style } = this.props;
    const { className, show } = this.state;

    return show && <div id="progress-bar" className={className} style={style} />;
  }
}

let fadeTimeoutId = 0;
let semaphore = 0;

export const isShown = () => semaphore > 0;

export const showBar = () => {
  semaphore += 1;

  if (semaphore === 1) {
    clearTimeout(fadeTimeoutId);
    _.setState({
      className: '',
      show: true,
    });
  }
};

const timeout = (t, cb) => setTimeout(cb, t);
const fadedOutMs = 500;

export const hideBar = (forced) => {
  if (semaphore === 1) {
    _.setState({ className: 'fade' });
    fadeTimeoutId = timeout(
      fadedOutMs,
      () => _.setState({
        className: '',
        show: false,
      }),
    );
  }

  semaphore -= (forced === true ? semaphore : 1);
  semaphore = Math.max(0, semaphore);
};
#progress-bar {
  border: 1px solid lightblue;
  position: fixed;
  top: 0;
  left: 0;
  opacity: 1;
  transition: opacity .5s ease-in-out;
  animation: progress-bar-grow 10s 0s infinite alternate backwards;
}

#progress-bar.fade {
  opacity: 0;
}

@keyframes progress-bar-grow {
  0%   { width: 0%; }
  100% { width: 100%; }
}