| 4 | |
| 5 | //https://github.com/bubblydoo/angular-react/blob/e0f370a7ea3563b1d92530aad207575c086ba3ef/projects/angular-react/src/lib/use-in-tree-create-root/use-in-tree-create-root.ts#L11 |
| 6 | export function useInTreeCreateRoot() { |
| 7 | // Use WeakMap to prevent memory leaks - DOM elements can be garbage collected |
| 8 | const rootsRef = useRef(new WeakMap<Element | DocumentFragment, ReactNode>()); |
| 9 | const rootMapRef = useRef(new WeakMap<Element | DocumentFragment, Root>()); |
| 10 | const [updateCounter, setUpdateCounter] = useState(0); |
| 11 | |
| 12 | // Track containers for iteration (since WeakMap is not iterable) |
| 13 | const [containers, setContainers] = useState<Set<Element | DocumentFragment>>(new Set()); |
| 14 | const getRoot = (container: Element | DocumentFragment) => { |
| 15 | return rootMapRef.current.get(container); |
| 16 | }; |
| 17 | const createRoot: typeof origCreateRoot = useCallback( |
| 18 | (container, options) => { |
| 19 | const root: Root = { |
| 20 | render: (children) => { |
| 21 | rootsRef.current.set(container, children); |
| 22 | setUpdateCounter(c => c + 1); |
| 23 | }, |
| 24 | unmount: () => { |
| 25 | rootsRef.current.delete(container); |
| 26 | rootMapRef.current.delete(container); |
| 27 | setContainers(prev => { |
| 28 | const newSet = new Set(prev); |
| 29 | newSet.delete(container); |
| 30 | return newSet; |
| 31 | }); |
| 32 | setUpdateCounter(c => c + 1); |
| 33 | }, |
| 34 | }; |
| 35 | |
| 36 | rootsRef.current.set(container, null); |
| 37 | rootMapRef.current.set(container, root); |
| 38 | setContainers(prev => new Set(prev).add(container)); |
| 39 | setUpdateCounter(c => c + 1); |
| 40 | |
| 41 | return root; |
| 42 | }, |
| 43 | [] |
| 44 | ); |
| 45 | |
| 46 | const portals = useMemo(() => { |
| 47 | return [...containers].map((container) => { |
| 48 | const root = rootsRef.current.get(container); |
| 49 | return root ? createPortal(root, container) : null; |
| 50 | }).filter(Boolean); |
| 51 | }, [containers, updateCounter]); |
| 52 | |
| 53 | return { createRoot, portals, getRoot }; |
| 54 | } |