import { injectCssIntoNode, injectGlobalStyle } from '../internal/style-injector/src/index.mjs';
import wn from '../node_modules/preact/compat/dist/compat.module.mjs';

/**
 * NOTE: These are currently only used for admin portal components. Other Stytch UI components use
 * utils from WebComponents.tsx instead.
 *
 * An opinionated React Component to Web Component binder.
 * High-level points:
 * - All React props are passed as props on the div, no attributes involved
 * - No support for incremental updates of props
 */ function CreateWebComponent(ReactComponent, webComponentName) {
    const existingRegistry = customElements.get(webComponentName);
    if (existingRegistry) {
        return existingRegistry;
    }
    class ReactWebComponent extends HTMLElement {
        props;
        rootRef;
        mountPoint;
        styleSlot;
        constructor(props){
            super();
            this.props = props;
            this.rootRef = document.createElement('div');
            this.append(this.rootRef);
        }
        connectedCallback() {
            injectGlobalStyle();
            this.styleSlot = document.createElement('section');
            this.rootRef.appendChild(this.styleSlot);
            this.mountPoint = document.createElement('span');
            this.styleSlot.appendChild(this.mountPoint);
            this.render(this.props);
        }
        disconnectedCallback() {
            if (!this.mountPoint) {
                return;
            }
            wn.unmountComponentAtNode(this.mountPoint);
        }
        render(props) {
            if (!this.mountPoint) {
                throw Error('Cannot render - no mount point defined');
            }
            if (!this.styleSlot) {
                throw Error('Cannot render - no style slot defined');
            }
            wn.render(/*#__PURE__*/ wn.createElement(ReactComponent, props), this.mountPoint);
        }
    }
    customElements.define(webComponentName, ReactWebComponent);
    return ReactWebComponent;
}
function CreateShadowWebComponent(ReactComponent, webComponentName) {
    const existingRegistry = customElements.get(webComponentName);
    if (existingRegistry) {
        return existingRegistry;
    }
    class ReactWebComponent extends HTMLElement {
        props;
        rootRef;
        mountPoint;
        styleSlot;
        constructor(props){
            super();
            this.props = props;
            this.rootRef = this.attachShadow({
                mode: 'open'
            });
        }
        connectedCallback() {
            const style = injectCssIntoNode();
            this.rootRef.appendChild(style);
            this.styleSlot = document.createElement('section');
            this.rootRef.appendChild(this.styleSlot);
            this.mountPoint = document.createElement('span');
            this.styleSlot.appendChild(this.mountPoint);
            this.render(this.props);
        }
        disconnectedCallback() {
            if (!this.mountPoint) {
                return;
            }
            wn.unmountComponentAtNode(this.mountPoint);
        }
        render(props) {
            if (!this.mountPoint) {
                throw Error('Cannot render - no mount point defined');
            }
            if (!this.styleSlot) {
                throw Error('Cannot render - no style slot defined');
            }
            wn.render(/*#__PURE__*/ wn.createElement(ReactComponent, props), this.mountPoint);
        }
    }
    customElements.define(webComponentName, ReactWebComponent);
    return ReactWebComponent;
}
/**
 * Web Components aren't really isomorphic at all
 * but it's important to delay the construction & definition of the WC class until we are on the clientside
 * because the HTMLElement we extend from, and the customElement registry we modify, don't exist on the server
 */ function CreateSSRSafeWebComponent(ReactComponent, webComponentName) {
    if (typeof window === 'undefined') {
        return ()=>null;
    }
    return (props)=>{
        const shadowDomEnabled = !!props.config?.enableShadowDOM;
        if (shadowDomEnabled) {
            const Component = CreateShadowWebComponent(ReactComponent, webComponentName);
            return new Component(props);
        } else {
            const Component = CreateWebComponent(ReactComponent, webComponentName);
            return new Component(props);
        }
    };
}

export { CreateSSRSafeWebComponent, CreateShadowWebComponent, CreateWebComponent };
//# sourceMappingURL=CreateWebComponent.mjs.map
