@embedpdf/plugin-selection 1.4.1 → 2.0.0-next.0

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 (44) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +445 -166
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +61 -24
  6. package/dist/lib/reducer.d.ts +2 -1
  7. package/dist/lib/selection-plugin.d.ts +25 -5
  8. package/dist/lib/selectors.d.ts +7 -7
  9. package/dist/lib/types.d.ts +62 -9
  10. package/dist/preact/index.cjs +1 -1
  11. package/dist/preact/index.cjs.map +1 -1
  12. package/dist/preact/index.js +88 -34
  13. package/dist/preact/index.js.map +1 -1
  14. package/dist/preact/utils.d.ts +1 -0
  15. package/dist/react/index.cjs +1 -1
  16. package/dist/react/index.cjs.map +1 -1
  17. package/dist/react/index.js +88 -34
  18. package/dist/react/index.js.map +1 -1
  19. package/dist/react/utils.d.ts +1 -0
  20. package/dist/shared/components/selection-layer.d.ts +7 -2
  21. package/dist/shared/index.d.ts +1 -0
  22. package/dist/shared/types.d.ts +7 -0
  23. package/dist/shared-preact/components/selection-layer.d.ts +7 -2
  24. package/dist/shared-preact/index.d.ts +1 -0
  25. package/dist/shared-preact/types.d.ts +7 -0
  26. package/dist/shared-react/components/selection-layer.d.ts +7 -2
  27. package/dist/shared-react/index.d.ts +1 -0
  28. package/dist/shared-react/types.d.ts +7 -0
  29. package/dist/svelte/components/SelectionLayer.svelte.d.ts +13 -2
  30. package/dist/svelte/index.cjs +1 -1
  31. package/dist/svelte/index.cjs.map +1 -1
  32. package/dist/svelte/index.d.ts +1 -0
  33. package/dist/svelte/index.js +162 -34
  34. package/dist/svelte/index.js.map +1 -1
  35. package/dist/svelte/types.d.ts +7 -0
  36. package/dist/vue/components/copy-to-clipboard.vue.d.ts +2 -1
  37. package/dist/vue/components/selection-layer.vue.d.ts +27 -3
  38. package/dist/vue/index.cjs +1 -1
  39. package/dist/vue/index.cjs.map +1 -1
  40. package/dist/vue/index.d.ts +1 -0
  41. package/dist/vue/index.js +137 -43
  42. package/dist/vue/index.js.map +1 -1
  43. package/dist/vue/types.d.ts +7 -0
  44. package/package.json +9 -8
@@ -1,62 +1,116 @@
1
1
  import { createPluginPackage } from "@embedpdf/core";
2
2
  import { SelectionPlugin, SelectionPluginPackage as SelectionPluginPackage$1 } from "@embedpdf/plugin-selection";
3
3
  export * from "@embedpdf/plugin-selection";
4
- import { jsx } from "preact/jsx-runtime";
4
+ import { jsxs, Fragment, jsx } from "preact/jsx-runtime";
5
5
  import "preact";
6
- import { useState, useEffect } from "preact/hooks";
7
- import { useCapability, usePlugin } from "@embedpdf/core/preact";
6
+ import { useState, useEffect, useMemo } from "preact/hooks";
7
+ import { Rotation } from "@embedpdf/models";
8
+ import { useCapability, usePlugin, useDocumentState } from "@embedpdf/core/preact";
9
+ import { CounterRotate } from "@embedpdf/utils/preact";
8
10
  const useSelectionCapability = () => useCapability(SelectionPlugin.id);
9
11
  const useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
10
- function SelectionLayer({ pageIndex, scale, background = "rgba(33,150,243)" }) {
12
+ function SelectionLayer({
13
+ documentId,
14
+ pageIndex,
15
+ scale: scaleOverride,
16
+ rotation: rotationOverride,
17
+ background = "rgba(33,150,243)",
18
+ selectionMenu
19
+ }) {
11
20
  const { plugin: selPlugin } = useSelectionPlugin();
21
+ const documentState = useDocumentState(documentId);
12
22
  const [rects, setRects] = useState([]);
13
23
  const [boundingRect, setBoundingRect] = useState(null);
24
+ const [placement, setPlacement] = useState(null);
14
25
  useEffect(() => {
15
- if (!selPlugin) return;
26
+ if (!selPlugin || !documentId) return;
16
27
  return selPlugin.registerSelectionOnPage({
28
+ documentId,
17
29
  pageIndex,
18
30
  onRectsChange: ({ rects: rects2, boundingRect: boundingRect2 }) => {
19
31
  setRects(rects2);
20
32
  setBoundingRect(boundingRect2);
21
33
  }
22
34
  });
23
- }, [selPlugin, pageIndex]);
35
+ }, [selPlugin, documentId, pageIndex]);
36
+ useEffect(() => {
37
+ if (!selPlugin || !documentId) return;
38
+ return selPlugin.onMenuPlacement(documentId, (newPlacement) => {
39
+ setPlacement(newPlacement);
40
+ });
41
+ }, [selPlugin, documentId]);
42
+ const actualScale = useMemo(() => {
43
+ if (scaleOverride !== void 0) return scaleOverride;
44
+ return (documentState == null ? void 0 : documentState.scale) ?? 1;
45
+ }, [scaleOverride, documentState == null ? void 0 : documentState.scale]);
46
+ const actualRotation = useMemo(() => {
47
+ if (rotationOverride !== void 0) return rotationOverride;
48
+ return (documentState == null ? void 0 : documentState.rotation) ?? Rotation.Degree0;
49
+ }, [rotationOverride, documentState == null ? void 0 : documentState.rotation]);
50
+ const shouldRenderMenu = selectionMenu && placement && placement.pageIndex === pageIndex && placement.isVisible;
24
51
  if (!boundingRect) return null;
25
- return /* @__PURE__ */ jsx(
26
- "div",
27
- {
28
- style: {
29
- position: "absolute",
30
- left: boundingRect.origin.x * scale,
31
- top: boundingRect.origin.y * scale,
32
- width: boundingRect.size.width * scale,
33
- height: boundingRect.size.height * scale,
34
- mixBlendMode: "multiply",
35
- isolation: "isolate"
36
- },
37
- children: rects.map((b, i) => /* @__PURE__ */ jsx(
38
- "div",
39
- {
40
- style: {
41
- position: "absolute",
42
- left: (b.origin.x - boundingRect.origin.x) * scale,
43
- top: (b.origin.y - boundingRect.origin.y) * scale,
44
- width: b.size.width * scale,
45
- height: b.size.height * scale,
46
- background,
47
- pointerEvents: "none"
52
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
53
+ /* @__PURE__ */ jsx(
54
+ "div",
55
+ {
56
+ style: {
57
+ position: "absolute",
58
+ left: boundingRect.origin.x * actualScale,
59
+ top: boundingRect.origin.y * actualScale,
60
+ width: boundingRect.size.width * actualScale,
61
+ height: boundingRect.size.height * actualScale,
62
+ mixBlendMode: "multiply",
63
+ isolation: "isolate",
64
+ pointerEvents: "none"
65
+ },
66
+ children: rects.map((b, i) => /* @__PURE__ */ jsx(
67
+ "div",
68
+ {
69
+ style: {
70
+ position: "absolute",
71
+ left: (b.origin.x - boundingRect.origin.x) * actualScale,
72
+ top: (b.origin.y - boundingRect.origin.y) * actualScale,
73
+ width: b.size.width * actualScale,
74
+ height: b.size.height * actualScale,
75
+ background
76
+ }
77
+ },
78
+ i
79
+ ))
80
+ }
81
+ ),
82
+ shouldRenderMenu && /* @__PURE__ */ jsx(
83
+ CounterRotate,
84
+ {
85
+ rect: {
86
+ origin: {
87
+ x: placement.rect.origin.x * actualScale,
88
+ y: placement.rect.origin.y * actualScale
89
+ },
90
+ size: {
91
+ width: placement.rect.size.width * actualScale,
92
+ height: placement.rect.size.height * actualScale
48
93
  }
49
94
  },
50
- i
51
- ))
52
- }
53
- );
95
+ rotation: actualRotation,
96
+ children: (props) => selectionMenu({
97
+ ...props,
98
+ context: {
99
+ type: "selection",
100
+ pageIndex
101
+ },
102
+ selected: true,
103
+ placement
104
+ })
105
+ }
106
+ )
107
+ ] });
54
108
  }
