{"version":3,"file":"renderUiShell.cjs","names":["_reactErrorBoundary","require","_bufferLatest","_createMessageBus","_renderReactInWebComponent","_createUiShellFullscreenState","_UiShell","_useHasUiShell","_jsxRuntime","optionalComponentSlotNames","exports","banners","rightSideMenu","sideNavFooter","topNavLeftSide","topNavRightSide","renderUiShell","appBackgroundColor","appBackgroundContrastMode","appElement","providedAppElement","appElementScrollingMode","breakpointConfig","hasStandardAppContentPadding","initialVisibleSections","languageCode","onError","console","error","onRender","parentElement","sideNavBackgroundColor","sideNavBackgroundContrastColor","topNavBackgroundColor","translationOverrides","nonce","window","cspNonce","document","createElement","setAttribute","uiShellDataAttribute","publish","publishPropChanges","subscribe","subscribeToPropChanges","createMessageBus","publishTranslationSettings","subscribeToTranslationSettings","publishSubscriptionCreated","subscribeToReactAppSubscribed","publishAfterReactAppReadyForProps","bufferLatest","publishAfterReactAppReadyForTranslationSettings","closeRightSideMenu","subscribeToCloseRightSideMenu","closeSideNavMenu","subscribeToCloseSideNavMenu","connect","connectFullscreenState","enterAppFullscreen","enterAppFullscreenNow","exitAppFullscreen","exitAppFullscreenNow","getFullscreenState","subscribeToFullscreenState","createUiShellFullscreenState","requestAfterReactAppReady","sendFullscreenRequest","slottedElements","Object","fromEntries","entries","map","optionalComponentKey","slotName","element","webComponentChildren","values","uiShellElement","renderReactInWebComponent","getReactComponent","reactRootElements","jsx","ErrorBoundary","fallback","children","UiShell","onSubscriptionCreated","optionalComponents","name","uiShellAppElement","appRootElement","uiShellStylesElement","stylesRootElement","webComponentParentElement","unsubscribeFromUnifiedUiShellRendered","setComponentProps","setTranslationSettings","appendChild"],"sources":["../../../src/ui-shell/renderUiShell.tsx"],"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 SetStateAction } from \"react\";\nimport { ErrorBoundary } from \"react-error-boundary\";\n\nimport { type FullscreenModeMessageBus } from \"../message-bus/index.js\";\nimport { bufferLatest } from \"../tools/bufferLatest.js\";\nimport { createMessageBus, PublishMessage } from \"../tools/createMessageBus.js\";\nimport { renderReactInWebComponent } from \"../web-component/renderReactInWebComponent.js\";\nimport { createUiShellFullscreenState } from \"./createUiShellFullscreenState.js\";\nimport {\n  UiShell,\n  UiShellProps,\n  UiShellTranslationSettings,\n} from \"./UiShell.js\";\nimport { UiShellNavComponentProps } from \"./uiShellContentTypes.js\";\nimport { uiShellDataAttribute } from \"./useHasUiShell.js\";\n\nexport const optionalComponentSlotNames: Record<\n  keyof Required<UiShellProps>[\"optionalComponents\"],\n  string\n> = {\n  banners: \"banners\",\n  rightSideMenu: \"right-side-menu\",\n  sideNavFooter: \"side-nav-footer\",\n  topNavLeftSide: \"top-nav-left-side\",\n  topNavRightSide: \"top-nav-right-side\",\n};\n\nexport type SlottedElements = Record<\n  keyof Required<UiShellProps>[\"optionalComponents\"],\n  HTMLDivElement\n>;\n\nexport type RenderedUiShell = {\n  closeRightSideMenu: PublishMessage<void>;\n  closeSideNavMenu: PublishMessage<void>;\n  /**\n   * Put the whole app area in fullscreen. UI Shell hides its top nav, side nav, and banners so the app fills the page.\n   *\n   * Use this when your app isn't built with Odyssey's `FullscreenButton`, for example a non-React app.\n   *\n   * The app area is one more entry in the page's fullscreen stack, so a `FullscreenRegion` can enter on top of it, and Escape goes back one step at a time. Removing `uiShellElement` from the page clears the stack.\n   */\n  enterAppFullscreen: () => void;\n  /**\n   * Take the app area out of fullscreen. A `FullscreenRegion` that entered on top of it stays in fullscreen.\n   */\n  exitAppFullscreen: () => void;\n  /**\n   * The page's current fullscreen state.\n   */\n  getFullscreenState: FullscreenModeMessageBus[\"getFullscreenState\"];\n  setComponentProps: ReturnType<\n    typeof bufferLatest<SetStateAction<UiShellNavComponentProps>>\n  >;\n  /**\n   * Update the shell's translation settings (`languageCode`, `translationOverrides`) at runtime.\n   *\n   * Call this after the consumer's locale changes to re-localize shell-rendered chrome (skip-to-content link, top nav icons, side nav toggle) without re-rendering UI Shell.\n   *\n   * Accepts a React `SetStateAction`: passing a plain object **replaces** the entire settings value (so omitting `translationOverrides` clears it). Pass an updater function — `(previous) => ({ ...previous, languageCode: \"es\" })` — to merge with\n   * the previous value.\n   */\n  setTranslationSettings: ReturnType<\n    typeof bufferLatest<SetStateAction<UiShellTranslationSettings>>\n  >;\n  slottedElements: SlottedElements;\n  /**\n   * Listen for fullscreen changes anywhere on the page, including ones from other apps. Returns a function that stops listening.\n   */\n  subscribeToFullscreenState: FullscreenModeMessageBus[\"subscribeToFullscreenState\"];\n  uiShellElement: ReturnType<typeof renderReactInWebComponent>;\n} & Partial<Pick<UiShellProps, \"appElement\">>;\n\n/**\n * This function renders UI Shell in a web component.\n * This function is agnostic to the UI framework for your app is using. Your application can be another web component, a React app, or even vanilla HTML.\n *\n * **All styles are self-contained.** Even though your application visually renders as children of the web component, its within the global `document` scope, not the web component's `ShadowRoot`. That means any global styles will not affect UI Shell but will affect your application.\n *\n * It places your app's root element in a web component <slot> and ensures it remains rendered in the event of a UI Shell error.\n * It also provides you with other elements fitted to slots in the web component. **In React, you can portal to these components.**\n */\nexport const renderUiShell = ({\n  appBackgroundColor,\n  appBackgroundContrastMode,\n  appElement: providedAppElement,\n  appElementScrollingMode,\n  breakpointConfig,\n  hasStandardAppContentPadding,\n  initialVisibleSections,\n  languageCode,\n  onError = console.error,\n  onRender,\n  parentElement,\n  sideNavBackgroundColor,\n  sideNavBackgroundContrastColor,\n  topNavBackgroundColor,\n  translationOverrides,\n  nonce = window.cspNonce,\n}: {\n  /**\n   * Optional nonce for CSP compliance.\n   */\n  nonce?: string;\n  /**\n   * Notifies when a React rendering error occurs. This could be useful for logging, reporting priority 0 issues, and recovering UI Shell when errors occur.\n   */\n  onError?: () => void;\n  /**\n   * Notify once when React has rendered UI Shell the first time.\n   */\n  onRender?: (renderedUiShell: RenderedUiShell) => void;\n  /**\n   * HTML element used as the container for UI Shell and the App. They're siblings inside this element.\n   */\n  parentElement: HTMLElement;\n} & Pick<\n  UiShellProps,\n  | \"appBackgroundColor\"\n  | \"appBackgroundContrastMode\"\n  | \"appElementScrollingMode\"\n  | \"breakpointConfig\"\n  | \"hasStandardAppContentPadding\"\n  | \"initialVisibleSections\"\n  | \"sideNavBackgroundColor\"\n  | \"sideNavBackgroundContrastColor\"\n  | \"topNavBackgroundColor\"\n> &\n  Partial<UiShellTranslationSettings> &\n  Partial<Pick<UiShellProps, \"appElement\">>) => {\n  const appElement = providedAppElement || document.createElement(\"div\");\n\n  // Add this attribute so `PageTemplate` and potentially other components will know if they're in UI Shell with special padding already available.\n  parentElement.setAttribute(uiShellDataAttribute, \"\");\n\n  const { publish: publishPropChanges, subscribe: subscribeToPropChanges } =\n    createMessageBus<SetStateAction<UiShellNavComponentProps>>();\n\n  const {\n    publish: publishTranslationSettings,\n    subscribe: subscribeToTranslationSettings,\n  } = createMessageBus<SetStateAction<UiShellTranslationSettings>>();\n\n  const {\n    publish: publishSubscriptionCreated,\n    subscribe: subscribeToReactAppSubscribed,\n  } = createMessageBus();\n\n  const publishAfterReactAppReadyForProps = bufferLatest({\n    publish: publishPropChanges,\n    subscribe: subscribeToReactAppSubscribed,\n  });\n\n  const publishAfterReactAppReadyForTranslationSettings = bufferLatest({\n    publish: publishTranslationSettings,\n    subscribe: subscribeToReactAppSubscribed,\n  });\n\n  publishAfterReactAppReadyForTranslationSettings({\n    languageCode,\n    translationOverrides,\n  });\n\n  const {\n    publish: closeRightSideMenu,\n    subscribe: subscribeToCloseRightSideMenu,\n  } = createMessageBus();\n\n  const { publish: closeSideNavMenu, subscribe: subscribeToCloseSideNavMenu } =\n    createMessageBus();\n\n  const {\n    connect: connectFullscreenState,\n    enterAppFullscreen: enterAppFullscreenNow,\n    exitAppFullscreen: exitAppFullscreenNow,\n    getFullscreenState,\n    subscribeToFullscreenState,\n  } = createUiShellFullscreenState();\n\n  // The page's fullscreen host starts when UI Shell's React tree renders, so a request made before then would reach no one. Like props, only the latest request is kept, so an enter followed by an exit leaves the app where it was.\n  const requestAfterReactAppReady = bufferLatest<() => void>({\n    publish: (sendFullscreenRequest) => sendFullscreenRequest(),\n    subscribe: subscribeToReactAppSubscribed,\n  });\n\n  const enterAppFullscreen = () =>\n    requestAfterReactAppReady(enterAppFullscreenNow);\n\n  const exitAppFullscreen = () =>\n    requestAfterReactAppReady(exitAppFullscreenNow);\n\n  const slottedElements = Object.fromEntries(\n    Object.entries(optionalComponentSlotNames).map(\n      ([optionalComponentKey, slotName]) => {\n        const element = document.createElement(\"div\");\n\n        element.setAttribute(\"slot\", slotName);\n\n        return [optionalComponentKey, element];\n      },\n    ),\n  ) as SlottedElements;\n\n  const webComponentChildren = Object.values(slottedElements);\n\n  const uiShellElement = renderReactInWebComponent({\n    getReactComponent: (reactRootElements) => (\n      <ErrorBoundary fallback={<div data-error />} onError={onError}>\n        <UiShell\n          appBackgroundColor={appBackgroundColor}\n          appBackgroundContrastMode={appBackgroundContrastMode}\n          appElement={appElement}\n          appElementScrollingMode={appElementScrollingMode}\n          breakpointConfig={breakpointConfig}\n          closeSideNavMenu={closeSideNavMenu}\n          connectFullscreenState={connectFullscreenState}\n          hasStandardAppContentPadding={hasStandardAppContentPadding}\n          initialVisibleSections={initialVisibleSections}\n          onError={onError}\n          onSubscriptionCreated={publishSubscriptionCreated}\n          // `optionalComponents` doesn't need to be memoized because gets passed in once, and this isn't a React component.\n          optionalComponents={Object.fromEntries(\n            Object.entries(optionalComponentSlotNames).map(\n              ([optionalComponentKey, slotName]) => [\n                optionalComponentKey,\n                <slot name={slotName} />,\n              ],\n            ),\n          )}\n          sideNavBackgroundColor={sideNavBackgroundColor}\n          sideNavBackgroundContrastColor={sideNavBackgroundContrastColor}\n          subscribeToCloseRightSideMenu={subscribeToCloseRightSideMenu}\n          subscribeToCloseSideNavMenu={subscribeToCloseSideNavMenu}\n          subscribeToPropChanges={subscribeToPropChanges}\n          subscribeToTranslationSettings={subscribeToTranslationSettings}\n          topNavBackgroundColor={topNavBackgroundColor}\n          uiShellAppElement={reactRootElements.appRootElement}\n          uiShellStylesElement={reactRootElements.stylesRootElement}\n        />\n      </ErrorBoundary>\n    ),\n    webComponentChildren,\n    webComponentParentElement: parentElement,\n    nonce,\n  });\n\n  const unsubscribeFromUnifiedUiShellRendered = subscribeToReactAppSubscribed(\n    () => {\n      unsubscribeFromUnifiedUiShellRendered();\n\n      onRender?.({\n        appElement,\n        closeRightSideMenu,\n        closeSideNavMenu,\n        enterAppFullscreen,\n        exitAppFullscreen,\n        getFullscreenState,\n        setComponentProps: publishAfterReactAppReadyForProps,\n        setTranslationSettings: publishAfterReactAppReadyForTranslationSettings,\n        slottedElements,\n        subscribeToFullscreenState,\n        uiShellElement,\n      });\n    },\n  );\n\n  parentElement.appendChild(appElement);\n\n  return {\n    appElement,\n    closeRightSideMenu,\n    closeSideNavMenu,\n    enterAppFullscreen,\n    exitAppFullscreen,\n    getFullscreenState,\n    setComponentProps: publishAfterReactAppReadyForProps,\n    setTranslationSettings: publishAfterReactAppReadyForTranslationSettings,\n    slottedElements,\n    subscribeToFullscreenState,\n    uiShellElement,\n  } satisfies RenderedUiShell;\n};\n"],"mappings":"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","ignoreList":[]}