@embedpdf/plugin-thumbnail 1.0.11 → 1.0.12

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.
Files changed (39) hide show
  1. package/dist/index.cjs +2 -170
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +1 -54
  4. package/dist/index.js +9 -17
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/index.d.ts +7 -0
  7. package/dist/lib/manifest.d.ts +4 -0
  8. package/dist/lib/thumbnail-plugin.d.ts +17 -0
  9. package/dist/lib/types.d.ts +30 -0
  10. package/dist/preact/adapter.d.ts +5 -0
  11. package/dist/preact/core.d.ts +1 -0
  12. package/dist/preact/index.cjs +2 -124
  13. package/dist/preact/index.cjs.map +1 -1
  14. package/dist/preact/index.d.ts +1 -34
  15. package/dist/preact/index.js +18 -24
  16. package/dist/preact/index.js.map +1 -1
  17. package/dist/react/adapter.d.ts +2 -0
  18. package/dist/react/core.d.ts +1 -0
  19. package/dist/react/index.cjs +2 -124
  20. package/dist/react/index.cjs.map +1 -1
  21. package/dist/react/index.d.ts +1 -30
  22. package/dist/react/index.js +17 -24
  23. package/dist/react/index.js.map +1 -1
  24. package/dist/shared-preact/components/index.d.ts +2 -0
  25. package/dist/shared-preact/components/thumbnail-img.d.ts +8 -0
  26. package/dist/shared-preact/components/thumbnails-pane.d.ts +10 -0
  27. package/dist/shared-preact/hooks/index.d.ts +1 -0
  28. package/dist/shared-preact/hooks/use-thumbnail.d.ts +11 -0
  29. package/dist/shared-preact/index.d.ts +2 -0
  30. package/dist/shared-react/components/index.d.ts +2 -0
  31. package/dist/shared-react/components/thumbnail-img.d.ts +8 -0
  32. package/dist/shared-react/components/thumbnails-pane.d.ts +10 -0
  33. package/dist/shared-react/hooks/index.d.ts +1 -0
  34. package/dist/shared-react/hooks/use-thumbnail.d.ts +11 -0
  35. package/dist/shared-react/index.d.ts +2 -0
  36. package/package.json +14 -11
  37. package/dist/index.d.cts +0 -54
  38. package/dist/preact/index.d.cts +0 -34
  39. package/dist/react/index.d.cts +0 -30
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/preact/index.ts","../../src/preact/hooks/use-thumbnail.ts","../../src/preact/components/thumbnails-pane.tsx","../../src/preact/components/thumbnail-img.tsx"],"sourcesContent":["export * from './hooks';\nexport * from './components';\n","import { useCapability, usePlugin } from '@embedpdf/core/preact';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","/** @jsxImportSource preact */\nimport { ComponentChildren, JSX } from 'preact';\nimport { useEffect, useRef, useState } from 'preact/hooks';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {\n style?: JSX.CSSProperties;\n children: (m: ThumbMeta) => ComponentChildren;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n","/** @jsxImportSource preact */\nimport { ComponentChildren, Fragment, JSX } from 'preact';\nimport { useEffect, useState, useRef } from 'preact/hooks';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<JSX.HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: JSX.CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n"],"mappings":"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","names":["window","import_hooks","import_jsx_runtime"]}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-thumbnail.ts","../../src/shared/components/thumbnail-img.tsx","../../src/shared/components/thumbnails-pane.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","import { useEffect, useState, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n","import { useEffect, useRef, useState, HTMLAttributes, CSSProperties, ReactNode } from '@framework';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {\n style?: CSSProperties;\n children: (m: ThumbMeta) => ReactNode;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n"],"names":["useThumbnailCapability","useCapability","ThumbnailPlugin","id","meta","style","props","provides","thumbs","url","setUrl","useState","urlRef","useRef","useEffect","task","renderThumb","pageIndex","window","devicePixelRatio","wait","blob","objectUrl","URL","createObjectURL","current","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","jsx","src","onLoad","selectedPage","scrollOptions","behavior","block","inline","viewportRef","setWindow","onWindow","vp","onScroll","setViewport","scrollTop","clientHeight","addEventListener","removeEventListener","items","length","item","find","it","top","scrollTo","wrapperHeight","labelHeight","ref","overflowY","position","children","height","totalHeight","map","m","usePlugin"],"mappings":"iRAIaA,EAAyB,IAAMC,gBAA+BC,EAAAA,gBAAgBC,qBCMpF,UAAkBC,KAAEA,EAAAC,MAAMA,KAAUC,IACzC,MAAQC,SAAUC,GAAWR,KACtBS,EAAKC,GAAUC,aAChBC,EAASC,SAAsB,MA8B9B,OA5BPC,EAAAA,WAAU,KACR,MAAMC,EAAO,MAAAP,OAAA,EAAAA,EAAQQ,YAAYZ,EAAKa,UAAWC,OAAOC,kBAOxD,OANM,MAAAJ,GAAAA,EAAAK,MAAMC,IACJ,MAAAC,EAAYC,IAAIC,gBAAgBH,GACtCT,EAAOa,QAAUH,EACjBZ,EAAOY,EAAS,GACfI,UAEI,KACDd,EAAOa,SACLF,IAAAI,gBAAgBf,EAAOa,SAC3Bb,EAAOa,QAAU,MAEjB,MAAAV,GAAAA,EAAMa,MAAM,CACVC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,wBACV,CAEL,GACC,CAAC5B,EAAKa,YASFR,EAAOwB,EAAAA,IAAA,MAAA,CAAIC,IAAKzB,EAAK0B,OAPJ,KAClBvB,EAAOa,UACLF,IAAAI,gBAAgBf,EAAOa,SAC3Bb,EAAOa,QAAU,KAAA,EAIgCpB,WAAkBC,IAAY,IACrF,yBCjCO,UAAwBD,MAC7BA,EAAA+B,aACAA,EAAAC,cACAA,EAAgB,CAAEC,SAAU,SAAUC,MAAO,UAAWC,OAAQ,cAC7DlC,IAEH,MAAQC,SAAUC,GAAWR,IACvByC,EAAc5B,SAAuB,OAEpCK,EAAQwB,GAAa/B,EAAAA,SAA6B,aAGzDG,EAAAA,WAAU,IAAM,MAAAN,OAAA,EAAAA,EAAQmC,SAASD,IAAY,CAAClC,IAG9CM,EAAAA,WAAU,KACR,MAAM8B,EAAKH,EAAYhB,QACvB,IAAKmB,EAAI,OACT,MAAMC,EAAW,IAAM,MAAArC,OAAA,EAAAA,EAAQsC,YAAYF,EAAGG,UAAWH,EAAGI,cAE5D,OADGJ,EAAAK,iBAAiB,SAAUJ,GACvB,IAAMD,EAAGM,oBAAoB,SAAUL,EAAQ,GACrD,CAACrC,IAGJM,EAAAA,WAAU,KACR,MAAM8B,EAAKH,EAAYhB,QAClBmB,GAAOpC,GAEiB,KAAzB,MAAAU,OAAA,EAAAA,EAAQiC,MAAMC,SAChB5C,EAAOsC,YAAYF,EAAGG,UAAWH,EAAGI,aAAY,GAEjD,CAAC9B,EAAQV,IAGZM,EAAAA,WAAU,KACJ,IAACsB,IAAiBlB,EAAQ,OAExB,MAAAmC,EAAOnC,EAAOiC,MAAMG,MAAMC,GAAOA,EAAGtC,UAAY,IAAMmB,IAC5D,IAAKiB,EAAM,OAEX,MAAMT,EAAKH,EAAYhB,QACvB,IAAKmB,EAAI,OAILS,EAAKG,IAAMZ,EAAGG,UADH,EAEbH,EAAGa,SAAS,CAAED,IAAKH,EAAKG,OAAQnB,IAEhCgB,EAAKG,IAAMH,EAAKK,cAAgBL,EAAKM,YACrCf,EAAGG,UAAYH,EAAGI,aALL,GAObJ,EAAGa,SAAS,CACVD,IAAKH,EAAKG,IAAMH,EAAKK,cAAgBL,EAAKM,YAAcf,EAAGI,gBACxDX,GACJ,GAEF,CAACD,EAAclB,EAAQmB,UAGvB,MAAI,CAAAuB,IAAKnB,EAAapC,MAAO,CAAEwD,UAAW,OAAQC,SAAU,cAAezD,MAAaC,EAEvFyD,eAAC,MAAI,CAAA1D,MAAO,CAAE2D,QAAQ,MAAA9C,SAAAA,EAAQ+C,cAAe,EAAGH,SAAU,YACvDC,SAAQ,MAAA7C,OAAA,EAAAA,EAAAiC,MAAMe,KAAKC,GAAM7D,EAAMyD,SAASI,QAIjD,8DF1EkC,IAAMC,YAA2BlE,EAAAA,gBAAgBC"}
@@ -1,34 +1 @@
1
- import * as _embedpdf_plugin_thumbnail from '@embedpdf/plugin-thumbnail';
2
- import { ThumbnailPlugin, ThumbMeta } from '@embedpdf/plugin-thumbnail';
3
- import { JSX, ComponentChildren } from 'preact';
4
-
5
- declare const useThumbnailPlugin: () => {
6
- plugin: ThumbnailPlugin | null;
7
- isLoading: boolean;
8
- ready: Promise<void>;
9
- };
10
- declare const useThumbnailCapability: () => {
11
- provides: Readonly<_embedpdf_plugin_thumbnail.ThumbnailCapability> | null;
12
- isLoading: boolean;
13
- ready: Promise<void>;
14
- };
15
-
16
- /** @jsxImportSource preact */
17
-
18
- type ThumbnailsProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {
19
- style?: JSX.CSSProperties;
20
- children: (m: ThumbMeta) => ComponentChildren;
21
- selectedPage?: number;
22
- scrollOptions?: ScrollIntoViewOptions;
23
- };
24
- declare function ThumbnailsPane({ style, selectedPage, scrollOptions, ...props }: ThumbnailsProps): JSX.Element;
25
-
26
- /** @jsxImportSource preact */
27
-
28
- type ThumbnailImgProps = Omit<JSX.HTMLAttributes<HTMLImageElement>, 'style'> & {
29
- style?: JSX.CSSProperties;
30
- meta: ThumbMeta;
31
- };
32
- declare function ThumbImg({ meta, style, ...props }: ThumbnailImgProps): JSX.Element | null;
33
-
34
- export { ThumbImg, ThumbnailsPane, useThumbnailCapability, useThumbnailPlugin };
1
+ export * from '../shared-preact';
@@ -1,12 +1,11 @@
1
- // src/preact/hooks/use-thumbnail.ts
2
- import { useCapability, usePlugin } from "@embedpdf/core/preact";
1
+ import { usePlugin, useCapability } from "@embedpdf/core/preact";
3
2
  import { ThumbnailPlugin } from "@embedpdf/plugin-thumbnail";
