{"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-viewport.svelte.ts","../../src/svelte/hooks/use-viewport-ref.svelte.ts","../../src/svelte/components/Viewport.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport { GateChangeEvent, ScrollActivity, ViewportPlugin } from '@embedpdf/plugin-viewport';\n\nexport const useViewportPlugin = () => usePlugin<ViewportPlugin>(ViewportPlugin.id);\nexport const useViewportCapability = () => useCapability<ViewportPlugin>(ViewportPlugin.id);\n\n/**\n * Hook to get the gated state of the viewport for a specific document.\n * The viewport children are not rendered when gated.\n * @param getDocumentId Function that returns the document ID\n */\nexport const useIsViewportGated = (getDocumentId: () => string | null) => {\n  const capability = useViewportCapability();\n\n  let isGated = $state(false);\n\n  // Reactive documentId\n  const documentId = $derived(getDocumentId());\n\n  $effect(() => {\n    const provides = capability.provides;\n    const docId = documentId;\n\n    if (!provides || !docId) {\n      isGated = false;\n      return;\n    }\n\n    // Set initial state\n    isGated = provides.isGated(docId);\n\n    // Subscribe to gate state changes\n    return provides.onGateChange((event: GateChangeEvent) => {\n      if (event.documentId === docId) {\n        isGated = event.isGated;\n      }\n    });\n  });\n\n  return {\n    get current() {\n      return isGated;\n    },\n  };\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param getDocumentId Function that returns the document ID\n */\nexport const useViewportScrollActivity = (getDocumentId: () => string | null) => {\n  const capability = useViewportCapability();\n\n  let scrollActivity = $state<ScrollActivity>({\n    isScrolling: false,\n    isSmoothScrolling: false,\n  });\n\n  // Reactive documentId\n  const documentId = $derived(getDocumentId());\n\n  $effect(() => {\n    const provides = capability.provides;\n    const docId = documentId;\n\n    if (!provides || !docId) {\n      scrollActivity = {\n        isScrolling: false,\n        isSmoothScrolling: false,\n      };\n      return;\n    }\n\n    // Subscribe to scroll activity events\n    return provides.onScrollActivity((event) => {\n      // Filter by documentId\n      if (event.documentId === docId) {\n        scrollActivity = event.activity;\n      }\n    });\n  });\n\n  return {\n    get current() {\n      return scrollActivity;\n    },\n  };\n};\n","import { type Rect } from '@embedpdf/models';\nimport { useViewportPlugin } from './use-viewport.svelte';\n\n/**\n * Hook to get a ref for the viewport container element with automatic setup/teardown\n * @param getDocumentId Function that returns the document ID\n */\nexport function useViewportRef(getDocumentId: () => string | null) {\n  const { plugin } = useViewportPlugin();\n\n  let containerRef = $state<HTMLDivElement | null>(null);\n\n  // Reactive documentId\n  const documentId = $derived(getDocumentId());\n\n  $effect.pre(() => {\n    if (!plugin) return;\n\n    const container = containerRef;\n    const docId = documentId;\n    if (!container || !docId) return;\n\n    // Register this viewport for the document\n    try {\n      plugin.registerViewport(docId);\n    } catch (error) {\n      console.error(`Failed to register viewport for document ${docId}:`, error);\n      return;\n    }\n\n    // On scroll\n    const onScroll = () => {\n      plugin.setViewportScrollMetrics(docId, {\n        scrollTop: container.scrollTop,\n        scrollLeft: container.scrollLeft,\n      });\n    };\n    container.addEventListener('scroll', onScroll);\n\n    // On resize\n    const resizeObserver = new ResizeObserver(() => {\n      plugin.setViewportResizeMetrics(docId, {\n        width: container.offsetWidth,\n        height: container.offsetHeight,\n        clientWidth: container.clientWidth,\n        clientHeight: container.clientHeight,\n        scrollTop: container.scrollTop,\n        scrollLeft: container.scrollLeft,\n        scrollWidth: container.scrollWidth,\n        scrollHeight: container.scrollHeight,\n        clientLeft: container.clientLeft,\n        clientTop: container.clientTop,\n      });\n    });\n    resizeObserver.observe(container);\n\n    // Subscribe to scroll requests for this document\n    const unsubscribeScrollRequest = plugin.onScrollRequest(\n      docId,\n      ({ x, y, behavior = 'auto' }) => {\n        requestAnimationFrame(() => {\n          container.scrollTo({ left: x, top: y, behavior });\n        });\n      },\n    );\n\n    // Store cleanup function\n    return () => {\n      plugin.unregisterViewport(docId);\n      container.removeEventListener('scroll', onScroll);\n      resizeObserver.disconnect();\n      unsubscribeScrollRequest();\n    };\n  });\n\n  return {\n    get containerRef() {\n      return containerRef;\n    },\n    set containerRef(el: HTMLDivElement | null) {\n      containerRef = el;\n    },\n  };\n}\n","<script lang=\"ts\">\n  import { setContext } from 'svelte';\n  import { useIsViewportGated, useViewportCapability, useViewportRef } from '../hooks';\n  import type { HTMLAttributes } from 'svelte/elements';\n  import type { Snippet } from 'svelte';\n\n  type ViewportProps = HTMLAttributes<HTMLDivElement> & {\n    /**\n     * The ID of the document that this viewport displays\n     */\n    documentId: string;\n    children: Snippet;\n    class?: string;\n  };\n\n  let { documentId, children, class: propsClass, ...restProps }: ViewportProps = $props();\n\n  let viewportGap = $state(0);\n\n  const viewportRef = useViewportRef(() => documentId);\n  const viewportCapability = useViewportCapability();\n  const isGated = useIsViewportGated(() => documentId);\n\n  // Provide the viewport element to child components via context\n  setContext('viewport-element', {\n    get current() {\n      return viewportRef.containerRef;\n    },\n  });\n\n  $effect(() => {\n    if (viewportCapability.provides) {\n      viewportGap = viewportCapability.provides.getViewportGap();\n    }\n  });\n</script>\n\n<div\n  {...restProps}\n  bind:this={viewportRef.containerRef}\n  style:width=\"100%\"\n  style:height=\"100%\"\n  style:overflow=\"auto\"\n  style:padding={`${viewportGap}px`}\n  class={propsClass}\n>\n  {#if !isGated.current}\n    {@render children()}\n  {/if}\n</div>\n"],"names":["useViewportPlugin","usePlugin","ViewportPlugin","id","useViewportCapability","useCapability","useIsViewportGated","getDocumentId","capability","isGated","$","state","documentId","user_effect","provides","docId","set","onGateChange","event","current","useViewportRef","plugin","containerRef","user_pre_effect","container","registerViewport","error","console","onScroll","setViewportScrollMetrics","scrollTop","scrollLeft","addEventListener","resizeObserver","ResizeObserver","setViewportResizeMetrics","width","offsetWidth","height","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","clientLeft","clientTop","observe","unsubscribeScrollRequest","onScrollRequest","x","y","behavior","requestAnimationFrame","scrollTo","left","top","unregisterViewport","removeEventListener","disconnect","el","restProps","rest_props","$$props","viewportGap","viewportRef","viewportCapability","setContext","getViewportGap","div","root","$$render","consequent","bind_this","$$value","scrollActivity","proxy","isScrolling","isSmoothScrolling","onScrollActivity","activity"],"mappings":"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"}