55
109
  function CopyToClipboard() {
56
110
  const { provides: sel } = useSelectionCapability();
57
111
  useEffect(() => {
58
112
  if (!sel) return;
59
- return sel.onCopyToClipboard((text) => {
113
+ return sel.onCopyToClipboard(({ text }) => {
60
114
  navigator.clipboard.writeText(text);
61
115
  });
62
116
  }, [sel]);
@@ -1 +1 @@
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","../../src/shared/index.ts"],"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, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\nimport { useSelectionCapability, useSelectionPlugin } 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 { plugin: selPlugin } = useSelectionPlugin();\n const [rects, setRects] = useState<Rect[]>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!selPlugin) return;\n\n return selPlugin.registerSelectionOnPage({\n pageIndex,\n onRectsChange: ({ rects, boundingRect }) => {\n setRects(rects);\n setBoundingRect(boundingRect);\n },\n });\n }, [selPlugin, pageIndex]);\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","import { createPluginPackage } from '@embedpdf/core';\nimport { SelectionPluginPackage as BaseSelectionPluginPackage } from '@embedpdf/plugin-selection';\n\nimport { CopyToClipboard } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-selection';\n\nexport const SelectionPluginPackage = createPluginPackage(BaseSelectionPluginPackage)\n .addUtility(CopyToClipboard)\n .build();\n"],"names":["rects","boundingRect","BaseSelectionPluginPackage"],"mappings":";;;;;;;AAGO,MAAM,yBAAyB,MAAM,cAA+B,gBAAgB,EAAE;AACtF,MAAM,qBAAqB,MAAM,UAA2B,gBAAgB,EAAE;ACM9E,SAAS,eAAe,EAAE,WAAW,OAAO,aAAa,sBAA6B;AAC3F,QAAM,EAAE,QAAQ,UAAU,IAAI,mBAAmB;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAC7C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAsB,IAAI;AAElE,YAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAEhB,WAAO,UAAU,wBAAwB;AAAA,MACvC;AAAA,MACA,eAAe,CAAC,EAAE,OAAAA,QAAO,cAAAC,oBAAmB;AAC1C,iBAASD,MAAK;AACd,wBAAgBC,aAAY;AAAA,MAAA;AAAA,IAC9B,CACD;AAAA,EAAA,GACA,CAAC,WAAW,SAAS,CAAC;AAErB,MAAA,CAAC,aAAqB,QAAA;AAGxB,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,aAAa,OAAO,IAAI;AAAA,QAC9B,KAAK,aAAa,OAAO,IAAI;AAAA,QAC7B,OAAO,aAAa,KAAK,QAAQ;AAAA,QACjC,QAAQ,aAAa,KAAK,SAAS;AAAA,QACnC,cAAc;AAAA,QACd,WAAW;AAAA,MACb;AAAA,MAEC,UAAM,MAAA,IAAI,CAAC,GAAG,MACb;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,OAAO;AAAA,YACL,UAAU;AAAA,YACV,OAAO,EAAE,OAAO,IAAI,aAAa,OAAO,KAAK;AAAA,YAC7C,MAAM,EAAE,OAAO,IAAI,aAAa,OAAO,KAAK;AAAA,YAC5C,OAAO,EAAE,KAAK,QAAQ;AAAA,YACtB,QAAQ,EAAE,KAAK,SAAS;AAAA,YACxB;AAAA,YACA,eAAe;AAAA,UAAA;AAAA,QACjB;AAAA,QATK;AAAA,MAWR,CAAA;AAAA,IAAA;AAAA,EACH;AAEJ;ACrDO,SAAS,kBAAkB;AAChC,QAAM,EAAE,UAAU,IAAI,IAAI,uBAAuB;AAEjD,YAAU,MAAM;AACd,QAAI,CAAC,IAAK;AACH,WAAA,IAAI,kBAAkB,CAAC,SAAS;AAC3B,gBAAA,UAAU,UAAU,IAAI;AAAA,IAAA,CACnC;AAAA,EAAA,GACA,CAAC,GAAG,CAAC;AAED,SAAA;AACT;ACNO,MAAM,yBAAyB,oBAAoBC,wBAA0B,EACjF,WAAW,eAAe,EAC1B,MAAM;"}
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","../../src/shared/index.ts"],"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, useMemo, useState } from '@framework';\nimport { Rect, Rotation } from '@embedpdf/models';\nimport { useSelectionPlugin } from '../hooks';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SelectionMenuPlacement } from '@embedpdf/plugin-selection';\nimport { SelectionSelectionMenuRenderFn } from '../types';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\n\ntype Props = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n background?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\nexport function SelectionLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n rotation: rotationOverride,\n background = 'rgba(33,150,243)',\n selectionMenu,\n}: Props) {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rects, setRects] = useState<Rect[]>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n // Store the placement object from the plugin\n const [placement, setPlacement] = useState<SelectionMenuPlacement | null>(null);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n return selPlugin.registerSelectionOnPage({\n documentId,\n pageIndex,\n onRectsChange: ({ rects, boundingRect }) => {\n setRects(rects);\n setBoundingRect(boundingRect);\n },\n });\n }, [selPlugin, documentId, pageIndex]);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n // Subscribe to menu placement changes for this specific document\n return selPlugin.onMenuPlacement(documentId, (newPlacement) => {\n // Optimization: We could filter here, but React state updates are cheap enough usually.\n // Ideally, check: if (newPlacement?.pageIndex === pageIndex)\n setPlacement(newPlacement);\n });\n }, [selPlugin, documentId]);\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (rotationOverride !== undefined) return rotationOverride;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [rotationOverride, documentState?.rotation]);\n\n const shouldRenderMenu =\n selectionMenu && placement && placement.pageIndex === pageIndex && placement.isVisible;\n\n if (!boundingRect) return null;\n\n return (\n <>\n <div\n style={{\n position: 'absolute',\n left: boundingRect.origin.x * actualScale,\n top: boundingRect.origin.y * actualScale,\n width: boundingRect.size.width * actualScale,\n height: boundingRect.size.height * actualScale,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n pointerEvents: 'none',\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) * actualScale,\n top: (b.origin.y - boundingRect.origin.y) * actualScale,\n width: b.size.width * actualScale,\n height: b.size.height * actualScale,\n background,\n }}\n />\n ))}\n </div>\n {shouldRenderMenu && (\n <CounterRotate\n rect={{\n origin: {\n x: placement.rect.origin.x * actualScale,\n y: placement.rect.origin.y * actualScale,\n },\n size: {\n width: placement.rect.size.width * actualScale,\n height: placement.rect.size.height * actualScale,\n },\n }}\n rotation={actualRotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'selection',\n pageIndex,\n },\n selected: true,\n placement,\n })\n }\n </CounterRotate>\n )}\n </>\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","import { createPluginPackage } from '@embedpdf/core';\nimport { SelectionPluginPackage as BaseSelectionPluginPackage } from '@embedpdf/plugin-selection';\n\nimport { CopyToClipboard } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from './types';\nexport * from '@embedpdf/plugin-selection';\n\nexport const SelectionPluginPackage = createPluginPackage(BaseSelectionPluginPackage)\n .addUtility(CopyToClipboard)\n .build();\n"],"names":["rects","boundingRect","BaseSelectionPluginPackage"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from '@embedpdf/utils/preact';
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-selection"),i=require("react/jsx-runtime"),o=require("react"),n=require("@embedpdf/core/react"),r=()=>n.useCapability(t.SelectionPlugin.id),l=()=>n.usePlugin(t.SelectionPlugin.id);function s(){const{provides:e}=r();return o.useEffect((()=>{if(e)return e.onCopyToClipboard((e=>{navigator.clipboard.writeText(e)}))}),[e]),null}const u=e.createPluginPackage(t.SelectionPluginPackage).addUtility(s).build();exports.CopyToClipboard=s,exports.SelectionLayer=function({pageIndex:e,scale:t,background:n="rgba(33,150,243)"}){const{plugin:r}=l(),[s,u]=o.useState([]),[a,c]=o.useState(null);return o.useEffect((()=>{if(r)return r.registerSelectionOnPage({pageIndex:e,onRectsChange:({rects:e,boundingRect:t})=>{u(e),c(t)}})}),[r,e]),a?i.jsx("div",{style:{position:"absolute",left:a.origin.x*t,top:a.origin.y*t,width:a.size.width*t,height:a.size.height*t,mixBlendMode:"multiply",isolation:"isolate"},children:s.map(((e,o)=>i.jsx("div",{style:{position:"absolute",left:(e.origin.x-a.origin.x)*t,top:(e.origin.y-a.origin.y)*t,width:e.size.width*t,height:e.size.height*t,background:n,pointerEvents:"none"}},o)))}):null},exports.SelectionPluginPackage=u,exports.useSelectionCapability=r,exports.useSelectionPlugin=l,Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-selection"),i=require("react/jsx-runtime"),o=require("react"),n=require("@embedpdf/models"),r=require("@embedpdf/core/react"),l=require("@embedpdf/utils/react"),s=()=>r.useCapability(t.SelectionPlugin.id),u=()=>r.usePlugin(t.SelectionPlugin.id);function c(){const{provides:e}=s();return o.useEffect(()=>{if(e)return e.onCopyToClipboard(({text:e})=>{navigator.clipboard.writeText(e)})},[e]),null}const a=e.createPluginPackage(t.SelectionPluginPackage).addUtility(c).build();exports.CopyToClipboard=c,exports.SelectionLayer=function({documentId:e,pageIndex:t,scale:s,rotation:c,background:a="rgba(33,150,243)",selectionMenu:d}){const{plugin:g}=u(),p=r.useDocumentState(e),[x,b]=o.useState([]),[h,f]=o.useState(null),[y,m]=o.useState(null);o.useEffect(()=>{if(g&&e)return g.registerSelectionOnPage({documentId:e,pageIndex:t,onRectsChange:({rects:e,boundingRect:t})=>{b(e),f(t)}})},[g,e,t]),o.useEffect(()=>{if(g&&e)return g.onMenuPlacement(e,e=>{m(e)})},[g,e]);const P=o.useMemo(()=>void 0!==s?s:(null==p?void 0:p.scale)??1,[s,null==p?void 0:p.scale]),S=o.useMemo(()=>void 0!==c?c:(null==p?void 0:p.rotation)??n.Rotation.Degree0,[c,null==p?void 0:p.rotation]),v=d&&y&&y.pageIndex===t&&y.isVisible;return h?i.jsxs(i.Fragment,{children:[i.jsx("div",{style:{position:"absolute",left:h.origin.x*P,top:h.origin.y*P,width:h.size.width*P,height:h.size.height*P,mixBlendMode:"multiply",isolation:"isolate",pointerEvents:"none"},children:x.map((e,t)=>i.jsx("div",{style:{position:"absolute",left:(e.origin.x-h.origin.x)*P,top:(e.origin.y-h.origin.y)*P,width:e.size.width*P,height:e.size.height*P,background:a}},t))}),v&&i.jsx(l.CounterRotate,{rect:{origin:{x:y.rect.origin.x*P,y:y.rect.origin.y*P},size:{width:y.rect.size.width*P,height:y.rect.size.height*P}},rotation:S,children:e=>d({...e,context:{type:"selection",pageIndex:t},selected:!0,placement:y})})]}):null},exports.SelectionPluginPackage=a,exports.useSelectionCapability=s,exports.useSelectionPlugin=u,Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/copy-to-clipboard.tsx","../../src/shared/index.ts","../../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 { createPluginPackage } from '@embedpdf/core';\nimport { SelectionPluginPackage as BaseSelectionPluginPackage } from '@embedpdf/plugin-selection';\n\nimport { CopyToClipboard } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-selection';\n\nexport const SelectionPluginPackage = createPluginPackage(BaseSelectionPluginPackage)\n .addUtility(CopyToClipboard)\n .build();\n","import { useEffect, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\nimport { useSelectionCapability, useSelectionPlugin } 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 { plugin: selPlugin } = useSelectionPlugin();\n const [rects, setRects] = useState<Rect[]>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!selPlugin) return;\n\n return selPlugin.registerSelectionOnPage({\n pageIndex,\n onRectsChange: ({ rects, boundingRect }) => {\n setRects(rects);\n setBoundingRect(boundingRect);\n },\n });\n }, [selPlugin, pageIndex]);\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","useSelectionPlugin","usePlugin","CopyToClipboard","provides","sel","useEffect","onCopyToClipboard","text","navigator","clipboard","writeText","SelectionPluginPackage","createPluginPackage","BaseSelectionPluginPackage","addUtility","build","pageIndex","scale","background","plugin","selPlugin","rects","setRects","useState","boundingRect","setBoundingRect","registerSelectionOnPage","onRectsChange","jsxRuntime","jsx","style","position","left","origin","x","top","y","width","size","height","mixBlendMode","isolation","children","map","b","i","pointerEvents"],"mappings":"8OAGaA,EAAyB,IAAMC,gBAA+BC,EAAAA,gBAAgBC,IAC9EC,EAAqB,IAAMC,YAA2BH,EAAAA,gBAAgBC,ICA5E,SAASG,IACd,MAAQC,SAAUC,GAAQR,IASnB,OAPPS,EAAAA,WAAU,KACR,GAAKD,EACE,OAAAA,EAAIE,mBAAmBC,IAClBC,UAAAC,UAAUC,UAAUH,EAAI,GACnC,GACA,CAACH,IAEG,IACT,CCNO,MAAMO,EAAyBC,EAAoBA,oBAAAC,EAA0BF,wBACjFG,WAAWZ,GACXa,yDCDI,UAAwBC,UAAEA,EAAAC,MAAWA,EAAOC,WAAAA,EAAa,qBAC9D,MAAQC,OAAQC,GAAcpB,KACvBqB,EAAOC,GAAYC,EAAAA,SAAiB,KACpCC,EAAcC,GAAmBF,EAAAA,SAAsB,MAc1D,OAZJlB,EAAAA,WAAU,KACR,GAAKe,EAEL,OAAOA,EAAUM,wBAAwB,CACvCV,YACAW,cAAe,EAAGN,MAAAA,EAAOG,aAAAA,MACvBF,EAASD,GACTI,EAAgBD,EAAY,GAE/B,GACA,CAACJ,EAAWJ,IAEVQ,EAGHI,EAAAC,IAAC,MAAA,CACCC,MAAO,CACLC,SAAU,WACVC,KAAMR,EAAaS,OAAOC,EAAIjB,EAC9BkB,IAAKX,EAAaS,OAAOG,EAAInB,EAC7BoB,MAAOb,EAAac,KAAKD,MAAQpB,EACjCsB,OAAQf,EAAac,KAAKC,OAAStB,EACnCuB,aAAc,WACdC,UAAW,WAGZC,SAAMrB,EAAAsB,KAAI,CAACC,EAAGC,IACbjB,EAAAC,IAAC,MAAA,CAECC,MAAO,CACLC,SAAU,WACVC,MAAOY,EAAEX,OAAOC,EAAIV,EAAaS,OAAOC,GAAKjB,EAC7CkB,KAAMS,EAAEX,OAAOG,EAAIZ,EAAaS,OAAOG,GAAKnB,EAC5CoB,MAAOO,EAAEN,KAAKD,MAAQpB,EACtBsB,OAAQK,EAAEN,KAAKC,OAAStB,EACxBC,aACA4B,cAAe,SARZD,OAhBa,IA8B5B"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/copy-to-clipboard.tsx","../../src/shared/index.ts","../../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 { createPluginPackage } from '@embedpdf/core';\nimport { SelectionPluginPackage as BaseSelectionPluginPackage } from '@embedpdf/plugin-selection';\n\nimport { CopyToClipboard } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from './types';\nexport * from '@embedpdf/plugin-selection';\n\nexport const SelectionPluginPackage = createPluginPackage(BaseSelectionPluginPackage)\n .addUtility(CopyToClipboard)\n .build();\n","import { useEffect, useMemo, useState } from '@framework';\nimport { Rect, Rotation } from '@embedpdf/models';\nimport { useSelectionPlugin } from '../hooks';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SelectionMenuPlacement } from '@embedpdf/plugin-selection';\nimport { SelectionSelectionMenuRenderFn } from '../types';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\n\ntype Props = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n background?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\nexport function SelectionLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n rotation: rotationOverride,\n background = 'rgba(33,150,243)',\n selectionMenu,\n}: Props) {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rects, setRects] = useState<Rect[]>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n // Store the placement object from the plugin\n const [placement, setPlacement] = useState<SelectionMenuPlacement | null>(null);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n return selPlugin.registerSelectionOnPage({\n documentId,\n pageIndex,\n onRectsChange: ({ rects, boundingRect }) => {\n setRects(rects);\n setBoundingRect(boundingRect);\n },\n });\n }, [selPlugin, documentId, pageIndex]);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n // Subscribe to menu placement changes for this specific document\n return selPlugin.onMenuPlacement(documentId, (newPlacement) => {\n // Optimization: We could filter here, but React state updates are cheap enough usually.\n // Ideally, check: if (newPlacement?.pageIndex === pageIndex)\n setPlacement(newPlacement);\n });\n }, [selPlugin, documentId]);\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (rotationOverride !== undefined) return rotationOverride;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [rotationOverride, documentState?.rotation]);\n\n const shouldRenderMenu =\n selectionMenu && placement && placement.pageIndex === pageIndex && placement.isVisible;\n\n if (!boundingRect) return null;\n\n return (\n <>\n <div\n style={{\n position: 'absolute',\n left: boundingRect.origin.x * actualScale,\n top: boundingRect.origin.y * actualScale,\n width: boundingRect.size.width * actualScale,\n height: boundingRect.size.height * actualScale,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n pointerEvents: 'none',\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) * actualScale,\n top: (b.origin.y - boundingRect.origin.y) * actualScale,\n width: b.size.width * actualScale,\n height: b.size.height * actualScale,\n background,\n }}\n />\n ))}\n </div>\n {shouldRenderMenu && (\n <CounterRotate\n rect={{\n origin: {\n x: placement.rect.origin.x * actualScale,\n y: placement.rect.origin.y * actualScale,\n },\n size: {\n width: placement.rect.size.width * actualScale,\n height: placement.rect.size.height * actualScale,\n },\n }}\n rotation={actualRotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'selection',\n pageIndex,\n },\n selected: true,\n placement,\n })\n }\n </CounterRotate>\n )}\n </>\n );\n}\n"],"names":["useSelectionCapability","useCapability","SelectionPlugin","id","useSelectionPlugin","usePlugin","CopyToClipboard","provides","sel","useEffect","onCopyToClipboard","text","navigator","clipboard","writeText","SelectionPluginPackage","createPluginPackage","BaseSelectionPluginPackage","addUtility","build","documentId","pageIndex","scale","scaleOverride","rotation","rotationOverride","background","selectionMenu","plugin","selPlugin","documentState","useDocumentState","rects","setRects","useState","boundingRect","setBoundingRect","placement","setPlacement","registerSelectionOnPage","onRectsChange","onMenuPlacement","newPlacement","actualScale","useMemo","actualRotation","Rotation","Degree0","shouldRenderMenu","isVisible","jsxs","Fragment","children","jsx","style","position","left","origin","x","top","y","width","size","height","mixBlendMode","isolation","pointerEvents","map","b","i","CounterRotate","rect","props","context","type","selected"],"mappings":"+SAGaA,EAAyB,IAAMC,gBAA+BC,EAAAA,gBAAgBC,IAC9EC,EAAqB,IAAMC,YAA2BH,EAAAA,gBAAgBC,ICA5E,SAASG,IACd,MAAQC,SAAUC,GAAQR,IAS1B,OAPAS,EAAAA,UAAU,KACR,GAAKD,EACL,OAAOA,EAAIE,kBAAkB,EAAGC,WAC9BC,UAAUC,UAAUC,UAAUH,MAE/B,CAACH,IAEG,IACT,CCLO,MAAMO,EAAyBC,EAAAA,oBAAoBC,EAAAA,wBACvDC,WAAWZ,GACXa,yDCKI,UAAwBC,WAC7BA,EAAAC,UACAA,EACAC,MAAOC,EACPC,SAAUC,EAAAC,WACVA,EAAa,mBAAAC,cACbA,IAEA,MAAQC,OAAQC,GAAczB,IACxB0B,EAAgBC,EAAAA,iBAAiBX,IAChCY,EAAOC,GAAYC,EAAAA,SAAiB,KACpCC,EAAcC,GAAmBF,EAAAA,SAAsB,OAGvDG,EAAWC,GAAgBJ,EAAAA,SAAwC,MAE1EzB,EAAAA,UAAU,KACR,GAAKoB,GAAcT,EAEnB,OAAOS,EAAUU,wBAAwB,CACvCnB,aACAC,YACAmB,cAAe,EAAGR,MAAAA,EAAOG,aAAAA,MACvBF,EAASD,GACTI,EAAgBD,OAGnB,CAACN,EAAWT,EAAYC,IAE3BZ,EAAAA,UAAU,KACR,GAAKoB,GAAcT,EAGnB,OAAOS,EAAUY,gBAAgBrB,EAAasB,IAG5CJ,EAAaI,MAEd,CAACb,EAAWT,IAEf,MAAMuB,EAAcC,EAAAA,QAAQ,SACJ,IAAlBrB,EAAoCA,SACjCO,WAAeR,QAAS,EAC9B,CAACC,EAAe,MAAAO,OAAA,EAAAA,EAAeR,QAE5BuB,EAAiBD,EAAAA,QAAQ,SACJ,IAArBnB,EAAuCA,GACpC,MAAAK,OAAA,EAAAA,EAAeN,WAAYsB,EAAAA,SAASC,QAC1C,CAACtB,EAAkB,MAAAK,OAAA,EAAAA,EAAeN,WAE/BwB,EACJrB,GAAiBU,GAAaA,EAAUhB,YAAcA,GAAagB,EAAUY,UAE/E,OAAKd,EAGHe,EAAAA,KAAAC,WAAA,CACEC,SAAA,CAAAC,EAAAA,IAAC,MAAA,CACCC,MAAO,CACLC,SAAU,WACVC,KAAMrB,EAAasB,OAAOC,EAAIf,EAC9BgB,IAAKxB,EAAasB,OAAOG,EAAIjB,EAC7BkB,MAAO1B,EAAa2B,KAAKD,MAAQlB,EACjCoB,OAAQ5B,EAAa2B,KAAKC,OAASpB,EACnCqB,aAAc,WACdC,UAAW,UACXC,cAAe,QAGhBd,SAAApB,EAAMmC,IAAI,CAACC,EAAGC,IACbhB,EAAAA,IAAC,MAAA,CAECC,MAAO,CACLC,SAAU,WACVC,MAAOY,EAAEX,OAAOC,EAAIvB,EAAasB,OAAOC,GAAKf,EAC7CgB,KAAMS,EAAEX,OAAOG,EAAIzB,EAAasB,OAAOG,GAAKjB,EAC5CkB,MAAOO,EAAEN,KAAKD,MAAQlB,EACtBoB,OAAQK,EAAEN,KAAKC,OAASpB,EACxBjB,eAPG2C,MAYVrB,GACCK,EAAAA,IAACiB,EAAAA,cAAA,CACCC,KAAM,CACJd,OAAQ,CACNC,EAAGrB,EAAUkC,KAAKd,OAAOC,EAAIf,EAC7BiB,EAAGvB,EAAUkC,KAAKd,OAAOG,EAAIjB,GAE/BmB,KAAM,CACJD,MAAOxB,EAAUkC,KAAKT,KAAKD,MAAQlB,EACnCoB,OAAQ1B,EAAUkC,KAAKT,KAAKC,OAASpB,IAGzCnB,SAAUqB,EAETO,SAACoB,GACA7C,EAAc,IACT6C,EACHC,QAAS,CACPC,KAAM,YACNrD,aAEFsD,UAAU,EACVtC,mBApDc,IA2D5B"}
@@ -1,61 +1,115 @@
1
1
  import { createPluginPackage } from "@embedpdf/core";
