{"version":3,"file":"useVisualViewport.cjs","names":["isServer","useState","useCallback"],"sources":["../../../src/hooks/useVisualViewport/useVisualViewport.ts"],"sourcesContent":["import { startTransition, useCallback, useEffect, useState } from 'react';\n\nimport { isServer } from '../../utils/isServer/index.ts';\n\ntype VisualViewportState = {\n  /** Viewport width (px) */\n  width: number;\n  /** Viewport height (px) */\n  height: number;\n  /**\n   * Viewport left offset (px) from the layout viewport\n   *\n   * Typically 0 unless horizontal scrolling or panning occurs\n   */\n  offsetLeft: number;\n  /**\n   * Viewport top offset (px) from the layout viewport\n   *\n   * On iOS: Becomes negative when keyboard appears (e.g., -300px means 300px keyboard height)\n   * On Android: Typically remains 0\n   *\n   * Use `-offsetTop` to get accurate keyboard height on iOS\n   */\n  offsetTop: number;\n  /**\n   * Pinch-zoom scaling factor\n   *\n   * - 1.0 = no zoom (default)\n   * - > 1.0 = zoomed in\n   * - < 1.0 = zoomed out (rare, depends on viewport settings)\n   *\n   * @example\n   * ```tsx\n   * const { viewport } = useVisualViewport();\n   * if (viewport && viewport.scale > 1.3) {\n   *   // Hide floating UI when user zooms in\n   *   setShowFloatingButton(false);\n   * }\n   * ```\n   */\n  scale: number;\n};\n\n/**\n * @description\n * `useVisualViewport` is a React hook that tracks Visual Viewport changes.\n * It returns the actual visible area in mobile WebView, which changes when\n * the keyboard appears or the user zooms/scrolls.\n *\n * **Important:** `viewport` is `null` on SSR or in browsers that don't support Visual Viewport API.\n * Always check for null before accessing viewport properties.\n *\n * **Tip:** If you only need keyboard height, use `useKeyboardHeight()` instead\n * for a simpler API.\n *\n * @returns {{ viewport: VisualViewportState | null }} An object containing the Visual Viewport state.\n * - viewport `VisualViewportState | null` - Visual Viewport state object, or `null` if not supported (SSR or browsers without the Visual Viewport API);\n * - viewport.width `number` - Viewport width in pixels;\n * - viewport.height `number` - Viewport height in pixels;\n * - viewport.offsetLeft `number` - Viewport left offset in pixels from the layout viewport. Typically 0 unless horizontal scrolling or panning occurs;\n * - viewport.offsetTop `number` - Viewport top offset in pixels from the layout viewport. Becomes negative on iOS when the keyboard appears, so use `-offsetTop` for the keyboard height. Typically remains 0 on Android;\n * - viewport.scale `number` - Pinch-zoom scaling factor. 1.0 means no zoom, greater than 1.0 means zoomed in;\n *\n * @see {@link useKeyboardHeight} - Simpler hook for keyboard height only\n *\n * @example\n * function CustomLayout() {\n *   const { viewport } = useVisualViewport();\n *\n *   // Always check for null first\n *   if (!viewport) {\n *     return <div>Visual Viewport not supported</div>;\n *   }\n *\n *   const { width, height, offsetTop, scale } = viewport;\n *\n *   // Hide floating UI when user zooms in\n *   const showFloatingUI = scale <= 1.3;\n *\n *   return (\n *     <div style={{ height }}>\n *       {showFloatingUI && <FloatingButton />}\n *       Viewport-aware content\n *     </div>\n *   );\n * }\n */\nexport function useVisualViewport(): { viewport: VisualViewportState | null } {\n  const visualViewport = isServer() ? null : window.visualViewport;\n\n  const [viewport, setViewport] = useState<VisualViewportState | null>(() =>\n    visualViewport != null ? getVisualViewportState(visualViewport) : null\n  );\n\n  const updateViewportState = useCallback(() => {\n    startTransition(() => {\n      setViewport(window.visualViewport != null ? getVisualViewportState(window.visualViewport) : null);\n    });\n  }, []);\n\n  useEffect(\n    function handleVisualViewportChange() {\n      window.visualViewport?.addEventListener('resize', updateViewportState);\n      window.visualViewport?.addEventListener('scroll', updateViewportState);\n\n      return function cleanup() {\n        window.visualViewport?.removeEventListener('resize', updateViewportState);\n        window.visualViewport?.removeEventListener('scroll', updateViewportState);\n      };\n    },\n    [updateViewportState]\n  );\n\n  return { viewport };\n}\n\nfunction getVisualViewportState(visualViewport: VisualViewport): VisualViewportState {\n  return {\n    width: visualViewport.width,\n    height: visualViewport.height,\n    offsetLeft: visualViewport.offsetLeft,\n    offsetTop: visualViewport.offsetTop,\n    scale: visualViewport.scale,\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFA,SAAgB,oBAA8D;CAC5E,MAAM,iBAAiBA,iBAAAA,SAAS,IAAI,OAAO,OAAO;CAElD,MAAM,CAAC,UAAU,gBAAA,GAAeC,MAAAA,SAAAA,OAC9B,kBAAkB,OAAO,uBAAuB,cAAc,IAAI,IACpE;CAEA,MAAM,uBAAA,GAAsBC,MAAAA,YAAAA,OAAkB;EAC5C,CAAA,GAAA,MAAA,gBAAA,OAAsB;GACpB,YAAY,OAAO,kBAAkB,OAAO,uBAAuB,OAAO,cAAc,IAAI,IAAI;EAClG,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,UAAA,CACE,SAAS,6BAA6B;EACpC,OAAO,gBAAgB,iBAAiB,UAAU,mBAAmB;EACrE,OAAO,gBAAgB,iBAAiB,UAAU,mBAAmB;EAErE,OAAO,SAAS,UAAU;GACxB,OAAO,gBAAgB,oBAAoB,UAAU,mBAAmB;GACxE,OAAO,gBAAgB,oBAAoB,UAAU,mBAAmB;EAC1E;CACF,GACA,CAAC,mBAAmB,CACtB;CAEA,OAAO,EAAE,SAAS;AACpB;AAEA,SAAS,uBAAuB,gBAAqD;CACnF,OAAO;EACL,OAAO,eAAe;EACtB,QAAQ,eAAe;EACvB,YAAY,eAAe;EAC3B,WAAW,eAAe;EAC1B,OAAO,eAAe;CACxB;AACF"}