{"version":3,"file":"useFullscreen.cjs","names":["_react","require","_withSelector","_index","_createStore","createSharedFullscreenModeMessageBus","store","createStore","connection","subscriberCount","getFullscreenModeMessageBus","getState","fullscreenModeMessageBus","getSubscriberCount","subscribe","onStoreChange","createFullscreenModeMessageBus","isFirstSubscriber","setState","unsubscribeFromFullscreenState","subscribeToFullscreenState","requestFullscreenState","destroy","getFullscreenState","emptyFullscreenState","publishFullscreenRequest","sendRequest","openFullscreenModeMessageBus","requestFullscreenModeMessageBus","sharedFullscreenModeMessageBus","getIsSameFullscreenSelection","currentSelection","nextSelection","fullscreenStackIndex","hasActiveFullscreen","isFullscreen","isInFullscreenStack","useFullscreen","fullscreenId","fullscreenSelection","useSyncExternalStoreWithSelector","fullscreenStack","getFullscreenStackIndex","getHasActiveFullscreen","getIsFullscreen","getIsInFullscreenStack","enterFullscreen","useCallback","exitFullscreen","toggleFullscreen","useMemo","exports","useHasActiveFullscreen"],"sources":["../../../src/fullscreen/useFullscreen.ts"],"sourcesContent":["/*!\n * Copyright (c) 2026-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 { useCallback, useMemo } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector\";\n\nimport {\n  createFullscreenModeMessageBus,\n  emptyFullscreenState,\n  type FullscreenModeMessageBus,\n  type FullscreenState,\n  getFullscreenStackIndex,\n  getHasActiveFullscreen,\n  getIsFullscreen,\n  getIsInFullscreenStack,\n} from \"../message-bus/index.js\";\nimport { createStore } from \"../tools/createStore.js\";\n\nexport type UseFullscreenArgs = {\n  /**\n   * The id from `useFullscreenId`, shared by the `FullscreenRegion` and every `FullscreenButton` that controls it.\n   */\n  fullscreenId: string;\n};\n\nexport type UseFullscreenResult = {\n  /**\n   * Put this id on top of the page's fullscreen stack, so its region is the one shown.\n   */\n  enterFullscreen: () => void;\n  /**\n   * Take this id out of the stack, wherever it is. The region under it, if any, is shown again.\n   */\n  exitFullscreen: () => void;\n  /**\n   * Where this id sits in the stack, from `0` at the bottom, or `-1` when it isn't in fullscreen. A region uses it to stack above the regions under it.\n   */\n  fullscreenStackIndex: number;\n  /**\n   * `true` when **anything** on the page is in fullscreen, in any app. UI Shell reads this to hide its navigation and banners.\n   */\n  hasActiveFullscreen: boolean;\n  /**\n   * `true` when this id is on **top** of the stack, so its region is the one the user sees and works in. Read this for focus, `inert`, and announcements.\n   */\n  isFullscreen: boolean;\n  /**\n   * `true` when this id is **anywhere** in the stack, even covered by a region above it. Read this for what lasts until the id exits: the region staying fixed over the page, and its button reading as pressed.\n   */\n  isInFullscreenStack: boolean;\n  /**\n   * Exit if this id is in the stack, otherwise enter.\n   */\n  toggleFullscreen: () => void;\n};\n\ntype FullscreenSelection = Pick<\n  UseFullscreenResult,\n  | \"fullscreenStackIndex\"\n  | \"hasActiveFullscreen\"\n  | \"isFullscreen\"\n  | \"isInFullscreenStack\"\n>;\n\ntype SharedConnectionStore = {\n  connection: { fullscreenModeMessageBus?: FullscreenModeMessageBus };\n  subscriberCount: number;\n};\n\n/**\n * One connection per bundle, opened by the first subscriber and closed by the last. Every hook in the bundle reads the same stack, and the page keeps one `message` listener per bundle no matter how many regions render.\n */\nconst createSharedFullscreenModeMessageBus = () => {\n  const store = createStore<SharedConnectionStore>({\n    connection: {},\n    subscriberCount: 0,\n  });\n\n  const getFullscreenModeMessageBus = () =>\n    store.getState(\"connection\")?.fullscreenModeMessageBus;\n\n  const getSubscriberCount = () => store.getState(\"subscriberCount\") ?? 0;\n\n  const subscribe = (onStoreChange: () => void) => {\n    const fullscreenModeMessageBus =\n      getFullscreenModeMessageBus() ?? createFullscreenModeMessageBus();\n    const isFirstSubscriber = getSubscriberCount() === 0;\n\n    store.setState(\"connection\", { fullscreenModeMessageBus });\n    store.setState(\"subscriberCount\", getSubscriberCount() + 1);\n\n    const unsubscribeFromFullscreenState =\n      fullscreenModeMessageBus.subscribeToFullscreenState(onStoreChange);\n\n    if (isFirstSubscriber) {\n      fullscreenModeMessageBus.requestFullscreenState();\n    }\n\n    return () => {\n      unsubscribeFromFullscreenState();\n      store.setState(\"subscriberCount\", getSubscriberCount() - 1);\n\n      if (getSubscriberCount() === 0) {\n        fullscreenModeMessageBus.destroy();\n        store.setState(\"connection\", {});\n      }\n    };\n  };\n\n  const getFullscreenState = (): FullscreenState =>\n    getFullscreenModeMessageBus()?.getFullscreenState() ?? emptyFullscreenState;\n\n  // A region's unmount cleanup runs after its own subscription closes, so its exit can arrive with no connection open. Sending needs no subscription, so a request never waits on one.\n  const publishFullscreenRequest = (\n    sendRequest: (fullscreenModeMessageBus: FullscreenModeMessageBus) => void,\n  ) => {\n    const openFullscreenModeMessageBus = getFullscreenModeMessageBus();\n\n    if (openFullscreenModeMessageBus) {\n      sendRequest(openFullscreenModeMessageBus);\n\n      return;\n    }\n\n    const requestFullscreenModeMessageBus = createFullscreenModeMessageBus();\n\n    sendRequest(requestFullscreenModeMessageBus);\n    requestFullscreenModeMessageBus.destroy();\n  };\n\n  return { getFullscreenState, publishFullscreenRequest, subscribe };\n};\n\nconst sharedFullscreenModeMessageBus = createSharedFullscreenModeMessageBus();\n\nconst getIsSameFullscreenSelection = (\n  currentSelection: FullscreenSelection,\n  nextSelection: FullscreenSelection,\n) =>\n  currentSelection.fullscreenStackIndex ===\n    nextSelection.fullscreenStackIndex &&\n  currentSelection.hasActiveFullscreen === nextSelection.hasActiveFullscreen &&\n  currentSelection.isFullscreen === nextSelection.isFullscreen &&\n  currentSelection.isInFullscreenStack === nextSelection.isInFullscreenStack;\n\n/**\n * Read and change one fullscreen id's place on the page.\n *\n * The page's stack lives in the fullscreen mode host, which Unified UI Shell runs. Every hook opens its own subscription to it, so a change re-renders only the components whose values changed. Without a host on the page, the stack stays empty and entering does nothing.\n *\n * | Value | `true` when | Use it for |\n * | --- | --- | --- |\n * | `isFullscreen` | this id is on top of the stack | focus, `inert`, announcements |\n * | `isInFullscreenStack` | this id is anywhere in the stack | staying fixed, a pressed button |\n * | `hasActiveFullscreen` | anything on the page is in fullscreen | hiding the shell's chrome |\n *\n * @experimental The fullscreen API is in alpha and may change in a future release.\n */\nexport const useFullscreen = ({\n  fullscreenId,\n}: UseFullscreenArgs): UseFullscreenResult => {\n  const fullscreenSelection = useSyncExternalStoreWithSelector(\n    sharedFullscreenModeMessageBus.subscribe,\n    sharedFullscreenModeMessageBus.getFullscreenState,\n    sharedFullscreenModeMessageBus.getFullscreenState,\n    ({ fullscreenStack }): FullscreenSelection => ({\n      fullscreenStackIndex: getFullscreenStackIndex({\n        fullscreenId,\n        fullscreenStack,\n      }),\n      hasActiveFullscreen: getHasActiveFullscreen({ fullscreenStack }),\n      isFullscreen: getIsFullscreen({ fullscreenId, fullscreenStack }),\n      isInFullscreenStack: getIsInFullscreenStack({\n        fullscreenId,\n        fullscreenStack,\n      }),\n    }),\n    getIsSameFullscreenSelection,\n  );\n\n  const enterFullscreen = useCallback(() => {\n    sharedFullscreenModeMessageBus.publishFullscreenRequest(\n      (fullscreenModeMessageBus) =>\n        fullscreenModeMessageBus.enterFullscreen({ fullscreenId }),\n    );\n  }, [fullscreenId]);\n\n  const exitFullscreen = useCallback(() => {\n    sharedFullscreenModeMessageBus.publishFullscreenRequest(\n      (fullscreenModeMessageBus) =>\n        fullscreenModeMessageBus.exitFullscreen({ fullscreenId }),\n    );\n  }, [fullscreenId]);\n\n  const toggleFullscreen = useCallback(() => {\n    if (fullscreenSelection.isInFullscreenStack) {\n      exitFullscreen();\n    } else {\n      enterFullscreen();\n    }\n  }, [\n    enterFullscreen,\n    exitFullscreen,\n    fullscreenSelection.isInFullscreenStack,\n  ]);\n\n  return useMemo(\n    () => ({\n      ...fullscreenSelection,\n      enterFullscreen,\n      exitFullscreen,\n      toggleFullscreen,\n    }),\n    [enterFullscreen, exitFullscreen, fullscreenSelection, toggleFullscreen],\n  );\n};\n\n/**\n * `true` when anything on the page is in fullscreen, in any app. For page chrome, such as UI Shell's navigation, that hides while a region fills the screen. It re-renders only when that answer changes.\n *\n * @experimental The fullscreen API is in alpha and may change in a future release.\n */\nexport const useHasActiveFullscreen = () =>\n  useSyncExternalStoreWithSelector(\n    sharedFullscreenModeMessageBus.subscribe,\n    sharedFullscreenModeMessageBus.getFullscreenState,\n    sharedFullscreenModeMessageBus.getFullscreenState,\n    getHasActiveFullscreen,\n  );\n"],"mappings":"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","ignoreList":[]}