@embedpdf/plugin-selection 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 (55) hide show
  1. package/dist/index.cjs +2 -450
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +1 -210
  4. package/dist/index.js +27 -53
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/actions.d.ts +57 -0
  7. package/dist/lib/index.d.ts +9 -0
  8. package/dist/lib/manifest.d.ts +4 -0
  9. package/dist/lib/reducer.d.ts +4 -0
  10. package/dist/lib/selection-plugin.d.ts +29 -0
  11. package/dist/lib/selectors.d.ts +14 -0
  12. package/dist/lib/types.d.ts +63 -0
  13. package/dist/lib/utils.d.ts +70 -0
  14. package/dist/preact/adapter.d.ts +4 -0
  15. package/dist/preact/core.d.ts +1 -0
  16. package/dist/preact/index.cjs +2 -170
  17. package/dist/preact/index.cjs.map +1 -1
  18. package/dist/preact/index.d.ts +1 -25
  19. package/dist/preact/index.js +10 -20
  20. package/dist/preact/index.js.map +1 -1
  21. package/dist/preact/interaction-manager.d.ts +1 -0
  22. package/dist/react/adapter.d.ts +2 -0
  23. package/dist/react/core.d.ts +1 -0
  24. package/dist/react/index.cjs +2 -170
  25. package/dist/react/index.cjs.map +1 -1
  26. package/dist/react/index.d.ts +1 -25
  27. package/dist/react/index.js +9 -20
  28. package/dist/react/index.js.map +1 -1
  29. package/dist/react/interaction-manager.d.ts +1 -0
  30. package/dist/shared-preact/components/copy-to-clipboard.d.ts +1 -0
  31. package/dist/shared-preact/components/index.d.ts +2 -0
  32. package/dist/shared-preact/components/selection-layer.d.ts +7 -0
  33. package/dist/shared-preact/hooks/index.d.ts +1 -0
  34. package/dist/shared-preact/hooks/use-selection.d.ts +11 -0
  35. package/dist/shared-preact/index.d.ts +2 -0
  36. package/dist/shared-react/components/copy-to-clipboard.d.ts +1 -0
  37. package/dist/shared-react/components/index.d.ts +2 -0
  38. package/dist/shared-react/components/selection-layer.d.ts +7 -0
  39. package/dist/shared-react/hooks/index.d.ts +1 -0
  40. package/dist/shared-react/hooks/use-selection.d.ts +11 -0
  41. package/dist/shared-react/index.d.ts +2 -0
  42. package/dist/vue/components/copy-to-clipboard.vue.d.ts +2 -0
  43. package/dist/vue/components/index.d.ts +2 -0
  44. package/dist/vue/components/selection-layer.vue.d.ts +9 -0
  45. package/dist/vue/hooks/index.d.ts +1 -0
  46. package/dist/vue/hooks/use-selection.d.ts +11 -0
  47. package/dist/vue/index.cjs +2 -0
  48. package/dist/vue/index.cjs.map +1 -0
  49. package/dist/vue/index.d.ts +2 -0
  50. package/dist/vue/index.js +145 -0
  51. package/dist/vue/index.js.map +1 -0
  52. package/package.json +23 -14
  53. package/dist/index.d.cts +0 -210
  54. package/dist/preact/index.d.cts +0 -25
  55. package/dist/react/index.d.cts +0 -25