4
- var useThumbnailPlugin = () => usePlugin(ThumbnailPlugin.id);
5
- var useThumbnailCapability = () => useCapability(ThumbnailPlugin.id);
6
-
7
- // src/preact/components/thumbnails-pane.tsx
8
- import { useEffect, useRef, useState } from "preact/hooks";
9
3
  import { jsx } from "preact/jsx-runtime";
4
+ import "preact";
5
+ import { useRef, useState, useEffect } from "preact/hooks";
6
+ import { ignore, PdfErrorCode } from "@embedpdf/models";
7
+ const useThumbnailPlugin = () => usePlugin(ThumbnailPlugin.id);
8
+ const useThumbnailCapability = () => useCapability(ThumbnailPlugin.id);
10
9
  function ThumbnailsPane({
11
10
  style,
12
11
  selectedPage,
@@ -16,18 +15,18 @@ function ThumbnailsPane({
16
15
  const { provides: thumbs } = useThumbnailCapability();
17
16
  const viewportRef = useRef(null);
18
17
  const [window2, setWindow] = useState(null);
19
- useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);
18
+ useEffect(() => thumbs == null ? void 0 : thumbs.onWindow(setWindow), [thumbs]);
20
19
  useEffect(() => {
21
20
  const vp = viewportRef.current;
22
21
  if (!vp) return;
23
- const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);
22
+ const onScroll = () => thumbs == null ? void 0 : thumbs.setViewport(vp.scrollTop, vp.clientHeight);
24
23
  vp.addEventListener("scroll", onScroll);
25
24
  return () => vp.removeEventListener("scroll", onScroll);
26
25
  }, [thumbs]);
27
26
  useEffect(() => {
28
27
  const vp = viewportRef.current;
29
28
  if (!vp || !thumbs) return;
30
- if (window2?.items.length === 0) {
29
+ if ((window2 == null ? void 0 : window2.items.length) === 0) {
31
30
  thumbs.setViewport(vp.scrollTop, vp.clientHeight);
32
31
  }
33
32
  }, [window2, thumbs]);
@@ -47,20 +46,15 @@ function ThumbnailsPane({
47
46
  });
48
47
  }
49
48
  }, [selectedPage, window2, scrollOptions]);