2
2
  import { SelectionPlugin, SelectionPluginPackage as SelectionPluginPackage$1 } from "@embedpdf/plugin-selection";
3
3
  export * from "@embedpdf/plugin-selection";
4
- import { jsx } from "react/jsx-runtime";
5
- import { useState, useEffect } from "react";
6
- import { useCapability, usePlugin } from "@embedpdf/core/react";
4
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
5
+ import { useState, useEffect, useMemo } from "react";
6
+ import { Rotation } from "@embedpdf/models";
7
+ import { useCapability, usePlugin, useDocumentState } from "@embedpdf/core/react";
8
+ import { CounterRotate } from "@embedpdf/utils/react";
7
9
  const useSelectionCapability = () => useCapability(SelectionPlugin.id);
8
10
  const useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
9
- function SelectionLayer({ pageIndex, scale, background = "rgba(33,150,243)" }) {
11
+ function SelectionLayer({
12
+ documentId,
13
+ pageIndex,
14
+ scale: scaleOverride,
15
+ rotation: rotationOverride,
16
+ background = "rgba(33,150,243)",
17
+ selectionMenu
18
+ }) {
10
19
  const { plugin: selPlugin } = useSelectionPlugin();
20
+ const documentState = useDocumentState(documentId);
11
21
  const [rects, setRects] = useState([]);
12
22
  const [boundingRect, setBoundingRect] = useState(null);
23
+ const [placement, setPlacement] = useState(null);
13
24
  useEffect(() => {
14
- if (!selPlugin) return;
25
+ if (!selPlugin || !documentId) return;
15
26
  return selPlugin.registerSelectionOnPage({
27
+ documentId,
16
28
  pageIndex,
17
29
  onRectsChange: ({ rects: rects2, boundingRect: boundingRect2 }) => {
18
30
  setRects(rects2);
19
31
  setBoundingRect(boundingRect2);
20
32
  }
21
33
  });
22
- }, [selPlugin, pageIndex]);
34
+ }, [selPlugin, documentId, pageIndex]);
35
+ useEffect(() => {
36
+ if (!selPlugin || !documentId) return;
37
+ return selPlugin.onMenuPlacement(documentId, (newPlacement) => {
38
+ setPlacement(newPlacement);
39
+ });
40
+ }, [selPlugin, documentId]);
41
+ const actualScale = useMemo(() => {
42
+ if (scaleOverride !== void 0) return scaleOverride;
43
+ return (documentState == null ? void 0 : documentState.scale) ?? 1;
44
+ }, [scaleOverride, documentState == null ? void 0 : documentState.scale]);
45
+ const actualRotation = useMemo(() => {
46
+ if (rotationOverride !== void 0) return rotationOverride;
47
+ return (documentState == null ? void 0 : documentState.rotation) ?? Rotation.Degree0;
48
+ }, [rotationOverride, documentState == null ? void 0 : documentState.rotation]);
49
+ const shouldRenderMenu = selectionMenu && placement && placement.pageIndex === pageIndex && placement.isVisible;
23
50
  if (!boundingRect) return null;