@@ -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/react/index.ts
21
- var react_exports = {};
22
- __export(react_exports, {
23
- CopyToClipboard: () => CopyToClipboard,
24
- SelectionLayer: () => SelectionLayer,
25
- useSelectionCapability: () => useSelectionCapability,
26
- useSelectionPlugin: () => useSelectionPlugin
27
- });
28
- module.exports = __toCommonJS(react_exports);
29
-
30
- // src/react/hooks/use-selection.ts
31
- var import_react = require("@embedpdf/core/react");
32
- var import_plugin_selection = require("@embedpdf/plugin-selection");
33
- var useSelectionCapability = () => (0, import_react.useCapability)(import_plugin_selection.SelectionPlugin.id);
34
- var useSelectionPlugin = () => (0, import_react.usePlugin)(import_plugin_selection.SelectionPlugin.id);
35
-
36
- // src/react/components/selection-layer.tsx
37
- var import_react2 = require("react");
38
- var import_models = require("@embedpdf/models");
39
- var import_react3 = require("@embedpdf/plugin-interaction-manager/react");
40
- var import_plugin_selection2 = require("@embedpdf/plugin-selection");
41
- var import_jsx_runtime = require("react/jsx-runtime");
42
- function SelectionLayer({ pageIndex, scale, background = "rgba(33,150,243)" }) {
43
- const { provides: sel } = useSelectionCapability();
44
- const { provides: im } = (0, import_react3.useInteractionManagerCapability)();
45
- const { register } = (0, import_react3.usePointerHandlers)({ pageIndex });
46
- const [rects, setRects] = (0, import_react2.useState)([]);
47
- const [boundingRect, setBoundingRect] = (0, import_react2.useState)(null);
48
- const { setCursor, removeCursor } = (0, import_react3.useCursor)();
49
- const geoCacheRef = (0, import_react2.useRef)(null);
50
- (0, import_react2.useEffect)(() => {
51
- if (!sel) return;
52
- return sel.onSelectionChange(() => {
53
- const mode = im?.getActiveMode();
54
- if (mode === "default") {
55
- setRects(sel.getHighlightRectsForPage(pageIndex));
56
- setBoundingRect(sel.getBoundingRectForPage(pageIndex));
57
- } else {
58
- setRects([]);
59
- setBoundingRect(null);
60
- }
61
- });
62
- }, [sel, pageIndex]);
63
- const cachedGlyphAt = (0, import_react2.useCallback)((pt) => {
64
- const geo = geoCacheRef.current;
65
- return geo ? (0, import_plugin_selection2.glyphAt)(geo, pt) : -1;
66
- }, []);
67
- (0, import_react2.useEffect)(() => {
68
- if (!sel) return;
69
- const task = sel.getGeometry(pageIndex);
70
- task.wait((g) => geoCacheRef.current = g, import_models.ignore);
71
- return () => {
72
- task.abort({
73
- code: import_models.PdfErrorCode.Cancelled,
74
- message: "Cancelled"
75
- });
76
- geoCacheRef.current = null;
77
- };
78
- }, [sel, pageIndex]);
79
- const handlers = (0, import_react2.useMemo)(
80
- () => ({
81
- onPointerDown: (point, _evt, modeId) => {
82
- if (!sel) return;
83
- if (!sel.isEnabledForMode(modeId)) return;
84
- sel.clear();
85
- const task = sel.getGeometry(pageIndex);
86
- task.wait((geo) => {
87
- const g = (0, import_plugin_selection2.glyphAt)(geo, point);
88
- if (g !== -1) sel.begin(pageIndex, g);
89
- }, import_models.ignore);
90
- },
91
- onPointerMove: (point, _evt, modeId) => {
92
- if (!sel) return;
93
- if (!sel.isEnabledForMode(modeId)) return;
94
- const g = cachedGlyphAt(point);
95
- if (g !== -1) {
96
- setCursor("selection-text", "text", 10);
97
- } else {
98
- removeCursor("selection-text");
99
- }
100
- if (g !== -1) sel.update(pageIndex, g);
101
- },
102
- onPointerUp: (_point, _evt, modeId) => {
103
- if (!sel) return;
104
- if (!sel.isEnabledForMode(modeId)) return;
105
- sel.end();
106
- },
107
- onHandlerActiveEnd(modeId) {
108
- if (!sel) return;
109
- if (!sel.isEnabledForMode(modeId)) return;
110
- sel.clear();
111
- }
112
- }),
113
- [sel, pageIndex, cachedGlyphAt]
114
- );
115
- (0, import_react2.useEffect)(() => {
116
- if (!register) return;
117
- return register(handlers);
118
- }, [register, handlers]);
119
- if (!boundingRect) return null;
120
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
121
- "div",
122
- {
123
- style: {
124
- position: "absolute",
125
- left: boundingRect.origin.x * scale,
126
- top: boundingRect.origin.y * scale,
127
- width: boundingRect.size.width * scale,
128
- height: boundingRect.size.height * scale,
129
- mixBlendMode: "multiply",
130
- isolation: "isolate"
131
- },
132
- children: rects.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
133
- "div",
134
- {
135
- style: {
136
- position: "absolute",
137
- left: (b.origin.x - boundingRect.origin.x) * scale,
138
- top: (b.origin.y - boundingRect.origin.y) * scale,
139
- width: b.size.width * scale,
140
- height: b.size.height * scale,
141
- background,
142
- pointerEvents: "none"
143
- }
144
- },
145
- i
146
- ))
147
- }
148
- );
149
- }
150
-
151
- // src/react/components/copy-to-clipboard.tsx
152
- var import_react4 = require("react");
153
- function CopyToClipboard() {
154
- const { provides: sel } = useSelectionCapability();
155
- (0, import_react4.useEffect)(() => {
156
- if (!sel) return;
157
- return sel.onCopyToClipboard((text) => {
158
- navigator.clipboard.writeText(text);
159
- });
160
- }, [sel]);
161
- return null;
162
- }
163
- // Annotate the CommonJS export names for ESM import in node:
164
- 0 && (module.exports = {
165
- CopyToClipboard,
166
- SelectionLayer,
167
- useSelectionCapability,
168
- useSelectionPlugin
169
- });
170
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-selection"),r=require("react/jsx-runtime"),i=require("react"),n=require("@embedpdf/models"),o=require("@embedpdf/plugin-interaction-manager/react"),l=()=>e.useCapability(t.SelectionPlugin.id);exports.CopyToClipboard=function(){const{provides:e}=l();return i.useEffect((()=>{if(e)return e.onCopyToClipboard((e=>{navigator.clipboard.writeText(e)}))}),[e]),null},exports.SelectionLayer=function({pageIndex:e,scale:s,background:u="rgba(33,150,243)"}){const{provides:a}=l(),{provides:d}=o.useInteractionManagerCapability(),{register:c}=o.usePointerHandlers({pageIndex:e}),[g,p]=i.useState([]),[f,b]=i.useState(null),{setCursor:h,removeCursor:x}=o.useCursor(),y=i.useRef(null);i.useEffect((()=>{if(a)return a.onSelectionChange((()=>{"default"===(null==d?void 0:d.getActiveMode())?(p(a.getHighlightRectsForPage(e)),b(a.getBoundingRectForPage(e))):(p([]),b(null))}))}),[a,e]);const m=i.useCallback((e=>{const r=y.current;return r?t.glyphAt(r,e):-1}),[]);i.useEffect((()=>{if(!a)return;const t=a.getGeometry(e);return t.wait((e=>y.current=e),n.ignore),()=>{t.abort({code:n.PdfErrorCode.Cancelled,message:"Cancelled"}),y.current=null}}),[a,e]);const C=i.useMemo((()=>({onPointerDown:(r,i,o)=>{if(!a)return;if(!a.isEnabledForMode(o))return;a.clear();a.getGeometry(e).wait((i=>{const n=t.glyphAt(i,r);-1!==n&&a.begin(e,n)}),n.ignore)},onPointerMove:(t,r,i)=>{if(!a)return;if(!a.isEnabledForMode(i))return;const n=m(t);-1!==n?h("selection-text","text",10):x("selection-text"),-1!==n&&a.update(e,n)},onPointerUp:(e,t,r)=>{a&&a.isEnabledForMode(r)&&a.end()},onHandlerActiveEnd(e){a&&a.isEnabledForMode(e)&&a.clear()}})),[a,e,m]);return i.useEffect((()=>{if(c)return c(C)}),[c,C]),f?r.jsx("div",{style:{position:"absolute",left:f.origin.x*s,top:f.origin.y*s,width:f.size.width*s,height:f.size.height*s,mixBlendMode:"multiply",isolation:"isolate"},children:g.map(((e,t)=>r.jsx("div",{style:{position:"absolute",left:(e.origin.x-f.origin.x)*s,top:(e.origin.y-f.origin.y)*s,width:e.size.width*s,height:e.size.height*s,background:u,pointerEvents:"none"}},t)))}):null},exports.useSelectionCapability=l,exports.useSelectionPlugin=()=>e.usePlugin(t.SelectionPlugin.id);
2
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/index.ts","../../src/react/hooks/use-selection.ts","../../src/react/components/selection-layer.tsx","../../src/react/components/copy-to-clipboard.tsx"],"sourcesContent":["export * from './hooks';\nexport * from './components';\n","import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { SelectionPlugin } from '@embedpdf/plugin-selection';\n\nexport const useSelectionCapability = () => useCapability<SelectionPlugin>(SelectionPlugin.id);\nexport const useSelectionPlugin = () => usePlugin<SelectionPlugin>(SelectionPlugin.id);\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { ignore, PdfErrorCode, PdfPageGeometry, Position, Rect } from '@embedpdf/models';\nimport {\n useCursor,\n useInteractionManagerCapability,\n usePointerHandlers,\n} from '@embedpdf/plugin-interaction-manager/react';\nimport { PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';\nimport { glyphAt } from '@embedpdf/plugin-selection';\n\nimport { useSelectionCapability } from '../hooks';\n\ntype Props = {\n pageIndex: number;\n scale: number;\n background?: string;\n};\n\nexport function SelectionLayer({ pageIndex, scale, background = 'rgba(33,150,243)' }: Props) {\n const { provides: sel } = useSelectionCapability();\n const { provides: im } = useInteractionManagerCapability();\n const { register } = usePointerHandlers({ pageIndex });\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n const { setCursor, removeCursor } = useCursor();\n const geoCacheRef = useRef<PdfPageGeometry | null>(null);\n\n /* subscribe to rect updates */\n useEffect(() => {\n if (!sel) return;\n return sel.onSelectionChange(() => {\n const mode = im?.getActiveMode();\n if (mode === 'default') {\n setRects(sel.getHighlightRectsForPage(pageIndex));\n setBoundingRect(sel.getBoundingRectForPage(pageIndex));\n } else {\n setRects([]);\n setBoundingRect(null);\n }\n });\n }, [sel, pageIndex]);\n\n /* cheap glyphAt cache for the active page */\n const cachedGlyphAt = useCallback((pt: Position) => {\n const geo = geoCacheRef.current;\n return geo ? glyphAt(geo, pt) : -1;\n }, []);\n\n // Initialize geometry cache\n useEffect(() => {\n if (!sel) return;\n const task = sel.getGeometry(pageIndex);\n task.wait((g) => (geoCacheRef.current = g), ignore);\n\n return () => {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'Cancelled',\n });\n geoCacheRef.current = null;\n };\n }, [sel, pageIndex]);\n\n const handlers = useMemo(\n (): PointerEventHandlersWithLifecycle<PointerEvent> => ({\n onPointerDown: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n // clear the selection\n sel.clear();\n const task = sel.getGeometry(pageIndex);\n task.wait((geo) => {\n const g = glyphAt(geo, point);\n if (g !== -1) sel.begin(pageIndex, g);\n }, ignore);\n },\n onPointerMove: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n const g = cachedGlyphAt(point);\n if (g !== -1) {\n setCursor('selection-text', 'text', 10);\n } else {\n removeCursor('selection-text');\n }\n if (g !== -1) sel.update(pageIndex, g);\n },\n onPointerUp: (_point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n sel.end();\n },\n onHandlerActiveEnd(modeId) {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n\n sel.clear();\n },\n }),\n [sel, pageIndex, cachedGlyphAt],\n );\n\n useEffect(() => {\n if (!register) return;\n return register(handlers);\n }, [register, handlers]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n left: boundingRect.origin.x * scale,\n top: boundingRect.origin.y * scale,\n width: boundingRect.size.width * scale,\n height: boundingRect.size.height * scale,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n }}\n >\n {rects.map((b, i) => (\n <div\n key={i}\n style={{\n position: 'absolute',\n left: (b.origin.x - boundingRect.origin.x) * scale,\n top: (b.origin.y - boundingRect.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background,\n pointerEvents: 'none',\n }}\n />\n ))}\n </div>\n );\n}\n","import { useEffect } from 'react';\n\nimport { useSelectionCapability } from '../hooks';\n\nexport function CopyToClipboard() {\n const { provides: sel } = useSelectionCapability();\n\n useEffect(() => {\n if (!sel) return;\n return sel.onCopyToClipboard((text) => {\n navigator.clipboard.writeText(text);\n });\n }, [sel]);\n\n return null;\n}\n"],"mappings":"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","names":["import_react","import_plugin_selection","import_react"]}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/copy-to-clipboard.tsx","../../src/shared/components/selection-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { SelectionPlugin } from '@embedpdf/plugin-selection';\n\nexport const useSelectionCapability = () => useCapability<SelectionPlugin>(SelectionPlugin.id);\nexport const useSelectionPlugin = () => usePlugin<SelectionPlugin>(SelectionPlugin.id);\n","import { useEffect } from '@framework';\n\nimport { useSelectionCapability } from '../hooks';\n\nexport function CopyToClipboard() {\n const { provides: sel } = useSelectionCapability();\n\n useEffect(() => {\n if (!sel) return;\n return sel.onCopyToClipboard((text) => {\n navigator.clipboard.writeText(text);\n });\n }, [sel]);\n\n return null;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from '@framework';\nimport { ignore, PdfErrorCode, PdfPageGeometry, Position, Rect } from '@embedpdf/models';\nimport {\n useCursor,\n useInteractionManagerCapability,\n usePointerHandlers,\n} from '@embedpdf/plugin-interaction-manager/@framework';\nimport { PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';\nimport { glyphAt } from '@embedpdf/plugin-selection';\n\nimport { useSelectionCapability } from '../hooks';\n\ntype Props = {\n pageIndex: number;\n scale: number;\n background?: string;\n};\n\nexport function SelectionLayer({ pageIndex, scale, background = 'rgba(33,150,243)' }: Props) {\n const { provides: sel } = useSelectionCapability();\n const { provides: im } = useInteractionManagerCapability();\n const { register } = usePointerHandlers({ pageIndex });\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n const { setCursor, removeCursor } = useCursor();\n const geoCacheRef = useRef<PdfPageGeometry | null>(null);\n\n /* subscribe to rect updates */\n useEffect(() => {\n if (!sel) return;\n return sel.onSelectionChange(() => {\n const mode = im?.getActiveMode();\n if (mode === 'default') {\n setRects(sel.getHighlightRectsForPage(pageIndex));\n setBoundingRect(sel.getBoundingRectForPage(pageIndex));\n } else {\n setRects([]);\n setBoundingRect(null);\n }\n });\n }, [sel, pageIndex]);\n\n /* cheap glyphAt cache for the active page */\n const cachedGlyphAt = useCallback((pt: Position) => {\n const geo = geoCacheRef.current;\n return geo ? glyphAt(geo, pt) : -1;\n }, []);\n\n // Initialize geometry cache\n useEffect(() => {\n if (!sel) return;\n const task = sel.getGeometry(pageIndex);\n task.wait((g) => (geoCacheRef.current = g), ignore);\n\n return () => {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'Cancelled',\n });\n geoCacheRef.current = null;\n };\n }, [sel, pageIndex]);\n\n const handlers = useMemo(\n (): PointerEventHandlersWithLifecycle<PointerEvent> => ({\n onPointerDown: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n // clear the selection\n sel.clear();\n const task = sel.getGeometry(pageIndex);\n task.wait((geo) => {\n const g = glyphAt(geo, point);\n if (g !== -1) sel.begin(pageIndex, g);\n }, ignore);\n },\n onPointerMove: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n const g = cachedGlyphAt(point);\n if (g !== -1) {\n setCursor('selection-text', 'text', 10);\n } else {\n removeCursor('selection-text');\n }\n if (g !== -1) sel.update(pageIndex, g);\n },\n onPointerUp: (_point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n sel.end();\n },\n onHandlerActiveEnd(modeId) {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n\n sel.clear();\n },\n }),\n [sel, pageIndex, cachedGlyphAt],\n );\n\n useEffect(() => {\n if (!register) return;\n return register(handlers);\n }, [register, handlers]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n left: boundingRect.origin.x * scale,\n top: boundingRect.origin.y * scale,\n width: boundingRect.size.width * scale,\n height: boundingRect.size.height * scale,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n }}\n >\n {rects.map((b, i) => (\n <div\n key={i}\n style={{\n position: 'absolute',\n left: (b.origin.x - boundingRect.origin.x) * scale,\n top: (b.origin.y - boundingRect.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background,\n pointerEvents: 'none',\n }}\n />\n ))}\n </div>\n );\n}\n"],"names":["useSelectionCapability","useCapability","SelectionPlugin","id","provides","sel","useEffect","onCopyToClipboard","text","navigator","clipboard","writeText","pageIndex","scale","background","im","useInteractionManagerCapability","register","usePointerHandlers","rects","setRects","useState","boundingRect","setBoundingRect","setCursor","removeCursor","useCursor","geoCacheRef","useRef","onSelectionChange","getActiveMode","getHighlightRectsForPage","getBoundingRectForPage","cachedGlyphAt","useCallback","pt","geo","current","glyphAt","task","getGeometry","wait","g","ignore","abort","code","PdfErrorCode","Cancelled","message","handlers","useMemo","onPointerDown","point","_evt","modeId","isEnabledForMode","clear","begin","onPointerMove","update","onPointerUp","_point","end","onHandlerActiveEnd","jsxRuntime","jsx","style","position","left","origin","x","top","y","width","size","height","mixBlendMode","isolation","children","map","b","i","pointerEvents","usePlugin"],"mappings":"wSAGaA,EAAyB,IAAMC,gBAA+BC,EAAAA,gBAAgBC,4BCCpF,WACL,MAAQC,SAAUC,GAAQL,IASnB,OAPPM,EAAAA,WAAU,KACR,GAAKD,EACE,OAAAA,EAAIE,mBAAmBC,IAClBC,UAAAC,UAAUC,UAAUH,EAAI,GACnC,GACA,CAACH,IAEG,IACT,yBCGO,UAAwBO,UAAEA,EAAAC,MAAWA,EAAOC,WAAAA,EAAa,qBAC9D,MAAQV,SAAUC,GAAQL,KAClBI,SAAUW,GAAOC,qCACnBC,SAAEA,GAAaC,qBAAmB,CAAEN,eACnCO,EAAOC,GAAYC,EAAAA,SAAsB,KACzCC,EAAcC,GAAmBF,EAAAA,SAAsB,OACxDG,UAAEA,EAAAC,aAAWA,GAAiBC,cAC9BC,EAAcC,SAA+B,MAGnDtB,EAAAA,WAAU,KACR,GAAKD,EACE,OAAAA,EAAIwB,mBAAkB,KAEd,aADI,MAAJd,OAAI,EAAAA,EAAAe,kBAENV,EAAAf,EAAI0B,yBAAyBnB,IACtBW,EAAAlB,EAAI2B,uBAAuBpB,MAE3CQ,EAAS,IACTG,EAAgB,MAAI,GAEvB,GACA,CAAClB,EAAKO,IAGH,MAAAqB,EAAgBC,eAAaC,IACjC,MAAMC,EAAMT,EAAYU,QACxB,OAAOD,EAAME,EAAAA,QAAQF,EAAKD,IAAM,CAAA,GAC/B,IAGH7B,EAAAA,WAAU,KACR,IAAKD,EAAK,OACJ,MAAAkC,EAAOlC,EAAImC,YAAY5B,GAG7B,OAFA2B,EAAKE,MAAMC,GAAOf,EAAYU,QAAUK,GAAIC,UAErC,KACLJ,EAAKK,MAAM,CACTC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,cAEXrB,EAAYU,QAAU,IAAA,CACxB,GACC,CAAChC,EAAKO,IAET,MAAMqC,EAAWC,EAAAA,SACf,KAAwD,CACtDC,cAAe,CAACC,EAAOC,EAAMC,KAC3B,IAAKjD,EAAK,OACV,IAAKA,EAAIkD,iBAAiBD,GAAS,OAEnCjD,EAAImD,QACSnD,EAAImC,YAAY5B,GACxB6B,MAAML,IACH,MAAAM,EAAIJ,EAAAA,QAAQF,EAAKgB,IACb,IAANV,GAAcrC,EAAAoD,MAAM7C,EAAW8B,EAAC,GACnCC,SAAM,EAEXe,cAAe,CAACN,EAAOC,EAAMC,KAC3B,IAAKjD,EAAK,OACV,IAAKA,EAAIkD,iBAAiBD,GAAS,OAC7B,MAAAZ,EAAIT,EAAcmB,IACV,IAAVV,EACQlB,EAAA,iBAAkB,OAAQ,IAEpCC,EAAa,mBAEL,IAANiB,GAAcrC,EAAAsD,OAAO/C,EAAW8B,EAAC,EAEvCkB,YAAa,CAACC,EAAQR,EAAMC,KACrBjD,GACAA,EAAIkD,iBAAiBD,IAC1BjD,EAAIyD,KAAI,EAEV,kBAAAC,CAAmBT,GACZjD,GACAA,EAAIkD,iBAAiBD,IAE1BjD,EAAImD,OAAM,KAGd,CAACnD,EAAKO,EAAWqB,IAQf,OALJ3B,EAAAA,WAAU,KACR,GAAKW,EACL,OAAOA,EAASgC,EAAQ,GACvB,CAAChC,EAAUgC,IAET3B,EAGH0C,EAAAC,IAAC,MAAA,CACCC,MAAO,CACLC,SAAU,WACVC,KAAM9C,EAAa+C,OAAOC,EAAIzD,EAC9B0D,IAAKjD,EAAa+C,OAAOG,EAAI3D,EAC7B4D,MAAOnD,EAAaoD,KAAKD,MAAQ5D,EACjC8D,OAAQrD,EAAaoD,KAAKC,OAAS9D,EACnC+D,aAAc,WACdC,UAAW,WAGZC,SAAM3D,EAAA4D,KAAI,CAACC,EAAGC,IACbjB,EAAAC,IAAC,MAAA,CAECC,MAAO,CACLC,SAAU,WACVC,MAAOY,EAAEX,OAAOC,EAAIhD,EAAa+C,OAAOC,GAAKzD,EAC7C0D,KAAMS,EAAEX,OAAOG,EAAIlD,EAAa+C,OAAOG,GAAK3D,EAC5C4D,MAAOO,EAAEN,KAAKD,MAAQ5D,EACtB8D,OAAQK,EAAEN,KAAKC,OAAS9D,EACxBC,aACAoE,cAAe,SARZD,OAhBa,IA8B5B,8DFrIkC,IAAME,YAA2BjF,EAAAA,gBAAgBC"}
@@ -1,25 +1 @@
1
- import * as _embedpdf_plugin_selection from '@embedpdf/plugin-selection';
2
- import { SelectionPlugin } from '@embedpdf/plugin-selection';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
4
-
5
- declare const useSelectionCapability: () => {
6
- provides: Readonly<_embedpdf_plugin_selection.SelectionCapability> | null;
7
- isLoading: boolean;
8
- ready: Promise<void>;
9
- };
10
- declare const useSelectionPlugin: () => {
11
- plugin: SelectionPlugin | null;
12
- isLoading: boolean;
13
- ready: Promise<void>;
14
- };
15
-
16
- type Props = {
17
- pageIndex: number;
18
- scale: number;
19
- background?: string;
20
- };
21
- declare function SelectionLayer({ pageIndex, scale, background }: Props): react_jsx_runtime.JSX.Element | null;
22
-
23
- declare function CopyToClipboard(): null;
24
-
25
- export { CopyToClipboard, SelectionLayer, useSelectionCapability, useSelectionPlugin };
1
+ export * from '../shared-react';
@@ -1,19 +1,11 @@
1
- // src/react/hooks/use-selection.ts
2
1
  import { useCapability, usePlugin } from "@embedpdf/core/react";
3
- import { SelectionPlugin } from "@embedpdf/plugin-selection";
4
- var useSelectionCapability = () => useCapability(SelectionPlugin.id);
5
- var useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
6
-
7
- // src/react/components/selection-layer.tsx
8
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
9
- import { ignore, PdfErrorCode } from "@embedpdf/models";
10
- import {
11
- useCursor,
12
- useInteractionManagerCapability,
13
- usePointerHandlers
14
- } from "@embedpdf/plugin-interaction-manager/react";
15
- import { glyphAt } from "@embedpdf/plugin-selection";
2
+ import { SelectionPlugin, glyphAt } from "@embedpdf/plugin-selection";
16
3
  import { jsx } from "react/jsx-runtime";
4
+ import { useState, useRef, useEffect, useCallback, useMemo } from "react";
5
+ import { ignore, PdfErrorCode } from "@embedpdf/models";
6
+ import { useInteractionManagerCapability, usePointerHandlers, useCursor } from "@embedpdf/plugin-interaction-manager/react";
7
+ const useSelectionCapability = () => useCapability(SelectionPlugin.id);
8
+ const useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
17
9
  function SelectionLayer({ pageIndex, scale, background = "rgba(33,150,243)" }) {
18
10
  const { provides: sel } = useSelectionCapability();
19
11
  const { provides: im } = useInteractionManagerCapability();
@@ -25,7 +17,7 @@ function SelectionLayer({ pageIndex, scale, background = "rgba(33,150,243)" }) {
25
17
  useEffect(() => {
26
18
  if (!sel) return;
27
19
  return sel.onSelectionChange(() => {
28
- const mode = im?.getActiveMode();
20
+ const mode = im == null ? void 0 : im.getActiveMode();
29
21
  if (mode === "default") {
30
22
  setRects(sel.getHighlightRectsForPage(pageIndex));
31
23
  setBoundingRect(sel.getBoundingRectForPage(pageIndex));
@@ -122,12 +114,9 @@ function SelectionLayer({ pageIndex, scale, background = "rgba(33,150,243)" }) {
122
114
  }
123
115
  );
124
116
  }
125
-
126
- // src/react/components/copy-to-clipboard.tsx
127
- import { useEffect as useEffect2 } from "react";
128
117
  function CopyToClipboard() {
129
118
  const { provides: sel } = useSelectionCapability();
130
- useEffect2(() => {
119
+ useEffect(() => {
131
120
  if (!sel) return;
132
121
  return sel.onCopyToClipboard((text) => {
133
122
  navigator.clipboard.writeText(text);
@@ -141,4 +130,4 @@ export {
141
130
  useSelectionCapability,
142
131
  useSelectionPlugin
143
132
  };
144
- //# sourceMappingURL=index.js.map
133
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/hooks/use-selection.ts","../../src/react/components/selection-layer.tsx","../../src/react/components/copy-to-clipboard.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { SelectionPlugin } from '@embedpdf/plugin-selection';\n\nexport const useSelectionCapability = () => useCapability<SelectionPlugin>(SelectionPlugin.id);\nexport const useSelectionPlugin = () => usePlugin<SelectionPlugin>(SelectionPlugin.id);\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { ignore, PdfErrorCode, PdfPageGeometry, Position, Rect } from '@embedpdf/models';\nimport {\n useCursor,\n useInteractionManagerCapability,\n usePointerHandlers,\n} from '@embedpdf/plugin-interaction-manager/react';\nimport { PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';\nimport { glyphAt } from '@embedpdf/plugin-selection';\n\nimport { useSelectionCapability } from '../hooks';\n\ntype Props = {\n pageIndex: number;\n scale: number;\n background?: string;\n};\n\nexport function SelectionLayer({ pageIndex, scale, background = 'rgba(33,150,243)' }: Props) {\n const { provides: sel } = useSelectionCapability();\n const { provides: im } = useInteractionManagerCapability();\n const { register } = usePointerHandlers({ pageIndex });\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n const { setCursor, removeCursor } = useCursor();\n const geoCacheRef = useRef<PdfPageGeometry | null>(null);\n\n /* subscribe to rect updates */\n useEffect(() => {\n if (!sel) return;\n return sel.onSelectionChange(() => {\n const mode = im?.getActiveMode();\n if (mode === 'default') {\n setRects(sel.getHighlightRectsForPage(pageIndex));\n setBoundingRect(sel.getBoundingRectForPage(pageIndex));\n } else {\n setRects([]);\n setBoundingRect(null);\n }\n });\n }, [sel, pageIndex]);\n\n /* cheap glyphAt cache for the active page */\n const cachedGlyphAt = useCallback((pt: Position) => {\n const geo = geoCacheRef.current;\n return geo ? glyphAt(geo, pt) : -1;\n }, []);\n\n // Initialize geometry cache\n useEffect(() => {\n if (!sel) return;\n const task = sel.getGeometry(pageIndex);\n task.wait((g) => (geoCacheRef.current = g), ignore);\n\n return () => {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'Cancelled',\n });\n geoCacheRef.current = null;\n };\n }, [sel, pageIndex]);\n\n const handlers = useMemo(\n (): PointerEventHandlersWithLifecycle<PointerEvent> => ({\n onPointerDown: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n // clear the selection\n sel.clear();\n const task = sel.getGeometry(pageIndex);\n task.wait((geo) => {\n const g = glyphAt(geo, point);\n if (g !== -1) sel.begin(pageIndex, g);\n }, ignore);\n },\n onPointerMove: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n const g = cachedGlyphAt(point);\n if (g !== -1) {\n setCursor('selection-text', 'text', 10);\n } else {\n removeCursor('selection-text');\n }\n if (g !== -1) sel.update(pageIndex, g);\n },\n onPointerUp: (_point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n sel.end();\n },\n onHandlerActiveEnd(modeId) {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n\n sel.clear();\n },\n }),\n [sel, pageIndex, cachedGlyphAt],\n );\n\n useEffect(() => {\n if (!register) return;\n return register(handlers);\n }, [register, handlers]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n left: boundingRect.origin.x * scale,\n top: boundingRect.origin.y * scale,\n width: boundingRect.size.width * scale,\n height: boundingRect.size.height * scale,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n }}\n >\n {rects.map((b, i) => (\n <div\n key={i}\n style={{\n position: 'absolute',\n left: (b.origin.x - boundingRect.origin.x) * scale,\n top: (b.origin.y - boundingRect.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background,\n pointerEvents: 'none',\n }}\n />\n ))}\n </div>\n );\n}\n","import { useEffect } from 'react';\n\nimport { useSelectionCapability } from '../hooks';\n\nexport function CopyToClipboard() {\n const { provides: sel } = useSelectionCapability();\n\n useEffect(() => {\n if (!sel) return;\n return sel.onCopyToClipboard((text) => {\n navigator.clipboard.writeText(text);\n });\n }, [sel]);\n\n return null;\n}\n"],"mappings":"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","names":["useEffect","useEffect"]}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/selection-layer.tsx","../../src/shared/components/copy-to-clipboard.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { SelectionPlugin } from '@embedpdf/plugin-selection';\n\nexport const useSelectionCapability = () => useCapability<SelectionPlugin>(SelectionPlugin.id);\nexport const useSelectionPlugin = () => usePlugin<SelectionPlugin>(SelectionPlugin.id);\n","import { useCallback, useEffect, useMemo, useRef, useState } from '@framework';\nimport { ignore, PdfErrorCode, PdfPageGeometry, Position, Rect } from '@embedpdf/models';\nimport {\n useCursor,\n useInteractionManagerCapability,\n usePointerHandlers,\n} from '@embedpdf/plugin-interaction-manager/@framework';\nimport { PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';\nimport { glyphAt } from '@embedpdf/plugin-selection';\n\nimport { useSelectionCapability } from '../hooks';\n\ntype Props = {\n pageIndex: number;\n scale: number;\n background?: string;\n};\n\nexport function SelectionLayer({ pageIndex, scale, background = 'rgba(33,150,243)' }: Props) {\n const { provides: sel } = useSelectionCapability();\n const { provides: im } = useInteractionManagerCapability();\n const { register } = usePointerHandlers({ pageIndex });\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n const { setCursor, removeCursor } = useCursor();\n const geoCacheRef = useRef<PdfPageGeometry | null>(null);\n\n /* subscribe to rect updates */\n useEffect(() => {\n if (!sel) return;\n return sel.onSelectionChange(() => {\n const mode = im?.getActiveMode();\n if (mode === 'default') {\n setRects(sel.getHighlightRectsForPage(pageIndex));\n setBoundingRect(sel.getBoundingRectForPage(pageIndex));\n } else {\n setRects([]);\n setBoundingRect(null);\n }\n });\n }, [sel, pageIndex]);\n\n /* cheap glyphAt cache for the active page */\n const cachedGlyphAt = useCallback((pt: Position) => {\n const geo = geoCacheRef.current;\n return geo ? glyphAt(geo, pt) : -1;\n }, []);\n\n // Initialize geometry cache\n useEffect(() => {\n if (!sel) return;\n const task = sel.getGeometry(pageIndex);\n task.wait((g) => (geoCacheRef.current = g), ignore);\n\n return () => {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'Cancelled',\n });\n geoCacheRef.current = null;\n };\n }, [sel, pageIndex]);\n\n const handlers = useMemo(\n (): PointerEventHandlersWithLifecycle<PointerEvent> => ({\n onPointerDown: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n // clear the selection\n sel.clear();\n const task = sel.getGeometry(pageIndex);\n task.wait((geo) => {\n const g = glyphAt(geo, point);\n if (g !== -1) sel.begin(pageIndex, g);\n }, ignore);\n },\n onPointerMove: (point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n const g = cachedGlyphAt(point);\n if (g !== -1) {\n setCursor('selection-text', 'text', 10);\n } else {\n removeCursor('selection-text');\n }\n if (g !== -1) sel.update(pageIndex, g);\n },\n onPointerUp: (_point, _evt, modeId) => {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n sel.end();\n },\n onHandlerActiveEnd(modeId) {\n if (!sel) return;\n if (!sel.isEnabledForMode(modeId)) return;\n\n sel.clear();\n },\n }),\n [sel, pageIndex, cachedGlyphAt],\n );\n\n useEffect(() => {\n if (!register) return;\n return register(handlers);\n }, [register, handlers]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n left: boundingRect.origin.x * scale,\n top: boundingRect.origin.y * scale,\n width: boundingRect.size.width * scale,\n height: boundingRect.size.height * scale,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n }}\n >\n {rects.map((b, i) => (\n <div\n key={i}\n style={{\n position: 'absolute',\n left: (b.origin.x - boundingRect.origin.x) * scale,\n top: (b.origin.y - boundingRect.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background,\n pointerEvents: 'none',\n }}\n />\n ))}\n </div>\n );\n}\n","import { useEffect } from '@framework';\n\nimport { useSelectionCapability } from '../hooks';\n\nexport function CopyToClipboard() {\n const { provides: sel } = useSelectionCapability();\n\n useEffect(() => {\n if (!sel) return;\n return sel.onCopyToClipboard((text) => {\n navigator.clipboard.writeText(text);\n });\n }, [sel]);\n\n return null;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from '@embedpdf/plugin-interaction-manager/react';
@@ -0,0 +1 @@
1
+ export declare function CopyToClipboard(): null;
@@ -0,0 +1,2 @@
1
+ export * from './selection-layer';
2
+ export * from './copy-to-clipboard';
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ pageIndex: number;
3
+ scale: number;
4
+ background?: string;
5
+ };
6
+ export declare function SelectionLayer({ pageIndex, scale, background }: Props): import("preact").JSX.Element | null;
7
+ export {};
@@ -0,0 +1 @@
1
+ export * from './use-selection';
@@ -0,0 +1,11 @@
1
+ import { SelectionPlugin } from '../../lib/index.ts';
2
+ export declare const useSelectionCapability: () => {
3
+ provides: Readonly<import('../../lib/index.ts').SelectionCapability> | null;
4
+ isLoading: boolean;
5
+ ready: Promise<void>;
6
+ };
7
+ export declare const useSelectionPlugin: () => {
8
+ plugin: SelectionPlugin | null;
9
+ isLoading: boolean;
10
+ ready: Promise<void>;
11
+ };
@@ -0,0 +1,2 @@
1
+ export * from './hooks';
2
+ export * from './components';
@@ -0,0 +1 @@
1
+ export declare function CopyToClipboard(): null;
@@ -0,0 +1,2 @@
1
+ export * from './selection-layer';
2
+ export * from './copy-to-clipboard';
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ pageIndex: number;
3
+ scale: number;
4
+ background?: string;
5
+ };
6
+ export declare function SelectionLayer({ pageIndex, scale, background }: Props): import("react/jsx-runtime").JSX.Element | null;
7
+ export {};
@@ -0,0 +1 @@
1
+ export * from './use-selection';
@@ -0,0 +1,11 @@
1
+ import { SelectionPlugin } from '../../lib/index.ts';
2
+ export declare const useSelectionCapability: () => {
3
+ provides: Readonly<import('../../lib/index.ts').SelectionCapability> | null;
4
+ isLoading: boolean;
5
+ ready: Promise<void>;
6
+ };
7
+ export declare const useSelectionPlugin: () => {
8
+ plugin: SelectionPlugin | null;
9
+ isLoading: boolean;
10
+ ready: Promise<void>;
11
+ };
@@ -0,0 +1,2 @@
1
+ export * from './hooks';
2
+ export * from './components';
@@ -0,0 +1,2 @@
1
+ declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ export { default as SelectionLayer } from './selection-layer.vue';
2
+ export { default as CopyToClipboard } from './copy-to-clipboard.vue';
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ pageIndex: number;
3
+ scale: number;
4
+ background?: string;
5
+ }
6
+ declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {
7
+ background: string;
8
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -0,0 +1 @@
1
+ export * from './use-selection';
@@ -0,0 +1,11 @@
1
+ import { SelectionPlugin } from '../../lib/index.ts';
2
+ /**
3
+ * Hook to get the selection plugin's capability API.
4
+ * This provides methods for controlling and listening to selection events.
5
+ */
6
+ export declare const useSelectionCapability: () => import('@embedpdf/core/vue').CapabilityState<Readonly<import('../../lib/index.ts').SelectionCapability>>;
7
+ /**
8
+ * Hook to get the raw selection plugin instance.
9
+ * Useful for accessing plugin-specific properties or methods not exposed in the capability.
10
+ */
11
+ export declare const useSelectionPlugin: () => import('@embedpdf/core/vue').PluginState<SelectionPlugin>;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/vue"),o=require("@embedpdf/plugin-selection"),t=require("vue"),l=require("@embedpdf/models"),a=require("@embedpdf/plugin-interaction-manager/vue"),n=()=>e.useCapability(o.SelectionPlugin.id),i=t.defineComponent({__name:"selection-layer",props:{pageIndex:{},scale:{},background:{default:"rgba(33, 150, 243)"}},setup(e){const i=e,{provides:r}=n(),{provides:u}=a.useInteractionManagerCapability(),{register:c}=a.usePointerHandlers({pageIndex:i.pageIndex}),{setCursor:d,removeCursor:s}=a.useCursor(),p=t.ref([]),g=t.ref(null);let v;t.watchEffect((e=>{if(r.value){e(r.value.onSelectionChange((()=>{var e;"default"===(null==(e=u.value)?void 0:e.getActiveMode())?(p.value=r.value.getHighlightRectsForPage(i.pageIndex),g.value=r.value.getBoundingRectForPage(i.pageIndex)):(p.value=[],g.value=null)})))}})),t.watchEffect((e=>{if(r.value){const o=r.value.getGeometry(i.pageIndex);o.wait((e=>v=e),l.ignore),e((()=>{o.abort({code:l.PdfErrorCode.Cancelled,message:"SelectionLayer unmounted"})}))}}));const x=t.computed((()=>({onPointerDown:(e,t,a)=>{if(!r.value||!r.value.isEnabledForMode(a))return;r.value.clear();r.value.getGeometry(i.pageIndex).wait((t=>{const l=o.glyphAt(t,e);-1!==l&&r.value.begin(i.pageIndex,l)}),l.ignore)},onPointerMove:(e,t,l)=>{if(!r.value||!r.value.isEnabledForMode(l))return;const a=v?o.glyphAt(v,e):-1;-1!==a?(d("selection-text","text",10),r.value.update(i.pageIndex,a)):s("selection-text")},onPointerUp:(e,o,t)=>{r.value&&r.value.isEnabledForMode(t)&&r.value.end()},onHandlerActiveEnd:e=>{r.value&&r.value.isEnabledForMode(e)&&r.value.clear()}})));return t.watchEffect((e=>{if(c){const o=c(x.value);o&&e(o)}})),(e,o)=>g.value?(t.openBlock(),t.createElementBlock("div",{key:0,style:t.normalizeStyle({position:"absolute",left:g.value.origin.x*e.scale+"px",top:g.value.origin.y*e.scale+"px",width:g.value.size.width*e.scale+"px",height:g.value.size.height*e.scale+"px",mixBlendMode:"multiply",isolation:"isolate",pointerEvents:"none"})},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(p.value,((o,l)=>(t.openBlock(),t.createElementBlock("div",{key:l,style:t.normalizeStyle({position:"absolute",left:(o.origin.x-g.value.origin.x)*e.scale+"px",top:(o.origin.y-g.value.origin.y)*e.scale+"px",width:o.size.width*e.scale+"px",height:o.size.height*e.scale+"px",background:e.background})},null,4)))),128))],4)):t.createCommentVNode("",!0)}}),r=t.defineComponent({__name:"copy-to-clipboard",setup(e){const{provides:o}=n();return t.watchEffect((e=>{if(o.value){e(o.value.onCopyToClipboard((e=>{navigator.clipboard.writeText(e).catch((e=>{console.error("Failed to copy text to clipboard:",e)}))})))}})),(e,o)=>null}});exports.CopyToClipboard=r,exports.SelectionLayer=i,exports.useSelectionCapability=n,exports.useSelectionPlugin=()=>e.usePlugin(o.SelectionPlugin.id);
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../../src/vue/hooks/use-selection.ts","../../src/vue/components/selection-layer.vue","../../src/vue/components/copy-to-clipboard.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { SelectionPlugin } from '@embedpdf/plugin-selection';\n\n/**\n * Hook to get the selection plugin's capability API.\n * This provides methods for controlling and listening to selection events.\n */\nexport const useSelectionCapability = () => useCapability<SelectionPlugin>(SelectionPlugin.id);\n\n/**\n * Hook to get the raw selection plugin instance.\n * Useful for accessing plugin-specific properties or methods not exposed in the capability.\n */\nexport const useSelectionPlugin = () => usePlugin<SelectionPlugin>(SelectionPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, watchEffect, computed } from 'vue';\nimport { ignore, PdfErrorCode, PdfPageGeometry, Rect } from '@embedpdf/models';\nimport {\n useCursor,\n useInteractionManagerCapability,\n usePointerHandlers,\n} from '@embedpdf/plugin-interaction-manager/vue';\nimport { PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';\nimport { glyphAt } from '@embedpdf/plugin-selection';\nimport { useSelectionCapability } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n scale: number;\n background?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n background: 'rgba(33, 150, 243)', // Default selection color\n});\n\nconst { provides: sel } = useSelectionCapability();\nconst { provides: im } = useInteractionManagerCapability();\nconst { register } = usePointerHandlers({ pageIndex: props.pageIndex });\nconst { setCursor, removeCursor } = useCursor();\n\nconst rects = ref<Rect[]>([]);\nconst boundingRect = ref<Rect | null>(null);\n\n// Subscribe to selection changes and update the rendered rectangles\nwatchEffect((onCleanup) => {\n if (sel.value) {\n const unsubscribe = sel.value.onSelectionChange(() => {\n const mode = im.value?.getActiveMode();\n if (mode === 'default') {\n rects.value = sel.value!.getHighlightRectsForPage(props.pageIndex);\n boundingRect.value = sel.value!.getBoundingRectForPage(props.pageIndex);\n } else {\n rects.value = [];\n boundingRect.value = null;\n }\n });\n onCleanup(unsubscribe);\n }\n});\n\n// Cache page geometry for faster hit-testing during pointer moves\nlet geoCache: PdfPageGeometry | undefined;\nwatchEffect((onCleanup) => {\n if (sel.value) {\n const task = sel.value.getGeometry(props.pageIndex);\n task.wait((g) => (geoCache = g), ignore);\n\n onCleanup(() => {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'SelectionLayer unmounted',\n });\n });\n }\n});\n\nconst handlers = computed(\n (): PointerEventHandlersWithLifecycle<PointerEvent> => ({\n onPointerDown: (point, _evt, modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n sel.value.clear();\n const task = sel.value.getGeometry(props.pageIndex);\n task.wait((geo) => {\n const g = glyphAt(geo, point);\n if (g !== -1) sel.value!.begin(props.pageIndex, g);\n }, ignore);\n },\n onPointerMove: (point, _evt, modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n const g = geoCache ? glyphAt(geoCache, point) : -1;\n if (g !== -1) {\n setCursor('selection-text', 'text', 10);\n sel.value.update(props.pageIndex, g);\n } else {\n removeCursor('selection-text');\n }\n },\n onPointerUp: (_point, _evt, modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n sel.value.end();\n },\n onHandlerActiveEnd: (modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n sel.value.clear();\n },\n }),\n);\n\n// Register the pointer handlers with the interaction manager\nwatchEffect((onCleanup) => {\n if (register) {\n const cleanup = register(handlers.value);\n if (cleanup) onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div\n v-if=\"boundingRect\"\n :style=\"{\n position: 'absolute',\n left: `${boundingRect.origin.x * scale}px`,\n top: `${boundingRect.origin.y * scale}px`,\n width: `${boundingRect.size.width * scale}px`,\n height: `${boundingRect.size.height * scale}px`,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n pointerEvents: 'none',\n }\"\n >\n <div\n v-for=\"(rect, i) in rects\"\n :key=\"i\"\n :style=\"{\n position: 'absolute',\n left: `${(rect.origin.x - boundingRect.origin.x) * scale}px`,\n top: `${(rect.origin.y - boundingRect.origin.y) * scale}px`,\n width: `${rect.size.width * scale}px`,\n height: `${rect.size.height * scale}px`,\n background: background,\n }\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { watchEffect } from 'vue';\nimport { useSelectionCapability } from '../hooks';\n\nconst { provides: sel } = useSelectionCapability();\n\n// This effect runs when the component is mounted and the capability is available.\n// It automatically handles unsubscribing when the component is unmounted.\nwatchEffect((onCleanup) => {\n if (sel.value) {\n const unsubscribe = sel.value.onCopyToClipboard((text) => {\n // Use the Clipboard API to write the text\n navigator.clipboard.writeText(text).catch((err) => {\n console.error('Failed to copy text to clipboard:', err);\n });\n });\n\n // Register the cleanup function to run on unmount or re-run\n onCleanup(unsubscribe);\n }\n});\n</script>\n\n<template>\n <!-- This component renders nothing to the DOM -->\n</template>\n"],"names":["useSelectionCapability","useCapability","SelectionPlugin","id","props","__props","provides","sel","im","useInteractionManagerCapability","register","usePointerHandlers","pageIndex","setCursor","removeCursor","useCursor","rects","ref","boundingRect","geoCache","vue$1","watchEffect","onCleanup","value","onSelectionChange","_a","getActiveMode","getHighlightRectsForPage","getBoundingRectForPage","task","getGeometry","wait","g","ignore","abort","code","PdfErrorCode","Cancelled","message","handlers","computed","onPointerDown","point","_evt","modeId","isEnabledForMode","clear","geo","glyphAt","begin","onPointerMove","update","onPointerUp","_point","end","onHandlerActiveEnd","cleanup","_createElementBlock","style","_normalizeStyle","left","origin","x","scale","top","y","width","size","height","_openBlock","createElementBlock","_Fragment","_renderList","renderList","rect","i","key","background","onCopyToClipboard","text","navigator","clipboard","writeText","catch","err","console","error","usePlugin"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './hooks';
2
+ export * from './components';