Skip to content

Instantly share code, notes, and snippets.

@lechup
Last active July 20, 2017 19:43
Show Gist options
  • Save lechup/0a614b4cd62ba4ea05d8ff78f1300bc6 to your computer and use it in GitHub Desktop.
Save lechup/0a614b4cd62ba4ea05d8ff78f1300bc6 to your computer and use it in GitHub Desktop.
React Loader component with react-transition-group Transitions
import React from "react";
import PropTypes from 'prop-types';
import Transition from 'react-transition-group/Transition';
import loaderSrc from "../../img/utils/loader.gif";
import './loader.less'
class Loader extends React.Component {
inTransition = false;
beforeTransitionEndInChangeCount = 0;
static propTypes = {
in: PropTypes.bool,
timeout: PropTypes.number,
};
static defaultProps = {
in: false,
timeout: 500
};
constructor(props) {
super(props);
this.state = {
in: this.props.in
}
}
allowNextOrDoPendingTransition = () => {
setTimeout(()=> {
if (this.beforeTransitionEndInChangeCount > 0) {
this.doPendingTransitions();
} else {
this.inTransition = false;
}
}, this.props.timeout)
};
doPendingTransitions = () => {
this.beforeTransitionEndInChangeCount--;
this.setState({in: !this.state.in});
if (this.beforeTransitionEndInChangeCount > 0) {
setTimeout(() => {
this.doPendingTransitions();
}, this.props.timeout)
} else {
this.inTransition = false;
}
};
componentWillReceiveProps(nextProps, nextState) {
if( this.props.in != nextProps.in ){
if (this.inTransition) {
this.beforeTransitionEndInChangeCount++;
} else {
this.inTransition = true;
this.setState({in: nextProps.in});
this.allowNextOrDoPendingTransition();
}
}
}
render() {
return (
<Transition timeout={this.props.timeout} in={this.state.in} >
{(status) => (
<div className={`loader ${status}`}>
<img src={ loaderSrc } />
</div>
)}
</Transition>
);
}
}
export default Loader;
.loader {
z-index: 1002;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
transition: opacity 500ms ease-in-out;
img {
position: absolute;
width: 100px;
height: 100px;
top: 50%;
left: 50%;
margin: -50px 0 0 -50px;
}
&.entered {
opacity: 1;
}
&.entering {
opacity: 1;
}
&.exited {
z-index: -1;
opacity: 1;
img {
opacity: 0;
}
}
&.exiting {
opacity: 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment