{"version":3,"file":"renderReactInWebComponent.cjs","names":["_client","require","_createReactRootElements","_encapsulateShadowDomFromGlobalStyles","_odysseyWebComponentVersionGenerated","_interopRequireDefault","e","__esModule","default","webComponentDataAttributeName","exports","versionedWebComponentName","version","toLowerCase","SsrFriendlyHtmlElementClass","globalThis","HTMLElement","WebComponentClass","getReactComponent","reactRootElements","elementName","localName","reactRoot","constructor","createReactRootElements","appRootElement","stylesRootElement","shadowRoot","attachShadow","mode","appendChild","setGetReactComponent","render","connectedCallback","encapsulateShadowDomFromGlobalStyles","nonce","getAttribute","window","cspNonce","Error","createRoot","disconnectedCallback","unmount","getReactWebComponent","webComponentName","customElements","get","define","element","document","createElement","setAttribute","renderReactInWebComponent","webComponentChildren","webComponentParentElement","webComponentRootElement","reactElement","Array","isArray","forEach","webComponentChild"],"sources":["../../../src/web-component/renderReactInWebComponent.ts"],"sourcesContent":["/*!\n * Copyright (c) 2024-present, Okta, Inc. and/or its affiliates. All rights reserved.\n * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the \"License.\")\n *\n * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *\n * See the License for the specific language governing permissions and limitations under the License.\n */\n\nimport { type ReactNode } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\n\nimport {\n  createReactRootElements,\n  type ReactRootElements,\n} from \"./createReactRootElements.js\";\nimport { encapsulateShadowDomFromGlobalStyles } from \"./encapsulateShadowDomFromGlobalStyles.js\";\nimport version from \"./odysseyWebComponentVersion.generated.js\";\n\ninterface GetReactWebComponentOptions {\n  getReactComponent: (reactRootElements: ReactRootElements) => ReactNode;\n  nonce: string;\n  webComponentName?: string;\n}\n\n// Used by selenium when selecting for odyssey web components regardless of their name.\nexport const webComponentDataAttributeName = \"data-odyssey-react-web-component\";\n\n// Unique name to avoid multiple versions of odyssey overwriting each other's implementations\nexport const versionedWebComponentName =\n  `odyssey-react-web-component-${version}`.toLowerCase();\n\nconst SsrFriendlyHtmlElementClass =\n  \"HTMLElement\" in globalThis\n    ? HTMLElement\n    : (class {} as unknown as typeof globalThis.HTMLElement);\n\nexport class WebComponentClass extends SsrFriendlyHtmlElementClass {\n  #getReactComponent: GetReactComponentInWebComponent | null = null;\n  readonly #reactRootElements: ReactRootElements;\n  public readonly elementName: string = this.localName;\n  #reactRoot: Root | null = null;\n\n  constructor() {\n    super();\n\n    this.#reactRootElements = createReactRootElements();\n    const { appRootElement, stylesRootElement } = this.#reactRootElements;\n\n    const shadowRoot = this.attachShadow({ mode: \"open\" });\n    shadowRoot.appendChild(stylesRootElement);\n    shadowRoot.appendChild(appRootElement);\n  }\n\n  /**\n   * Provides the function used to initialize react content that is specific to this instance of the web component, which is used later in the connectedCallback.\n   *\n   * Always set immediately after creation via document.createElement\n   */\n  setGetReactComponent(getReactComponent: GetReactComponentInWebComponent) {\n    this.#getReactComponent = getReactComponent;\n    if (this.#reactRoot) {\n      this.#reactRoot.render(this.#getReactComponent(this.#reactRootElements));\n    }\n  }\n\n  connectedCallback() {\n    encapsulateShadowDomFromGlobalStyles({\n      nonce: this.getAttribute(\"nonce\") || window.cspNonce,\n      stylesRootElement: this.#reactRootElements.stylesRootElement,\n    });\n\n    if (this.#reactRoot) {\n      throw new Error(\n        `connectedCallback fired when reactRoot is already mounted.`,\n      );\n    }\n\n    this.#reactRoot = createRoot(this.#reactRootElements.appRootElement);\n\n    if (this.#getReactComponent) {\n      this.#reactRoot.render(this.#getReactComponent(this.#reactRootElements));\n    }\n  }\n\n  disconnectedCallback() {\n    if (!this.#reactRoot) {\n      throw new Error(\n        `disconnectedCallback fired when reactRoot is already unmounted.`,\n      );\n    }\n\n    this.#reactRoot.unmount();\n    this.#reactRoot = null;\n    // #getReactComponent is preserved — if reconnected it will render on connectedCallback\n  }\n}\n\n/**\n * Returns a constructed web component which manages it's own shadow dom and react dom roots. A custom name can be specified, otherwise a default is provided\n */\nexport const getReactWebComponent = ({\n  webComponentName = versionedWebComponentName,\n  getReactComponent,\n  nonce,\n}: GetReactWebComponentOptions) => {\n  // This name hasn't been defined yet. Add a definition for it before constructing one.\n  if (!customElements.get(webComponentName)) {\n    customElements.define(webComponentName, WebComponentClass);\n  }\n\n  const element = document.createElement(webComponentName) as InstanceType<\n    typeof WebComponentClass\n  >;\n  // Set selenium attribute so this can be selected\n  element.setAttribute(webComponentDataAttributeName, \"\");\n  // Set the nonce for CSP compliance\n  element.setAttribute(\"nonce\", nonce);\n  // function used for creating react content\n  element.setGetReactComponent(getReactComponent);\n  return element;\n};\n\nexport type GetReactComponentInWebComponent = (\n  reactRootElements: ReactRootElements,\n) => ReactNode;\n\nexport type RenderReactInWebComponentProps = {\n  /**\n   * This is a callback function for rendering your React component or app in the Web Component. It gives you access to the Shadow DOM elements if you need them for Odyssey, Emotion, or MUI.\n   *\n   * You will need to add `<slot>` elements if you want to pass child elements or components or React apps. You can have multiple slots in your app if you add a `name` attribute to your `<slot>` elements.\n   */\n  getReactComponent: GetReactComponentInWebComponent;\n  /**\n   * Optional nonce for CSP compliance. Defaults to `window.cspNonce`.\n   */\n  nonce?: string;\n  /**\n   * One or more HTML elements that are going to render as `children` of the web component. If your React component doesn't take children, this is unnecessary.\n   *\n   * Typically, a React app root element is passed, but it can include an array of other elements if there are multiple slots for children.\n   *\n   * You will need to have rendered `<slot>` elements in your React component or `children` won't show up.\n   */\n  webComponentChildren?: HTMLElement | HTMLElement[];\n  /**\n   * Optional name given to this web component.\n   * Defaults to a 'odyssey-react-wc-' plus the current odyssey version\n   */\n  webComponentName?: string;\n} & (\n  | {\n      /**\n       * The React app renders in the web component, but the web component needs to be rendered in the document.\n       *\n       * This is the element the web component is rendered into.\n       */\n      webComponentParentElement: HTMLElement;\n      webComponentRootElement?: never;\n    }\n  | {\n      webComponentParentElement?: never;\n      /**\n       * @deprecated Use `webComponentParentElement` instead.\n       */\n      webComponentRootElement: HTMLElement;\n    }\n);\n\n/**\n * Lets you render React apps or components in a Web Component.\n *\n * This is useful when global styles are causing conflicts with your React components.\n */\nexport const renderReactInWebComponent = ({\n  webComponentName,\n  getReactComponent,\n  webComponentChildren,\n  webComponentParentElement,\n  webComponentRootElement,\n  nonce = window.cspNonce,\n}: RenderReactInWebComponentProps) => {\n  const reactElement = getReactWebComponent({\n    getReactComponent,\n    webComponentName,\n    nonce,\n  });\n\n  if (webComponentChildren) {\n    (Array.isArray(webComponentChildren)\n      ? webComponentChildren\n      : [webComponentChildren]\n    ).forEach((webComponentChild) => {\n      reactElement.appendChild(webComponentChild);\n    });\n  }\n\n  if (webComponentParentElement) {\n    webComponentParentElement.appendChild(reactElement);\n  }\n  // Remove this condition when `webComponentRootElement` is no longer a prop.\n  else if (webComponentRootElement) {\n    webComponentRootElement.appendChild(reactElement);\n  }\n\n  return reactElement;\n};\n"],"mappings":"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","ignoreList":[]}