UNPKG

react-native-root-siblings

Version:

react native root sibling elements manager

87 lines 2.85 kB
import React, { useEffect, useState } from 'react'; import { AppRegistry } from 'react-native'; import ChildrenWrapper from './ChildrenWrapper'; import wrapRootComponent from './wrapRootComponent'; let siblingWrapper = sibling => sibling; function renderSibling(sibling) { return siblingWrapper(sibling); } if (!global.__rootSiblingsInjected && !global.__rootSiblingsDisabled) { AppRegistry.setWrapperComponentProvider(() => { return Root; }); global.__rootSiblingsInjected = true; } export function setSiblingWrapper(wrapper) { siblingWrapper = wrapper; } const { Root, manager: defaultManager } = wrapRootComponent(ChildrenWrapper, renderSibling); let uuid = 0; const managerStack = [defaultManager]; const inactiveManagers = new Set(); function getActiveManager() { for (let i = managerStack.length - 1; i >= 0; i--) { const manager = managerStack[i]; if (!inactiveManagers.has(manager)) { return manager; } } return defaultManager; } export default class RootSiblingsManager { constructor(element, callback) { this.id = `root-sibling-${uuid + 1}`; this.manager = getActiveManager(); this.manager.update(this.id, element, callback); uuid++; } update(element, callback) { this.manager.update(this.id, element, callback); } destroy(callback) { this.manager.destroy(this.id, callback); } } export function RootSiblingParent(props) { const { inactive } = props; const [sibling] = useState(() => { const { Root: parentRoot, manager: parentManager } = wrapRootComponent(ChildrenWrapper, renderSibling); managerStack.push(parentManager); if (inactive) { inactiveManagers.add(parentManager); } return { Root: parentRoot, manager: parentManager }; }); useEffect(() => { return () => { if (sibling) { const index = managerStack.indexOf(sibling.manager); if (index > 0) { managerStack.splice(index, 1); } } }; }, [sibling]); if (inactive && sibling && !inactiveManagers.has(sibling.manager)) { inactiveManagers.add(sibling.manager); } else if (!inactive && sibling && inactiveManagers.has(sibling.manager)) { inactiveManagers.delete(sibling.manager); } const Parent = sibling.Root; return <Parent>{props.children}</Parent>; } export function RootSiblingPortal(props) { const [sibling] = useState(() => new RootSiblingsManager(null)); sibling.update(props.children); useEffect(() => { if (sibling) { return () => sibling.destroy(); } }, [sibling]); return null; } //# sourceMappingURL=RootSiblingsManager.js.map