UNPKG

@wordpress/interactivity

Version:

Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.

97 lines (89 loc) 2.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createPortal = createPortal; var _preact = require("preact"); /** * External dependencies */ /** * @param {import('../../src/index').RenderableProps<{ context: any }>} props */ function ContextProvider(props) { this.getChildContext = () => props.context; return props.children; } /** * Portal component * * @this {import('./internal').Component} * @param {object | null | undefined} props * * TODO: use createRoot() instead of fake root */ function Portal(props) { const _this = this; const container = props._container; _this.componentWillUnmount = function () { (0, _preact.render)(null, _this._temp); _this._temp = null; _this._container = null; }; // When we change container we should clear our old container and // indicate a new mount. if (_this._container && _this._container !== container) { _this.componentWillUnmount(); } // When props.vnode is undefined/false/null we are dealing with some kind of // conditional vnode. This should not trigger a render. if (props._vnode) { if (!_this._temp) { _this._container = container; // Create a fake DOM parent node that manages a subset of `container`'s children: _this._temp = { nodeType: 1, parentNode: container, childNodes: [], appendChild(child) { this.childNodes.push(child); _this._container.appendChild(child); }, insertBefore(child) { this.childNodes.push(child); _this._container.appendChild(child); }, removeChild(child) { this.childNodes.splice( // eslint-disable-next-line no-bitwise this.childNodes.indexOf(child) >>> 1, 1); _this._container.removeChild(child); } }; } // Render our wrapping element into temp. (0, _preact.render)((0, _preact.createElement)(ContextProvider, { context: _this.context }, props._vnode), _this._temp); } // When we come from a conditional render, on a mounted // portal we should clear the DOM. else if (_this._temp) { _this.componentWillUnmount(); } } /** * Create a `Portal` to continue rendering the vnode tree at a different DOM node * * @param {import('./internal').VNode} vnode The vnode to render * @param {import('./internal').PreactElement} container The DOM node to continue rendering in to. */ function createPortal(vnode, container) { const el = (0, _preact.createElement)(Portal, { _vnode: vnode, _container: container }); el.containerInfo = container; return el; } //# sourceMappingURL=portals.js.map