{"version":3,"file":"useDOMContext.mjs","sources":["../../../../../src/lib/layouts/context-aware/hooks/useDOMContext.ts"],"sourcesContent":["/**\n * @fileoverview useDOMContext Hook\n *\n * Provides access to the full DOM context from the DOMContextProvider.\n *\n * @module layouts/context-aware/hooks/useDOMContext\n * @author Agent 4 - PhD Context Systems Expert\n * @version 1.0.0\n */\n\nimport type React from 'react';\nimport { useRef, useEffect, useCallback, useMemo, useState, type RefObject } from 'react';\n\nimport type { DOMContext, UseDOMContextReturn, LayoutAncestor } from '../types';\nimport { useDOMContextValue, useDOMContextRefresh } from '../DOMContextProvider';\nimport { getDOMContextTracker } from '../dom-context';\n\n// ============================================================================\n// useDOMContext Hook\n// ============================================================================\n\n/**\n * Hook to access the full DOM context.\n *\n * @remarks\n * This is the primary hook for accessing DOM context information.\n * It provides the complete context object along with utilities\n * for working with the context.\n *\n * @returns DOM context, loading state, ref, and refresh function\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const { context, isLoading, ref, refresh } = useDOMContext();\n *\n *   if (isLoading) {\n *     return <Loading />;\n *   }\n *\n *   return (\n *     <div ref={ref}>\n *       Viewport: {context.viewport.width}x{context.viewport.height}\n *       <button onClick={refresh}>Refresh</button>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useDOMContext(): UseDOMContextReturn {\n  const context = useDOMContextValue();\n  const refreshFn = useDOMContextRefresh();\n  const elementRef = useRef<HTMLElement>(null);\n\n  // Compute loading state\n  const isLoading = !context.isInitialized && !context.isSSR;\n\n  // Create stable refresh function\n  const refresh = useCallback(() => {\n    if (refreshFn) {\n      refreshFn();\n    } else if (elementRef.current) {\n      // Fallback: manually invalidate element cache\n      const tracker = getDOMContextTracker();\n      tracker.invalidate(elementRef.current);\n    }\n  }, [refreshFn]);\n\n  return {\n    context,\n    isLoading,\n    ref: elementRef,\n    refresh,\n  };\n}\n\n// ============================================================================\n// useDOMContextWithElement Hook\n// ============================================================================\n\n/**\n * Hook to access DOM context for a specific element.\n *\n * @remarks\n * This hook is useful when you need to track a specific element\n * that may be different from the context provider's element.\n *\n * @param elementRef - Ref to the element to track\n * @returns DOM context for the element\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const myRef = useRef<HTMLDivElement>(null);\n *   const { ancestors, bounds } = useDOMContextWithElement(myRef);\n *\n *   return (\n *     <div ref={myRef}>\n *       {ancestors.length > 0 && (\n *         <span>Parent layout: {ancestors[0].layoutType}</span>\n *       )}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useDOMContextWithElement(elementRef: RefObject<HTMLElement>): {\n  ancestors: readonly LayoutAncestor[];\n  bounds: ReturnType<typeof getDOMContextTracker.prototype.getBounds> | null;\n  layoutType: ReturnType<typeof getDOMContextTracker.prototype.getLayoutType> | null;\n  refresh: () => void;\n} {\n  const context = useDOMContextValue();\n  const tracker = getDOMContextTracker();\n\n  // Get element-specific information\n  const [elementInfo, setElementInfo] = useState<{\n    ancestors: readonly LayoutAncestor[];\n    bounds: ReturnType<typeof tracker.getBounds> | null;\n    layoutType: ReturnType<typeof tracker.getLayoutType> | null;\n  }>({\n    ancestors: [] as readonly LayoutAncestor[],\n    bounds: null,\n    layoutType: null,\n  });\n\n  useEffect(() => {\n    const element = elementRef.current;\n    const timeoutId = setTimeout(() => {\n      if (element === null || context.isSSR) {\n        setElementInfo({\n          ancestors: [] as readonly LayoutAncestor[],\n          bounds: null,\n          layoutType: null,\n        });\n        return;\n      }\n\n      setElementInfo({\n        ancestors: tracker.getAncestry(element),\n        bounds: tracker.getBounds(element),\n        layoutType: tracker.getLayoutType(element),\n      });\n    }, 0);\n\n    return () => clearTimeout(timeoutId);\n  }, [elementRef, context.isSSR, context.lastUpdated, tracker]);\n\n  // Refresh function\n  const refresh = useCallback(() => {\n    if (elementRef.current !== null) {\n      tracker.invalidate(elementRef.current);\n    }\n  }, [elementRef, tracker]);\n\n  return {\n    ...elementInfo,\n    refresh,\n  };\n}\n\n// ============================================================================\n// useContextSelector Hook\n// ============================================================================\n\n/**\n * Selector function type for DOM context.\n */\nexport type DOMContextSelector<T> = (context: DOMContext) => T;\n\n/**\n * Hook to select specific parts of the DOM context.\n *\n * @remarks\n * This hook optimizes re-renders by only triggering updates\n * when the selected value changes.\n *\n * @param selector - Function to select part of context\n * @returns Selected value\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   // Only re-renders when viewport width changes\n *   const width = useContextSelector((ctx) => ctx.viewport.width);\n *\n *   return <div>Width: {width}</div>;\n * }\n * ```\n */\nexport function useContextSelector<T>(selector: DOMContextSelector<T>): T {\n  const context = useDOMContextValue();\n  return useMemo(() => selector(context), [context, selector]);\n}\n\n// ============================================================================\n// useContextEffect Hook\n// ============================================================================\n\n/**\n * Hook to run effects when specific context values change.\n *\n * @remarks\n * This is similar to useEffect but with a selector for\n * DOM context changes.\n *\n * @param selector - Function to select trigger value\n * @param effect - Effect function to run\n * @param deps - Additional dependencies\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   useContextEffect(\n *     (ctx) => ctx.viewport.orientation,\n *     (orientation) => {\n *       console.log('Orientation changed:', orientation);\n *     }\n *   );\n *\n *   return <div>...</div>;\n * }\n * ```\n */\nexport function useContextEffect<T>(\n  selector: DOMContextSelector<T>,\n  effect: (value: T) => void | (() => void),\n  deps: React.DependencyList = []\n): void {\n  const value = useContextSelector(selector);\n\n  useEffect(() => {\n    return effect(value);\n    // eslint-disable-next-line react-hooks/exhaustive-deps -- deps array is intentionally spread from user input\n  }, [value, effect, ...deps]);\n}\n"],"names":["useDOMContext","context","useDOMContextValue","refreshFn","useDOMContextRefresh","elementRef","useRef","isLoading","refresh","useCallback","getDOMContextTracker","useDOMContextWithElement","tracker","elementInfo","setElementInfo","useState","useEffect","element","timeoutId","useContextSelector","selector","useMemo","useContextEffect","effect","deps","value"],"mappings":";;;AAiDO,SAASA,IAAqC;AACnD,QAAMC,IAAUC,EAAA,GACVC,IAAYC,EAAA,GACZC,IAAaC,EAAoB,IAAI,GAGrCC,IAAY,CAACN,EAAQ,iBAAiB,CAACA,EAAQ,OAG/CO,IAAUC,EAAY,MAAM;AAChC,IAAIN,IACFA,EAAA,IACSE,EAAW,WAEJK,EAAA,EACR,WAAWL,EAAW,OAAO;AAAA,EAEzC,GAAG,CAACF,CAAS,CAAC;AAEd,SAAO;AAAA,IACL,SAAAF;AAAA,IACA,WAAAM;AAAA,IACA,KAAKF;AAAA,IACL,SAAAG;AAAA,EAAA;AAEJ;AAgCO,SAASG,EAAyBN,GAKvC;AACA,QAAMJ,IAAUC,EAAA,GACVU,IAAUF,EAAA,GAGV,CAACG,GAAaC,CAAc,IAAIC,EAInC;AAAA,IACD,WAAW,CAAA;AAAA,IACX,QAAQ;AAAA,IACR,YAAY;AAAA,EAAA,CACb;AAED,EAAAC,EAAU,MAAM;AACd,UAAMC,IAAUZ,EAAW,SACrBa,IAAY,WAAW,MAAM;AACjC,UAAID,MAAY,QAAQhB,EAAQ,OAAO;AACrC,QAAAa,EAAe;AAAA,UACb,WAAW,CAAA;AAAA,UACX,QAAQ;AAAA,UACR,YAAY;AAAA,QAAA,CACb;AACD;AAAA,MACF;AAEA,MAAAA,EAAe;AAAA,QACb,WAAWF,EAAQ,YAAYK,CAAO;AAAA,QACtC,QAAQL,EAAQ,UAAUK,CAAO;AAAA,QACjC,YAAYL,EAAQ,cAAcK,CAAO;AAAA,MAAA,CAC1C;AAAA,IACH,GAAG,CAAC;AAEJ,WAAO,MAAM,aAAaC,CAAS;AAAA,EACrC,GAAG,CAACb,GAAYJ,EAAQ,OAAOA,EAAQ,aAAaW,CAAO,CAAC;AAG5D,QAAMJ,IAAUC,EAAY,MAAM;AAChC,IAAIJ,EAAW,YAAY,QACzBO,EAAQ,WAAWP,EAAW,OAAO;AAAA,EAEzC,GAAG,CAACA,GAAYO,CAAO,CAAC;AAExB,SAAO;AAAA,IACL,GAAGC;AAAA,IACH,SAAAL;AAAA,EAAA;AAEJ;AA+BO,SAASW,EAAsBC,GAAoC;AACxE,QAAMnB,IAAUC,EAAA;AAChB,SAAOmB,EAAQ,MAAMD,EAASnB,CAAO,GAAG,CAACA,GAASmB,CAAQ,CAAC;AAC7D;AA+BO,SAASE,EACdF,GACAG,GACAC,IAA6B,CAAA,GACvB;AACN,QAAMC,IAAQN,EAAmBC,CAAQ;AAEzC,EAAAJ,EAAU,MACDO,EAAOE,CAAK,GAElB,CAACA,GAAOF,GAAQ,GAAGC,CAAI,CAAC;AAC7B;"}