{"version":3,"file":"usePortalContext.mjs","sources":["../../../../../src/lib/layouts/context-aware/hooks/usePortalContext.ts"],"sourcesContent":["/**\n * @fileoverview usePortalContext Hook\n *\n * Provides access to portal context and z-index management.\n *\n * @module layouts/context-aware/hooks/usePortalContext\n * @author Agent 4 - PhD Context Systems Expert\n * @version 1.0.0\n */\n\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { RefCallback } from 'react';\n\nimport type {\n  PortalContext,\n  DOMContextSnapshot,\n  ZIndexLayer,\n  UsePortalContextReturn,\n} from '../types';\nimport { Z_INDEX_LAYERS } from '../types';\nimport { useDOMContextValue } from '../DOMContextProvider';\nimport { usePortalBridgeContext } from '../PortalBridge';\n// import {\n//   getPortalContextManager,\n//   getPortalHierarchy,\n// } from '../portal-bridge';\nimport { getZIndexManager, getLayerZIndex } from '../z-index-manager';\n\n// ============================================================================\n// usePortalContext Hook\n// ============================================================================\n\n/**\n * Hook to access portal context information.\n *\n * @remarks\n * This hook provides information about whether the component is\n * inside a portal, the source context, and z-index management utilities.\n *\n * @returns Portal context information and utilities\n *\n * @example\n * ```tsx\n * function ModalContent() {\n *   const {\n *     portal,\n *     isInPortal,\n *     sourceContext,\n *     layer,\n *     getLayerZIndex,\n *   } = usePortalContext();\n *\n *   return (\n *     <div>\n *       {isInPortal && (\n *         <p>\n *           This is in a portal at z-index layer: {layer}\n *           (z-index: {getLayerZIndex(layer)})\n *         </p>\n *       )}\n *       {sourceContext && (\n *         <p>\n *           Source viewport width: {sourceContext.viewport.width}px\n *         </p>\n *       )}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function usePortalContext(): UsePortalContextReturn {\n  // Try to get context from PortalBridge first\n  const bridgeContext = usePortalBridgeContext();\n\n  // Fall back to DOM context\n  const domContext = useDOMContextValue();\n  const portal = bridgeContext ?? domContext.portal;\n\n  // Get layer z-index function\n  const getZIndex = useCallback((layer: ZIndexLayer): number => {\n    return getLayerZIndex(layer);\n  }, []);\n\n  // Determine current layer\n  const layer: ZIndexLayer = useMemo(() => {\n    if (!portal) {\n      return 'base';\n    }\n\n    // Find the layer that matches the portal's z-index\n    const entries = Object.entries(Z_INDEX_LAYERS) as [ZIndexLayer, number][];\n    const matchingEntry = entries.find(([_, zIndex]) => zIndex === portal.layer);\n    return matchingEntry?.[0] ?? 'base';\n  }, [portal]);\n\n  return {\n    portal,\n    isInPortal: portal !== null,\n    sourceContext: portal?.sourceContext ?? null,\n    layer,\n    getLayerZIndex: getZIndex,\n  };\n}\n\n// ============================================================================\n// Specialized Portal Hooks\n// ============================================================================\n\n/**\n * Hook to check if inside a portal.\n *\n * @returns Whether inside a portal\n *\n * @example\n * ```tsx\n * function ConditionalComponent() {\n *   const isInPortal = useIsInPortal();\n *\n *   if (isInPortal) {\n *     return <PortalOptimizedVersion />;\n *   }\n *\n *   return <NormalVersion />;\n * }\n * ```\n */\nexport function useIsInPortal(): boolean {\n  const { isInPortal } = usePortalContext();\n  return isInPortal;\n}\n\n/**\n * Hook to get the source context from before the portal.\n *\n * @returns Source context snapshot or null\n *\n * @example\n * ```tsx\n * function ContextAwareModal() {\n *   const sourceContext = useSourceContext();\n *\n *   if (sourceContext) {\n *     // Use source viewport for positioning calculations\n *     const { viewport } = sourceContext;\n *     // ...\n *   }\n *\n *   return <ModalContent />;\n * }\n * ```\n */\nexport function useSourceContext(): DOMContextSnapshot | null {\n  const { sourceContext } = usePortalContext();\n  return sourceContext;\n}\n\n/**\n * Hook to get the current portal nesting depth.\n *\n * @returns Nesting depth (0 if not in portal)\n *\n * @example\n * ```tsx\n * function NestedModal() {\n *   const nestingDepth = usePortalNestingDepth();\n *\n *   return (\n *     <div style={{ zIndex: 1400 + nestingDepth }}>\n *       Nested modal at depth {nestingDepth}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function usePortalNestingDepth(): number {\n  const { portal } = usePortalContext();\n  return portal?.nestingDepth ?? 0;\n}\n\n/**\n * Hook to get the portal hierarchy.\n *\n * @returns Array of portal contexts from innermost to outermost\n *\n * @example\n * ```tsx\n * function PortalDebug() {\n *   const hierarchy = usePortalHierarchy();\n *\n *   return (\n *     <div>\n *       <p>Portal depth: {hierarchy.length}</p>\n *       {hierarchy.map((portal, i) => (\n *         <p key={i}>Level {i}: {portal.portalId}</p>\n *       ))}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function usePortalHierarchy(): PortalContext[] {\n  const { portal } = usePortalContext();\n\n  return useMemo(() => {\n    if (!portal) {\n      return [];\n    }\n\n    const hierarchy: PortalContext[] = [];\n    let current: PortalContext | null = portal;\n\n    while (current) {\n      hierarchy.push(current);\n      current = current.parentPortal;\n    }\n\n    return hierarchy;\n  }, [portal]);\n}\n\n// ============================================================================\n// Z-Index Hooks\n// ============================================================================\n\n/**\n * Hook to get z-index value for a specific layer.\n *\n * @param layer - Z-index layer\n * @returns Z-index value\n *\n * @example\n * ```tsx\n * function FloatingElement() {\n *   const zIndex = useZIndexForLayer('popover');\n *\n *   return (\n *     <div style={{ zIndex }}>\n *       Floating content\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useZIndexForLayer(layer: ZIndexLayer): number {\n  return useMemo(() => Z_INDEX_LAYERS[layer], [layer]);\n}\n\n/**\n * Hook to get the current element's z-index context.\n *\n * @returns Z-index context from DOM context\n *\n * @example\n * ```tsx\n * function StackingAwareComponent() {\n *   const zIndexContext = useZIndexContext();\n *\n *   return (\n *     <div>\n *       Current z-index: {zIndexContext.zIndex}\n *       Layer: {zIndexContext.layer}\n *       Creates stacking context: {zIndexContext.createsStackingContext ? 'yes' : 'no'}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useZIndexContext(): {\n  zIndex: number;\n  layer: ZIndexLayer;\n  createsStackingContext: boolean;\n} {\n  const domContext = useDOMContextValue();\n  return domContext.zIndex;\n}\n\n/**\n * Hook to register an element with the z-index manager.\n *\n * @param layer - Z-index layer to register in\n * @returns Registration info and utilities\n *\n * @example\n * ```tsx\n * function ManagedOverlay() {\n *   const { ref, zIndex, bringToFront } = useZIndexRegistration('modal');\n *\n *   return (\n *     <div ref={ref} style={{ zIndex }} onClick={bringToFront}>\n *       Click to bring to front\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useZIndexRegistration(layer: ZIndexLayer = 'base'): {\n  ref: RefCallback<HTMLElement>;\n  zIndex: number;\n  bringToFront: () => void;\n  sendToBack: () => void;\n} {\n  const elementRef = useRef<HTMLElement | null>(null);\n  const zIndexManager = getZIndexManager();\n\n  // Registration ref callback\n  const ref = useCallback(\n    (node: HTMLElement | null) => {\n      // Unregister previous element\n      if (elementRef.current !== null) {\n        zIndexManager.unregister(elementRef.current);\n      }\n\n      // Register new element\n      if (node !== null) {\n        const registration = zIndexManager.register(node, { layer });\n        node.style.zIndex = String(registration.zIndex);\n        elementRef.current = node;\n      } else {\n        elementRef.current = null;\n      }\n    },\n    [layer, zIndexManager]\n  );\n\n  // Get z-index (static value based on layer, not dependent on ref)\n  const zIndex = useMemo(() => {\n    return Z_INDEX_LAYERS[layer];\n  }, [layer]);\n\n  // Bring to front\n  const bringToFront = useCallback(() => {\n    if (elementRef.current) {\n      zIndexManager.bringToFront(elementRef.current);\n      const reg = zIndexManager.getRegistration(elementRef.current);\n      if (reg) {\n        elementRef.current.style.zIndex = String(reg.zIndex);\n      }\n    }\n  }, [zIndexManager]);\n\n  // Send to back\n  const sendToBack = useCallback(() => {\n    if (elementRef.current) {\n      zIndexManager.sendToBack(elementRef.current);\n      const reg = zIndexManager.getRegistration(elementRef.current);\n      if (reg) {\n        elementRef.current.style.zIndex = String(reg.zIndex);\n      }\n    }\n  }, [zIndexManager]);\n\n  return { ref, zIndex, bringToFront, sendToBack };\n}\n\n/**\n * Hook to get all z-index layers for reference.\n *\n * @returns Record of layer names to z-index values\n *\n * @example\n * ```tsx\n * function ZIndexReference() {\n *   const layers = useZIndexLayers();\n *\n *   return (\n *     <ul>\n *       {Object.entries(layers).map(([name, value]) => (\n *         <li key={name}>{name}: {value}</li>\n *       ))}\n *     </ul>\n *   );\n * }\n * ```\n */\nexport function useZIndexLayers(): Record<ZIndexLayer, number> {\n  return Z_INDEX_LAYERS;\n}\n"],"names":["usePortalContext","bridgeContext","usePortalBridgeContext","domContext","useDOMContextValue","portal","getZIndex","useCallback","layer","getLayerZIndex","useMemo","Z_INDEX_LAYERS","_","zIndex","useIsInPortal","isInPortal","useSourceContext","sourceContext","usePortalNestingDepth","usePortalHierarchy","hierarchy","current","useZIndexForLayer","useZIndexContext","useZIndexRegistration","elementRef","useRef","zIndexManager","getZIndexManager","ref","node","registration","bringToFront","reg","sendToBack","useZIndexLayers"],"mappings":"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"}