From b674d186cf5f97bf6856753b2fc91a498b5c385a Mon Sep 17 00:00:00 2001 From: Bruce Date: Mon, 11 Apr 2022 11:57:29 -0500 Subject: [PATCH 1/4] Fixing portal by switching from ReactDOM.unstable_renderSubtreeIntoContainer to React.createPortal, so that the context from PortalSettings, carries through when having multiple layers. --- components/utilities/dialog/portal.jsx | 30 ++++++++++---------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/components/utilities/dialog/portal.jsx b/components/utilities/dialog/portal.jsx index 95eba84403..9d25cfc5da 100644 --- a/components/utilities/dialog/portal.jsx +++ b/components/utilities/dialog/portal.jsx @@ -17,6 +17,7 @@ class Portal extends Component { this.portalNode = null; this.state = { isOpen: false, + portalContainer: null, }; } @@ -68,12 +69,18 @@ class Portal extends Component { this.portalNodeInstance = this.props.onMount ? this.props.onMount(undefined, { portal: this.portalNode }) : this.portalNode; + + if (!this.props.portalMount) { + this.setState({ portalContainer: this.portalNode }); + } } } unmountPortal() { if (this.portalNode) { - ReactDOM.unmountComponentAtNode(this.portalNode); + if (this.portalMount) { + ReactDOM.unmountComponentAtNode(this.portalNode); + } this.portalNode.parentNode.removeChild(this.portalNode); } this.portalNode = null; @@ -119,28 +126,13 @@ class Portal extends Component { this.updatePortal(); // update after subtree renders }, }); - } else { - // actual render - ReactDOM.unstable_renderSubtreeIntoContainer( - this, - this.getChildren(), - this.portalNode, - () => { - this.updatePortal(); // update after subtree renders - - if (this.state.isOpen === false) { - if (this.props.onOpen) { - this.props.onOpen(undefined, { portal: this.getChildren() }); - } - this.setState({ isOpen: true }); - } - } - ); } } render() { - return null; + return !this.props.portalMount && this.state.portalContainer + ? ReactDOM.createPortal(this.props.children, this.state.portalContainer) + : null; } } From 1e967480f74c322883597e8d0bf5c0dd8cd84c87 Mon Sep 17 00:00:00 2001 From: Bruce Date: Mon, 11 Apr 2022 15:03:00 -0500 Subject: [PATCH 2/4] Removed the onOpen prop since it is no longer being used in Portal.jsx --- components/utilities/dialog/portal.jsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/utilities/dialog/portal.jsx b/components/utilities/dialog/portal.jsx index 9d25cfc5da..ebf9e061d8 100644 --- a/components/utilities/dialog/portal.jsx +++ b/components/utilities/dialog/portal.jsx @@ -167,10 +167,6 @@ Portal.propTypes = { * Triggers when Portal render tree mounts. Pass in an undefined event and `{ portal: [node] }`` */ onMount: PropTypes.func, - /* - * Triggers when the portal is mounted. - */ - onOpen: PropTypes.func, /* * Triggers when Portal re-renders its tree. */ @@ -198,7 +194,6 @@ Portal.defaultProps = { renderTag: 'span', renderTo: null, onMount: () => null, - onOpen: () => null, onUpdate: () => null, onUnmount: () => null, }; From 4f87456c6d47382dc71fe467defbf7bac4a741ef Mon Sep 17 00:00:00 2001 From: Bruce Date: Mon, 11 Apr 2022 15:25:18 -0500 Subject: [PATCH 3/4] Added the onOpen prop back into the Portal component and state changes when it's not a portalMount and using the actual react portals so it does not have breaking changes if someone is using these props. --- components/utilities/dialog/portal.jsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/utilities/dialog/portal.jsx b/components/utilities/dialog/portal.jsx index ebf9e061d8..dc1269a3c8 100644 --- a/components/utilities/dialog/portal.jsx +++ b/components/utilities/dialog/portal.jsx @@ -126,6 +126,11 @@ class Portal extends Component { this.updatePortal(); // update after subtree renders }, }); + } else if (this.state.isOpen === false) { + if (this.props.onOpen) { + this.props.onOpen(undefined, { portal: this.getChildren() }); + } + this.setState({ isOpen: true }); } } @@ -167,6 +172,10 @@ Portal.propTypes = { * Triggers when Portal render tree mounts. Pass in an undefined event and `{ portal: [node] }`` */ onMount: PropTypes.func, + /* + * Triggers when the portal is mounted. + */ + onOpen: PropTypes.func, /* * Triggers when Portal re-renders its tree. */ @@ -194,6 +203,7 @@ Portal.defaultProps = { renderTag: 'span', renderTo: null, onMount: () => null, + onOpen: () => null, onUpdate: () => null, onUnmount: () => null, }; From cfecc39c0b3f29d20aa12447999ace530fa155ce Mon Sep 17 00:00:00 2001 From: Bruce Date: Mon, 11 Apr 2022 16:28:48 -0500 Subject: [PATCH 4/4] Added the updatePortal method before setting the state for the portalContainer so the id, classNames and styles get into the portalNode before updating the state for portalContainer --- components/utilities/dialog/portal.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/components/utilities/dialog/portal.jsx b/components/utilities/dialog/portal.jsx index dc1269a3c8..4e17dfbb4d 100644 --- a/components/utilities/dialog/portal.jsx +++ b/components/utilities/dialog/portal.jsx @@ -71,6 +71,7 @@ class Portal extends Component { : this.portalNode; if (!this.props.portalMount) { + this.updatePortal(); this.setState({ portalContainer: this.portalNode }); } }