@backstage/plugin-techdocs-react
Version:
Shared frontend utilities for TechDocs and Addons
63 lines (60 loc) • 2.19 kB
JavaScript
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