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