diff --git a/src/AnotherComponent.jsx b/src/AnotherComponent.jsx index f2832f3..537650e 100644 --- a/src/AnotherComponent.jsx +++ b/src/AnotherComponent.jsx @@ -1,10 +1,11 @@ import React from "react"; +import { useShadowStyles } from "./ShadowRoot"; import * as styles from './AnotherComponent.css' assert { type: 'css' }; -// Adopt all sheets into the document -document.adoptedStyleSheets = [...document.adoptedStyleSheets, styles.default]; - export const AnotherComponent = () => { + + useShadowStyles(styles.default); + return
Another Component
; diff --git a/src/App.jsx b/src/App.jsx index 15b5071..8bad826 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,30 +1,25 @@ import React from "react"; -import root from 'react-shadow'; +import { ShadowRoot } from './ShadowRoot'; import { Component } from './Component'; import { AnotherComponent } from './AnotherComponent'; export const App = () => { - const ref = React.useRef(); - - React.useEffect(() => { - console.log(ref.current.shadowRoot.adoptedStyleSheets[0]); - }, []); - const [anotherLoaded, setAnotherLoaded] = React.useState(false); const onBtnClick = () => { setAnotherLoaded(true); } - // See "propTypes": https://www.npmjs.com/package/react-shadow - // Adopt the document's adoptedStyleSheets into the shadow root. - return + return <> + {!anotherLoaded && } {anotherLoaded && } - ; + + + + + }; \ No newline at end of file diff --git a/src/Component.jsx b/src/Component.jsx index 24149a8..2026399 100644 --- a/src/Component.jsx +++ b/src/Component.jsx @@ -1,10 +1,11 @@ import React from "react"; +import { useShadowStyles } from "./ShadowRoot"; import * as styles from './Component.css' assert { type: 'css' }; -// Adopt all sheets into the document -document.adoptedStyleSheets = [...document.adoptedStyleSheets, styles.default]; - export const Component = () => { + + useShadowStyles(styles.default); + return
Hello World
; diff --git a/src/ShadowRoot.jsx b/src/ShadowRoot.jsx new file mode 100644 index 0000000..9f2d1a4 --- /dev/null +++ b/src/ShadowRoot.jsx @@ -0,0 +1,47 @@ +import * as React from "react"; +import root from "react-shadow"; + +// A React context for adding Constructable stylesheets to appropriate shadow roots +export const ShadowContext = React.createContext(null); + +export const useShadowContext = () => { + return React.useContext(ShadowContext); +}; + +// Helper hook for adding sheets to context +export const useShadowStyles = (styles) => { + const context = useShadowContext(); + React.useEffect(() => { + context.addSheet(styles); + return () => context.removeSheet(styles); + }, []); +}; + +// Component for providing and managing context +export const ShadowRoot = (props) => { + + // Use React state to force re-render when stylesheets change + const [ stylesheets, setStylesheets ] = React.useState([]); + + const value = React.useMemo(() => { + // Set makes it simple to add/remove sheets + const sheets = new Set(); + return { + addSheet(sheet) { + sheets.add(sheet); + setStylesheets([...sheets]); // Possibly not the most efficient way to do this + }, + removeSheet(sheet) { + sheets.delete(sheet); + setStylesheets([...sheets]); + } + } + }, []); + + // Provide the context and render into a shadow root + return ( + + + ); + +}; \ No newline at end of file