24
- return /* @__PURE__ */ jsx(
25
- "div",
26
- {
27
- style: {
28
- position: "absolute",
29
- left: boundingRect.origin.x * scale,
30
- top: boundingRect.origin.y * scale,
31
- width: boundingRect.size.width * scale,
32
- height: boundingRect.size.height * scale,
33
- mixBlendMode: "multiply",
34
- isolation: "isolate"
35
- },
36
- children: rects.map((b, i) => /* @__PURE__ */ jsx(
37
- "div",
38
- {
39
- style: {
40
- position: "absolute",
41
- left: (b.origin.x - boundingRect.origin.x) * scale,
42
- top: (b.origin.y - boundingRect.origin.y) * scale,
43
- width: b.size.width * scale,
44
- height: b.size.height * scale,
45
- background,
46
- pointerEvents: "none"
51
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
52
+ /* @__PURE__ */ jsx(
53
+ "div",
54
+ {
55
+ style: {
56
+ position: "absolute",
57
+ left: boundingRect.origin.x * actualScale,
58
+ top: boundingRect.origin.y * actualScale,
59
+ width: boundingRect.size.width * actualScale,
60
+ height: boundingRect.size.height * actualScale,
61
+ mixBlendMode: "multiply",
62
+ isolation: "isolate",
63
+ pointerEvents: "none"
64
+ },
65
+ children: rects.map((b, i) => /* @__PURE__ */ jsx(
66
+ "div",
67
+ {
68
+ style: {
69
+ position: "absolute",
70
+ left: (b.origin.x - boundingRect.origin.x) * actualScale,
71
+ top: (b.origin.y - boundingRect.origin.y) * actualScale,
72
+ width: b.size.width * actualScale,
73
+ height: b.size.height * actualScale,
74
+ background
75
+ }
76
+ },
77
+ i
78
+ ))
79
+ }
80
+ ),
81
+ shouldRenderMenu && /* @__PURE__ */ jsx(
82
+ CounterRotate,
83
+ {
84
+ rect: {
85
+ origin: {
86
+ x: placement.rect.origin.x * actualScale,
87
+ y: placement.rect.origin.y * actualScale
88
+ },
89
+ size: {
90
+ width: placement.rect.size.width * actualScale,
91
+ height: placement.rect.size.height * actualScale
47
92
  }
48
93
  },
49
- i
50
- ))
51
- }
52
- );
94
+ rotation: actualRotation,
95
+ children: (props) => selectionMenu({
96
+ ...props,
97
+ context: {
98
+ type: "selection",
99
+ pageIndex
100
+ },
101
+ selected: true,
102
+ placement
103
+ })
104
+ }
105
+ )
106
+ ] });
53
107
  }
