@compiled/react
Version:
A familiar and performant compile time CSS-in-JS library for React.
94 lines • 3.89 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StyleContainerProvider = exports.useStyleContainer = exports.clientStyleContainer = void 0;
const react_1 = __importDefault(require("react"));
const is_server_environment_js_1 = require("./is-server-environment.js");
/**
* Singleton holding the currently active style container config on the client.
* Read directly by useStyleContainer().
*/
exports.clientStyleContainer = null;
/**
* Returns the currently active style container config.
*/
const useStyleContainer = () => {
return exports.clientStyleContainer;
};
exports.useStyleContainer = useStyleContainer;
/**
* Provides a custom DOM container for Compiled style injection within a React subtree.
*
* **Runtime mode only.** This provider is not supported in server environments or when
* using CSS extraction (`@compiled/babel-plugin-strip-runtime`). In extraction mode,
* `CS`/`CC` components are removed at build time, so there is nothing for this provider
* to intercept. Supporting Shadow DOM with extraction is a known limitation and is
* planned as future work.
*
* Use this when rendering Compiled components inside a Shadow DOM, where styles
* inserted into the main document `<head>` are not visible to the shadow tree.
*
* The `cacheKey` must be unique per container and is used to namespace the
* deduplication cache so styles are tracked independently per container.
*
* @example
* ```tsx
* import { StyleContainerProvider } from '@compiled/react';
* import { createPortal } from 'react-dom';
*
* function ShadowHost() {
* const hostRef = useRef<HTMLDivElement>(null);
* const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);
*
* useEffect(() => {
* if (hostRef.current && !hostRef.current.shadowRoot) {
* setShadowRoot(hostRef.current.attachShadow({ mode: 'open' }));
* }
* }, []);
*
* return (
* <div ref={hostRef}>
* {shadowRoot &&
* createPortal(
* <StyleContainerProvider container={shadowRoot} cacheKey="my-shadow-root">
* <MyCompiledComponent />
* </StyleContainerProvider>,
* shadowRoot
* )}
* </div>
* );
* }
* ```
*/
function StyleContainerProvider({ container, cacheKey, children, }) {
if ((0, is_server_environment_js_1.isServerEnvironment)()) {
if (process.env.NODE_ENV === 'development') {
console.warn('@compiled/react: StyleContainerProvider has no effect in server environments. ' +
'Shadow DOM content should be rendered client-side only (e.g. inside a portal ' +
'guarded by useEffect/useState).');
}
return children;
}
// On the client, set the singleton synchronously during the render phase via
// useMemo so CS children pick it up immediately.
// eslint-disable-next-line react-hooks/rules-of-hooks
react_1.default.useMemo(() => {
exports.clientStyleContainer = { container, cacheKey };
}, [container, cacheKey]);
// Clear the singleton when this provider unmounts.
// Note: nested StyleContainerProviders are not supported. If an inner provider
// unmounts, this will clear clientStyleContainer to null rather than restoring
// the outer provider's value. This is an acceptable limitation for the intended
// use case of a single provider wrapping a shadow DOM subtree.
// eslint-disable-next-line react-hooks/rules-of-hooks
react_1.default.useEffect(() => {
return () => {
exports.clientStyleContainer = null;
};
}, []);
return children;
}
exports.StyleContainerProvider = StyleContainerProvider;
//# sourceMappingURL=style-container.js.map