UNPKG

@backstage/plugin-techdocs-react

Version:

Shared frontend utilities for TechDocs and Addons

63 lines (60 loc) 2.19 kB
import { useState, useEffect, useMemo } from 'react'; import debounce from 'lodash/debounce'; import { useTechDocsReaderPage } from './context.esm.js'; const useShadowRoot = () => { const { shadowRoot } = useTechDocsReaderPage(); return shadowRoot; }; const useShadowRootElements = (selectors) => { const shadowRoot = useShadowRoot(); const [root, setRootNode] = useState(shadowRoot?.firstChild); useEffect(() => { let observer; if (shadowRoot) { observer = new MutationObserver(() => { setRootNode(shadowRoot?.firstChild); }); observer.observe(shadowRoot, { attributes: true, characterData: true, childList: true, subtree: true }); } return () => observer?.disconnect(); }, [shadowRoot]); if (!root || !(root instanceof HTMLElement)) return []; return selectors.map((selector) => root.querySelectorAll(selector)).filter((nodeList) => nodeList.length).map((nodeList) => Array.from(nodeList)).flat(); }; const isValidSelection = (newSelection) => { return newSelection.toString() && newSelection.rangeCount && newSelection.getRangeAt(0).getBoundingClientRect().top; }; const useShadowRootSelection = (waitMillis = 0) => { const shadowRoot = useShadowRoot(); const [selection, setSelection] = useState(null); const handleSelectionChange = useMemo( () => debounce(() => { const shadowDocument = shadowRoot; const newSelection = shadowDocument.getSelection ? shadowDocument.getSelection() : document.getSelection(); if (newSelection && isValidSelection(newSelection)) { setSelection(newSelection); } else { setSelection(null); } }, waitMillis), [shadowRoot, setSelection, waitMillis] ); useEffect(() => { window.document.addEventListener("selectionchange", handleSelectionChange); return () => { handleSelectionChange.cancel(); window.document.removeEventListener( "selectionchange", handleSelectionChange ); }; }, [handleSelectionChange]); return selection; }; export { useShadowRoot, useShadowRootElements, useShadowRootSelection }; //# sourceMappingURL=hooks.esm.js.map