54
108
  function CopyToClipboard() {
55
109
  const { provides: sel } = useSelectionCapability();
56
110
  useEffect(() => {
57
111
  if (!sel) return;
58
- return sel.onCopyToClipboard((text) => {
112
+ return sel.onCopyToClipboard(({ text }) => {
59
113
  navigator.clipboard.writeText(text);
60
114
  });
61
115
  }, [sel]);
@@ -1 +1 @@
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","../../src/shared/index.ts"],"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, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\nimport { useSelectionCapability, useSelectionPlugin } 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 { plugin: selPlugin } = useSelectionPlugin();\n const [rects, setRects] = useState<Rect[]>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!selPlugin) return;\n\n return selPlugin.registerSelectionOnPage({\n pageIndex,\n onRectsChange: ({ rects, boundingRect }) => {\n setRects(rects);\n setBoundingRect(boundingRect);\n },\n });\n }, [selPlugin, pageIndex]);\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","import { createPluginPackage } from '@embedpdf/core';\nimport { SelectionPluginPackage as BaseSelectionPluginPackage } from '@embedpdf/plugin-selection';\n\nimport { CopyToClipboard } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-selection';\n\nexport const SelectionPluginPackage = createPluginPackage(BaseSelectionPluginPackage)\n .addUtility(CopyToClipboard)\n .build();\n"],"names":["rects","boundingRect","BaseSelectionPluginPackage"],"mappings":";;;;;;AAGO,MAAM,yBAAyB,MAAM,cAA+B,gBAAgB,EAAE;AACtF,MAAM,qBAAqB,MAAM,UAA2B,gBAAgB,EAAE;ACM9E,SAAS,eAAe,EAAE,WAAW,OAAO,aAAa,sBAA6B;AAC3F,QAAM,EAAE,QAAQ,UAAU,IAAI,mBAAmB;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAC7C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAsB,IAAI;AAElE,YAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAEhB,WAAO,UAAU,wBAAwB;AAAA,MACvC;AAAA,MACA,eAAe,CAAC,EAAE,OAAAA,QAAO,cAAAC,oBAAmB;AAC1C,iBAASD,MAAK;AACd,wBAAgBC,aAAY;AAAA,MAAA;AAAA,IAC9B,CACD;AAAA,EAAA,GACA,CAAC,WAAW,SAAS,CAAC;AAErB,MAAA,CAAC,aAAqB,QAAA;AAGxB,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,aAAa,OAAO,IAAI;AAAA,QAC9B,KAAK,aAAa,OAAO,IAAI;AAAA,QAC7B,OAAO,aAAa,KAAK,QAAQ;AAAA,QACjC,QAAQ,aAAa,KAAK,SAAS;AAAA,QACnC,cAAc;AAAA,QACd,WAAW;AAAA,MACb;AAAA,MAEC,UAAM,MAAA,IAAI,CAAC,GAAG,MACb;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,OAAO;AAAA,YACL,UAAU;AAAA,YACV,OAAO,EAAE,OAAO,IAAI,aAAa,OAAO,KAAK;AAAA,YAC7C,MAAM,EAAE,OAAO,IAAI,aAAa,OAAO,KAAK;AAAA,YAC5C,OAAO,EAAE,KAAK,QAAQ;AAAA,YACtB,QAAQ,EAAE,KAAK,SAAS;AAAA,YACxB;AAAA,YACA,eAAe;AAAA,UAAA;AAAA,QACjB;AAAA,QATK;AAAA,MAWR,CAAA;AAAA,IAAA;AAAA,EACH;AAEJ;ACrDO,SAAS,kBAAkB;AAChC,QAAM,EAAE,UAAU,IAAI,IAAI,uBAAuB;AAEjD,YAAU,MAAM;AACd,QAAI,CAAC,IAAK;AACH,WAAA,IAAI,kBAAkB,CAAC,SAAS;AAC3B,gBAAA,UAAU,UAAU,IAAI;AAAA,IAAA,CACnC;AAAA,EAAA,GACA,CAAC,GAAG,CAAC;AAED,SAAA;AACT;ACNO,MAAM,yBAAyB,oBAAoBC,wBAA0B,EACjF,WAAW,eAAe,EAC1B,MAAM;"}
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","../../src/shared/index.ts"],"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, useMemo, useState } from '@framework';\nimport { Rect, Rotation } from '@embedpdf/models';\nimport { useSelectionPlugin } from '../hooks';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SelectionMenuPlacement } from '@embedpdf/plugin-selection';\nimport { SelectionSelectionMenuRenderFn } from '../types';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\n\ntype Props = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n background?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\nexport function SelectionLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n rotation: rotationOverride,\n background = 'rgba(33,150,243)',\n selectionMenu,\n}: Props) {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rects, setRects] = useState<Rect[]>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n // Store the placement object from the plugin\n const [placement, setPlacement] = useState<SelectionMenuPlacement | null>(null);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n return selPlugin.registerSelectionOnPage({\n documentId,\n pageIndex,\n onRectsChange: ({ rects, boundingRect }) => {\n setRects(rects);\n setBoundingRect(boundingRect);\n },\n });\n }, [selPlugin, documentId, pageIndex]);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n // Subscribe to menu placement changes for this specific document\n return selPlugin.onMenuPlacement(documentId, (newPlacement) => {\n // Optimization: We could filter here, but React state updates are cheap enough usually.\n // Ideally, check: if (newPlacement?.pageIndex === pageIndex)\n setPlacement(newPlacement);\n });\n }, [selPlugin, documentId]);\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (rotationOverride !== undefined) return rotationOverride;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [rotationOverride, documentState?.rotation]);\n\n const shouldRenderMenu =\n selectionMenu && placement && placement.pageIndex === pageIndex && placement.isVisible;\n\n if (!boundingRect) return null;\n\n return (\n <>\n <div\n style={{\n position: 'absolute',\n left: boundingRect.origin.x * actualScale,\n top: boundingRect.origin.y * actualScale,\n width: boundingRect.size.width * actualScale,\n height: boundingRect.size.height * actualScale,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n pointerEvents: 'none',\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) * actualScale,\n top: (b.origin.y - boundingRect.origin.y) * actualScale,\n width: b.size.width * actualScale,\n height: b.size.height * actualScale,\n background,\n }}\n />\n ))}\n </div>\n {shouldRenderMenu && (\n <CounterRotate\n rect={{\n origin: {\n x: placement.rect.origin.x * actualScale,\n y: placement.rect.origin.y * actualScale,\n },\n size: {\n width: placement.rect.size.width * actualScale,\n height: placement.rect.size.height * actualScale,\n },\n }}\n rotation={actualRotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'selection',\n pageIndex,\n },\n selected: true,\n placement,\n })\n }\n </CounterRotate>\n )}\n </>\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","import { createPluginPackage } from '@embedpdf/core';\nimport { SelectionPluginPackage as BaseSelectionPluginPackage } from '@embedpdf/plugin-selection';\n\nimport { CopyToClipboard } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from './types';\nexport * from '@embedpdf/plugin-selection';\n\nexport const SelectionPluginPackage = createPluginPackage(BaseSelectionPluginPackage)\n .addUtility(CopyToClipboard)\n .build();\n"],"names":["rects","boundingRect","BaseSelectionPluginPackage"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from '@embedpdf/utils/react';
@@ -1,7 +1,12 @@
1
+ import { Rotation } from '@embedpdf/models';
2
+ import { SelectionSelectionMenuRenderFn } from '../types';
1
3
  type Props = {
4
+ documentId: string;
2
5
  pageIndex: number;
3
- scale: number;
6
+ scale?: number;
7
+ rotation?: Rotation;
4
8
  background?: string;
9
+ selectionMenu?: SelectionSelectionMenuRenderFn;
5
10
  };