50
- return /* @__PURE__ */ jsx("div", { ref: viewportRef, style: { overflowY: "auto", position: "relative", ...style }, ...props, children: /* @__PURE__ */ jsx("div", { style: { height: window2?.totalHeight ?? 0, position: "relative" }, children: window2?.items.map((m) => props.children(m)) }) });
49
+ return /* @__PURE__ */ jsx("div", { ref: viewportRef, style: { overflowY: "auto", position: "relative", ...style }, ...props, children: /* @__PURE__ */ jsx("div", { style: { height: (window2 == null ? void 0 : window2.totalHeight) ?? 0, position: "relative" }, children: window2 == null ? void 0 : window2.items.map((m) => props.children(m)) }) });
51
50
  }
52
-
53
- // src/preact/components/thumbnail-img.tsx
54
- import { useEffect as useEffect2, useState as useState2, useRef as useRef2 } from "preact/hooks";
55
- import { ignore, PdfErrorCode } from "@embedpdf/models";
56
- import { jsx as jsx2 } from "preact/jsx-runtime";
57
51
  function ThumbImg({ meta, style, ...props }) {
58
52
  const { provides: thumbs } = useThumbnailCapability();
59
- const [url, setUrl] = useState2();
60
- const urlRef = useRef2(null);
61
- useEffect2(() => {
62
- const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);
63
- task?.wait((blob) => {
53
+ const [url, setUrl] = useState();
54
+ const urlRef = useRef(null);
55
+ useEffect(() => {
56
+ const task = thumbs == null ? void 0 : thumbs.renderThumb(meta.pageIndex, window.devicePixelRatio);
57
+ task == null ? void 0 : task.wait((blob) => {
64
58
  const objectUrl = URL.createObjectURL(blob);
65
59
  urlRef.current = objectUrl;
66
60
  setUrl(objectUrl);
@@ -70,7 +64,7 @@ function ThumbImg({ meta, style, ...props }) {
70
64
  URL.revokeObjectURL(urlRef.current);
71
65
  urlRef.current = null;
72
66
  } else {
73
- task?.abort({
67
+ task == null ? void 0 : task.abort({
74
68
  code: PdfErrorCode.Cancelled,
75
69
  message: "canceled render task"
76
70
  });
@@ -83,7 +77,7 @@ function ThumbImg({ meta, style, ...props }) {
83
77
  urlRef.current = null;
84
78
  }
85
79
  };
86
- return url ? /* @__PURE__ */ jsx2("img", { src: url, onLoad: handleImageLoad, style, ...props }) : null;
80
+ return url ? /* @__PURE__ */ jsx("img", { src: url, onLoad: handleImageLoad, style, ...props }) : null;
87
81
  }
88
82
  export {
89
83
  ThumbImg,
@@ -91,4 +85,4 @@ export {
91
85
  useThumbnailCapability,
92
86
  useThumbnailPlugin
93
87
  };
94
- //# sourceMappingURL=index.js.map
88
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/preact/hooks/use-thumbnail.ts","../../src/preact/components/thumbnails-pane.tsx","../../src/preact/components/thumbnail-img.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/preact';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","/** @jsxImportSource preact */\nimport { ComponentChildren, JSX } from 'preact';\nimport { useEffect, useRef, useState } from 'preact/hooks';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {\n style?: JSX.CSSProperties;\n children: (m: ThumbMeta) => ComponentChildren;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n","/** @jsxImportSource preact */\nimport { ComponentChildren, Fragment, JSX } from 'preact';\nimport { useEffect, useState, useRef } from 'preact/hooks';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<JSX.HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: JSX.CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n"],"mappings":"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","names":["window","useEffect","useState","useRef","jsx","useState","useRef","useEffect"]}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-thumbnail.ts","../../src/shared/components/thumbnails-pane.tsx","../../src/shared/components/thumbnail-img.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","import { useEffect, useRef, useState, HTMLAttributes, CSSProperties, ReactNode } from '@framework';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {\n style?: CSSProperties;\n children: (m: ThumbMeta) => ReactNode;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n","import { useEffect, useState, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n"],"names":["window"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { Fragment, useEffect, useRef, useState, useCallback, useMemo } from 'react';
2
+ export type { ReactNode, HTMLAttributes, CSSProperties } from 'react';
@@ -0,0 +1 @@
1
+ export * from '@embedpdf/core/react';
@@ -1,124 +1,2 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/react/index.ts
21
- var react_exports = {};
22
- __export(react_exports, {
23
- ThumbImg: () => ThumbImg,
24
- ThumbnailsPane: () => ThumbnailsPane,
25
- useThumbnailCapability: () => useThumbnailCapability,
26
- useThumbnailPlugin: () => useThumbnailPlugin
27
- });
28
- module.exports = __toCommonJS(react_exports);
29
-
30
- // src/react/hooks/use-thumbnail.ts
31
- var import_react = require("@embedpdf/core/react");
32
- var import_plugin_thumbnail = require("@embedpdf/plugin-thumbnail");
33
- var useThumbnailPlugin = () => (0, import_react.usePlugin)(import_plugin_thumbnail.ThumbnailPlugin.id);
34
- var useThumbnailCapability = () => (0, import_react.useCapability)(import_plugin_thumbnail.ThumbnailPlugin.id);
35
-
36
- // src/react/components/thumbnails-pane.tsx
37
- var import_react2 = require("react");
38
- var import_jsx_runtime = require("react/jsx-runtime");
39
- function ThumbnailsPane({
40
- style,
41
- selectedPage,
42
- scrollOptions = { behavior: "smooth", block: "nearest", inline: "nearest" },
43
- ...props
44
- }) {
45
- const { provides: thumbs } = useThumbnailCapability();
46
- const viewportRef = (0, import_react2.useRef)(null);
47
- const [window2, setWindow] = (0, import_react2.useState)(null);
48
- (0, import_react2.useEffect)(() => thumbs?.onWindow(setWindow), [thumbs]);
49
- (0, import_react2.useEffect)(() => {
50
- const vp = viewportRef.current;
51
- if (!vp) return;
52
- const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);
53
- vp.addEventListener("scroll", onScroll);
54
- return () => vp.removeEventListener("scroll", onScroll);
55
- }, [thumbs]);
56
- (0, import_react2.useEffect)(() => {
57
- const vp = viewportRef.current;
58
- if (!vp || !thumbs) return;
59
- if (window2?.items.length === 0) {
60
- thumbs.setViewport(vp.scrollTop, vp.clientHeight);
61
- }
62
- }, [window2, thumbs]);
63
- (0, import_react2.useEffect)(() => {
64
- if (!selectedPage || !window2) return;
65
- const item = window2.items.find((it) => it.pageIndex + 1 === selectedPage);
66
- if (!item) return;
67
- const vp = viewportRef.current;
68
- if (!vp) return;
69
- const margin = 8;
70
- if (item.top < vp.scrollTop + margin) {
71
- vp.scrollTo({ top: item.top, ...scrollOptions });
72
- } else if (item.top + item.wrapperHeight + item.labelHeight > vp.scrollTop + vp.clientHeight - margin) {
73
- vp.scrollTo({
74
- top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,
75
- ...scrollOptions
76
- });
77
- }
78
- }, [selectedPage, window2, scrollOptions]);
79
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: viewportRef, style: { overflowY: "auto", position: "relative", ...style }, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: window2?.totalHeight ?? 0, position: "relative" }, children: window2?.items.map((m) => props.children(m)) }) });
80
- }
81
-
82
- // src/react/components/thumbnail-img.tsx
83
- var import_react3 = require("react");
84
- var import_models = require("@embedpdf/models");
85
- var import_jsx_runtime2 = require("react/jsx-runtime");
86
- function ThumbImg({ meta, style, ...props }) {
87
- const { provides: thumbs } = useThumbnailCapability();
88
- const [url, setUrl] = (0, import_react3.useState)();
89
- const urlRef = (0, import_react3.useRef)(null);
90
- (0, import_react3.useEffect)(() => {
91
- const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);
92
- task?.wait((blob) => {
93
- const objectUrl = URL.createObjectURL(blob);
94
- urlRef.current = objectUrl;
95
- setUrl(objectUrl);
96
- }, import_models.ignore);
97
- return () => {
98
- if (urlRef.current) {
99
- URL.revokeObjectURL(urlRef.current);
100
- urlRef.current = null;
101
- } else {
102
- task?.abort({
103
- code: import_models.PdfErrorCode.Cancelled,
104
- message: "canceled render task"
105
- });
106
- }
107
- };
108
- }, [meta.pageIndex]);
109
- const handleImageLoad = () => {
110
- if (urlRef.current) {
111
- URL.revokeObjectURL(urlRef.current);
112
- urlRef.current = null;
113
- }
114
- };
115
- return url ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: url, onLoad: handleImageLoad, style, ...props }) : null;
116
- }
117
- // Annotate the CommonJS export names for ESM import in node:
118
- 0 && (module.exports = {
119
- ThumbImg,
120
- ThumbnailsPane,
121
- useThumbnailCapability,
122
- useThumbnailPlugin
123
- });
124
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-thumbnail"),r=require("react/jsx-runtime"),n=require("react"),l=require("@embedpdf/models"),i=()=>e.useCapability(t.ThumbnailPlugin.id);exports.ThumbImg=function({meta:e,style:t,...o}){const{provides:s}=i(),[u,c]=n.useState(),a=n.useRef(null);return n.useEffect((()=>{const t=null==s?void 0:s.renderThumb(e.pageIndex,window.devicePixelRatio);return null==t||t.wait((e=>{const t=URL.createObjectURL(e);a.current=t,c(t)}),l.ignore),()=>{a.current?(URL.revokeObjectURL(a.current),a.current=null):null==t||t.abort({code:l.PdfErrorCode.Cancelled,message:"canceled render task"})}}),[e.pageIndex]),u?r.jsx("img",{src:u,onLoad:()=>{a.current&&(URL.revokeObjectURL(a.current),a.current=null)},style:t,...o}):null},exports.ThumbnailsPane=function({style:e,selectedPage:t,scrollOptions:l={behavior:"smooth",block:"nearest",inline:"nearest"},...o}){const{provides:s}=i(),u=n.useRef(null),[c,a]=n.useState(null);return n.useEffect((()=>null==s?void 0:s.onWindow(a)),[s]),n.useEffect((()=>{const e=u.current;if(!e)return;const t=()=>null==s?void 0:s.setViewport(e.scrollTop,e.clientHeight);return e.addEventListener("scroll",t),()=>e.removeEventListener("scroll",t)}),[s]),n.useEffect((()=>{const e=u.current;e&&s&&0===(null==c?void 0:c.items.length)&&s.setViewport(e.scrollTop,e.clientHeight)}),[c,s]),n.useEffect((()=>{if(!t||!c)return;const e=c.items.find((e=>e.pageIndex+1===t));if(!e)return;const r=u.current;if(!r)return;e.top<r.scrollTop+8?r.scrollTo({top:e.top,...l}):e.top+e.wrapperHeight+e.labelHeight>r.scrollTop+r.clientHeight-8&&r.scrollTo({top:e.top+e.wrapperHeight+e.labelHeight-r.clientHeight,...l})}),[t,c,l]),r.jsx("div",{ref:u,style:{overflowY:"auto",position:"relative",...e},...o,children:r.jsx("div",{style:{height:(null==c?void 0:c.totalHeight)??0,position:"relative"},children:null==c?void 0:c.items.map((e=>o.children(e)))})})},exports.useThumbnailCapability=i,exports.useThumbnailPlugin=()=>e.usePlugin(t.ThumbnailPlugin.id);
2
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/index.ts","../../src/react/hooks/use-thumbnail.ts","../../src/react/components/thumbnails-pane.tsx","../../src/react/components/thumbnail-img.tsx"],"sourcesContent":["export * from './hooks';\nexport * from './components';\n","import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","import { useEffect, useRef, useState } from 'react';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {\n style?: React.CSSProperties;\n children: (m: ThumbMeta) => React.ReactNode;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n","import { useEffect, useState, useRef } from 'react';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<React.HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: React.CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n"],"mappings":"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","names":["import_react","window","import_react","import_jsx_runtime"]}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-thumbnail.ts","../../src/shared/components/thumbnail-img.tsx","../../src/shared/components/thumbnails-pane.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","import { useEffect, useState, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n","import { useEffect, useRef, useState, HTMLAttributes, CSSProperties, ReactNode } from '@framework';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {\n style?: CSSProperties;\n children: (m: ThumbMeta) => ReactNode;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n"],"names":["useThumbnailCapability","useCapability","ThumbnailPlugin","id","meta","style","props","provides","thumbs","url","setUrl","useState","urlRef","useRef","useEffect","task","renderThumb","pageIndex","window","devicePixelRatio","wait","blob","objectUrl","URL","createObjectURL","current","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","jsx","src","onLoad","selectedPage","scrollOptions","behavior","block","inline","viewportRef","setWindow","onWindow","vp","onScroll","setViewport","scrollTop","clientHeight","addEventListener","removeEventListener","items","length","item","find","it","top","scrollTo","wrapperHeight","labelHeight","ref","overflowY","position","children","height","totalHeight","map","m","usePlugin"],"mappings":"gPAIaA,EAAyB,IAAMC,gBAA+BC,EAAAA,gBAAgBC,qBCMpF,UAAkBC,KAAEA,EAAAC,MAAMA,KAAUC,IACzC,MAAQC,SAAUC,GAAWR,KACtBS,EAAKC,GAAUC,aAChBC,EAASC,SAAsB,MA8B9B,OA5BPC,EAAAA,WAAU,KACR,MAAMC,EAAO,MAAAP,OAAA,EAAAA,EAAQQ,YAAYZ,EAAKa,UAAWC,OAAOC,kBAOxD,OANM,MAAAJ,GAAAA,EAAAK,MAAMC,IACJ,MAAAC,EAAYC,IAAIC,gBAAgBH,GACtCT,EAAOa,QAAUH,EACjBZ,EAAOY,EAAS,GACfI,UAEI,KACDd,EAAOa,SACLF,IAAAI,gBAAgBf,EAAOa,SAC3Bb,EAAOa,QAAU,MAEjB,MAAAV,GAAAA,EAAMa,MAAM,CACVC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,wBACV,CAEL,GACC,CAAC5B,EAAKa,YASFR,EAAOwB,EAAAA,IAAA,MAAA,CAAIC,IAAKzB,EAAK0B,OAPJ,KAClBvB,EAAOa,UACLF,IAAAI,gBAAgBf,EAAOa,SAC3Bb,EAAOa,QAAU,KAAA,EAIgCpB,WAAkBC,IAAY,IACrF,yBCjCO,UAAwBD,MAC7BA,EAAA+B,aACAA,EAAAC,cACAA,EAAgB,CAAEC,SAAU,SAAUC,MAAO,UAAWC,OAAQ,cAC7DlC,IAEH,MAAQC,SAAUC,GAAWR,IACvByC,EAAc5B,SAAuB,OAEpCK,EAAQwB,GAAa/B,EAAAA,SAA6B,aAGzDG,EAAAA,WAAU,IAAM,MAAAN,OAAA,EAAAA,EAAQmC,SAASD,IAAY,CAAClC,IAG9CM,EAAAA,WAAU,KACR,MAAM8B,EAAKH,EAAYhB,QACvB,IAAKmB,EAAI,OACT,MAAMC,EAAW,IAAM,MAAArC,OAAA,EAAAA,EAAQsC,YAAYF,EAAGG,UAAWH,EAAGI,cAE5D,OADGJ,EAAAK,iBAAiB,SAAUJ,GACvB,IAAMD,EAAGM,oBAAoB,SAAUL,EAAQ,GACrD,CAACrC,IAGJM,EAAAA,WAAU,KACR,MAAM8B,EAAKH,EAAYhB,QAClBmB,GAAOpC,GAEiB,KAAzB,MAAAU,OAAA,EAAAA,EAAQiC,MAAMC,SAChB5C,EAAOsC,YAAYF,EAAGG,UAAWH,EAAGI,aAAY,GAEjD,CAAC9B,EAAQV,IAGZM,EAAAA,WAAU,KACJ,IAACsB,IAAiBlB,EAAQ,OAExB,MAAAmC,EAAOnC,EAAOiC,MAAMG,MAAMC,GAAOA,EAAGtC,UAAY,IAAMmB,IAC5D,IAAKiB,EAAM,OAEX,MAAMT,EAAKH,EAAYhB,QACvB,IAAKmB,EAAI,OAILS,EAAKG,IAAMZ,EAAGG,UADH,EAEbH,EAAGa,SAAS,CAAED,IAAKH,EAAKG,OAAQnB,IAEhCgB,EAAKG,IAAMH,EAAKK,cAAgBL,EAAKM,YACrCf,EAAGG,UAAYH,EAAGI,aALL,GAObJ,EAAGa,SAAS,CACVD,IAAKH,EAAKG,IAAMH,EAAKK,cAAgBL,EAAKM,YAAcf,EAAGI,gBACxDX,GACJ,GAEF,CAACD,EAAclB,EAAQmB,UAGvB,MAAI,CAAAuB,IAAKnB,EAAapC,MAAO,CAAEwD,UAAW,OAAQC,SAAU,cAAezD,MAAaC,EAEvFyD,eAAC,MAAI,CAAA1D,MAAO,CAAE2D,QAAQ,MAAA9C,SAAAA,EAAQ+C,cAAe,EAAGH,SAAU,YACvDC,SAAQ,MAAA7C,OAAA,EAAAA,EAAAiC,MAAMe,KAAKC,GAAM7D,EAAMyD,SAASI,QAIjD,8DF1EkC,IAAMC,YAA2BlE,EAAAA,gBAAgBC"}
@@ -1,30 +1 @@
1
- import * as _embedpdf_plugin_thumbnail from '@embedpdf/plugin-thumbnail';
2
- import { ThumbnailPlugin, ThumbMeta } from '@embedpdf/plugin-thumbnail';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
4
-
5
- declare const useThumbnailPlugin: () => {
6
- plugin: ThumbnailPlugin | null;
7
- isLoading: boolean;
8
- ready: Promise<void>;
9
- };
10
- declare const useThumbnailCapability: () => {
11
- provides: Readonly<_embedpdf_plugin_thumbnail.ThumbnailCapability> | null;
12
- isLoading: boolean;
13
- ready: Promise<void>;
14
- };
15
-
16
- type ThumbnailsProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {
17
- style?: React.CSSProperties;
18
- children: (m: ThumbMeta) => React.ReactNode;
19
- selectedPage?: number;
20
- scrollOptions?: ScrollIntoViewOptions;
21
- };
22
- declare function ThumbnailsPane({ style, selectedPage, scrollOptions, ...props }: ThumbnailsProps): react_jsx_runtime.JSX.Element;
23
-
24
- type ThumbnailImgProps = Omit<React.HTMLAttributes<HTMLImageElement>, 'style'> & {
25
- style?: React.CSSProperties;
26
- meta: ThumbMeta;
27
- };
28
- declare function ThumbImg({ meta, style, ...props }: ThumbnailImgProps): react_jsx_runtime.JSX.Element | null;
29
-
30
- export { ThumbImg, ThumbnailsPane, useThumbnailCapability, useThumbnailPlugin };
1
+ export * from '../shared-react';
@@ -1,12 +1,10 @@
1
- // src/react/hooks/use-thumbnail.ts
2
- import { useCapability, usePlugin } from "@embedpdf/core/react";
1
+ import { usePlugin, useCapability } from "@embedpdf/core/react";
3
2
  import { ThumbnailPlugin } from "@embedpdf/plugin-thumbnail";
