@embedpdf/plugin-viewport 2.0.0-next.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -21
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +2 -3
- package/dist/lib/viewport-plugin.d.ts +0 -4
- package/dist/preact/adapter.d.ts +3 -3
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +13 -14
- package/dist/preact/index.js.map +1 -1
- package/dist/react/adapter.d.ts +2 -2
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +12 -13
- package/dist/react/index.js.map +1 -1
- package/dist/shared/context/index.d.ts +1 -0
- package/dist/shared/context/viewport-element-context.d.ts +7 -0
- package/dist/shared/hooks/use-viewport.d.ts +6 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared-preact/context/index.d.ts +1 -0
- package/dist/shared-preact/context/viewport-element-context.d.ts +7 -0
- package/dist/shared-preact/hooks/use-viewport.d.ts +6 -0
- package/dist/shared-preact/index.d.ts +1 -0
- package/dist/shared-react/context/index.d.ts +1 -0
- package/dist/shared-react/context/viewport-element-context.d.ts +7 -0
- package/dist/shared-react/hooks/use-viewport.d.ts +6 -0
- package/dist/shared-react/index.d.ts +1 -0
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js +9 -10
- package/dist/svelte/index.js.map +1 -1
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +5 -11
- package/dist/vue/index.js.map +1 -1
- package/package.json +5 -5
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { BasePluginConfig, EventHook } from '@embedpdf/core';
|
|
2
|
-
import { Rect } from '@embedpdf/models';
|
|
3
2
|
export interface ViewportState {
|
|
4
3
|
viewportGap: number;
|
|
5
4
|
documents: Record<string, ViewportDocumentState>;
|
|
@@ -25,6 +24,8 @@ export interface ViewportInputMetrics {
|
|
|
25
24
|
clientHeight: number;
|
|
26
25
|
scrollWidth: number;
|
|
27
26
|
scrollHeight: number;
|
|
27
|
+
clientLeft: number;
|
|
28
|
+
clientTop: number;
|
|
28
29
|
}
|
|
29
30
|
export interface ViewportMetrics extends ViewportInputMetrics {
|
|
30
31
|
relativePosition: {
|
|
@@ -85,7 +86,6 @@ export interface ViewportScope {
|
|
|
85
86
|
getGates(): string[];
|
|
86
87
|
gate(key: string): void;
|
|
87
88
|
releaseGate(key: string): void;
|
|
88
|
-
getBoundingRect(): Rect;
|
|
89
89
|
onViewportChange: EventHook<ViewportMetrics>;
|
|
90
90
|
onScrollChange: EventHook<ViewportScrollMetrics>;
|
|
91
91
|
onScrollActivity: EventHook<ScrollActivity>;
|
|
@@ -100,7 +100,6 @@ export interface ViewportCapability {
|
|
|
100
100
|
isGated(documentId?: string): boolean;
|
|
101
101
|
hasGate(key: string, documentId?: string): boolean;
|
|
102
102
|
getGates(documentId?: string): string[];
|
|
103
|
-
getBoundingRect(): Rect;
|
|
104
103
|
forDocument(documentId: string): ViewportScope;
|
|
105
104
|
gate(key: string, documentId: string): void;
|
|
106
105
|
releaseGate(key: string, documentId: string): void;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { BasePlugin, PluginRegistry, Listener } from '@embedpdf/core';
|
|
2
|
-
import { Rect } from '@embedpdf/models';
|
|
3
2
|
import { ViewportAction } from './actions';
|
|
4
3
|
import { ViewportPluginConfig, ViewportState, ViewportCapability, ViewportScrollMetrics, ViewportInputMetrics, ScrollToPayload } from './types';
|
|
5
4
|
export declare class ViewportPlugin extends BasePlugin<ViewportPluginConfig, ViewportCapability, ViewportState, ViewportAction> {
|
|
@@ -11,7 +10,6 @@ export declare class ViewportPlugin extends BasePlugin<ViewportPluginConfig, Vie
|
|
|
11
10
|
private readonly scrollActivity$;
|
|
12
11
|
private readonly gateState$;
|
|
13
12
|
private readonly scrollRequests$;
|
|
14
|
-
private rectProviders;
|
|
15
13
|
private readonly scrollEndDelay;
|
|
16
14
|
constructor(id: string, registry: PluginRegistry, config: ViewportPluginConfig);
|
|
17
15
|
protected onDocumentLoadingStarted(documentId: string): void;
|
|
@@ -23,7 +21,6 @@ export declare class ViewportPlugin extends BasePlugin<ViewportPluginConfig, Vie
|
|
|
23
21
|
setViewportResizeMetrics(documentId: string, metrics: ViewportInputMetrics): void;
|
|
24
22
|
setViewportScrollMetrics(documentId: string, scrollMetrics: ViewportScrollMetrics): void;
|
|
25
23
|
onScrollRequest(documentId: string, listener: Listener<ScrollToPayload>): import('@embedpdf/core').Unsubscribe;
|
|
26
|
-
registerBoundingRectProvider(documentId: string, provider: (() => Rect) | null): void;
|
|
27
24
|
gate(key: string, documentId: string): void;
|
|
28
25
|
releaseGate(key: string, documentId: string): void;
|
|
29
26
|
private getViewportState;
|
|
@@ -33,7 +30,6 @@ export declare class ViewportPlugin extends BasePlugin<ViewportPluginConfig, Vie
|
|
|
33
30
|
private isGated;
|
|
34
31
|
private hasGate;
|
|
35
32
|
private getGates;
|
|
36
|
-
private getBoundingRect;
|
|
37
33
|
private scrollTo;
|
|
38
34
|
private bumpScrollActivity;
|
|
39
35
|
onStoreUpdated(prevState: ViewportState, newState: ViewportState): void;
|
package/dist/preact/adapter.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { Fragment } from 'preact';
|
|
2
|
-
export { useEffect, useRef, useState, useCallback, useMemo, useLayoutEffect } from 'preact/hooks';
|
|
3
|
-
export type { ComponentChildren as ReactNode } from 'preact';
|
|
1
|
+
export { Fragment, createContext } from 'preact';
|
|
2
|
+
export { useEffect, useRef, useState, useCallback, useMemo, useLayoutEffect, useContext, } from 'preact/hooks';
|
|
3
|
+
export type { ComponentChildren as ReactNode, RefObject } from 'preact';
|
|
4
4
|
export type CSSProperties = import('preact').JSX.CSSProperties;
|
|
5
5
|
export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
|
package/dist/preact/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact/jsx-runtime")
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact/jsx-runtime"),t=require("preact"),r=require("preact/hooks"),o=require("@embedpdf/core/preact"),i=require("@embedpdf/plugin-viewport"),s=t.createContext(null),l=()=>o.usePlugin(i.ViewportPlugin.id),n=()=>o.useCapability(i.ViewportPlugin.id),c=e=>{const{provides:t}=n(),[o,i]=r.useState((null==t?void 0:t.isGated(e))??!1);return r.useEffect(()=>{if(t)return i(t.isGated(e)),t.onGateChange(t=>{t.documentId===e&&i(t.isGated)})},[t,e]),o};function u(e){const{plugin:t}=l(),o=r.useRef(null);return r.useLayoutEffect(()=>{if(!t)return;const r=o.current;if(!r)return;try{t.registerViewport(e)}catch(n){return void console.error(`Failed to register viewport for document ${e}:`,n)}const i=()=>{t.setViewportScrollMetrics(e,{scrollTop:r.scrollTop,scrollLeft:r.scrollLeft})};r.addEventListener("scroll",i);const s=new ResizeObserver(()=>{t.setViewportResizeMetrics(e,{width:r.offsetWidth,height:r.offsetHeight,clientWidth:r.clientWidth,clientHeight:r.clientHeight,scrollTop:r.scrollTop,scrollLeft:r.scrollLeft,scrollWidth:r.scrollWidth,scrollHeight:r.scrollHeight,clientLeft:r.clientLeft,clientTop:r.clientTop})});s.observe(r);const l=t.onScrollRequest(e,({x:e,y:t,behavior:o="auto"})=>{requestAnimationFrame(()=>{r.scrollTo({left:e,top:t,behavior:o})})});return()=>{t.unregisterViewport(e),s.disconnect(),r.removeEventListener("scroll",i),l()}},[t,e]),o}exports.Viewport=function({children:t,documentId:o,...i}){const[l,p]=r.useState(0),d=u(o),{provides:a}=n(),f=c(o);r.useEffect(()=>{a&&p(a.getViewportGap())},[a]);const{style:h,...g}=i;return e.jsx(s.Provider,{value:d,children:e.jsx("div",{...g,ref:d,style:{width:"100%",height:"100%",overflow:"auto",..."object"==typeof h?h:{},padding:`${l}px`},children:!f&&t})})},exports.ViewportElementContext=s,exports.useIsViewportGated=c,exports.useViewportCapability=n,exports.useViewportElement=()=>r.useContext(s),exports.useViewportPlugin=l,exports.useViewportRef=u,exports.useViewportScrollActivity=e=>{const{provides:t}=n(),[o,i]=r.useState({isScrolling:!1,isSmoothScrolling:!1});return r.useEffect(()=>{if(t)return t.onScrollActivity(t=>{t.documentId===e&&i(t.activity)})},[t,e]),o},Object.keys(i).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>i[e]})});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { useEffect, useState } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n //
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/context/viewport-element-context.ts","../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { createContext, RefObject } from '@framework';\n\n/**\n * Context to share the viewport DOM element reference with child components.\n * This allows child components (like ZoomGestureWrapper) to access the viewport\n * container element without DOM traversal.\n */\nexport const ViewportElementContext = createContext<RefObject<HTMLDivElement> | null>(null);\n","import { useEffect, useState, useContext, RefObject } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { GateChangeEvent, ScrollActivity, ViewportPlugin } from '@embedpdf/plugin-viewport';\nimport { ViewportElementContext } from '../context';\n\nexport const useViewportPlugin = () => usePlugin<ViewportPlugin>(ViewportPlugin.id);\nexport const useViewportCapability = () => useCapability<ViewportPlugin>(ViewportPlugin.id);\n\n/**\n * Hook to get the viewport DOM element ref from context.\n * Must be used within a Viewport component.\n */\nexport const useViewportElement = (): RefObject<HTMLDivElement> | null => {\n return useContext(ViewportElementContext);\n};\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n // On scroll\n const onScroll = () => {\n viewportPlugin.setViewportScrollMetrics(documentId, {\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 viewportPlugin.setViewportResizeMetrics(documentId, {\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 = viewportPlugin.onScrollRequest(\n documentId,\n ({ x, y, behavior = 'auto' }) => {\n requestAnimationFrame(() => {\n container.scrollTo({ left: x, top: y, behavior });\n });\n },\n );\n\n // Cleanup\n return () => {\n viewportPlugin.unregisterViewport(documentId);\n resizeObserver.disconnect();\n container.removeEventListener('scroll', onScroll);\n unsubscribeScrollRequest();\n };\n }, [viewportPlugin, documentId]);\n\n return containerRef;\n}\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { useIsViewportGated, useViewportCapability } from '../hooks';\nimport { useViewportRef } from '../hooks/use-viewport-ref';\nimport { ViewportElementContext } from '../context';\n\ntype ViewportProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n /**\n * The ID of the document that this viewport displays\n */\n documentId: string;\n};\n\nexport function Viewport({ children, documentId, ...props }: ViewportProps) {\n const [viewportGap, setViewportGap] = useState(0);\n const viewportRef = useViewportRef(documentId);\n const { provides: viewportProvides } = useViewportCapability();\n const isGated = useIsViewportGated(documentId);\n\n useEffect(() => {\n if (viewportProvides) {\n setViewportGap(viewportProvides.getViewportGap());\n }\n }, [viewportProvides]);\n\n const { style, ...restProps } = props;\n\n return (\n <ViewportElementContext.Provider value={viewportRef}>\n <div\n {...restProps}\n ref={viewportRef}\n style={{\n width: '100%',\n height: '100%',\n overflow: 'auto',\n ...(typeof style === 'object' ? style : {}),\n padding: `${viewportGap}px`,\n }}\n >\n {!isGated && children}\n </div>\n </ViewportElementContext.Provider>\n );\n}\n"],"names":["ViewportElementContext","createContext","useViewportPlugin","usePlugin","ViewportPlugin","id","useViewportCapability","useCapability","useIsViewportGated","documentId","provides","isGated","setIsGated","useState","useEffect","onGateChange","event","useViewportRef","plugin","viewportPlugin","containerRef","useRef","useLayoutEffect","container","current","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","disconnect","removeEventListener","children","props","viewportGap","setViewportGap","viewportRef","viewportProvides","getViewportGap","style","restProps","jsx","Provider","value","ref","overflow","padding","useContext","scrollActivity","setScrollActivity","isScrolling","isSmoothScrolling","onScrollActivity","activity"],"mappings":"8OAOaA,EAAyBC,EAAAA,cAAgD,MCFzEC,EAAoB,IAAMC,YAA0BC,EAAAA,eAAeC,IACnEC,EAAwB,IAAMC,gBAA8BH,EAAAA,eAAeC,IAe3EG,EAAsBC,IACjC,MAAMC,SAAEA,GAAaJ,KACdK,EAASC,GAAcC,EAAAA,UAAS,MAAAH,OAAA,EAAAA,EAAUC,QAAQF,MAAe,GAgBxE,OAdAK,EAAAA,UAAU,KACR,GAAKJ,EAML,OAHAE,EAAWF,EAASC,QAAQF,IAGrBC,EAASK,aAAcC,IACxBA,EAAMP,aAAeA,GACvBG,EAAWI,EAAML,YAGpB,CAACD,EAAUD,IAEPE,GCnCF,SAASM,EAAeR,GAC7B,MAAQS,OAAQC,GAAmBjB,IAC7BkB,EAAeC,EAAAA,OAAuB,MA6D5C,OA3DAC,EAAAA,gBAAgB,KACd,IAAKH,EAAgB,OAErB,MAAMI,EAAYH,EAAaI,QAC/B,IAAKD,EAAW,OAGhB,IACEJ,EAAeM,iBAAiBhB,EAClC,OAASiB,GAEP,YADAC,QAAQD,MAAM,4CAA4CjB,KAAeiB,EAE3E,CAGA,MAAME,EAAW,KACfT,EAAeU,yBAAyBpB,EAAY,CAClDqB,UAAWP,EAAUO,UACrBC,WAAYR,EAAUQ,cAG1BR,EAAUS,iBAAiB,SAAUJ,GAGrC,MAAMK,EAAiB,IAAIC,eAAe,KACxCf,EAAegB,yBAAyB1B,EAAY,CAClD2B,MAAOb,EAAUc,YACjBC,OAAQf,EAAUgB,aAClBC,YAAajB,EAAUiB,YACvBC,aAAclB,EAAUkB,aACxBX,UAAWP,EAAUO,UACrBC,WAAYR,EAAUQ,WACtBW,YAAanB,EAAUmB,YACvBC,aAAcpB,EAAUoB,aACxBC,WAAYrB,EAAUqB,WACtBC,UAAWtB,EAAUsB,cAGzBZ,EAAea,QAAQvB,GAGvB,MAAMwB,EAA2B5B,EAAe6B,gBAC9CvC,EACA,EAAGwC,IAAGC,IAAGC,WAAW,WAClBC,sBAAsB,KACpB7B,EAAU8B,SAAS,CAAEC,KAAML,EAAGM,IAAKL,EAAGC,iBAM5C,MAAO,KACLhC,EAAeqC,mBAAmB/C,GAClCwB,EAAewB,aACflC,EAAUmC,oBAAoB,SAAU9B,GACxCmB,MAED,CAAC5B,EAAgBV,IAEbW,CACT,kBCvDO,UAAkBuC,SAAEA,EAAAlD,WAAUA,KAAemD,IAClD,MAAOC,EAAaC,GAAkBjD,EAAAA,SAAS,GACzCkD,EAAc9C,EAAeR,IAC3BC,SAAUsD,GAAqB1D,IACjCK,EAAUH,EAAmBC,GAEnCK,EAAAA,UAAU,KACJkD,GACFF,EAAeE,EAAiBC,mBAEjC,CAACD,IAEJ,MAAME,MAAEA,KAAUC,GAAcP,EAEhC,OACEQ,EAAAA,IAACpE,EAAuBqE,SAAvB,CAAgCC,MAAOP,EACtCJ,SAAAS,EAAAA,IAAC,MAAA,IACKD,EACJI,IAAKR,EACLG,MAAO,CACL9B,MAAO,OACPE,OAAQ,OACRkC,SAAU,UACW,iBAAVN,EAAqBA,EAAQ,CAAA,EACxCO,QAAS,GAAGZ,OAGbF,UAAChD,GAAWgD,KAIrB,2HFhCkC,IACzBe,EAAAA,WAAW1E,0FAiCsBS,IACxC,MAAMC,SAAEA,GAAaJ,KACdqE,EAAgBC,GAAqB/D,WAAyB,CACnEgE,aAAa,EACbC,mBAAmB,IAerB,OAZAhE,EAAAA,UAAU,KACR,GAAKJ,EAGL,OAAOA,EAASqE,iBAAkB/D,IAE5BA,EAAMP,aAAeA,GACvBmE,EAAkB5D,EAAMgE,aAG3B,CAACtE,EAAUD,IAEPkE"}
|
package/dist/preact/index.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { jsx } from "preact/jsx-runtime";
|
|
2
|
-
import "preact";
|
|
3
|
-
import { useState, useEffect, useRef, useLayoutEffect } from "preact/hooks";
|
|
2
|
+
import { createContext } from "preact";
|
|
3
|
+
import { useContext, useState, useEffect, useRef, useLayoutEffect } from "preact/hooks";
|
|
4
4
|
import { usePlugin, useCapability } from "@embedpdf/core/preact";
|
|
5
5
|
import { ViewportPlugin } from "@embedpdf/plugin-viewport";
|
|
6
6
|
export * from "@embedpdf/plugin-viewport";
|
|
7
|
+
const ViewportElementContext = createContext(null);
|
|
7
8
|
const useViewportPlugin = () => usePlugin(ViewportPlugin.id);
|
|
8
9
|
const useViewportCapability = () => useCapability(ViewportPlugin.id);
|
|
10
|
+
const useViewportElement = () => {
|
|
11
|
+
return useContext(ViewportElementContext);
|
|
12
|
+
};
|
|
9
13
|
const useIsViewportGated = (documentId) => {
|
|
10
14
|
const { provides } = useViewportCapability();
|
|
11
15
|
const [isGated, setIsGated] = useState((provides == null ? void 0 : provides.isGated(documentId)) ?? false);
|
|
@@ -49,14 +53,6 @@ function useViewportRef(documentId) {
|
|
|
49
53
|
console.error(`Failed to register viewport for document ${documentId}:`, error);
|
|
50
54
|
return;
|
|
51
55
|
}
|
|
52
|
-
const provideRect = () => {
|
|
53
|
-
const r = container.getBoundingClientRect();
|
|
54
|
-
return {
|
|
55
|
-
origin: { x: r.left, y: r.top },
|
|
56
|
-
size: { width: r.width, height: r.height }
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
viewportPlugin.registerBoundingRectProvider(documentId, provideRect);
|
|
60
56
|
const onScroll = () => {
|
|
61
57
|
viewportPlugin.setViewportScrollMetrics(documentId, {
|
|
62
58
|
scrollTop: container.scrollTop,
|
|
@@ -73,7 +69,9 @@ function useViewportRef(documentId) {
|
|
|
73
69
|
scrollTop: container.scrollTop,
|
|
74
70
|
scrollLeft: container.scrollLeft,
|
|
75
71
|
scrollWidth: container.scrollWidth,
|
|
76
|
-
scrollHeight: container.scrollHeight
|
|
72
|
+
scrollHeight: container.scrollHeight,
|
|
73
|
+
clientLeft: container.clientLeft,
|
|
74
|
+
clientTop: container.clientTop
|
|
77
75
|
});
|
|
78
76
|
});
|
|
79
77
|
resizeObserver.observe(container);
|
|
@@ -87,7 +85,6 @@ function useViewportRef(documentId) {
|
|
|
87
85
|
);
|
|
88
86
|
return () => {
|
|
89
87
|
viewportPlugin.unregisterViewport(documentId);
|
|
90
|
-
viewportPlugin.registerBoundingRectProvider(documentId, null);
|
|
91
88
|
resizeObserver.disconnect();
|
|
92
89
|
container.removeEventListener("scroll", onScroll);
|
|
93
90
|
unsubscribeScrollRequest();
|
|
@@ -106,7 +103,7 @@ function Viewport({ children, documentId, ...props }) {
|
|
|
106
103
|
}
|
|
107
104
|
}, [viewportProvides]);
|
|
108
105
|
const { style, ...restProps } = props;
|
|
109
|
-
return /* @__PURE__ */ jsx(
|
|
106
|
+
return /* @__PURE__ */ jsx(ViewportElementContext.Provider, { value: viewportRef, children: /* @__PURE__ */ jsx(
|
|
110
107
|
"div",
|
|
111
108
|
{
|
|
112
109
|
...restProps,
|
|
@@ -120,12 +117,14 @@ function Viewport({ children, documentId, ...props }) {
|
|
|
120
117
|
},
|
|
121
118
|
children: !isGated && children
|
|
122
119
|
}
|
|
123
|
-
);
|
|
120
|
+
) });
|
|
124
121
|
}
|
|
125
122
|
export {
|
|
126
123
|
Viewport,
|
|
124
|
+
ViewportElementContext,
|
|
127
125
|
useIsViewportGated,
|
|
128
126
|
useViewportCapability,
|
|
127
|
+
useViewportElement,
|
|
129
128
|
useViewportPlugin,
|
|
130
129
|
useViewportRef,
|
|
131
130
|
useViewportScrollActivity
|
package/dist/preact/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { useEffect, useState } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n //
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/context/viewport-element-context.ts","../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { createContext, RefObject } from '@framework';\n\n/**\n * Context to share the viewport DOM element reference with child components.\n * This allows child components (like ZoomGestureWrapper) to access the viewport\n * container element without DOM traversal.\n */\nexport const ViewportElementContext = createContext<RefObject<HTMLDivElement> | null>(null);\n","import { useEffect, useState, useContext, RefObject } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { GateChangeEvent, ScrollActivity, ViewportPlugin } from '@embedpdf/plugin-viewport';\nimport { ViewportElementContext } from '../context';\n\nexport const useViewportPlugin = () => usePlugin<ViewportPlugin>(ViewportPlugin.id);\nexport const useViewportCapability = () => useCapability<ViewportPlugin>(ViewportPlugin.id);\n\n/**\n * Hook to get the viewport DOM element ref from context.\n * Must be used within a Viewport component.\n */\nexport const useViewportElement = (): RefObject<HTMLDivElement> | null => {\n return useContext(ViewportElementContext);\n};\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n // On scroll\n const onScroll = () => {\n viewportPlugin.setViewportScrollMetrics(documentId, {\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 viewportPlugin.setViewportResizeMetrics(documentId, {\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 = viewportPlugin.onScrollRequest(\n documentId,\n ({ x, y, behavior = 'auto' }) => {\n requestAnimationFrame(() => {\n container.scrollTo({ left: x, top: y, behavior });\n });\n },\n );\n\n // Cleanup\n return () => {\n viewportPlugin.unregisterViewport(documentId);\n resizeObserver.disconnect();\n container.removeEventListener('scroll', onScroll);\n unsubscribeScrollRequest();\n };\n }, [viewportPlugin, documentId]);\n\n return containerRef;\n}\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { useIsViewportGated, useViewportCapability } from '../hooks';\nimport { useViewportRef } from '../hooks/use-viewport-ref';\nimport { ViewportElementContext } from '../context';\n\ntype ViewportProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n /**\n * The ID of the document that this viewport displays\n */\n documentId: string;\n};\n\nexport function Viewport({ children, documentId, ...props }: ViewportProps) {\n const [viewportGap, setViewportGap] = useState(0);\n const viewportRef = useViewportRef(documentId);\n const { provides: viewportProvides } = useViewportCapability();\n const isGated = useIsViewportGated(documentId);\n\n useEffect(() => {\n if (viewportProvides) {\n setViewportGap(viewportProvides.getViewportGap());\n }\n }, [viewportProvides]);\n\n const { style, ...restProps } = props;\n\n return (\n <ViewportElementContext.Provider value={viewportRef}>\n <div\n {...restProps}\n ref={viewportRef}\n style={{\n width: '100%',\n height: '100%',\n overflow: 'auto',\n ...(typeof style === 'object' ? style : {}),\n padding: `${viewportGap}px`,\n }}\n >\n {!isGated && children}\n </div>\n </ViewportElementContext.Provider>\n );\n}\n"],"names":[],"mappings":"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"}
|
package/dist/react/adapter.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Fragment, useEffect, useRef, useState, useCallback, useMemo, useLayoutEffect, } from 'react';
|
|
2
|
-
export type { ReactNode, HTMLAttributes, CSSProperties } from 'react';
|
|
1
|
+
export { Fragment, useEffect, useRef, useState, useCallback, useMemo, useLayoutEffect, createContext, useContext, } from 'react';
|
|
2
|
+
export type { ReactNode, HTMLAttributes, CSSProperties, RefObject } from 'react';
|
package/dist/react/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),r=require("@embedpdf/core/react"),o=require("@embedpdf/plugin-viewport"),i=()=>r.usePlugin(o.ViewportPlugin.id),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),r=require("@embedpdf/core/react"),o=require("@embedpdf/plugin-viewport"),i=t.createContext(null),s=()=>r.usePlugin(o.ViewportPlugin.id),l=()=>r.useCapability(o.ViewportPlugin.id),n=e=>{const{provides:r}=l(),[o,i]=t.useState((null==r?void 0:r.isGated(e))??!1);return t.useEffect(()=>{if(r)return i(r.isGated(e)),r.onGateChange(t=>{t.documentId===e&&i(t.isGated)})},[r,e]),o};function c(e){const{plugin:r}=s(),o=t.useRef(null);return t.useLayoutEffect(()=>{if(!r)return;const t=o.current;if(!t)return;try{r.registerViewport(e)}catch(n){return void console.error(`Failed to register viewport for document ${e}:`,n)}const i=()=>{r.setViewportScrollMetrics(e,{scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})};t.addEventListener("scroll",i);const s=new ResizeObserver(()=>{r.setViewportResizeMetrics(e,{width:t.offsetWidth,height:t.offsetHeight,clientWidth:t.clientWidth,clientHeight:t.clientHeight,scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,scrollWidth:t.scrollWidth,scrollHeight:t.scrollHeight,clientLeft:t.clientLeft,clientTop:t.clientTop})});s.observe(t);const l=r.onScrollRequest(e,({x:e,y:r,behavior:o="auto"})=>{requestAnimationFrame(()=>{t.scrollTo({left:e,top:r,behavior:o})})});return()=>{r.unregisterViewport(e),s.disconnect(),t.removeEventListener("scroll",i),l()}},[r,e]),o}exports.Viewport=function({children:r,documentId:o,...s}){const[u,p]=t.useState(0),d=c(o),{provides:a}=l(),f=n(o);t.useEffect(()=>{a&&p(a.getViewportGap())},[a]);const{style:h,...g}=s;return e.jsx(i.Provider,{value:d,children:e.jsx("div",{...g,ref:d,style:{width:"100%",height:"100%",overflow:"auto",..."object"==typeof h?h:{},padding:`${u}px`},children:!f&&r})})},exports.ViewportElementContext=i,exports.useIsViewportGated=n,exports.useViewportCapability=l,exports.useViewportElement=()=>t.useContext(i),exports.useViewportPlugin=s,exports.useViewportRef=c,exports.useViewportScrollActivity=e=>{const{provides:r}=l(),[o,i]=t.useState({isScrolling:!1,isSmoothScrolling:!1});return t.useEffect(()=>{if(r)return r.onScrollActivity(t=>{t.documentId===e&&i(t.activity)})},[r,e]),o},Object.keys(o).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>o[e]})});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { useEffect, useState } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n //
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/context/viewport-element-context.ts","../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { createContext, RefObject } from '@framework';\n\n/**\n * Context to share the viewport DOM element reference with child components.\n * This allows child components (like ZoomGestureWrapper) to access the viewport\n * container element without DOM traversal.\n */\nexport const ViewportElementContext = createContext<RefObject<HTMLDivElement> | null>(null);\n","import { useEffect, useState, useContext, RefObject } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { GateChangeEvent, ScrollActivity, ViewportPlugin } from '@embedpdf/plugin-viewport';\nimport { ViewportElementContext } from '../context';\n\nexport const useViewportPlugin = () => usePlugin<ViewportPlugin>(ViewportPlugin.id);\nexport const useViewportCapability = () => useCapability<ViewportPlugin>(ViewportPlugin.id);\n\n/**\n * Hook to get the viewport DOM element ref from context.\n * Must be used within a Viewport component.\n */\nexport const useViewportElement = (): RefObject<HTMLDivElement> | null => {\n return useContext(ViewportElementContext);\n};\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n // On scroll\n const onScroll = () => {\n viewportPlugin.setViewportScrollMetrics(documentId, {\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 viewportPlugin.setViewportResizeMetrics(documentId, {\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 = viewportPlugin.onScrollRequest(\n documentId,\n ({ x, y, behavior = 'auto' }) => {\n requestAnimationFrame(() => {\n container.scrollTo({ left: x, top: y, behavior });\n });\n },\n );\n\n // Cleanup\n return () => {\n viewportPlugin.unregisterViewport(documentId);\n resizeObserver.disconnect();\n container.removeEventListener('scroll', onScroll);\n unsubscribeScrollRequest();\n };\n }, [viewportPlugin, documentId]);\n\n return containerRef;\n}\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { useIsViewportGated, useViewportCapability } from '../hooks';\nimport { useViewportRef } from '../hooks/use-viewport-ref';\nimport { ViewportElementContext } from '../context';\n\ntype ViewportProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n /**\n * The ID of the document that this viewport displays\n */\n documentId: string;\n};\n\nexport function Viewport({ children, documentId, ...props }: ViewportProps) {\n const [viewportGap, setViewportGap] = useState(0);\n const viewportRef = useViewportRef(documentId);\n const { provides: viewportProvides } = useViewportCapability();\n const isGated = useIsViewportGated(documentId);\n\n useEffect(() => {\n if (viewportProvides) {\n setViewportGap(viewportProvides.getViewportGap());\n }\n }, [viewportProvides]);\n\n const { style, ...restProps } = props;\n\n return (\n <ViewportElementContext.Provider value={viewportRef}>\n <div\n {...restProps}\n ref={viewportRef}\n style={{\n width: '100%',\n height: '100%',\n overflow: 'auto',\n ...(typeof style === 'object' ? style : {}),\n padding: `${viewportGap}px`,\n }}\n >\n {!isGated && children}\n </div>\n </ViewportElementContext.Provider>\n );\n}\n"],"names":["ViewportElementContext","createContext","useViewportPlugin","usePlugin","ViewportPlugin","id","useViewportCapability","useCapability","useIsViewportGated","documentId","provides","isGated","setIsGated","useState","useEffect","onGateChange","event","useViewportRef","plugin","viewportPlugin","containerRef","useRef","useLayoutEffect","container","current","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","disconnect","removeEventListener","children","props","viewportGap","setViewportGap","viewportRef","viewportProvides","getViewportGap","style","restProps","jsx","Provider","value","ref","overflow","padding","useContext","scrollActivity","setScrollActivity","isScrolling","isSmoothScrolling","onScrollActivity","activity"],"mappings":"iNAOaA,EAAyBC,EAAAA,cAAgD,MCFzEC,EAAoB,IAAMC,YAA0BC,EAAAA,eAAeC,IACnEC,EAAwB,IAAMC,gBAA8BH,EAAAA,eAAeC,IAe3EG,EAAsBC,IACjC,MAAMC,SAAEA,GAAaJ,KACdK,EAASC,GAAcC,EAAAA,UAAS,MAAAH,OAAA,EAAAA,EAAUC,QAAQF,MAAe,GAgBxE,OAdAK,EAAAA,UAAU,KACR,GAAKJ,EAML,OAHAE,EAAWF,EAASC,QAAQF,IAGrBC,EAASK,aAAcC,IACxBA,EAAMP,aAAeA,GACvBG,EAAWI,EAAML,YAGpB,CAACD,EAAUD,IAEPE,GCnCF,SAASM,EAAeR,GAC7B,MAAQS,OAAQC,GAAmBjB,IAC7BkB,EAAeC,EAAAA,OAAuB,MA6D5C,OA3DAC,EAAAA,gBAAgB,KACd,IAAKH,EAAgB,OAErB,MAAMI,EAAYH,EAAaI,QAC/B,IAAKD,EAAW,OAGhB,IACEJ,EAAeM,iBAAiBhB,EAClC,OAASiB,GAEP,YADAC,QAAQD,MAAM,4CAA4CjB,KAAeiB,EAE3E,CAGA,MAAME,EAAW,KACfT,EAAeU,yBAAyBpB,EAAY,CAClDqB,UAAWP,EAAUO,UACrBC,WAAYR,EAAUQ,cAG1BR,EAAUS,iBAAiB,SAAUJ,GAGrC,MAAMK,EAAiB,IAAIC,eAAe,KACxCf,EAAegB,yBAAyB1B,EAAY,CAClD2B,MAAOb,EAAUc,YACjBC,OAAQf,EAAUgB,aAClBC,YAAajB,EAAUiB,YACvBC,aAAclB,EAAUkB,aACxBX,UAAWP,EAAUO,UACrBC,WAAYR,EAAUQ,WACtBW,YAAanB,EAAUmB,YACvBC,aAAcpB,EAAUoB,aACxBC,WAAYrB,EAAUqB,WACtBC,UAAWtB,EAAUsB,cAGzBZ,EAAea,QAAQvB,GAGvB,MAAMwB,EAA2B5B,EAAe6B,gBAC9CvC,EACA,EAAGwC,IAAGC,IAAGC,WAAW,WAClBC,sBAAsB,KACpB7B,EAAU8B,SAAS,CAAEC,KAAML,EAAGM,IAAKL,EAAGC,iBAM5C,MAAO,KACLhC,EAAeqC,mBAAmB/C,GAClCwB,EAAewB,aACflC,EAAUmC,oBAAoB,SAAU9B,GACxCmB,MAED,CAAC5B,EAAgBV,IAEbW,CACT,kBCvDO,UAAkBuC,SAAEA,EAAAlD,WAAUA,KAAemD,IAClD,MAAOC,EAAaC,GAAkBjD,EAAAA,SAAS,GACzCkD,EAAc9C,EAAeR,IAC3BC,SAAUsD,GAAqB1D,IACjCK,EAAUH,EAAmBC,GAEnCK,EAAAA,UAAU,KACJkD,GACFF,EAAeE,EAAiBC,mBAEjC,CAACD,IAEJ,MAAME,MAAEA,KAAUC,GAAcP,EAEhC,OACEQ,EAAAA,IAACpE,EAAuBqE,SAAvB,CAAgCC,MAAOP,EACtCJ,SAAAS,EAAAA,IAAC,MAAA,IACKD,EACJI,IAAKR,EACLG,MAAO,CACL9B,MAAO,OACPE,OAAQ,OACRkC,SAAU,UACW,iBAAVN,EAAqBA,EAAQ,CAAA,EACxCO,QAAS,GAAGZ,OAGbF,UAAChD,GAAWgD,KAIrB,2HFhCkC,IACzBe,EAAAA,WAAW1E,0FAiCsBS,IACxC,MAAMC,SAAEA,GAAaJ,KACdqE,EAAgBC,GAAqB/D,WAAyB,CACnEgE,aAAa,EACbC,mBAAmB,IAerB,OAZAhE,EAAAA,UAAU,KACR,GAAKJ,EAGL,OAAOA,EAASqE,iBAAkB/D,IAE5BA,EAAMP,aAAeA,GACvBmE,EAAkB5D,EAAMgE,aAG3B,CAACtE,EAAUD,IAEPkE"}
|
package/dist/react/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect, useRef, useLayoutEffect } from "react";
|
|
2
|
+
import { createContext, useContext, useState, useEffect, useRef, useLayoutEffect } from "react";
|
|
3
3
|
import { usePlugin, useCapability } from "@embedpdf/core/react";
|
|
4
4
|
import { ViewportPlugin } from "@embedpdf/plugin-viewport";
|
|
5
5
|
export * from "@embedpdf/plugin-viewport";
|
|
6
|
+
const ViewportElementContext = createContext(null);
|
|
6
7
|
const useViewportPlugin = () => usePlugin(ViewportPlugin.id);
|
|
7
8
|
const useViewportCapability = () => useCapability(ViewportPlugin.id);
|
|
9
|
+
const useViewportElement = () => {
|
|
10
|
+
return useContext(ViewportElementContext);
|
|
11
|
+
};
|
|
8
12
|
const useIsViewportGated = (documentId) => {
|
|
9
13
|
const { provides } = useViewportCapability();
|
|
10
14
|
const [isGated, setIsGated] = useState((provides == null ? void 0 : provides.isGated(documentId)) ?? false);
|
|
@@ -48,14 +52,6 @@ function useViewportRef(documentId) {
|
|
|
48
52
|
console.error(`Failed to register viewport for document ${documentId}:`, error);
|
|
49
53
|
return;
|
|
50
54
|
}
|
|
51
|
-
const provideRect = () => {
|
|
52
|
-
const r = container.getBoundingClientRect();
|
|
53
|
-
return {
|
|
54
|
-
origin: { x: r.left, y: r.top },
|
|
55
|
-
size: { width: r.width, height: r.height }
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
viewportPlugin.registerBoundingRectProvider(documentId, provideRect);
|
|
59
55
|
const onScroll = () => {
|
|
60
56
|
viewportPlugin.setViewportScrollMetrics(documentId, {
|
|
61
57
|
scrollTop: container.scrollTop,
|
|
@@ -72,7 +68,9 @@ function useViewportRef(documentId) {
|
|
|
72
68
|
scrollTop: container.scrollTop,
|
|
73
69
|
scrollLeft: container.scrollLeft,
|
|
74
70
|
scrollWidth: container.scrollWidth,
|
|
75
|
-
scrollHeight: container.scrollHeight
|
|
71
|
+
scrollHeight: container.scrollHeight,
|
|
72
|
+
clientLeft: container.clientLeft,
|
|
73
|
+
clientTop: container.clientTop
|
|
76
74
|
});
|
|
77
75
|
});
|
|
78
76
|
resizeObserver.observe(container);
|
|
@@ -86,7 +84,6 @@ function useViewportRef(documentId) {
|
|
|
86
84
|
);
|
|
87
85
|
return () => {
|
|
88
86
|
viewportPlugin.unregisterViewport(documentId);
|
|
89
|
-
viewportPlugin.registerBoundingRectProvider(documentId, null);
|
|
90
87
|
resizeObserver.disconnect();
|
|
91
88
|
container.removeEventListener("scroll", onScroll);
|
|
92
89
|
unsubscribeScrollRequest();
|
|
@@ -105,7 +102,7 @@ function Viewport({ children, documentId, ...props }) {
|
|
|
105
102
|
}
|
|
106
103
|
}, [viewportProvides]);
|
|
107
104
|
const { style, ...restProps } = props;
|
|
108
|
-
return /* @__PURE__ */ jsx(
|
|
105
|
+
return /* @__PURE__ */ jsx(ViewportElementContext.Provider, { value: viewportRef, children: /* @__PURE__ */ jsx(
|
|
109
106
|
"div",
|
|
110
107
|
{
|
|
111
108
|
...restProps,
|
|
@@ -119,12 +116,14 @@ function Viewport({ children, documentId, ...props }) {
|
|
|
119
116
|
},
|
|
120
117
|
children: !isGated && children
|
|
121
118
|
}
|
|
122
|
-
);
|
|
119
|
+
) });
|
|
123
120
|
}
|
|
124
121
|
export {
|
|
125
122
|
Viewport,
|
|
123
|
+
ViewportElementContext,
|
|
126
124
|
useIsViewportGated,
|
|
127
125
|
useViewportCapability,
|
|
126
|
+
useViewportElement,
|
|
128
127
|
useViewportPlugin,
|
|
129
128
|
useViewportRef,
|
|
130
129
|
useViewportScrollActivity
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { useEffect, useState } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n //
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/context/viewport-element-context.ts","../../src/shared/hooks/use-viewport.ts","../../src/shared/hooks/use-viewport-ref.ts","../../src/shared/components/viewport.tsx"],"sourcesContent":["import { createContext, RefObject } from '@framework';\n\n/**\n * Context to share the viewport DOM element reference with child components.\n * This allows child components (like ZoomGestureWrapper) to access the viewport\n * container element without DOM traversal.\n */\nexport const ViewportElementContext = createContext<RefObject<HTMLDivElement> | null>(null);\n","import { useEffect, useState, useContext, RefObject } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { GateChangeEvent, ScrollActivity, ViewportPlugin } from '@embedpdf/plugin-viewport';\nimport { ViewportElementContext } from '../context';\n\nexport const useViewportPlugin = () => usePlugin<ViewportPlugin>(ViewportPlugin.id);\nexport const useViewportCapability = () => useCapability<ViewportPlugin>(ViewportPlugin.id);\n\n/**\n * Hook to get the viewport DOM element ref from context.\n * Must be used within a Viewport component.\n */\nexport const useViewportElement = (): RefObject<HTMLDivElement> | null => {\n return useContext(ViewportElementContext);\n};\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 documentId Document ID.\n */\nexport const useIsViewportGated = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [isGated, setIsGated] = useState(provides?.isGated(documentId) ?? false);\n\n useEffect(() => {\n if (!provides) return;\n\n // Set initial state\n setIsGated(provides.isGated(documentId));\n\n // Subscribe to gate state changes\n return provides.onGateChange((event: GateChangeEvent) => {\n if (event.documentId === documentId) {\n setIsGated(event.isGated);\n }\n });\n }, [provides, documentId]);\n\n return isGated;\n};\n\n/**\n * Hook to get scroll activity for a specific document\n * @param documentId Document ID.\n */\nexport const useViewportScrollActivity = (documentId: string) => {\n const { provides } = useViewportCapability();\n const [scrollActivity, setScrollActivity] = useState<ScrollActivity>({\n isScrolling: false,\n isSmoothScrolling: false,\n });\n\n useEffect(() => {\n if (!provides) return;\n\n // Subscribe to scroll activity events\n return provides.onScrollActivity((event) => {\n // Filter by documentId if provided\n if (event.documentId === documentId) {\n setScrollActivity(event.activity);\n }\n });\n }, [provides, documentId]);\n\n return scrollActivity;\n};\n","import { Rect } from '@embedpdf/models';\nimport { useLayoutEffect, useRef } from '@framework';\nimport { useViewportPlugin } from './use-viewport';\n\nexport function useViewportRef(documentId: string) {\n const { plugin: viewportPlugin } = useViewportPlugin();\n const containerRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n if (!viewportPlugin) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n // Register this viewport for the document\n try {\n viewportPlugin.registerViewport(documentId);\n } catch (error) {\n console.error(`Failed to register viewport for document ${documentId}:`, error);\n return;\n }\n\n // On scroll\n const onScroll = () => {\n viewportPlugin.setViewportScrollMetrics(documentId, {\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 viewportPlugin.setViewportResizeMetrics(documentId, {\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 = viewportPlugin.onScrollRequest(\n documentId,\n ({ x, y, behavior = 'auto' }) => {\n requestAnimationFrame(() => {\n container.scrollTo({ left: x, top: y, behavior });\n });\n },\n );\n\n // Cleanup\n return () => {\n viewportPlugin.unregisterViewport(documentId);\n resizeObserver.disconnect();\n container.removeEventListener('scroll', onScroll);\n unsubscribeScrollRequest();\n };\n }, [viewportPlugin, documentId]);\n\n return containerRef;\n}\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { useIsViewportGated, useViewportCapability } from '../hooks';\nimport { useViewportRef } from '../hooks/use-viewport-ref';\nimport { ViewportElementContext } from '../context';\n\ntype ViewportProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n /**\n * The ID of the document that this viewport displays\n */\n documentId: string;\n};\n\nexport function Viewport({ children, documentId, ...props }: ViewportProps) {\n const [viewportGap, setViewportGap] = useState(0);\n const viewportRef = useViewportRef(documentId);\n const { provides: viewportProvides } = useViewportCapability();\n const isGated = useIsViewportGated(documentId);\n\n useEffect(() => {\n if (viewportProvides) {\n setViewportGap(viewportProvides.getViewportGap());\n }\n }, [viewportProvides]);\n\n const { style, ...restProps } = props;\n\n return (\n <ViewportElementContext.Provider value={viewportRef}>\n <div\n {...restProps}\n ref={viewportRef}\n style={{\n width: '100%',\n height: '100%',\n overflow: 'auto',\n ...(typeof style === 'object' ? style : {}),\n padding: `${viewportGap}px`,\n }}\n >\n {!isGated && children}\n </div>\n </ViewportElementContext.Provider>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './viewport-element-context';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RefObject } from '../../react/adapter.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Context to share the viewport DOM element reference with child components.
|
|
4
|
+
* This allows child components (like ZoomGestureWrapper) to access the viewport
|
|
5
|
+
* container element without DOM traversal.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ViewportElementContext: import('react').Context<RefObject<HTMLDivElement> | null>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RefObject } from '../../react/adapter.ts';
|
|
1
2
|
import { ScrollActivity, ViewportPlugin } from '../../index.ts';
|
|
2
3
|
export declare const useViewportPlugin: () => {
|
|
3
4
|
plugin: ViewportPlugin | null;
|
|
@@ -9,6 +10,11 @@ export declare const useViewportCapability: () => {
|
|
|
9
10
|
isLoading: boolean;
|
|
10
11
|
ready: Promise<void>;
|
|
11
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Hook to get the viewport DOM element ref from context.
|
|
15
|
+
* Must be used within a Viewport component.
|
|
16
|
+
*/
|
|
17
|
+
export declare const useViewportElement: () => RefObject<HTMLDivElement> | null;
|
|
12
18
|
/**
|
|
13
19
|
* Hook to get the gated state of the viewport for a specific document.
|
|
14
20
|
* The viewport children are not rendered when gated.
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './viewport-element-context';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RefObject } from '../../preact/adapter.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Context to share the viewport DOM element reference with child components.
|
|
4
|
+
* This allows child components (like ZoomGestureWrapper) to access the viewport
|
|
5
|
+
* container element without DOM traversal.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ViewportElementContext: import('preact').Context<RefObject<HTMLDivElement> | null>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RefObject } from '../../preact/adapter.ts';
|
|
1
2
|
import { ScrollActivity, ViewportPlugin } from '../../lib/index.ts';
|
|
2
3
|
export declare const useViewportPlugin: () => {
|
|
3
4
|
plugin: ViewportPlugin | null;
|
|
@@ -9,6 +10,11 @@ export declare const useViewportCapability: () => {
|
|
|
9
10
|
isLoading: boolean;
|
|
10
11
|
ready: Promise<void>;
|
|
11
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Hook to get the viewport DOM element ref from context.
|
|
15
|
+
* Must be used within a Viewport component.
|
|
16
|
+
*/
|
|
17
|
+
export declare const useViewportElement: () => RefObject<HTMLDivElement> | null;
|
|
12
18
|
/**
|
|
13
19
|
* Hook to get the gated state of the viewport for a specific document.
|
|
14
20
|
* The viewport children are not rendered when gated.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './viewport-element-context';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RefObject } from '../../react/adapter.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Context to share the viewport DOM element reference with child components.
|
|
4
|
+
* This allows child components (like ZoomGestureWrapper) to access the viewport
|
|
5
|
+
* container element without DOM traversal.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ViewportElementContext: import('react').Context<RefObject<HTMLDivElement> | null>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RefObject } from '../../react/adapter.ts';
|
|
1
2
|
import { ScrollActivity, ViewportPlugin } from '../../lib/index.ts';
|
|
2
3
|
export declare const useViewportPlugin: () => {
|
|
3
4
|
plugin: ViewportPlugin | null;
|
|
@@ -9,6 +10,11 @@ export declare const useViewportCapability: () => {
|
|
|
9
10
|
isLoading: boolean;
|
|
10
11
|
ready: Promise<void>;
|
|
11
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Hook to get the viewport DOM element ref from context.
|
|
15
|
+
* Must be used within a Viewport component.
|
|
16
|
+
*/
|
|
17
|
+
export declare const useViewportElement: () => RefObject<HTMLDivElement> | null;
|
|
12
18
|
/**
|
|
13
19
|
* Hook to get the gated state of the viewport for a specific document.
|
|
14
20
|
* The viewport children are not rendered when gated.
|
package/dist/svelte/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),require("svelte/internal/disclose-version");const e=require("svelte/internal/client"),t=require("@embedpdf/core/svelte"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),require("svelte/internal/disclose-version");const e=require("svelte/internal/client"),t=require("svelte"),r=require("@embedpdf/core/svelte"),o=require("@embedpdf/plugin-viewport");function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}const s=i(e),n=()=>r.usePlugin(o.ViewportPlugin.id),l=()=>r.useCapability(o.ViewportPlugin.id),c=e=>{const t=l();let r=s.state(!1);const o=s.derived(e);return s.user_effect(()=>{const e=t.provides,i=s.get(o);if(e&&i)return s.set(r,e.isGated(i),!0),e.onGateChange(e=>{e.documentId===i&&s.set(r,e.isGated,!0)});s.set(r,!1)}),{get current(){return s.get(r)}}};function u(e){const{plugin:t}=n();let r=s.state(null);const o=s.derived(e);return s.user_pre_effect(()=>{if(!t)return;const e=s.get(r),i=s.get(o);if(!e||!i)return;try{t.registerViewport(i)}catch(u){return void console.error(`Failed to register viewport for document ${i}:`,u)}const n=()=>{t.setViewportScrollMetrics(i,{scrollTop:e.scrollTop,scrollLeft:e.scrollLeft})};e.addEventListener("scroll",n);const l=new ResizeObserver(()=>{t.setViewportResizeMetrics(i,{width:e.offsetWidth,height:e.offsetHeight,clientWidth:e.clientWidth,clientHeight:e.clientHeight,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft,scrollWidth:e.scrollWidth,scrollHeight:e.scrollHeight,clientLeft:e.clientLeft,clientTop:e.clientTop})});l.observe(e);const c=t.onScrollRequest(i,({x:t,y:r,behavior:o="auto"})=>{requestAnimationFrame(()=>{e.scrollTo({left:t,top:r,behavior:o})})});return()=>{t.unregisterViewport(i),e.removeEventListener("scroll",n),l.disconnect(),c()}}),{get containerRef(){return s.get(r)},set containerRef(e){s.set(r,e,!0)}}}var p=s.from_html("<div><!></div>");exports.Viewport=function(e,r){s.push(r,!0);let o=s.rest_props(r,["$$slots","$$events","$$legacy","documentId","children","class"]),i=s.state(0);const n=u(()=>r.documentId),d=l(),a=c(()=>r.documentId);t.setContext("viewport-element",{get current(){return n.containerRef}}),s.user_effect(()=>{d.provides&&s.set(i,d.provides.getViewportGap(),!0)});var f=p();s.attribute_effect(f,()=>({...o,class:r.class,[s.STYLE]:{width:"100%",height:"100%",overflow:"auto",padding:`${s.get(i)}px`}}));var g=s.child(f),v=e=>{var t=s.comment(),o=s.first_child(t);s.snippet(o,()=>r.children),s.append(e,t)};s.if(g,e=>{a.current||e(v)}),s.reset(f),s.bind_this(f,e=>n.containerRef=e,()=>null==n?void 0:n.containerRef),s.append(e,f),s.pop()},exports.useIsViewportGated=c,exports.useViewportCapability=l,exports.useViewportPlugin=n,exports.useViewportRef=u,exports.useViewportScrollActivity=e=>{const t=l();let r=s.state(s.proxy({isScrolling:!1,isSmoothScrolling:!1}));const o=s.derived(e);return s.user_effect(()=>{const e=t.provides,i=s.get(o);if(e&&i)return e.onScrollActivity(e=>{e.documentId===i&&s.set(r,e.activity,!0)});s.set(r,{isScrolling:!1,isSmoothScrolling:!1},!0)}),{get current(){return s.get(r)}}},Object.keys(o).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>o[e]})});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|