diff --git a/src/components/ui/popup/PopupStack.jsx b/src/components/ui/popup/PopupStack.jsx index f901322..9f4a5cc 100644 --- a/src/components/ui/popup/PopupStack.jsx +++ b/src/components/ui/popup/PopupStack.jsx @@ -15,6 +15,14 @@ export class PopupStack extends Component { destroy: PropTypes.func.isRequired }; + componentWillMount() { + document.addEventListener('keyup', this.onKeyPress); + } + + componentWillUnmount() { + document.removeEventListener('keyup', this.onKeyPress); + } + render() { const {popups} = this.props; @@ -59,6 +67,16 @@ export class PopupStack extends Component { this.props.destroy(popup); }; } + + onKeyPress = (event) => { + if (event.which === 27) { // ESC key + const popup = this.props.popups.slice(-1)[0]; + + if (popup && !popup.disableOverlayClose) { + this.props.destroy(popup); + } + } + }; } import { connect } from 'react-redux'; diff --git a/tests/components/ui/popup/PopupStack.test.jsx b/tests/components/ui/popup/PopupStack.test.jsx index 8e42f78..b0a4c74 100644 --- a/tests/components/ui/popup/PopupStack.test.jsx +++ b/tests/components/ui/popup/PopupStack.test.jsx @@ -105,4 +105,63 @@ describe('', () => { sinon.assert.notCalled(props.destroy); }); + + it('should hide popup, when esc pressed', () => { + const props = { + destroy: sinon.stub(), + popups: [ + { + Popup: DummyPopup + } + ] + }; + mount(); + + const event = new Event('keyup'); + event.which = 27; + document.dispatchEvent(event); + + sinon.assert.calledOnce(props.destroy); + }); + + it('should hide first popup in stack', () => { + const props = { + destroy: sinon.stub(), + popups: [ + { + Popup() {return null;} + }, + { + Popup: DummyPopup + } + ] + }; + mount(); + + const event = new Event('keyup'); + event.which = 27; + document.dispatchEvent(event); + + sinon.assert.calledOnce(props.destroy); + sinon.assert.calledWithExactly(props.destroy, props.popups[1]); + }); + + it('should NOT hide popup on esc pressed if disableOverlayClose', () => { + const props = { + destroy: sinon.stub(), + popups: [ + { + Popup: DummyPopup, + disableOverlayClose: true + } + ] + }; + mount(); + + const event = new Event('keyup'); + event.which = 27; + document.dispatchEvent(event); + + sinon.assert.notCalled(props.destroy); + }); });