4
- var useThumbnailPlugin = () => usePlugin(ThumbnailPlugin.id);
5
- var useThumbnailCapability = () => useCapability(ThumbnailPlugin.id);
6
-
7
- // src/react/components/thumbnails-pane.tsx
8
- import { useEffect, useRef, useState } from "react";
9
3
  import { jsx } from "react/jsx-runtime";
4
+ import { useRef, useState, useEffect } from "react";
5
+ import { ignore, PdfErrorCode } from "@embedpdf/models";
6
+ const useThumbnailPlugin = () => usePlugin(ThumbnailPlugin.id);
7
+ const useThumbnailCapability = () => useCapability(ThumbnailPlugin.id);
10
8
  function ThumbnailsPane({
11
9
  style,
12
10
  selectedPage,
@@ -16,18 +14,18 @@ function ThumbnailsPane({
16
14
  const { provides: thumbs } = useThumbnailCapability();
17
15
  const viewportRef = useRef(null);
18
16
  const [window2, setWindow] = useState(null);
19
- useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);
17
+ useEffect(() => thumbs == null ? void 0 : thumbs.onWindow(setWindow), [thumbs]);
20
18
  useEffect(() => {
21
19
  const vp = viewportRef.current;
22
20
  if (!vp) return;
23
- const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);
21
+ const onScroll = () => thumbs == null ? void 0 : thumbs.setViewport(vp.scrollTop, vp.clientHeight);
24
22
  vp.addEventListener("scroll", onScroll);
25
23
  return () => vp.removeEventListener("scroll", onScroll);
26
24
  }, [thumbs]);
27
25
  useEffect(() => {
28
26
  const vp = viewportRef.current;
29
27
  if (!vp || !thumbs) return;
30
- if (window2?.items.length === 0) {
28
+ if ((window2 == null ? void 0 : window2.items.length) === 0) {
31
29
  thumbs.setViewport(vp.scrollTop, vp.clientHeight);
32
30
  }
33
31
  }, [window2, thumbs]);
@@ -47,20 +45,15 @@ function ThumbnailsPane({
47
45
  });
48
46
  }
49
47
  }, [selectedPage, window2, scrollOptions]);
