@embedpdf/plugin-thumbnail 1.0.11 → 1.0.13

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
package/dist/index.cjs CHANGED
@@ -1,170 +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/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- THUMBNAIL_PLUGIN_ID: () => THUMBNAIL_PLUGIN_ID,
24
- ThumbnailPlugin: () => ThumbnailPlugin,
25
- ThumbnailPluginPackage: () => ThumbnailPluginPackage,
26
- manifest: () => manifest
27
- });
28
- module.exports = __toCommonJS(index_exports);
29
-
30
- // src/lib/manifest.ts
31
- var THUMBNAIL_PLUGIN_ID = "thumbnail";
32
- var manifest = {
33
- id: THUMBNAIL_PLUGIN_ID,
34
- name: "Thumbnail Plugin",
35
- version: "1.0.0",
36
- provides: ["thumbnail"],
37
- requires: ["render"],
38
- optional: [],
39
- defaultConfig: {
40
- enabled: true,
41
- width: 150,
42
- gap: 10,
43
- buffer: 3,
44
- labelHeight: 16
45
- }
46
- };
47
-
48
- // src/lib/thumbnail-plugin.ts
49
- var import_core = require("@embedpdf/core");
50
- var import_models = require("@embedpdf/models");
51
- var ThumbnailPlugin = class extends import_core.BasePlugin {
52
- constructor(id, registry, cfg) {
53
- super(id, registry);
54
- this.cfg = cfg;
55
- this.thumbs = [];
56
- this.window = null;
57
- this.emitWindow = (0, import_core.createBehaviorEmitter)();
58
- this.taskCache = /* @__PURE__ */ new Map();
59
- this.renderCapability = this.registry.getPlugin("render").provides();
60
- this.coreStore.onAction(import_core.SET_DOCUMENT, (_action, state) => {
61
- this.taskCache.clear();
62
- this.setWindowState(state);
63
- });
64
- }
65
- /* ------------ init ------------------------------------------------ */
66
- async initialize() {
67
- }
68
- setWindowState(state) {
69
- const core = state.core;
70
- if (!core.document) return;
71
- const W = this.cfg.width ?? 120;
72
- const L = this.cfg.labelHeight ?? 16;
73
- const GAP = this.cfg.gap ?? 8;
74
- let offset = 0;
75
- this.thumbs = core.document.pages.map((p) => {
76
- const ratio = p.size.height / p.size.width;
77
- const thumbH = Math.round(W * ratio);
78
- const wrapH = thumbH + L;
79
- const meta = {
80
- pageIndex: p.index,
81
- width: W,
82
- height: thumbH,
83
- wrapperHeight: wrapH,
84
- top: offset,
85
- labelHeight: L
86
- };
87
- offset += wrapH + GAP;
88
- return meta;
89
- });
90
- this.window = {
91
- start: -1,
92
- end: -1,
93
- items: [],
94
- totalHeight: offset - GAP
95
- // last item has no gap below
96
- };
97
- this.emitWindow.emit(this.window);
98
- }
99
- /* ------------ capability ----------------------------------------- */
100
- buildCapability() {
101
- return {
102
- onWindow: this.emitWindow.on,
103
- setViewport: (y, h) => this.updateWindow(y, h),
104
- renderThumb: (idx, dpr) => this.renderThumb(idx, dpr)
105
- };
106
- }
107
- /* ------------ windowing math ------------------------------------- */
108
- updateWindow(scrollY, viewportH) {
109
- const BUF = this.cfg.buffer ?? 3;
110
- let low = 0, high = this.thumbs.length - 1, first = 0;
111
- while (low <= high) {
112
- const mid = low + high >> 1;
113
- const m = this.thumbs[mid];
114
- if (m.top + m.wrapperHeight < scrollY) low = mid + 1;
115
- else {
116
- first = mid;
117
- high = mid - 1;
118
- }
119
- }
120
- let last = first;
121
- const limit = scrollY + viewportH;
122
- while (last + 1 < this.thumbs.length && this.thumbs[last].top < limit) last++;
123
- last = Math.min(this.thumbs.length - 1, last + BUF);
124
- const start = Math.max(0, first - BUF);
125
- if (this.window && start === this.window.start && last === this.window.end) return;
126
- this.window = {
127
- start,
128
- end: last,
129
- items: this.thumbs.slice(start, last + 1),
130
- totalHeight: this.window.totalHeight
131
- };
132
- this.emitWindow.emit(this.window);
133
- }
134
- /* ------------ thumbnail raster ----------------------------------- */
135
- renderThumb(idx, dpr) {
136
- if (this.taskCache.has(idx)) return this.taskCache.get(idx);
137
- const core = this.coreState.core;
138
- const page = core.document.pages[idx];
139
- const scale = (this.cfg.width ?? 120) / page.size.width;
140
- const task = this.renderCapability.renderPageRect({
141
- pageIndex: idx,
142
- rect: { origin: { x: 0, y: 0 }, size: page.size },
143
- scaleFactor: scale,
144
- dpr
145
- });
146
- this.taskCache.set(idx, task);
147
- task.wait(import_models.ignore, () => {
148
- this.taskCache.delete(idx);
149
- });
150
- return task;
151
- }
152
- };
153
- ThumbnailPlugin.id = "thumbnail";
154
-
155
- // src/lib/index.ts
156
- var ThumbnailPluginPackage = {
157
- manifest,
158
- create: (registry, _engine, config) => new ThumbnailPlugin(THUMBNAIL_PLUGIN_ID, registry, config),
159
- reducer: () => {
160
- },
161
- initialState: {}
162
- };
163
- // Annotate the CommonJS export names for ESM import in node:
164
- 0 && (module.exports = {
165
- THUMBNAIL_PLUGIN_ID,
166
- ThumbnailPlugin,
167
- ThumbnailPluginPackage,
168
- manifest
169
- });
170
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("@embedpdf/core"),e=require("@embedpdf/models"),i="thumbnail",s={id:i,name:"Thumbnail Plugin",version:"1.0.0",provides:["thumbnail"],requires:["render"],optional:[],defaultConfig:{enabled:!0,width:150,gap:10,buffer:3,labelHeight:16}},h=class extends t.BasePlugin{constructor(e,i,s){super(e,i),this.cfg=s,this.thumbs=[],this.window=null,this.emitWindow=t.createBehaviorEmitter(),this.taskCache=new Map,this.renderCapability=this.registry.getPlugin("render").provides(),this.coreStore.onAction(t.SET_DOCUMENT,((t,e)=>{this.taskCache.clear(),this.setWindowState(e)}))}async initialize(){}setWindowState(t){const e=t.core;if(!e.document)return;const i=this.cfg.width??120,s=this.cfg.labelHeight??16,h=this.cfg.gap??8;let n=0;this.thumbs=e.document.pages.map((t=>{const e=t.size.height/t.size.width,r=Math.round(i*e),a=r+s,o={pageIndex:t.index,width:i,height:r,wrapperHeight:a,top:n,labelHeight:s};return n+=a+h,o})),this.window={start:-1,end:-1,items:[],totalHeight:n-h},this.emitWindow.emit(this.window)}buildCapability(){return{onWindow:this.emitWindow.on,setViewport:(t,e)=>this.updateWindow(t,e),renderThumb:(t,e)=>this.renderThumb(t,e)}}updateWindow(t,e){const i=this.cfg.buffer??3;let s=0,h=this.thumbs.length-1,n=0;for(;s<=h;){const e=s+h>>1,i=this.thumbs[e];i.top+i.wrapperHeight<t?s=e+1:(n=e,h=e-1)}let r=n;const a=t+e;for(;r+1<this.thumbs.length&&this.thumbs[r].top<a;)r++;r=Math.min(this.thumbs.length-1,r+i);const o=Math.max(0,n-i);this.window&&o===this.window.start&&r===this.window.end||(this.window={start:o,end:r,items:this.thumbs.slice(o,r+1),totalHeight:this.window.totalHeight},this.emitWindow.emit(this.window))}renderThumb(t,i){if(this.taskCache.has(t))return this.taskCache.get(t);const s=this.coreState.core.document.pages[t],h=(this.cfg.width??120)/s.size.width,n=this.renderCapability.renderPageRect({pageIndex:t,rect:{origin:{x:0,y:0},size:s.size},scaleFactor:h,dpr:i});return this.taskCache.set(t,n),n.wait(e.ignore,(()=>{this.taskCache.delete(t)})),n}};h.id="thumbnail";let n=h;const r={manifest:s,create:(t,e,s)=>new n(i,t,s),reducer:()=>{},initialState:{}};exports.THUMBNAIL_PLUGIN_ID=i,exports.ThumbnailPlugin=n,exports.ThumbnailPluginPackage=r,exports.manifest=s;
2
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/manifest.ts","../src/lib/thumbnail-plugin.ts","../src/lib/index.ts"],"sourcesContent":["export * from './lib';\n","import { PluginManifest } from '@embedpdf/core';\nimport { ThumbnailPluginConfig } from './types';\n\nexport const THUMBNAIL_PLUGIN_ID = 'thumbnail';\n\nexport const manifest: PluginManifest<ThumbnailPluginConfig> = {\n id: THUMBNAIL_PLUGIN_ID,\n name: 'Thumbnail Plugin',\n version: '1.0.0',\n provides: ['thumbnail'],\n requires: ['render'],\n optional: [],\n defaultConfig: {\n enabled: true,\n width: 150,\n gap: 10,\n buffer: 3,\n labelHeight: 16,\n },\n};\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n PluginRegistry,\n SET_DOCUMENT,\n StoreState,\n} from '@embedpdf/core';\nimport { ThumbMeta, ThumbnailPluginConfig, WindowState } from './types';\nimport { ThumbnailCapability } from './types';\nimport { ignore, PdfErrorReason, Task } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\n\nexport class ThumbnailPlugin extends BasePlugin<ThumbnailPluginConfig, ThumbnailCapability> {\n static readonly id = 'thumbnail' as const;\n\n private renderCapability: RenderCapability;\n private thumbs: ThumbMeta[] = [];\n private window: WindowState | null = null;\n private readonly emitWindow = createBehaviorEmitter<WindowState>();\n private readonly taskCache = new Map<number, Task<Blob, PdfErrorReason>>();\n\n constructor(\n id: string,\n registry: PluginRegistry,\n private cfg: ThumbnailPluginConfig,\n ) {\n super(id, registry);\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n this.taskCache.clear();\n this.setWindowState(state);\n });\n }\n\n /* ------------ init ------------------------------------------------ */\n async initialize(): Promise<void> {}\n\n private setWindowState(state: StoreState<CoreState>) {\n const core = state.core;\n\n if (!core.document) return;\n\n const W = this.cfg.width ?? 120;\n const L = this.cfg.labelHeight ?? 16; // label\n const GAP = this.cfg.gap ?? 8;\n\n let offset = 0;\n this.thumbs = core.document.pages.map((p) => {\n const ratio = p.size.height / p.size.width;\n const thumbH = Math.round(W * ratio);\n const wrapH = thumbH + L; // no GAP here\n\n const meta: ThumbMeta = {\n pageIndex: p.index,\n width: W,\n height: thumbH,\n wrapperHeight: wrapH,\n top: offset,\n labelHeight: L,\n };\n offset += wrapH + GAP; // GAP added *after* wrapper\n return meta;\n });\n\n this.window = {\n start: -1,\n end: -1,\n items: [],\n totalHeight: offset - GAP, // last item has no gap below\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ capability ----------------------------------------- */\n protected buildCapability(): ThumbnailCapability {\n return {\n onWindow: this.emitWindow.on,\n setViewport: (y, h) => this.updateWindow(y, h),\n renderThumb: (idx, dpr) => this.renderThumb(idx, dpr),\n };\n }\n\n /* ------------ windowing math ------------------------------------- */\n private updateWindow(scrollY: number, viewportH: number) {\n const BUF = this.cfg.buffer ?? 3;\n\n /* -------- find first visible wrapper ---------- */\n let low = 0,\n high = this.thumbs.length - 1,\n first = 0;\n while (low <= high) {\n const mid = (low + high) >> 1;\n const m = this.thumbs[mid];\n if (m.top + m.wrapperHeight < scrollY) low = mid + 1;\n else {\n first = mid;\n high = mid - 1;\n }\n }\n\n /* -------- find last visible + buffer ---------- */\n let last = first;\n const limit = scrollY + viewportH;\n while (last + 1 < this.thumbs.length && this.thumbs[last].top < limit) last++;\n last = Math.min(this.thumbs.length - 1, last + BUF);\n\n const start = Math.max(0, first - BUF);\n if (this.window && start === this.window.start && last === this.window.end) return;\n\n this.window = {\n start,\n end: last,\n items: this.thumbs.slice(start, last + 1),\n totalHeight: this.window!.totalHeight,\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ thumbnail raster ----------------------------------- */\n private renderThumb(idx: number, dpr: number) {\n if (this.taskCache.has(idx)) return this.taskCache.get(idx)!;\n\n const core = this.coreState.core;\n const page = core.document!.pages[idx];\n const scale = (this.cfg.width ?? 120) / page.size.width;\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: idx,\n rect: { origin: { x: 0, y: 0 }, size: page.size },\n scaleFactor: scale,\n dpr,\n });\n\n this.taskCache.set(idx, task);\n\n task.wait(ignore, () => {\n this.taskCache.delete(idx);\n });\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, THUMBNAIL_PLUGIN_ID } from './manifest';\nimport { ThumbnailPluginConfig } from './types';\nimport { ThumbnailPlugin } from './thumbnail-plugin';\n\nexport const ThumbnailPluginPackage: PluginPackage<ThumbnailPlugin, ThumbnailPluginConfig> = {\n manifest,\n create: (registry, _engine, config) => new ThumbnailPlugin(THUMBNAIL_PLUGIN_ID, registry, config),\n reducer: () => {},\n initialState: {},\n};\n\nexport * from './thumbnail-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/thumbnail-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { ThumbnailPluginConfig } from './types';\n\nexport const THUMBNAIL_PLUGIN_ID = 'thumbnail';\n\nexport const manifest: PluginManifest<ThumbnailPluginConfig> = {\n id: THUMBNAIL_PLUGIN_ID,\n name: 'Thumbnail Plugin',\n version: '1.0.0',\n provides: ['thumbnail'],\n requires: ['render'],\n optional: [],\n defaultConfig: {\n enabled: true,\n width: 150,\n gap: 10,\n buffer: 3,\n labelHeight: 16,\n },\n};\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n PluginRegistry,\n SET_DOCUMENT,\n StoreState,\n} from '@embedpdf/core';\nimport { ThumbMeta, ThumbnailPluginConfig, WindowState } from './types';\nimport { ThumbnailCapability } from './types';\nimport { ignore, PdfErrorReason, Task } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\n\nexport class ThumbnailPlugin extends BasePlugin<ThumbnailPluginConfig, ThumbnailCapability> {\n static readonly id = 'thumbnail' as const;\n\n private renderCapability: RenderCapability;\n private thumbs: ThumbMeta[] = [];\n private window: WindowState | null = null;\n private readonly emitWindow = createBehaviorEmitter<WindowState>();\n private readonly taskCache = new Map<number, Task<Blob, PdfErrorReason>>();\n\n constructor(\n id: string,\n registry: PluginRegistry,\n private cfg: ThumbnailPluginConfig,\n ) {\n super(id, registry);\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n this.taskCache.clear();\n this.setWindowState(state);\n });\n }\n\n /* ------------ init ------------------------------------------------ */\n async initialize(): Promise<void> {}\n\n private setWindowState(state: StoreState<CoreState>) {\n const core = state.core;\n\n if (!core.document) return;\n\n const W = this.cfg.width ?? 120;\n const L = this.cfg.labelHeight ?? 16; // label\n const GAP = this.cfg.gap ?? 8;\n\n let offset = 0;\n this.thumbs = core.document.pages.map((p) => {\n const ratio = p.size.height / p.size.width;\n const thumbH = Math.round(W * ratio);\n const wrapH = thumbH + L; // no GAP here\n\n const meta: ThumbMeta = {\n pageIndex: p.index,\n width: W,\n height: thumbH,\n wrapperHeight: wrapH,\n top: offset,\n labelHeight: L,\n };\n offset += wrapH + GAP; // GAP added *after* wrapper\n return meta;\n });\n\n this.window = {\n start: -1,\n end: -1,\n items: [],\n totalHeight: offset - GAP, // last item has no gap below\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ capability ----------------------------------------- */\n protected buildCapability(): ThumbnailCapability {\n return {\n onWindow: this.emitWindow.on,\n setViewport: (y, h) => this.updateWindow(y, h),\n renderThumb: (idx, dpr) => this.renderThumb(idx, dpr),\n };\n }\n\n /* ------------ windowing math ------------------------------------- */\n private updateWindow(scrollY: number, viewportH: number) {\n const BUF = this.cfg.buffer ?? 3;\n\n /* -------- find first visible wrapper ---------- */\n let low = 0,\n high = this.thumbs.length - 1,\n first = 0;\n while (low <= high) {\n const mid = (low + high) >> 1;\n const m = this.thumbs[mid];\n if (m.top + m.wrapperHeight < scrollY) low = mid + 1;\n else {\n first = mid;\n high = mid - 1;\n }\n }\n\n /* -------- find last visible + buffer ---------- */\n let last = first;\n const limit = scrollY + viewportH;\n while (last + 1 < this.thumbs.length && this.thumbs[last].top < limit) last++;\n last = Math.min(this.thumbs.length - 1, last + BUF);\n\n const start = Math.max(0, first - BUF);\n if (this.window && start === this.window.start && last === this.window.end) return;\n\n this.window = {\n start,\n end: last,\n items: this.thumbs.slice(start, last + 1),\n totalHeight: this.window!.totalHeight,\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ thumbnail raster ----------------------------------- */\n private renderThumb(idx: number, dpr: number) {\n if (this.taskCache.has(idx)) return this.taskCache.get(idx)!;\n\n const core = this.coreState.core;\n const page = core.document!.pages[idx];\n const scale = (this.cfg.width ?? 120) / page.size.width;\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: idx,\n rect: { origin: { x: 0, y: 0 }, size: page.size },\n scaleFactor: scale,\n dpr,\n });\n\n this.taskCache.set(idx, task);\n\n task.wait(ignore, () => {\n this.taskCache.delete(idx);\n });\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, THUMBNAIL_PLUGIN_ID } from './manifest';\nimport { ThumbnailPluginConfig } from './types';\nimport { ThumbnailPlugin } from './thumbnail-plugin';\n\nexport const ThumbnailPluginPackage: PluginPackage<ThumbnailPlugin, ThumbnailPluginConfig> = {\n manifest,\n create: (registry, _engine, config) => new ThumbnailPlugin(THUMBNAIL_PLUGIN_ID, registry, config),\n reducer: () => {},\n initialState: {},\n};\n\nexport * from './thumbnail-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["THUMBNAIL_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","enabled","width","gap","buffer","labelHeight","_ThumbnailPlugin","BasePlugin","constructor","registry","cfg","super","this","thumbs","window","emitWindow","createBehaviorEmitter","taskCache","Map","renderCapability","getPlugin","coreStore","onAction","SET_DOCUMENT","_action","state","clear","setWindowState","initialize","core","document","W","L","GAP","offset","pages","map","p","ratio","size","height","thumbH","Math","round","wrapH","meta","pageIndex","index","wrapperHeight","top","start","end","items","totalHeight","emit","buildCapability","onWindow","on","setViewport","y","h","updateWindow","renderThumb","idx","dpr","scrollY","viewportH","BUF","low","high","length","first","mid","m","last","limit","min","max","slice","has","get","page","coreState","scale","task","renderPageRect","rect","origin","x","scaleFactor","set","wait","ignore","delete","ThumbnailPlugin","ThumbnailPluginPackage","create","_engine","config","reducer","initialState"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,54 +1 @@
1
- import { BasePluginConfig, BasePlugin, PluginRegistry, PluginManifest, PluginPackage } from '@embedpdf/core';
2
- import { Task, PdfErrorReason } from '@embedpdf/models';
3
-
4
- interface ThumbnailPluginConfig extends BasePluginConfig {
5
- width?: number;
6
- gap?: number;
7
- buffer?: number;
8
- labelHeight?: number;
9
- }
10
- interface ThumbMeta {
11
- pageIndex: number;
12
- width: number;
13
- height: number;
14
- wrapperHeight: number;
15
- top: number;
16
- labelHeight: number;
17
- }
18
- interface WindowState {
19
- start: number;
20
- end: number;
21
- items: ThumbMeta[];
22
- totalHeight: number;
23
- }
24
- interface ThumbnailCapability {
25
- /** called from UI on every scroll */
26
- setViewport(offsetY: number, viewportH: number): void;
27
- /** listen to window changes */
28
- onWindow(cb: (w: WindowState) => void): () => void;
29
- /** lazily render one thumb */
30
- renderThumb(pageIdx: number, dpr: number): Task<Blob, PdfErrorReason>;
31
- }
32
-
33
- declare class ThumbnailPlugin extends BasePlugin<ThumbnailPluginConfig, ThumbnailCapability> {
34
- private cfg;
35
- static readonly id: "thumbnail";
36
- private renderCapability;
37
- private thumbs;
38
- private window;
39
- private readonly emitWindow;
40
- private readonly taskCache;
41
- constructor(id: string, registry: PluginRegistry, cfg: ThumbnailPluginConfig);
42
- initialize(): Promise<void>;
43
- private setWindowState;
44
- protected buildCapability(): ThumbnailCapability;
45
- private updateWindow;
46
- private renderThumb;
47
- }
48
-
49
- declare const THUMBNAIL_PLUGIN_ID = "thumbnail";
50
- declare const manifest: PluginManifest<ThumbnailPluginConfig>;
51
-
52
- declare const ThumbnailPluginPackage: PluginPackage<ThumbnailPlugin, ThumbnailPluginConfig>;
53
-
54
- export { THUMBNAIL_PLUGIN_ID, type ThumbMeta, type ThumbnailCapability, ThumbnailPlugin, type ThumbnailPluginConfig, ThumbnailPluginPackage, type WindowState, manifest };
1
+ export * from './lib';
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
- // src/lib/manifest.ts
2
- var THUMBNAIL_PLUGIN_ID = "thumbnail";
3
- var manifest = {
1
+ import { BasePlugin, createBehaviorEmitter, SET_DOCUMENT } from "@embedpdf/core";
2
+ import { ignore } from "@embedpdf/models";
3
+ const THUMBNAIL_PLUGIN_ID = "thumbnail";
4
+ const manifest = {
4
5
  id: THUMBNAIL_PLUGIN_ID,
5
6
  name: "Thumbnail Plugin",
6
7
  version: "1.0.0",
@@ -15,15 +16,7 @@ var manifest = {
15
16
  labelHeight: 16
16
17
  }
17
18
  };
18
-
19
- // src/lib/thumbnail-plugin.ts
20
- import {
21
- BasePlugin,
22
- createBehaviorEmitter,
23
- SET_DOCUMENT
24
- } from "@embedpdf/core";
25
- import { ignore } from "@embedpdf/models";
26
- var ThumbnailPlugin = class extends BasePlugin {
19
+ const _ThumbnailPlugin = class _ThumbnailPlugin extends BasePlugin {
27
20
  constructor(id, registry, cfg) {
28
21
  super(id, registry);
29
22
  this.cfg = cfg;
@@ -125,10 +118,9 @@ var ThumbnailPlugin = class extends BasePlugin {
125
118
  return task;
126
119
  }
127
120
  };
128
- ThumbnailPlugin.id = "thumbnail";
129
-
130
- // src/lib/index.ts
131
- var ThumbnailPluginPackage = {
121
+ _ThumbnailPlugin.id = "thumbnail";
122
+ let ThumbnailPlugin = _ThumbnailPlugin;
123
+ const ThumbnailPluginPackage = {
132
124
  manifest,
133
125
  create: (registry, _engine, config) => new ThumbnailPlugin(THUMBNAIL_PLUGIN_ID, registry, config),
134
126
  reducer: () => {
@@ -141,4 +133,4 @@ export {
141
133
  ThumbnailPluginPackage,
142
134
  manifest
143
135
  };
144
- //# sourceMappingURL=index.js.map
136
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/manifest.ts","../src/lib/thumbnail-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { ThumbnailPluginConfig } from './types';\n\nexport const THUMBNAIL_PLUGIN_ID = 'thumbnail';\n\nexport const manifest: PluginManifest<ThumbnailPluginConfig> = {\n id: THUMBNAIL_PLUGIN_ID,\n name: 'Thumbnail Plugin',\n version: '1.0.0',\n provides: ['thumbnail'],\n requires: ['render'],\n optional: [],\n defaultConfig: {\n enabled: true,\n width: 150,\n gap: 10,\n buffer: 3,\n labelHeight: 16,\n },\n};\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n PluginRegistry,\n SET_DOCUMENT,\n StoreState,\n} from '@embedpdf/core';\nimport { ThumbMeta, ThumbnailPluginConfig, WindowState } from './types';\nimport { ThumbnailCapability } from './types';\nimport { ignore, PdfErrorReason, Task } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\n\nexport class ThumbnailPlugin extends BasePlugin<ThumbnailPluginConfig, ThumbnailCapability> {\n static readonly id = 'thumbnail' as const;\n\n private renderCapability: RenderCapability;\n private thumbs: ThumbMeta[] = [];\n private window: WindowState | null = null;\n private readonly emitWindow = createBehaviorEmitter<WindowState>();\n private readonly taskCache = new Map<number, Task<Blob, PdfErrorReason>>();\n\n constructor(\n id: string,\n registry: PluginRegistry,\n private cfg: ThumbnailPluginConfig,\n ) {\n super(id, registry);\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n this.taskCache.clear();\n this.setWindowState(state);\n });\n }\n\n /* ------------ init ------------------------------------------------ */\n async initialize(): Promise<void> {}\n\n private setWindowState(state: StoreState<CoreState>) {\n const core = state.core;\n\n if (!core.document) return;\n\n const W = this.cfg.width ?? 120;\n const L = this.cfg.labelHeight ?? 16; // label\n const GAP = this.cfg.gap ?? 8;\n\n let offset = 0;\n this.thumbs = core.document.pages.map((p) => {\n const ratio = p.size.height / p.size.width;\n const thumbH = Math.round(W * ratio);\n const wrapH = thumbH + L; // no GAP here\n\n const meta: ThumbMeta = {\n pageIndex: p.index,\n width: W,\n height: thumbH,\n wrapperHeight: wrapH,\n top: offset,\n labelHeight: L,\n };\n offset += wrapH + GAP; // GAP added *after* wrapper\n return meta;\n });\n\n this.window = {\n start: -1,\n end: -1,\n items: [],\n totalHeight: offset - GAP, // last item has no gap below\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ capability ----------------------------------------- */\n protected buildCapability(): ThumbnailCapability {\n return {\n onWindow: this.emitWindow.on,\n setViewport: (y, h) => this.updateWindow(y, h),\n renderThumb: (idx, dpr) => this.renderThumb(idx, dpr),\n };\n }\n\n /* ------------ windowing math ------------------------------------- */\n private updateWindow(scrollY: number, viewportH: number) {\n const BUF = this.cfg.buffer ?? 3;\n\n /* -------- find first visible wrapper ---------- */\n let low = 0,\n high = this.thumbs.length - 1,\n first = 0;\n while (low <= high) {\n const mid = (low + high) >> 1;\n const m = this.thumbs[mid];\n if (m.top + m.wrapperHeight < scrollY) low = mid + 1;\n else {\n first = mid;\n high = mid - 1;\n }\n }\n\n /* -------- find last visible + buffer ---------- */\n let last = first;\n const limit = scrollY + viewportH;\n while (last + 1 < this.thumbs.length && this.thumbs[last].top < limit) last++;\n last = Math.min(this.thumbs.length - 1, last + BUF);\n\n const start = Math.max(0, first - BUF);\n if (this.window && start === this.window.start && last === this.window.end) return;\n\n this.window = {\n start,\n end: last,\n items: this.thumbs.slice(start, last + 1),\n totalHeight: this.window!.totalHeight,\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ thumbnail raster ----------------------------------- */\n private renderThumb(idx: number, dpr: number) {\n if (this.taskCache.has(idx)) return this.taskCache.get(idx)!;\n\n const core = this.coreState.core;\n const page = core.document!.pages[idx];\n const scale = (this.cfg.width ?? 120) / page.size.width;\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: idx,\n rect: { origin: { x: 0, y: 0 }, size: page.size },\n scaleFactor: scale,\n dpr,\n });\n\n this.taskCache.set(idx, task);\n\n task.wait(ignore, () => {\n this.taskCache.delete(idx);\n });\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, THUMBNAIL_PLUGIN_ID } from './manifest';\nimport { ThumbnailPluginConfig } from './types';\nimport { ThumbnailPlugin } from './thumbnail-plugin';\n\nexport const ThumbnailPluginPackage: PluginPackage<ThumbnailPlugin, ThumbnailPluginConfig> = {\n manifest,\n create: (registry, _engine, config) => new ThumbnailPlugin(THUMBNAIL_PLUGIN_ID, registry, config),\n reducer: () => {},\n initialState: {},\n};\n\nexport * from './thumbnail-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"index.js","sources":["../src/lib/manifest.ts","../src/lib/thumbnail-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { ThumbnailPluginConfig } from './types';\n\nexport const THUMBNAIL_PLUGIN_ID = 'thumbnail';\n\nexport const manifest: PluginManifest<ThumbnailPluginConfig> = {\n id: THUMBNAIL_PLUGIN_ID,\n name: 'Thumbnail Plugin',\n version: '1.0.0',\n provides: ['thumbnail'],\n requires: ['render'],\n optional: [],\n defaultConfig: {\n enabled: true,\n width: 150,\n gap: 10,\n buffer: 3,\n labelHeight: 16,\n },\n};\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n PluginRegistry,\n SET_DOCUMENT,\n StoreState,\n} from '@embedpdf/core';\nimport { ThumbMeta, ThumbnailPluginConfig, WindowState } from './types';\nimport { ThumbnailCapability } from './types';\nimport { ignore, PdfErrorReason, Task } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\n\nexport class ThumbnailPlugin extends BasePlugin<ThumbnailPluginConfig, ThumbnailCapability> {\n static readonly id = 'thumbnail' as const;\n\n private renderCapability: RenderCapability;\n private thumbs: ThumbMeta[] = [];\n private window: WindowState | null = null;\n private readonly emitWindow = createBehaviorEmitter<WindowState>();\n private readonly taskCache = new Map<number, Task<Blob, PdfErrorReason>>();\n\n constructor(\n id: string,\n registry: PluginRegistry,\n private cfg: ThumbnailPluginConfig,\n ) {\n super(id, registry);\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n this.taskCache.clear();\n this.setWindowState(state);\n });\n }\n\n /* ------------ init ------------------------------------------------ */\n async initialize(): Promise<void> {}\n\n private setWindowState(state: StoreState<CoreState>) {\n const core = state.core;\n\n if (!core.document) return;\n\n const W = this.cfg.width ?? 120;\n const L = this.cfg.labelHeight ?? 16; // label\n const GAP = this.cfg.gap ?? 8;\n\n let offset = 0;\n this.thumbs = core.document.pages.map((p) => {\n const ratio = p.size.height / p.size.width;\n const thumbH = Math.round(W * ratio);\n const wrapH = thumbH + L; // no GAP here\n\n const meta: ThumbMeta = {\n pageIndex: p.index,\n width: W,\n height: thumbH,\n wrapperHeight: wrapH,\n top: offset,\n labelHeight: L,\n };\n offset += wrapH + GAP; // GAP added *after* wrapper\n return meta;\n });\n\n this.window = {\n start: -1,\n end: -1,\n items: [],\n totalHeight: offset - GAP, // last item has no gap below\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ capability ----------------------------------------- */\n protected buildCapability(): ThumbnailCapability {\n return {\n onWindow: this.emitWindow.on,\n setViewport: (y, h) => this.updateWindow(y, h),\n renderThumb: (idx, dpr) => this.renderThumb(idx, dpr),\n };\n }\n\n /* ------------ windowing math ------------------------------------- */\n private updateWindow(scrollY: number, viewportH: number) {\n const BUF = this.cfg.buffer ?? 3;\n\n /* -------- find first visible wrapper ---------- */\n let low = 0,\n high = this.thumbs.length - 1,\n first = 0;\n while (low <= high) {\n const mid = (low + high) >> 1;\n const m = this.thumbs[mid];\n if (m.top + m.wrapperHeight < scrollY) low = mid + 1;\n else {\n first = mid;\n high = mid - 1;\n }\n }\n\n /* -------- find last visible + buffer ---------- */\n let last = first;\n const limit = scrollY + viewportH;\n while (last + 1 < this.thumbs.length && this.thumbs[last].top < limit) last++;\n last = Math.min(this.thumbs.length - 1, last + BUF);\n\n const start = Math.max(0, first - BUF);\n if (this.window && start === this.window.start && last === this.window.end) return;\n\n this.window = {\n start,\n end: last,\n items: this.thumbs.slice(start, last + 1),\n totalHeight: this.window!.totalHeight,\n };\n this.emitWindow.emit(this.window);\n }\n\n /* ------------ thumbnail raster ----------------------------------- */\n private renderThumb(idx: number, dpr: number) {\n if (this.taskCache.has(idx)) return this.taskCache.get(idx)!;\n\n const core = this.coreState.core;\n const page = core.document!.pages[idx];\n const scale = (this.cfg.width ?? 120) / page.size.width;\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: idx,\n rect: { origin: { x: 0, y: 0 }, size: page.size },\n scaleFactor: scale,\n dpr,\n });\n\n this.taskCache.set(idx, task);\n\n task.wait(ignore, () => {\n this.taskCache.delete(idx);\n });\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, THUMBNAIL_PLUGIN_ID } from './manifest';\nimport { ThumbnailPluginConfig } from './types';\nimport { ThumbnailPlugin } from './thumbnail-plugin';\n\nexport const ThumbnailPluginPackage: PluginPackage<ThumbnailPlugin, ThumbnailPluginConfig> = {\n manifest,\n create: (registry, _engine, config) => new ThumbnailPlugin(THUMBNAIL_PLUGIN_ID, registry, config),\n reducer: () => {},\n initialState: {},\n};\n\nexport * from './thumbnail-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { PluginPackage } from '@embedpdf/core';
2
+ import { ThumbnailPluginConfig } from './types';
3
+ import { ThumbnailPlugin } from './thumbnail-plugin';
4
+ export declare const ThumbnailPluginPackage: PluginPackage<ThumbnailPlugin, ThumbnailPluginConfig>;
5
+ export * from './thumbnail-plugin';
6
+ export * from './types';
7
+ export * from './manifest';
@@ -0,0 +1,4 @@
1
+ import { PluginManifest } from '@embedpdf/core';
2
+ import { ThumbnailPluginConfig } from './types';
3
+ export declare const THUMBNAIL_PLUGIN_ID = "thumbnail";
4
+ export declare const manifest: PluginManifest<ThumbnailPluginConfig>;
@@ -0,0 +1,17 @@
1
+ import { BasePlugin, PluginRegistry } from '@embedpdf/core';
2
+ import { ThumbnailPluginConfig, ThumbnailCapability } from './types';
3
+ export declare class ThumbnailPlugin extends BasePlugin<ThumbnailPluginConfig, ThumbnailCapability> {
4
+ private cfg;
5
+ static readonly id: "thumbnail";
6
+ private renderCapability;
7
+ private thumbs;
8
+ private window;
9
+ private readonly emitWindow;
10
+ private readonly taskCache;
11
+ constructor(id: string, registry: PluginRegistry, cfg: ThumbnailPluginConfig);
12
+ initialize(): Promise<void>;
13
+ private setWindowState;
14
+ protected buildCapability(): ThumbnailCapability;
15
+ private updateWindow;
16
+ private renderThumb;
17
+ }
@@ -0,0 +1,30 @@
1
+ import { BasePluginConfig } from '@embedpdf/core';
2
+ import { PdfErrorReason, Task } from '@embedpdf/models';
3
+ export interface ThumbnailPluginConfig extends BasePluginConfig {
4
+ width?: number;
5
+ gap?: number;
6
+ buffer?: number;
7
+ labelHeight?: number;
8
+ }
9
+ export interface ThumbMeta {
10
+ pageIndex: number;
11
+ width: number;
12
+ height: number;
13
+ wrapperHeight: number;
14
+ top: number;
15
+ labelHeight: number;
16
+ }
17
+ export interface WindowState {
18
+ start: number;
19
+ end: number;
20
+ items: ThumbMeta[];
21
+ totalHeight: number;
22
+ }
23
+ export interface ThumbnailCapability {
24
+ /** called from UI on every scroll */
25
+ setViewport(offsetY: number, viewportH: number): void;
26
+ /** listen to window changes */
27
+ onWindow(cb: (w: WindowState) => void): () => void;
28
+ /** lazily render one thumb */
29
+ renderThumb(pageIdx: number, dpr: number): Task<Blob, PdfErrorReason>;
30
+ }
@@ -0,0 +1,5 @@
1
+ export { Fragment } from 'preact';
2
+ export { useEffect, useRef, useState, useCallback, useMemo } from 'preact/hooks';
3
+ export type { ComponentChildren as ReactNode } from 'preact';
4
+ export type CSSProperties = import('preact').JSX.CSSProperties;
5
+ export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
@@ -0,0 +1 @@
1
+ export * from '@embedpdf/core/preact';
@@ -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/preact/index.ts
21
- var preact_exports = {};
22
- __export(preact_exports, {
23
- ThumbImg: () => ThumbImg,
24
- ThumbnailsPane: () => ThumbnailsPane,
25
- useThumbnailCapability: () => useThumbnailCapability,
26
- useThumbnailPlugin: () => useThumbnailPlugin
27
- });
28
- module.exports = __toCommonJS(preact_exports);
29
-
30
- // src/preact/hooks/use-thumbnail.ts
31
- var import_preact = require("@embedpdf/core/preact");
32
- var import_plugin_thumbnail = require("@embedpdf/plugin-thumbnail");
33
- var useThumbnailPlugin = () => (0, import_preact.usePlugin)(import_plugin_thumbnail.ThumbnailPlugin.id);
34
- var useThumbnailCapability = () => (0, import_preact.useCapability)(import_plugin_thumbnail.ThumbnailPlugin.id);
35
-
36
- // src/preact/components/thumbnails-pane.tsx
37
- var import_hooks = require("preact/hooks");
38
- var import_jsx_runtime = require("preact/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_hooks.useRef)(null);
47
- const [window2, setWindow] = (0, import_hooks.useState)(null);
48
- (0, import_hooks.useEffect)(() => thumbs?.onWindow(setWindow), [thumbs]);
49
- (0, import_hooks.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_hooks.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_hooks.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/preact/components/thumbnail-img.tsx
83
- var import_hooks3 = require("preact/hooks");
84
- var import_models = require("@embedpdf/models");
85
- var import_jsx_runtime2 = require("preact/jsx-runtime");
86
- function ThumbImg({ meta, style, ...props }) {
87
- const { provides: thumbs } = useThumbnailCapability();
88
- const [url, setUrl] = (0, import_hooks3.useState)();
89
- const urlRef = (0, import_hooks3.useRef)(null);
90
- (0, import_hooks3.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/preact"),t=require("@embedpdf/plugin-thumbnail"),r=require("preact/jsx-runtime");require("preact");const n=require("preact/hooks"),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