diff --git a/lib/skylight.js b/lib/skylight.js index 5b822af..a92840c 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -28,13 +28,6 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var isOpening = function isOpening(s1, s2) { - return !s1.isVisible && s2.isVisible; -}; -var isClosing = function isClosing(s1, s2) { - return s1.isVisible && !s2.isVisible; -}; - var SkyLight = function (_React$Component) { _inherits(SkyLight, _React$Component); @@ -43,41 +36,68 @@ var SkyLight = function (_React$Component) { var _this = _possibleConstructorReturn(this, (SkyLight.__proto__ || Object.getPrototypeOf(SkyLight)).call(this, props)); - _this.state = { isVisible: false }; + _this.state = { + isOperationInProgress: false, + nextIsVisible: null, + isVisible: false + }; return _this; } _createClass(SkyLight, [{ - key: 'componentWillUpdate', - value: function componentWillUpdate(nextProps, nextState) { - if (isOpening(this.state, nextState) && this.props.beforeOpen) { - this.props.beforeOpen(); + key: 'componentDidUpdate', + value: function componentDidUpdate(prevProps, prevState) { + var _props = this.props, + afterOpen = _props.afterOpen, + afterClose = _props.afterClose, + beforeOpen = _props.beforeOpen, + beforeClose = _props.beforeClose; + var _state = this.state, + isOperationInProgress = _state.isOperationInProgress, + nextIsVisible = _state.nextIsVisible; + + + if (isOperationInProgress && nextIsVisible === true) { + if (beforeOpen) { + beforeOpen(); + } + this._completeShowOperation(); } - if (isClosing(this.state, nextState) && this.props.beforeClose) { - this.props.beforeClose(); + if (isOperationInProgress && nextIsVisible === false) { + if (beforeClose) { + beforeClose(); + } + this._completeHideOperation(); } - } - }, { - key: 'componentDidUpdate', - value: function componentDidUpdate(prevProps, prevState) { - if (isOpening(prevState, this.state) && this.props.afterOpen) { - this.props.afterOpen(); + + if (!isOperationInProgress && prevState.nextIsVisible === true && afterOpen) { + afterOpen(); } - if (isClosing(prevState, this.state) && this.props.afterClose) { - this.props.afterClose(); + if (!isOperationInProgress && prevState.nextIsVisible === false && afterClose) { + afterClose(); } } }, { key: 'show', value: function show() { - this.setState({ isVisible: true }); + this.setState({ isOperationInProgress: true, nextIsVisible: true }); } }, { key: 'hide', value: function hide() { - this.setState({ isVisible: false }); + this.setState({ isOperationInProgress: true, nextIsVisible: false }); + } + }, { + key: '_completeShowOperation', + value: function _completeShowOperation() { + this.setState({ isVisible: true, isOperationInProgress: false, nextIsVisible: null }); + } + }, { + key: '_completeHideOperation', + value: function _completeHideOperation() { + this.setState({ isVisible: false, isOperationInProgress: false, nextIsVisible: null }); } }, { key: '_onOverlayClicked', diff --git a/lib/skylightstateless.js b/lib/skylightstateless.js index d15a131..be15ff8 100644 --- a/lib/skylightstateless.js +++ b/lib/skylightstateless.js @@ -42,8 +42,8 @@ var SkyLightStateless = function (_React$Component) { } _createClass(SkyLightStateless, [{ - key: 'componentWillMount', - value: function componentWillMount() { + key: 'componentDidMount', + value: function componentDidMount() { document.addEventListener("keydown", this._handlerEsc.bind(this)); } }, { diff --git a/src/skylight.jsx b/src/skylight.jsx index 9f58b6b..8513b16 100644 --- a/src/skylight.jsx +++ b/src/skylight.jsx @@ -2,42 +2,60 @@ import React from 'react'; import PropTypes from 'prop-types'; import SkylightStateless from './skylightstateless'; -const isOpening = (s1, s2) => !s1.isVisible && s2.isVisible; -const isClosing = (s1, s2) => s1.isVisible && !s2.isVisible; - export default class SkyLight extends React.Component { constructor(props) { super(props); - this.state = { isVisible: false }; + this.state = { + isOperationInProgress: false, + nextIsVisible: null, + isVisible: false, + }; } - componentWillUpdate(nextProps, nextState) { - if (isOpening(this.state, nextState) && this.props.beforeOpen) { - this.props.beforeOpen(); + componentDidUpdate(prevProps, prevState) { + const { + afterOpen, afterClose, beforeOpen, beforeClose + } = this.props; + const { isOperationInProgress, nextIsVisible } = this.state; + + if (isOperationInProgress && nextIsVisible === true) { + if (beforeOpen) { + beforeOpen(); + } + this._completeShowOperation(); } - if (isClosing(this.state, nextState) && this.props.beforeClose) { - this.props.beforeClose(); + if (isOperationInProgress && nextIsVisible === false) { + if (beforeClose) { + beforeClose(); + } + this._completeHideOperation(); } - } - componentDidUpdate(prevProps, prevState) { - if (isOpening(prevState, this.state) && this.props.afterOpen) { - this.props.afterOpen(); + if (!isOperationInProgress && prevState.nextIsVisible === true && afterOpen) { + afterOpen(); } - if (isClosing(prevState, this.state) && this.props.afterClose) { - this.props.afterClose(); + if (!isOperationInProgress && prevState.nextIsVisible === false && afterClose) { + afterClose(); } } show() { - this.setState({ isVisible: true }); + this.setState({ isOperationInProgress: true, nextIsVisible: true }); } hide() { - this.setState({ isVisible: false }); + this.setState({ isOperationInProgress: true, nextIsVisible: false }); + } + + _completeShowOperation() { + this.setState({ isVisible: true, isOperationInProgress: false, nextIsVisible: null }); + } + + _completeHideOperation() { + this.setState({ isVisible: false, isOperationInProgress: false, nextIsVisible: null }); } _onOverlayClicked() { @@ -51,12 +69,14 @@ export default class SkyLight extends React.Component { } render() { - return ( this._onOverlayClicked()} - onCloseClicked={() => this.hide()} - />); + return ( + this._onOverlayClicked()} + onCloseClicked={() => this.hide()} + /> + ); } } diff --git a/src/skylightstateless.jsx b/src/skylightstateless.jsx index e78eb9f..3372d6a 100644 --- a/src/skylightstateless.jsx +++ b/src/skylightstateless.jsx @@ -5,7 +5,7 @@ import assign from './utils/assign'; export default class SkyLightStateless extends React.Component { - componentWillMount() { + componentDidMount() { document.addEventListener("keydown", this._handlerEsc.bind(this)); } @@ -44,7 +44,7 @@ export default class SkyLightStateless extends React.Component { const overlayStyles = mergeStyles('overlayStyles'); const closeButtonStyle = mergeStyles('closeButtonStyle'); const titleStyle = mergeStyles('titleStyle'); - + let finalStyle; if(isVisible) { finalStyle = assign({}, dialogStyles, styles.animationOpen); @@ -53,7 +53,7 @@ export default class SkyLightStateless extends React.Component { finalStyle = assign({}, dialogStyles, styles.animationBase); overlayStyles.display = 'none'; } - + finalStyle.transitionDuration = `${this.props.transitionDuration}ms`; overlayStyles.transitionDuration = `${this.props.transitionDuration}ms`; @@ -78,8 +78,8 @@ export default class SkyLightStateless extends React.Component {
{overlay}
- this.onCloseClicked()} style={closeButtonStyle} @@ -91,7 +91,7 @@ export default class SkyLightStateless extends React.Component {
); - + } }