50
- return /* @__PURE__ */ jsx("div", { ref: viewportRef, style: { overflowY: "auto", position: "relative", ...style }, ...props, children: /* @__PURE__ */ jsx("div", { style: { height: window2?.totalHeight ?? 0, position: "relative" }, children: window2?.items.map((m) => props.children(m)) }) });
48
+ return /* @__PURE__ */ jsx("div", { ref: viewportRef, style: { overflowY: "auto", position: "relative", ...style }, ...props, children: /* @__PURE__ */ jsx("div", { style: { height: (window2 == null ? void 0 : window2.totalHeight) ?? 0, position: "relative" }, children: window2 == null ? void 0 : window2.items.map((m) => props.children(m)) }) });
51
49
  }
52
-
53
- // src/react/components/thumbnail-img.tsx
54
- import { useEffect as useEffect2, useState as useState2, useRef as useRef2 } from "react";
55
- import { ignore, PdfErrorCode } from "@embedpdf/models";
56
- import { jsx as jsx2 } from "react/jsx-runtime";
57
50
  function ThumbImg({ meta, style, ...props }) {
58
51
  const { provides: thumbs } = useThumbnailCapability();
59
- const [url, setUrl] = useState2();
60
- const urlRef = useRef2(null);
61
- useEffect2(() => {
62
- const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);
63
- task?.wait((blob) => {
52
+ const [url, setUrl] = useState();
53
+ const urlRef = useRef(null);
54
+ useEffect(() => {
55
+ const task = thumbs == null ? void 0 : thumbs.renderThumb(meta.pageIndex, window.devicePixelRatio);
56
+ task == null ? void 0 : task.wait((blob) => {
64
57
  const objectUrl = URL.createObjectURL(blob);
65
58
  urlRef.current = objectUrl;
66
59
  setUrl(objectUrl);
@@ -70,7 +63,7 @@ function ThumbImg({ meta, style, ...props }) {
70
63
  URL.revokeObjectURL(urlRef.current);
71
64
  urlRef.current = null;
72
65
  } else {
73
- task?.abort({
66
+ task == null ? void 0 : task.abort({
74
67
  code: PdfErrorCode.Cancelled,
75
68
  message: "canceled render task"
76
69
  });
@@ -83,7 +76,7 @@ function ThumbImg({ meta, style, ...props }) {
83
76
  urlRef.current = null;
84
77
  }
85
78
  };
86
- return url ? /* @__PURE__ */ jsx2("img", { src: url, onLoad: handleImageLoad, style, ...props }) : null;
79
+ return url ? /* @__PURE__ */ jsx("img", { src: url, onLoad: handleImageLoad, style, ...props }) : null;
87
80
  }
88
81
  export {
89
82
  ThumbImg,
@@ -91,4 +84,4 @@ export {
91
84
  useThumbnailCapability,
92
85
  useThumbnailPlugin
93
86
  };
94
- //# sourceMappingURL=index.js.map
87
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/hooks/use-thumbnail.ts","../../src/react/components/thumbnails-pane.tsx","../../src/react/components/thumbnail-img.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","import { useEffect, useRef, useState } from 'react';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {\n style?: React.CSSProperties;\n children: (m: ThumbMeta) => React.ReactNode;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n","import { useEffect, useState, useRef } from 'react';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<React.HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: React.CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n"],"mappings":";AAAA,SAAS,eAAe,iBAAiB;AACzC,SAAS,uBAAuB;AAEzB,IAAM,qBAAqB,MAAM,UAA2B,gBAAgB,EAAE;AAC9E,IAAM,yBAAyB,MAAM,cAA+B,gBAAgB,EAAE;;;ACJ7F,SAAS,WAAW,QAAQ,gBAAgB;AAwEtC;AA7DC,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,gBAAgB,EAAE,UAAU,UAAU,OAAO,WAAW,QAAQ,UAAU;AAAA,EAC1E,GAAG;AACL,GAAoB;AAClB,QAAM,EAAE,UAAU,OAAO,IAAI,uBAAuB;AACpD,QAAM,cAAc,OAAuB,IAAI;AAE/C,QAAM,CAACA,SAAQ,SAAS,IAAI,SAA6B,IAAI;AAG7D,YAAU,MAAM,QAAQ,SAAS,SAAS,GAAG,CAAC,MAAM,CAAC;AAGrD,YAAU,MAAM;AACd,UAAM,KAAK,YAAY;AACvB,QAAI,CAAC,GAAI;AACT,UAAM,WAAW,MAAM,QAAQ,YAAY,GAAG,WAAW,GAAG,YAAY;AACxE,OAAG,iBAAiB,UAAU,QAAQ;AACtC,WAAO,MAAM,GAAG,oBAAoB,UAAU,QAAQ;AAAA,EACxD,GAAG,CAAC,MAAM,CAAC;AAGX,YAAU,MAAM;AACd,UAAM,KAAK,YAAY;AACvB,QAAI,CAAC,MAAM,CAAC,OAAQ;AAEpB,QAAIA,SAAQ,MAAM,WAAW,GAAG;AAC9B,aAAO,YAAY,GAAG,WAAW,GAAG,YAAY;AAAA,IAClD;AAAA,EACF,GAAG,CAACA,SAAQ,MAAM,CAAC;AAGnB,YAAU,MAAM;AACd,QAAI,CAAC,gBAAgB,CAACA,QAAQ;AAE9B,UAAM,OAAOA,QAAO,MAAM,KAAK,CAAC,OAAO,GAAG,YAAY,MAAM,YAAY;AACxE,QAAI,CAAC,KAAM;AAEX,UAAM,KAAK,YAAY;AACvB,QAAI,CAAC,GAAI;AAGT,UAAM,SAAS;AACf,QAAI,KAAK,MAAM,GAAG,YAAY,QAAQ;AACpC,SAAG,SAAS,EAAE,KAAK,KAAK,KAAK,GAAG,cAAc,CAAC;AAAA,IACjD,WACE,KAAK,MAAM,KAAK,gBAAgB,KAAK,cACrC,GAAG,YAAY,GAAG,eAAe,QACjC;AACA,SAAG,SAAS;AAAA,QACV,KAAK,KAAK,MAAM,KAAK,gBAAgB,KAAK,cAAc,GAAG;AAAA,QAC3D,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,cAAcA,SAAQ,aAAa,CAAC;AAExC,SACE,oBAAC,SAAI,KAAK,aAAa,OAAO,EAAE,WAAW,QAAQ,UAAU,YAAY,GAAG,MAAM,GAAI,GAAG,OAEvF,8BAAC,SAAI,OAAO,EAAE,QAAQA,SAAQ,eAAe,GAAG,UAAU,WAAW,GAClE,UAAAA,SAAQ,MAAM,IAAI,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC,GAC7C,GACF;AAEJ;;;AC7EA,SAAS,aAAAC,YAAW,YAAAC,WAAU,UAAAC,eAAc;AAE5C,SAAS,QAAQ,oBAAoB;AAyCtB,gBAAAC,YAAA;AAjCR,SAAS,SAAS,EAAE,MAAM,OAAO,GAAG,MAAM,GAAsB;AACrE,QAAM,EAAE,UAAU,OAAO,IAAI,uBAAuB;AACpD,QAAM,CAAC,KAAK,MAAM,IAAIC,UAAiB;AACvC,QAAM,SAASC,QAAsB,IAAI;AAEzC,EAAAC,WAAU,MAAM;AACd,UAAM,OAAO,QAAQ,YAAY,KAAK,WAAW,OAAO,gBAAgB;AACxE,UAAM,KAAK,CAAC,SAAS;AACnB,YAAM,YAAY,IAAI,gBAAgB,IAAI;AAC1C,aAAO,UAAU;AACjB,aAAO,SAAS;AAAA,IAClB,GAAG,MAAM;AAET,WAAO,MAAM;AACX,UAAI,OAAO,SAAS;AAClB,YAAI,gBAAgB,OAAO,OAAO;AAClC,eAAO,UAAU;AAAA,MACnB,OAAO;AACL,cAAM,MAAM;AAAA,UACV,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAK,SAAS,CAAC;AAEnB,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,SAAS;AAClB,UAAI,gBAAgB,OAAO,OAAO;AAClC,aAAO,UAAU;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,MAAM,gBAAAH,KAAC,SAAI,KAAK,KAAK,QAAQ,iBAAiB,OAAe,GAAG,OAAO,IAAK;AACrF;","names":["window","useEffect","useState","useRef","jsx","useState","useRef","useEffect"]}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-thumbnail.ts","../../src/shared/components/thumbnails-pane.tsx","../../src/shared/components/thumbnail-img.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ThumbnailPlugin } from '@embedpdf/plugin-thumbnail';\n\nexport const useThumbnailPlugin = () => usePlugin<ThumbnailPlugin>(ThumbnailPlugin.id);\nexport const useThumbnailCapability = () => useCapability<ThumbnailPlugin>(ThumbnailPlugin.id);\n","import { useEffect, useRef, useState, HTMLAttributes, CSSProperties, ReactNode } from '@framework';\nimport { ThumbMeta, WindowState } from '@embedpdf/plugin-thumbnail';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailsProps = Omit<HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {\n style?: CSSProperties;\n children: (m: ThumbMeta) => ReactNode;\n selectedPage?: number;\n scrollOptions?: ScrollIntoViewOptions;\n};\n\nexport function ThumbnailsPane({\n style,\n selectedPage,\n scrollOptions = { behavior: 'smooth', block: 'nearest', inline: 'nearest' },\n ...props\n}: ThumbnailsProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const viewportRef = useRef<HTMLDivElement>(null);\n\n const [window, setWindow] = useState<WindowState | null>(null);\n\n /* 1️⃣ subscribe once to window updates */\n useEffect(() => thumbs?.onWindow(setWindow), [thumbs]);\n\n /* 2️⃣ keep plugin in sync while the user scrolls */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const onScroll = () => thumbs?.setViewport(vp.scrollTop, vp.clientHeight);\n vp.addEventListener('scroll', onScroll);\n return () => vp.removeEventListener('scroll', onScroll);\n }, [thumbs]);\n\n /* 3️⃣ kick-start (or re-kick) after document change */\n useEffect(() => {\n const vp = viewportRef.current;\n if (!vp || !thumbs) return;\n\n if (window?.items.length === 0) {\n thumbs.setViewport(vp.scrollTop, vp.clientHeight);\n }\n }, [window, thumbs]);\n\n /* 4️⃣ whenever selectedPage or window changes, ensure it’s visible */\n useEffect(() => {\n if (!selectedPage || !window) return;\n\n const item = window.items.find((it) => it.pageIndex + 1 === selectedPage);\n if (!item) return; // not in current window yet → wait for next update\n\n const vp = viewportRef.current;\n if (!vp) return;\n\n // Scroll only if the item is above or below the viewport “padding” zone\n const margin = 8; // px\n if (item.top < vp.scrollTop + margin) {\n vp.scrollTo({ top: item.top, ...scrollOptions });\n } else if (\n item.top + item.wrapperHeight + item.labelHeight >\n vp.scrollTop + vp.clientHeight - margin\n ) {\n vp.scrollTo({\n top: item.top + item.wrapperHeight + item.labelHeight - vp.clientHeight,\n ...scrollOptions,\n });\n }\n }, [selectedPage, window, scrollOptions]);\n\n return (\n <div ref={viewportRef} style={{ overflowY: 'auto', position: 'relative', ...style }} {...props}>\n {/* spacer keeps correct scroll height even before first window arrives */}\n <div style={{ height: window?.totalHeight ?? 0, position: 'relative' }}>\n {window?.items.map((m) => props.children(m))}\n </div>\n </div>\n );\n}\n","import { useEffect, useState, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { ThumbMeta } from '@embedpdf/plugin-thumbnail';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useThumbnailCapability } from '../hooks';\n\ntype ThumbnailImgProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n style?: CSSProperties;\n meta: ThumbMeta;\n};\n\nexport function ThumbImg({ meta, style, ...props }: ThumbnailImgProps) {\n const { provides: thumbs } = useThumbnailCapability();\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n useEffect(() => {\n const task = thumbs?.renderThumb(meta.pageIndex, window.devicePixelRatio);\n task?.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task?.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [meta.pageIndex]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return url ? <img src={url} onLoad={handleImageLoad} style={style} {...props} /> : null;\n}\n"],"names":["window"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './thumbnails-pane';
2
+ export * from './thumbnail-img';
@@ -0,0 +1,8 @@
1
+ import { HTMLAttributes, CSSProperties } from '../../preact/adapter.ts';
2
+ import { ThumbMeta } from '../../lib/index.ts';
3
+ type ThumbnailImgProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {
4
+ style?: CSSProperties;
5
+ meta: ThumbMeta;
6
+ };
7
+ export declare function ThumbImg({ meta, style, ...props }: ThumbnailImgProps): import("preact").JSX.Element | null;
8
+ export {};
@@ -0,0 +1,10 @@
1
+ import { HTMLAttributes, CSSProperties, ReactNode } from '../../preact/adapter.ts';
2
+ import { ThumbMeta } from '../../lib/index.ts';
3
+ type ThumbnailsProps = Omit<HTMLAttributes<HTMLDivElement>, 'style' | 'children'> & {
4
+ style?: CSSProperties;
5
+ children: (m: ThumbMeta) => ReactNode;
6
+ selectedPage?: number;
7
+ scrollOptions?: ScrollIntoViewOptions;
8
+ };
9
+ export declare function ThumbnailsPane({ style, selectedPage, scrollOptions, ...props }: ThumbnailsProps): import("preact").JSX.Element;
10
+ export {};
@@ -0,0 +1 @@
1
+ export * from './use-thumbnail';