UNPKG

@backstage/plugin-techdocs-react

Version:

Shared frontend utilities for TechDocs and Addons

95 lines (92 loc) 2.82 kB
import { jsx, Fragment, jsxs } from 'react/jsx-runtime'; import { useState, useCallback, useEffect } from 'react'; import { create } from 'jss'; import StylesProvider from '@material-ui/styles/StylesProvider'; import jssPreset from '@material-ui/styles/jssPreset'; const SHADOW_DOM_STYLE_LOAD_EVENT = "TECH_DOCS_SHADOW_DOM_STYLE_LOAD"; const useShadowDomStylesEvents = (element) => { useEffect(() => { if (!element) { return () => { }; } const styles = element.querySelectorAll( 'head > link[rel="stylesheet"]' ); let count = styles?.length ?? 0; const event = new CustomEvent(SHADOW_DOM_STYLE_LOAD_EVENT); if (!count) { element.dispatchEvent(event); return () => { }; } const handleLoad = () => { if (--count === 0) { element.dispatchEvent(event); } }; styles?.forEach((style) => { style.addEventListener("load", handleLoad); }); return () => { styles?.forEach((style) => { style.removeEventListener("load", handleLoad); }); }; }, [element]); }; const useShadowDomStylesLoading = (element) => { const [loading, setLoading] = useState(false); useEffect(() => { if (!element) return () => { }; setLoading(true); const style = element.style; style.setProperty("opacity", "0"); const handleLoad = () => { setLoading(false); style.setProperty("opacity", "1"); }; element.addEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, handleLoad); return () => { element.removeEventListener(SHADOW_DOM_STYLE_LOAD_EVENT, handleLoad); }; }, [element]); return loading; }; const TechDocsShadowDom = (props) => { const { element, onAppend, children } = props; const [jss, setJss] = useState( create({ ...jssPreset(), insertionPoint: void 0 }) ); useShadowDomStylesEvents(element); const ref = useCallback( (shadowHost) => { if (!element || !shadowHost) return; setJss( create({ ...jssPreset(), insertionPoint: element.querySelector("head") || void 0 }) ); let shadowRoot = shadowHost.shadowRoot; if (!shadowRoot) { shadowRoot = shadowHost.attachShadow({ mode: "open" }); } shadowRoot.replaceChildren(element); if (typeof onAppend === "function") { onAppend(shadowRoot); } }, [element, onAppend] ); return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(StylesProvider, { jss, sheetsManager: /* @__PURE__ */ new Map(), children: [ /* @__PURE__ */ jsx("div", { ref, "data-testid": "techdocs-native-shadowroot" }), children ] }) }); }; export { SHADOW_DOM_STYLE_LOAD_EVENT, TechDocsShadowDom, useShadowDomStylesLoading }; //# sourceMappingURL=component.esm.js.map