From 896f83ca700aeb499db1f796a5675306c94f632d Mon Sep 17 00:00:00 2001 From: Sam Kvale Date: Wed, 29 Jan 2020 10:19:49 -0600 Subject: [PATCH] fix(popper): Create modal manager on demand as a singleton --- src/utils/_Popper.js | 9 +++++---- src/utils/modalManager.js | 10 +++++++++- src/utils/modalManager.test.js | 9 +++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 src/utils/modalManager.test.js diff --git a/src/utils/_Popper.js b/src/utils/_Popper.js index abb807397..4378a10d9 100644 --- a/src/utils/_Popper.js +++ b/src/utils/_Popper.js @@ -1,7 +1,7 @@ import classnames from 'classnames'; import Foco from 'react-foco'; +import { getModalManager } from './modalManager'; import keycode from 'keycode'; -import { modalManager } from './modalManager'; import PropTypes from 'prop-types'; import React from 'react'; import ReactDOM from 'react-dom'; @@ -11,6 +11,7 @@ import { POPPER_PLACEMENTS, POPPER_SIZING_TYPES } from './constants'; class Popper extends React.Component { constructor(props) { super(props); + this.modalManager = getModalManager(); } componentDidMount() { @@ -36,19 +37,19 @@ class Popper extends React.Component { _onShow() { const container = ReactDOM.findDOMNode(this) || document.body; - modalManager.add(this, container); + this.modalManager.add(this, container); document.addEventListener('keydown', this._handleDocumentKeyDown); } _onHide() { - modalManager.remove(this); + this.modalManager.remove(this); document.removeEventListener('keydown', this._handleDocumentKeyDown); } _handleDocumentKeyDown = (e) => { - if (modalManager.isTopModal(this)) { + if (this.modalManager.isTopModal(this)) { this.props.onKeyDown(e); if (e.keyCode === keycode.codes.esc && this.props.onEscapeKey) { diff --git a/src/utils/modalManager.js b/src/utils/modalManager.js index 1c5a0e663..a48c3a5f0 100644 --- a/src/utils/modalManager.js +++ b/src/utils/modalManager.js @@ -1,3 +1,11 @@ import ModalManager from 'react-overlays/ModalManager'; -export let modalManager = new ModalManager({ hideSiblingNodes: false, handleContainerOverflow: false }); +let modalManager; + +export const getModalManager = () => { + if (modalManager) { + return modalManager; + } + modalManager = new ModalManager({ hideSiblingNodes: false, handleContainerOverflow: false }); + return modalManager; +}; diff --git a/src/utils/modalManager.test.js b/src/utils/modalManager.test.js new file mode 100644 index 000000000..572b61ca2 --- /dev/null +++ b/src/utils/modalManager.test.js @@ -0,0 +1,9 @@ +import { getModalManager } from './modalManager'; + +describe('modal manager', () => { + it('is a singleton created on demand', () => { + const manager1 = getModalManager(); + const manager2 = getModalManager(); + expect(manager1).toBe(manager2); + }); +});