6
- export declare function SelectionLayer({ pageIndex, scale, background }: Props): import("react/jsx-runtime").JSX.Element | null;
11
+ export declare function SelectionLayer({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: Props): import("react/jsx-runtime").JSX.Element | null;
7
12
  export {};
@@ -1,4 +1,5 @@
1
1
  export * from './hooks';
2
2
  export * from './components';
3
+ export * from './types';
3
4
  export * from '../index.ts';
4
5
  export declare const SelectionPluginPackage: import('@embedpdf/core').WithAutoMount<import('@embedpdf/core').PluginPackage<import('../index.ts').SelectionPlugin, import('../index.ts').SelectionPluginConfig, import('../index.ts').SelectionState, import('../lib/actions').SelectionAction>>;
@@ -0,0 +1,7 @@
1
+ import { SelectionMenuRenderFn, SelectionMenuPropsBase } from '../react/utils.ts';
2
+ export interface SelectionSelectionContext {
3
+ type: 'selection';
4
+ pageIndex: number;
5
+ }
6
+ export type SelectionSelectionMenuRenderFn = SelectionMenuRenderFn<SelectionSelectionContext>;
7
+ export type SelectionSelectionMenuProps = SelectionMenuPropsBase<SelectionSelectionContext>;
@@ -1,7 +1,12 @@
1
+ import { Rotation } from '@embedpdf/models';
2
+ import { SelectionSelectionMenuRenderFn } from '../types';
1
3
  type Props = {
4
+ documentId: string;
2
5
  pageIndex: number;
3
- scale: number;
6
+ scale?: number;
7
+ rotation?: Rotation;
4
8
  background?: string;
9
+ selectionMenu?: SelectionSelectionMenuRenderFn;
5
10
  };
6
- export declare function SelectionLayer({ pageIndex, scale, background }: Props): import("preact").JSX.Element | null;
11
+ export declare function SelectionLayer({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: Props): import("preact").JSX.Element | null;
7
12
  export {};
@@ -1,4 +1,5 @@
1
1
  export * from './hooks';
2
2
  export * from './components';
3
+ export * from './types';
3
4
  export * from '../lib/index.ts';
4
5
  export declare const SelectionPluginPackage: import('@embedpdf/core').WithAutoMount<import('@embedpdf/core').PluginPackage<import('../lib/index.ts').SelectionPlugin, import('../lib/index.ts').SelectionPluginConfig, import('../lib/index.ts').SelectionState, import('../lib/actions').SelectionAction>>;
@@ -0,0 +1,7 @@
1
+ import { SelectionMenuRenderFn, SelectionMenuPropsBase } from '../preact/utils.ts';
2
+ export interface SelectionSelectionContext {
3
+ type: 'selection';
4
+ pageIndex: number;
5
+ }
6
+ export type SelectionSelectionMenuRenderFn = SelectionMenuRenderFn<SelectionSelectionContext>;
7
+ export type SelectionSelectionMenuProps = SelectionMenuPropsBase<SelectionSelectionContext>;
@@ -1,7 +1,12 @@
1
+ import { Rotation } from '@embedpdf/models';
2
+ import { SelectionSelectionMenuRenderFn } from '../types';
1
3
  type Props = {
4
+ documentId: string;
2
5
  pageIndex: number;
3
- scale: number;
6
+ scale?: number;
7
+ rotation?: Rotation;
4
8
  background?: string;
9
+ selectionMenu?: SelectionSelectionMenuRenderFn;
5
10
  };
6
- export declare function SelectionLayer({ pageIndex, scale, background }: Props): import("react/jsx-runtime").JSX.Element | null;
11
+ export declare function SelectionLayer({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: Props): import("react/jsx-runtime").JSX.Element | null;
7
12
  export {};
@@ -1,4 +1,5 @@
1
1
  export * from './hooks';
2
2
  export * from './components';
3
+ export * from './types';
3
4
  export * from '../lib/index.ts';
4
5
  export declare const SelectionPluginPackage: import('@embedpdf/core').WithAutoMount<import('@embedpdf/core').PluginPackage<import('../lib/index.ts').SelectionPlugin, import('../lib/index.ts').SelectionPluginConfig, import('../lib/index.ts').SelectionState, import('../lib/actions').SelectionAction>>;
@@ -0,0 +1,7 @@
1
+ import { SelectionMenuRenderFn, SelectionMenuPropsBase } from '../react/utils.ts';
2
+ export interface SelectionSelectionContext {
3
+ type: 'selection';
4
+ pageIndex: number;
5
+ }
6
+ export type SelectionSelectionMenuRenderFn = SelectionMenuRenderFn<SelectionSelectionContext>;
7
+ export type SelectionSelectionMenuProps = SelectionMenuPropsBase<SelectionSelectionContext>;
@@ -1,10 +1,21 @@
1
+ import { Snippet } from 'svelte';
2
+ import { Rotation } from '@embedpdf/models';
3
+ import { SelectionSelectionMenuRenderFn, SelectionSelectionMenuProps } from '../types';
1
4
  interface SelectionLayerProps {
5
+ /** Document ID */
6
+ documentId: string;
2
7
  /** Index of the page this layer lives on */
3
8
  pageIndex: number;
4
- /** Scale of the page */
5
- scale: number;
9
+ /** Scale of the page (optional, defaults to document scale) */
10
+ scale?: number;
11
+ /** Rotation of the page (optional, defaults to document rotation) */
12
+ rotation?: Rotation;
6
13
  /** Background color for selection rectangles */
7
14
  background?: string;
15
+ /** Render function for selection menu (schema-driven approach) */
16
+ selectionMenu?: SelectionSelectionMenuRenderFn;
17
+ /** Snippet for custom selection menu (slot-based approach) */
18
+ selectionMenuSnippet?: Snippet<[SelectionSelectionMenuProps]>;
8
19
  }
9
20
  declare const SelectionLayer: import('svelte', { with: { "resolution-mode": "import" } }).Component<SelectionLayerProps, {}, "">;
10
21
  type SelectionLayer = ReturnType<typeof SelectionLayer>;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-selection");require("svelte/internal/disclose-version");const i=require("svelte/internal/client"),o=require("@embedpdf/core/svelte");function n(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const i in e)if("default"!==i){const o=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,o.get?o:{enumerable:!0,get:()=>e[i]})}return t.default=e,Object.freeze(t)}const r=n(i),l=()=>o.useCapability(t.SelectionPlugin.id),s=()=>o.usePlugin(t.SelectionPlugin.id);var c=r.from_html("<div></div>"),a=r.from_html("<div></div>");function p(e,t){r.push(t,!0);const i=l();r.user_effect((()=>{if(i.provides)return i.provides.onCopyToClipboard((e=>{navigator.clipboard.writeText(e).catch((e=>{console.error("Failed to copy text to clipboard:",e)}))}))})),r.pop()}const g=e.createPluginPackage(t.SelectionPluginPackage).addUtility(p).build();exports.CopyToClipboard=p,exports.SelectionLayer=function(e,t){r.push(t,!0);let i=r.prop(t,"background",3,"rgba(33, 150, 243, 0.4)");const o=s();let n=r.state(r.proxy([])),l=r.state(null);r.user_effect((()=>{const e=t.pageIndex;if(o.plugin)return o.plugin.registerSelectionOnPage({pageIndex:e,onRectsChange:({rects:e,boundingRect:t})=>{r.set(n,e,!0),r.set(l,t,!0)}})}));var p=r.comment(),g=r.first_child(p),u=e=>{var o=a();let s;r.each(o,21,(()=>r.get(n)),r.index,((e,o)=>{var n=c();let s;r.template_effect((e=>s=r.set_style(n,"",s,e)),[()=>({position:"absolute",left:(r.get(o).origin.x-r.get(l).origin.x)*t.scale+"px",top:(r.get(o).origin.y-r.get(l).origin.y)*t.scale+"px",width:r.get(o).size.width*t.scale+"px",height:r.get(o).size.height*t.scale+"px",background:i(),"pointer-events":"none"})]),r.append(e,n)})),r.reset(o),r.template_effect((e=>s=r.set_style(o,"",s,e)),[()=>({position:"absolute",left:r.get(l).origin.x*t.scale+"px",top:r.get(l).origin.y*t.scale+"px",width:r.get(l).size.width*t.scale+"px",height:r.get(l).size.height*t.scale+"px","mix-blend-mode":"multiply",isolation:"isolate","pointer-events":"none"})]),r.append(e,o)};r.if(g,(e=>{r.get(l)&&e(u)})),r.append(e,p),r.pop()},exports.SelectionPluginPackage=g,exports.useSelectionCapability=l,exports.useSelectionPlugin=s,Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-selection");require("svelte/internal/disclose-version");const i=require("svelte/internal/client");require("svelte");const n=require("@embedpdf/models"),o=require("@embedpdf/core/svelte"),r=require("@embedpdf/utils/svelte");function l(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const i in e)if("default"!==i){const n=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,n.get?n:{enumerable:!0,get:()=>e[i]})}return t.default=e,Object.freeze(t)}const s=l(i),c=()=>o.useCapability(t.SelectionPlugin.id),p=()=>o.usePlugin(t.SelectionPlugin.id);var d=s.from_html("<div></div>"),g=s.from_html("<div></div> <!>",1);function a(e,t){s.push(t,!0);const i=c();s.user_effect(()=>{if(i.provides)return i.provides.onCopyToClipboard(({text:e})=>{navigator.clipboard.writeText(e).catch(e=>{console.error("Failed to copy text to clipboard:",e)})})}),s.pop()}const u=e.createPluginPackage(t.SelectionPluginPackage).addUtility(a).build();exports.CopyToClipboard=a,exports.SelectionLayer=function(e,t){s.push(t,!0);let i=s.prop(t,"background",3,"rgba(33,150,243)");const l=p(),c=o.useDocumentState(()=>t.documentId);let a=s.state(s.proxy([])),u=s.state(null),f=s.state(null);const v=s.derived(()=>{var e;return void 0!==t.scale?t.scale:(null==(e=c.current)?void 0:e.scale)??1}),m=s.derived(()=>{var e;return void 0!==t.rotation?t.rotation:(null==(e=c.current)?void 0:e.rotation)??n.Rotation.Degree0}),b=s.derived(()=>Boolean(s.get(f)&&s.get(f).pageIndex===t.pageIndex&&s.get(f).isVisible&&(t.selectionMenu||t.selectionMenuSnippet)));s.user_effect(()=>l.plugin&&t.documentId?l.plugin.registerSelectionOnPage({documentId:t.documentId,pageIndex:t.pageIndex,onRectsChange:({rects:e,boundingRect:t})=>{s.set(a,e,!0),s.set(u,t,!0)}}):(s.set(a,[],!0),void s.set(u,null))),s.user_effect(()=>{if(l.plugin&&t.documentId)return l.plugin.onMenuPlacement(t.documentId,e=>{s.set(f,e,!0)});s.set(f,null)});var h=s.comment(),x=s.first_child(h),y=e=>{var n=g(),o=s.first_child(n);let l;s.each(o,21,()=>s.get(a),s.index,(e,t)=>{var n=d();let o;s.template_effect(()=>o=s.set_style(n,"",o,{position:"absolute",left:(s.get(t).origin.x-s.get(u).origin.x)*s.get(v)+"px",top:(s.get(t).origin.y-s.get(u).origin.y)*s.get(v)+"px",width:s.get(t).size.width*s.get(v)+"px",height:s.get(t).size.height*s.get(v)+"px",background:i(),"pointer-events":"none"})),s.append(e,n)}),s.reset(o);var c=s.sibling(o,2),p=e=>{{const i=(e,i)=>{const n=s.derived(()=>function(e,i){return{context:{type:"selection",pageIndex:t.pageIndex},selected:!0,rect:e,placement:{suggestTop:(null==(n=s.get(f))?void 0:n.suggestTop)??!1,spaceAbove:(null==(o=s.get(f))?void 0:o.spaceAbove)??0,spaceBelow:(null==(r=s.get(f))?void 0:r.spaceBelow)??0},menuWrapperProps:i};var n,o,r}(null==i?void 0:i().rect,null==i?void 0:i().menuWrapperProps));var o=s.comment(),r=s.first_child(o),l=e=>{const i=s.derived(()=>t.selectionMenu(s.get(n)));var o=s.comment(),r=s.first_child(o),l=e=>{var t=s.comment(),n=s.first_child(t);s.component(n,()=>s.get(i).component,(e,t)=>{t(e,s.spread_props(()=>s.get(i).props))}),s.append(e,t)};s.if(r,e=>{s.get(i)&&e(l)}),s.append(e,o)},c=e=>{var i=s.comment(),o=s.first_child(i),r=e=>{var i=s.comment(),o=s.first_child(i);s.snippet(o,()=>t.selectionMenuSnippet,()=>s.get(n)),s.append(e,i)};s.if(o,e=>{t.selectionMenuSnippet&&e(r)},!0),s.append(e,i)};s.if(r,e=>{t.selectionMenu?e(l):e(c,!1)}),s.append(e,o)};let n=s.derived(()=>({origin:{x:s.get(f).rect.origin.x*s.get(v),y:s.get(f).rect.origin.y*s.get(v)},size:{width:s.get(f).rect.size.width*s.get(v),height:s.get(f).rect.size.height*s.get(v)}}));r.CounterRotate(e,{get rect(){return s.get(n)},get rotation(){return s.get(m)},children:i,$$slots:{default:!0}})}};s.if(c,e=>{s.get(b)&&s.get(f)&&e(p)}),s.template_effect(()=>l=s.set_style(o,"",l,{position:"absolute",left:s.get(u).origin.x*s.get(v)+"px",top:s.get(u).origin.y*s.get(v)+"px",width:s.get(u).size.width*s.get(v)+"px",height:s.get(u).size.height*s.get(v)+"px","mix-blend-mode":"multiply",isolation:"isolate","pointer-events":"none"})),s.append(e,n)};s.if(x,e=>{s.get(u)&&e(y)}),s.append(e,h),s.pop()},exports.SelectionPluginPackage=u,exports.useSelectionCapability=c,exports.useSelectionPlugin=p,Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
2
2
  //# sourceMappingURL=index.cjs.map