@embedpdf/plugin-selection 2.15.0 → 3.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -21
- package/dist/index.cjs +575 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +167 -0
- package/dist/index.d.ts +167 -1
- package/dist/index.js +549 -1508
- package/dist/index.js.map +1 -1
- package/package.json +21 -62
- package/dist/lib/actions.d.ts +0 -103
- package/dist/lib/handlers/index.d.ts +0 -2
- package/dist/lib/handlers/marquee-selection.handler.d.ts +0 -30
- package/dist/lib/handlers/text-selection.handler.d.ts +0 -52
- package/dist/lib/index.d.ts +0 -9
- package/dist/lib/manifest.d.ts +0 -4
- package/dist/lib/reducer.d.ts +0 -5
- package/dist/lib/selection-plugin.d.ts +0 -121
- package/dist/lib/selectors.d.ts +0 -14
- package/dist/lib/types.d.ts +0 -268
- package/dist/lib/utils.d.ts +0 -108
- package/dist/preact/adapter.d.ts +0 -4
- package/dist/preact/core.d.ts +0 -1
- package/dist/preact/index.cjs +0 -2
- package/dist/preact/index.cjs.map +0 -1
- package/dist/preact/index.d.ts +0 -1
- package/dist/preact/index.js +0 -218
- package/dist/preact/index.js.map +0 -1
- package/dist/preact/interaction-manager.d.ts +0 -1
- package/dist/preact/utils.d.ts +0 -1
- package/dist/react/adapter.d.ts +0 -2
- package/dist/react/core.d.ts +0 -1
- package/dist/react/index.cjs +0 -2
- package/dist/react/index.cjs.map +0 -1
- package/dist/react/index.d.ts +0 -1
- package/dist/react/index.js +0 -217
- package/dist/react/index.js.map +0 -1
- package/dist/react/interaction-manager.d.ts +0 -1
- package/dist/react/utils.d.ts +0 -1
- package/dist/shared/components/copy-to-clipboard.d.ts +0 -1
- package/dist/shared/components/index.d.ts +0 -4
- package/dist/shared/components/marquee-selection.d.ts +0 -36
- package/dist/shared/components/selection-layer.d.ts +0 -29
- package/dist/shared/components/text-selection.d.ts +0 -21
- package/dist/shared/hooks/index.d.ts +0 -1
- package/dist/shared/hooks/use-selection.d.ts +0 -11
- package/dist/shared/index.d.ts +0 -5
- package/dist/shared/types.d.ts +0 -7
- package/dist/shared-preact/components/copy-to-clipboard.d.ts +0 -1
- package/dist/shared-preact/components/index.d.ts +0 -4
- package/dist/shared-preact/components/marquee-selection.d.ts +0 -36
- package/dist/shared-preact/components/selection-layer.d.ts +0 -29
- package/dist/shared-preact/components/text-selection.d.ts +0 -21
- package/dist/shared-preact/hooks/index.d.ts +0 -1
- package/dist/shared-preact/hooks/use-selection.d.ts +0 -11
- package/dist/shared-preact/index.d.ts +0 -5
- package/dist/shared-preact/types.d.ts +0 -7
- package/dist/shared-react/components/copy-to-clipboard.d.ts +0 -1
- package/dist/shared-react/components/index.d.ts +0 -4
- package/dist/shared-react/components/marquee-selection.d.ts +0 -36
- package/dist/shared-react/components/selection-layer.d.ts +0 -29
- package/dist/shared-react/components/text-selection.d.ts +0 -21
- package/dist/shared-react/hooks/index.d.ts +0 -1
- package/dist/shared-react/hooks/use-selection.d.ts +0 -11
- package/dist/shared-react/index.d.ts +0 -5
- package/dist/shared-react/types.d.ts +0 -7
- package/dist/svelte/components/CopyToClipboard.svelte.d.ts +0 -3
- package/dist/svelte/components/MarqueeSelection.svelte.d.ts +0 -27
- package/dist/svelte/components/SelectionLayer.svelte.d.ts +0 -32
- package/dist/svelte/components/TextSelection.svelte.d.ts +0 -22
- package/dist/svelte/components/index.d.ts +0 -4
- package/dist/svelte/hooks/index.d.ts +0 -1
- package/dist/svelte/hooks/use-selection.svelte.d.ts +0 -19
- package/dist/svelte/index.cjs +0 -2
- package/dist/svelte/index.cjs.map +0 -1
- package/dist/svelte/index.d.ts +0 -5
- package/dist/svelte/index.js +0 -359
- package/dist/svelte/index.js.map +0 -1
- package/dist/svelte/types.d.ts +0 -7
- package/dist/vue/components/copy-to-clipboard.vue.d.ts +0 -3
- package/dist/vue/components/index.d.ts +0 -4
- package/dist/vue/components/marquee-selection.vue.d.ts +0 -29
- package/dist/vue/components/selection-layer.vue.d.ts +0 -60
- package/dist/vue/components/text-selection.vue.d.ts +0 -51
- package/dist/vue/hooks/index.d.ts +0 -1
- package/dist/vue/hooks/use-selection.d.ts +0 -11
- package/dist/vue/index.cjs +0 -2
- package/dist/vue/index.cjs.map +0 -1
- package/dist/vue/index.d.ts +0 -5
- package/dist/vue/index.js +0 -311
- package/dist/vue/index.js.map +0 -1
- package/dist/vue/types.d.ts +0 -7
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/text-selection.tsx","../../src/shared/components/marquee-selection.tsx","../../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, 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 TextSelectionProps = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */\n background?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * TextSelection renders text selection highlight rects and the selection menu.\n * It registers the text selection handler on the page and subscribes to menu\n * placement changes.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport function TextSelection({\n documentId,\n pageIndex,\n scale: scaleOverride,\n rotation: rotationOverride,\n background = 'rgba(33,150,243)',\n selectionMenu,\n}: TextSelectionProps) {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const page = documentState?.document?.pages?.[pageIndex];\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 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 // Combine page intrinsic rotation with document rotation\n const pageRotation = page?.rotation ?? 0;\n const docRotation = documentState?.rotation ?? 0;\n return ((pageRotation + docRotation) % 4) as Rotation;\n }, [rotationOverride, page?.rotation, 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, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useSelectionPlugin } from '../hooks';\n\ninterface MarqueeSelectionProps {\n /** Document ID */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page (optional, defaults to document scale) */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */\n background?: string;\n /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */\n borderColor?: string;\n /** Border style. Default: 'dashed' */\n borderStyle?: 'solid' | 'dashed' | 'dotted';\n /**\n * @deprecated Use `borderColor` instead.\n */\n stroke?: string;\n /**\n * @deprecated Use `background` instead.\n */\n fill?: string;\n}\n\n/**\n * MarqueeSelection renders a selection rectangle when the user drags to select items.\n * It registers the marquee handler on the page.\n *\n * Other plugins (e.g., annotation, form, redaction) can subscribe to `onMarqueeEnd` to\n * determine which objects intersect with the marquee rect.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport const MarqueeSelection = ({\n documentId,\n pageIndex,\n scale,\n className,\n background,\n borderColor,\n borderStyle = 'dashed',\n stroke,\n fill,\n}: MarqueeSelectionProps) => {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rect, setRect] = useState<Rect | null>(null);\n\n // Resolve deprecated props: new CSS-standard props take precedence\n const resolvedBorderColor = borderColor ?? stroke ?? 'rgba(0,122,204,0.8)';\n const resolvedBackground = background ?? fill ?? 'rgba(0,122,204,0.15)';\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n return selPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale: actualScale,\n onRectChange: setRect,\n });\n }, [selPlugin, documentId, pageIndex, actualScale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * actualScale,\n top: rect.origin.y * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n border: `1px ${borderStyle} ${resolvedBorderColor}`,\n background: resolvedBackground,\n boxSizing: 'border-box',\n zIndex: 1000,\n }}\n className={className}\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","import { Fragment } from '@framework';\nimport { Rotation } from '@embedpdf/models';\nimport { TextSelectionStyle, MarqueeSelectionStyle } from '@embedpdf/plugin-selection';\nimport { SelectionSelectionMenuRenderFn } from '../types';\nimport { TextSelection } from './text-selection';\nimport { MarqueeSelection } from './marquee-selection';\n\ntype Props = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /**\n * @deprecated Use `textStyle.background` instead.\n */\n background?: string;\n /** Styling options for text selection highlights */\n textStyle?: TextSelectionStyle;\n /** Styling options for the marquee selection rectangle */\n marqueeStyle?: MarqueeSelectionStyle;\n /** Optional CSS class applied to the marquee rectangle */\n marqueeClassName?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * SelectionLayer is a convenience component that composes both text selection\n * and marquee selection on a single page.\n *\n * For advanced use cases, you can use `TextSelection` and `MarqueeSelection`\n * individually.\n */\nexport function SelectionLayer({\n documentId,\n pageIndex,\n scale,\n rotation,\n background,\n textStyle,\n marqueeStyle,\n marqueeClassName,\n selectionMenu,\n}: Props) {\n return (\n <Fragment>\n <TextSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n background={textStyle?.background ?? background}\n selectionMenu={selectionMenu}\n />\n <MarqueeSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n background={marqueeStyle?.background}\n borderColor={marqueeStyle?.borderColor}\n borderStyle={marqueeStyle?.borderStyle}\n className={marqueeClassName}\n />\n </Fragment>\n );\n}\n"],"names":["useSelectionCapability","useCapability","SelectionPlugin","id","useSelectionPlugin","usePlugin","TextSelection","documentId","pageIndex","scale","scaleOverride","rotation","rotationOverride","background","selectionMenu","plugin","selPlugin","documentState","useDocumentState","page","_b","_a","document","pages","rects","setRects","useState","boundingRect","setBoundingRect","placement","setPlacement","useEffect","registerSelectionOnPage","onRectsChange","onMenuPlacement","newPlacement","actualScale","useMemo","actualRotation","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","MarqueeSelection","className","borderColor","borderStyle","stroke","fill","setRect","resolvedBorderColor","resolvedBackground","registerMarqueeOnPage","onRectChange","border","boxSizing","zIndex","CopyToClipboard","provides","sel","onCopyToClipboard","text","navigator","clipboard","writeText","SelectionPluginPackage","createPluginPackage","BaseSelectionPluginPackage","addUtility","build","textStyle","marqueeStyle","marqueeClassName"],"mappings":"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"}
|
package/dist/preact/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../shared-preact';
|
package/dist/preact/index.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { createPluginPackage } from "@embedpdf/core";
|
|
2
|
-
import { SelectionPlugin, SelectionPluginPackage as SelectionPluginPackage$1 } from "@embedpdf/plugin-selection";
|
|
3
|
-
export * from "@embedpdf/plugin-selection";
|
|
4
|
-
import { jsxs, Fragment, jsx } from "preact/jsx-runtime";
|
|
5
|
-
import { Fragment as Fragment$1 } from "preact";
|
|
6
|
-
import { useState, useEffect, useMemo } from "preact/hooks";
|
|
7
|
-
import { useCapability, usePlugin, useDocumentState } from "@embedpdf/core/preact";
|
|
8
|
-
import { CounterRotate } from "@embedpdf/utils/preact";
|
|
9
|
-
const useSelectionCapability = () => useCapability(SelectionPlugin.id);
|
|
10
|
-
const useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
|
|
11
|
-
function TextSelection({
|
|
12
|
-
documentId,
|
|
13
|
-
pageIndex,
|
|
14
|
-
scale: scaleOverride,
|
|
15
|
-
rotation: rotationOverride,
|
|
16
|
-
background = "rgba(33,150,243)",
|
|
17
|
-
selectionMenu
|
|
18
|
-
}) {
|
|
19
|
-
var _a, _b;
|
|
20
|
-
const { plugin: selPlugin } = useSelectionPlugin();
|
|
21
|
-
const documentState = useDocumentState(documentId);
|
|
22
|
-
const page = (_b = (_a = documentState == null ? void 0 : documentState.document) == null ? void 0 : _a.pages) == null ? void 0 : _b[pageIndex];
|
|
23
|
-
const [rects, setRects] = useState([]);
|
|
24
|
-
const [boundingRect, setBoundingRect] = useState(null);
|
|
25
|
-
const [placement, setPlacement] = useState(null);
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
if (!selPlugin || !documentId) return;
|
|
28
|
-
return selPlugin.registerSelectionOnPage({
|
|
29
|
-
documentId,
|
|
30
|
-
pageIndex,
|
|
31
|
-
onRectsChange: ({ rects: rects2, boundingRect: boundingRect2 }) => {
|
|
32
|
-
setRects(rects2);
|
|
33
|
-
setBoundingRect(boundingRect2);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}, [selPlugin, documentId, pageIndex]);
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
if (!selPlugin || !documentId) return;
|
|
39
|
-
return selPlugin.onMenuPlacement(documentId, (newPlacement) => {
|
|
40
|
-
setPlacement(newPlacement);
|
|
41
|
-
});
|
|
42
|
-
}, [selPlugin, documentId]);
|
|
43
|
-
const actualScale = useMemo(() => {
|
|
44
|
-
if (scaleOverride !== void 0) return scaleOverride;
|
|
45
|
-
return (documentState == null ? void 0 : documentState.scale) ?? 1;
|
|
46
|
-
}, [scaleOverride, documentState == null ? void 0 : documentState.scale]);
|
|
47
|
-
const actualRotation = useMemo(() => {
|
|
48
|
-
if (rotationOverride !== void 0) return rotationOverride;
|
|
49
|
-
const pageRotation = (page == null ? void 0 : page.rotation) ?? 0;
|
|
50
|
-
const docRotation = (documentState == null ? void 0 : documentState.rotation) ?? 0;
|
|
51
|
-
return (pageRotation + docRotation) % 4;
|
|
52
|
-
}, [rotationOverride, page == null ? void 0 : page.rotation, documentState == null ? void 0 : documentState.rotation]);
|
|
53
|
-
const shouldRenderMenu = selectionMenu && placement && placement.pageIndex === pageIndex && placement.isVisible;
|
|
54
|
-
if (!boundingRect) return null;
|
|
55
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
56
|
-
/* @__PURE__ */ jsx(
|
|
57
|
-
"div",
|
|
58
|
-
{
|
|
59
|
-
style: {
|
|
60
|
-
position: "absolute",
|
|
61
|
-
left: boundingRect.origin.x * actualScale,
|
|
62
|
-
top: boundingRect.origin.y * actualScale,
|
|
63
|
-
width: boundingRect.size.width * actualScale,
|
|
64
|
-
height: boundingRect.size.height * actualScale,
|
|
65
|
-
mixBlendMode: "multiply",
|
|
66
|
-
isolation: "isolate",
|
|
67
|
-
pointerEvents: "none"
|
|
68
|
-
},
|
|
69
|
-
children: rects.map((b, i) => /* @__PURE__ */ jsx(
|
|
70
|
-
"div",
|
|
71
|
-
{
|
|
72
|
-
style: {
|
|
73
|
-
position: "absolute",
|
|
74
|
-
left: (b.origin.x - boundingRect.origin.x) * actualScale,
|
|
75
|
-
top: (b.origin.y - boundingRect.origin.y) * actualScale,
|
|
76
|
-
width: b.size.width * actualScale,
|
|
77
|
-
height: b.size.height * actualScale,
|
|
78
|
-
background
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
i
|
|
82
|
-
))
|
|
83
|
-
}
|
|
84
|
-
),
|
|
85
|
-
shouldRenderMenu && /* @__PURE__ */ jsx(
|
|
86
|
-
CounterRotate,
|
|
87
|
-
{
|
|
88
|
-
rect: {
|
|
89
|
-
origin: {
|
|
90
|
-
x: placement.rect.origin.x * actualScale,
|
|
91
|
-
y: placement.rect.origin.y * actualScale
|
|
92
|
-
},
|
|
93
|
-
size: {
|
|
94
|
-
width: placement.rect.size.width * actualScale,
|
|
95
|
-
height: placement.rect.size.height * actualScale
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
rotation: actualRotation,
|
|
99
|
-
children: (props) => selectionMenu({
|
|
100
|
-
...props,
|
|
101
|
-
context: {
|
|
102
|
-
type: "selection",
|
|
103
|
-
pageIndex
|
|
104
|
-
},
|
|
105
|
-
selected: true,
|
|
106
|
-
placement
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
)
|
|
110
|
-
] });
|
|
111
|
-
}
|
|
112
|
-
const MarqueeSelection = ({
|
|
113
|
-
documentId,
|
|
114
|
-
pageIndex,
|
|
115
|
-
scale,
|
|
116
|
-
className,
|
|
117
|
-
background,
|
|
118
|
-
borderColor,
|
|
119
|
-
borderStyle = "dashed",
|
|
120
|
-
stroke,
|
|
121
|
-
fill
|
|
122
|
-
}) => {
|
|
123
|
-
const { plugin: selPlugin } = useSelectionPlugin();
|
|
124
|
-
const documentState = useDocumentState(documentId);
|
|
125
|
-
const [rect, setRect] = useState(null);
|
|
126
|
-
const resolvedBorderColor = borderColor ?? stroke ?? "rgba(0,122,204,0.8)";
|
|
127
|
-
const resolvedBackground = background ?? fill ?? "rgba(0,122,204,0.15)";
|
|
128
|
-
const actualScale = useMemo(() => {
|
|
129
|
-
if (scale !== void 0) return scale;
|
|
130
|
-
return (documentState == null ? void 0 : documentState.scale) ?? 1;
|
|
131
|
-
}, [scale, documentState == null ? void 0 : documentState.scale]);
|
|
132
|
-
useEffect(() => {
|
|
133
|
-
if (!selPlugin || !documentId) return;
|
|
134
|
-
return selPlugin.registerMarqueeOnPage({
|
|
135
|
-
documentId,
|
|
136
|
-
pageIndex,
|
|
137
|
-
scale: actualScale,
|
|
138
|
-
onRectChange: setRect
|
|
139
|
-
});
|
|
140
|
-
}, [selPlugin, documentId, pageIndex, actualScale]);
|
|
141
|
-
if (!rect) return null;
|
|
142
|
-
return /* @__PURE__ */ jsx(
|
|
143
|
-
"div",
|
|
144
|
-
{
|
|
145
|
-
style: {
|
|
146
|
-
position: "absolute",
|
|
147
|
-
pointerEvents: "none",
|
|
148
|
-
left: rect.origin.x * actualScale,
|
|
149
|
-
top: rect.origin.y * actualScale,
|
|
150
|
-
width: rect.size.width * actualScale,
|
|
151
|
-
height: rect.size.height * actualScale,
|
|
152
|
-
border: `1px ${borderStyle} ${resolvedBorderColor}`,
|
|
153
|
-
background: resolvedBackground,
|
|
154
|
-
boxSizing: "border-box",
|
|
155
|
-
zIndex: 1e3
|
|
156
|
-
},
|
|
157
|
-
className
|
|
158
|
-
}
|
|
159
|
-
);
|
|
160
|
-
};
|
|
161
|
-
function SelectionLayer({
|
|
162
|
-
documentId,
|
|
163
|
-
pageIndex,
|
|
164
|
-
scale,
|
|
165
|
-
rotation,
|
|
166
|
-
background,
|
|
167
|
-
textStyle,
|
|
168
|
-
marqueeStyle,
|
|
169
|
-
marqueeClassName,
|
|
170
|
-
selectionMenu
|
|
171
|
-
}) {
|
|
172
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
173
|
-
/* @__PURE__ */ jsx(
|
|
174
|
-
TextSelection,
|
|
175
|
-
{
|
|
176
|
-
documentId,
|
|
177
|
-
pageIndex,
|
|
178
|
-
scale,
|
|
179
|
-
rotation,
|
|
180
|
-
background: (textStyle == null ? void 0 : textStyle.background) ?? background,
|
|
181
|
-
selectionMenu
|
|
182
|
-
}
|
|
183
|
-
),
|
|
184
|
-
/* @__PURE__ */ jsx(
|
|
185
|
-
MarqueeSelection,
|
|
186
|
-
{
|
|
187
|
-
documentId,
|
|
188
|
-
pageIndex,
|
|
189
|
-
scale,
|
|
190
|
-
background: marqueeStyle == null ? void 0 : marqueeStyle.background,
|
|
191
|
-
borderColor: marqueeStyle == null ? void 0 : marqueeStyle.borderColor,
|
|
192
|
-
borderStyle: marqueeStyle == null ? void 0 : marqueeStyle.borderStyle,
|
|
193
|
-
className: marqueeClassName
|
|
194
|
-
}
|
|
195
|
-
)
|
|
196
|
-
] });
|
|
197
|
-
}
|
|
198
|
-
function CopyToClipboard() {
|
|
199
|
-
const { provides: sel } = useSelectionCapability();
|
|
200
|
-
useEffect(() => {
|
|
201
|
-
if (!sel) return;
|
|
202
|
-
return sel.onCopyToClipboard(({ text }) => {
|
|
203
|
-
navigator.clipboard.writeText(text);
|
|
204
|
-
});
|
|
205
|
-
}, [sel]);
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
const SelectionPluginPackage = createPluginPackage(SelectionPluginPackage$1).addUtility(CopyToClipboard).build();
|
|
209
|
-
export {
|
|
210
|
-
CopyToClipboard,
|
|
211
|
-
MarqueeSelection,
|
|
212
|
-
SelectionLayer,
|
|
213
|
-
SelectionPluginPackage,
|
|
214
|
-
TextSelection,
|
|
215
|
-
useSelectionCapability,
|
|
216
|
-
useSelectionPlugin
|
|
217
|
-
};
|
|
218
|
-
//# sourceMappingURL=index.js.map
|
package/dist/preact/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/text-selection.tsx","../../src/shared/components/marquee-selection.tsx","../../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 TextSelectionProps = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */\n background?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * TextSelection renders text selection highlight rects and the selection menu.\n * It registers the text selection handler on the page and subscribes to menu\n * placement changes.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport function TextSelection({\n documentId,\n pageIndex,\n scale: scaleOverride,\n rotation: rotationOverride,\n background = 'rgba(33,150,243)',\n selectionMenu,\n}: TextSelectionProps) {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const page = documentState?.document?.pages?.[pageIndex];\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 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 // Combine page intrinsic rotation with document rotation\n const pageRotation = page?.rotation ?? 0;\n const docRotation = documentState?.rotation ?? 0;\n return ((pageRotation + docRotation) % 4) as Rotation;\n }, [rotationOverride, page?.rotation, 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, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useSelectionPlugin } from '../hooks';\n\ninterface MarqueeSelectionProps {\n /** Document ID */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page (optional, defaults to document scale) */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */\n background?: string;\n /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */\n borderColor?: string;\n /** Border style. Default: 'dashed' */\n borderStyle?: 'solid' | 'dashed' | 'dotted';\n /**\n * @deprecated Use `borderColor` instead.\n */\n stroke?: string;\n /**\n * @deprecated Use `background` instead.\n */\n fill?: string;\n}\n\n/**\n * MarqueeSelection renders a selection rectangle when the user drags to select items.\n * It registers the marquee handler on the page.\n *\n * Other plugins (e.g., annotation, form, redaction) can subscribe to `onMarqueeEnd` to\n * determine which objects intersect with the marquee rect.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport const MarqueeSelection = ({\n documentId,\n pageIndex,\n scale,\n className,\n background,\n borderColor,\n borderStyle = 'dashed',\n stroke,\n fill,\n}: MarqueeSelectionProps) => {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rect, setRect] = useState<Rect | null>(null);\n\n // Resolve deprecated props: new CSS-standard props take precedence\n const resolvedBorderColor = borderColor ?? stroke ?? 'rgba(0,122,204,0.8)';\n const resolvedBackground = background ?? fill ?? 'rgba(0,122,204,0.15)';\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n return selPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale: actualScale,\n onRectChange: setRect,\n });\n }, [selPlugin, documentId, pageIndex, actualScale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * actualScale,\n top: rect.origin.y * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n border: `1px ${borderStyle} ${resolvedBorderColor}`,\n background: resolvedBackground,\n boxSizing: 'border-box',\n zIndex: 1000,\n }}\n className={className}\n />\n );\n};\n","import { Fragment } from '@framework';\nimport { Rotation } from '@embedpdf/models';\nimport { TextSelectionStyle, MarqueeSelectionStyle } from '@embedpdf/plugin-selection';\nimport { SelectionSelectionMenuRenderFn } from '../types';\nimport { TextSelection } from './text-selection';\nimport { MarqueeSelection } from './marquee-selection';\n\ntype Props = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /**\n * @deprecated Use `textStyle.background` instead.\n */\n background?: string;\n /** Styling options for text selection highlights */\n textStyle?: TextSelectionStyle;\n /** Styling options for the marquee selection rectangle */\n marqueeStyle?: MarqueeSelectionStyle;\n /** Optional CSS class applied to the marquee rectangle */\n marqueeClassName?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * SelectionLayer is a convenience component that composes both text selection\n * and marquee selection on a single page.\n *\n * For advanced use cases, you can use `TextSelection` and `MarqueeSelection`\n * individually.\n */\nexport function SelectionLayer({\n documentId,\n pageIndex,\n scale,\n rotation,\n background,\n textStyle,\n marqueeStyle,\n marqueeClassName,\n selectionMenu,\n}: Props) {\n return (\n <Fragment>\n <TextSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n background={textStyle?.background ?? background}\n selectionMenu={selectionMenu}\n />\n <MarqueeSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n background={marqueeStyle?.background}\n borderColor={marqueeStyle?.borderColor}\n borderStyle={marqueeStyle?.borderStyle}\n className={marqueeClassName}\n />\n </Fragment>\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","Fragment","BaseSelectionPluginPackage"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@embedpdf/plugin-interaction-manager/preact';
|
package/dist/preact/utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@embedpdf/utils/preact';
|
package/dist/react/adapter.d.ts
DELETED
package/dist/react/core.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@embedpdf/core/react';
|
package/dist/react/index.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-selection"),o=require("react/jsx-runtime"),i=require("react"),n=require("@embedpdf/core/react"),r=require("@embedpdf/utils/react"),l=()=>n.useCapability(t.SelectionPlugin.id),u=()=>n.usePlugin(t.SelectionPlugin.id);function s({documentId:e,pageIndex:t,scale:l,rotation:s,background:a="rgba(33,150,243)",selectionMenu:d}){var c,g;const{plugin:p}=u(),x=n.useDocumentState(e),b=null==(g=null==(c=null==x?void 0:x.document)?void 0:c.pages)?void 0:g[t],[h,m]=i.useState([]),[f,y]=i.useState(null),[v,S]=i.useState(null);i.useEffect(()=>{if(p&&e)return p.registerSelectionOnPage({documentId:e,pageIndex:t,onRectsChange:({rects:e,boundingRect:t})=>{m(e),y(t)}})},[p,e,t]),i.useEffect(()=>{if(p&&e)return p.onMenuPlacement(e,e=>{S(e)})},[p,e]);const I=i.useMemo(()=>void 0!==l?l:(null==x?void 0:x.scale)??1,[l,null==x?void 0:x.scale]),P=i.useMemo(()=>{if(void 0!==s)return s;return(((null==b?void 0:b.rotation)??0)+((null==x?void 0:x.rotation)??0))%4},[s,null==b?void 0:b.rotation,null==x?void 0:x.rotation]),k=d&&v&&v.pageIndex===t&&v.isVisible;return f?o.jsxs(o.Fragment,{children:[o.jsx("div",{style:{position:"absolute",left:f.origin.x*I,top:f.origin.y*I,width:f.size.width*I,height:f.size.height*I,mixBlendMode:"multiply",isolation:"isolate",pointerEvents:"none"},children:h.map((e,t)=>o.jsx("div",{style:{position:"absolute",left:(e.origin.x-f.origin.x)*I,top:(e.origin.y-f.origin.y)*I,width:e.size.width*I,height:e.size.height*I,background:a}},t))}),k&&o.jsx(r.CounterRotate,{rect:{origin:{x:v.rect.origin.x*I,y:v.rect.origin.y*I},size:{width:v.rect.size.width*I,height:v.rect.size.height*I}},rotation:P,children:e=>d({...e,context:{type:"selection",pageIndex:t},selected:!0,placement:v})})]}):null}const a=({documentId:e,pageIndex:t,scale:r,className:l,background:s,borderColor:a,borderStyle:d="dashed",stroke:c,fill:g})=>{const{plugin:p}=u(),x=n.useDocumentState(e),[b,h]=i.useState(null),m=a??c??"rgba(0,122,204,0.8)",f=s??g??"rgba(0,122,204,0.15)",y=i.useMemo(()=>void 0!==r?r:(null==x?void 0:x.scale)??1,[r,null==x?void 0:x.scale]);return i.useEffect(()=>{if(p&&e)return p.registerMarqueeOnPage({documentId:e,pageIndex:t,scale:y,onRectChange:h})},[p,e,t,y]),b?o.jsx("div",{style:{position:"absolute",pointerEvents:"none",left:b.origin.x*y,top:b.origin.y*y,width:b.size.width*y,height:b.size.height*y,border:`1px ${d} ${m}`,background:f,boxSizing:"border-box",zIndex:1e3},className:l}):null};function d(){const{provides:e}=l();return i.useEffect(()=>{if(e)return e.onCopyToClipboard(({text:e})=>{navigator.clipboard.writeText(e)})},[e]),null}const c=e.createPluginPackage(t.SelectionPluginPackage).addUtility(d).build();exports.CopyToClipboard=d,exports.MarqueeSelection=a,exports.SelectionLayer=function({documentId:e,pageIndex:t,scale:n,rotation:r,background:l,textStyle:u,marqueeStyle:d,marqueeClassName:c,selectionMenu:g}){return o.jsxs(i.Fragment,{children:[o.jsx(s,{documentId:e,pageIndex:t,scale:n,rotation:r,background:(null==u?void 0:u.background)??l,selectionMenu:g}),o.jsx(a,{documentId:e,pageIndex:t,scale:n,background:null==d?void 0:d.background,borderColor:null==d?void 0:d.borderColor,borderStyle:null==d?void 0:d.borderStyle,className:c})]})},exports.SelectionPluginPackage=c,exports.TextSelection=s,exports.useSelectionCapability=l,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
|
-
//# sourceMappingURL=index.cjs.map
|
package/dist/react/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/text-selection.tsx","../../src/shared/components/marquee-selection.tsx","../../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, 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 TextSelectionProps = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */\n background?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * TextSelection renders text selection highlight rects and the selection menu.\n * It registers the text selection handler on the page and subscribes to menu\n * placement changes.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport function TextSelection({\n documentId,\n pageIndex,\n scale: scaleOverride,\n rotation: rotationOverride,\n background = 'rgba(33,150,243)',\n selectionMenu,\n}: TextSelectionProps) {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const page = documentState?.document?.pages?.[pageIndex];\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 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 // Combine page intrinsic rotation with document rotation\n const pageRotation = page?.rotation ?? 0;\n const docRotation = documentState?.rotation ?? 0;\n return ((pageRotation + docRotation) % 4) as Rotation;\n }, [rotationOverride, page?.rotation, 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, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useSelectionPlugin } from '../hooks';\n\ninterface MarqueeSelectionProps {\n /** Document ID */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page (optional, defaults to document scale) */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */\n background?: string;\n /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */\n borderColor?: string;\n /** Border style. Default: 'dashed' */\n borderStyle?: 'solid' | 'dashed' | 'dotted';\n /**\n * @deprecated Use `borderColor` instead.\n */\n stroke?: string;\n /**\n * @deprecated Use `background` instead.\n */\n fill?: string;\n}\n\n/**\n * MarqueeSelection renders a selection rectangle when the user drags to select items.\n * It registers the marquee handler on the page.\n *\n * Other plugins (e.g., annotation, form, redaction) can subscribe to `onMarqueeEnd` to\n * determine which objects intersect with the marquee rect.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport const MarqueeSelection = ({\n documentId,\n pageIndex,\n scale,\n className,\n background,\n borderColor,\n borderStyle = 'dashed',\n stroke,\n fill,\n}: MarqueeSelectionProps) => {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rect, setRect] = useState<Rect | null>(null);\n\n // Resolve deprecated props: new CSS-standard props take precedence\n const resolvedBorderColor = borderColor ?? stroke ?? 'rgba(0,122,204,0.8)';\n const resolvedBackground = background ?? fill ?? 'rgba(0,122,204,0.15)';\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n return selPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale: actualScale,\n onRectChange: setRect,\n });\n }, [selPlugin, documentId, pageIndex, actualScale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * actualScale,\n top: rect.origin.y * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n border: `1px ${borderStyle} ${resolvedBorderColor}`,\n background: resolvedBackground,\n boxSizing: 'border-box',\n zIndex: 1000,\n }}\n className={className}\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","import { Fragment } from '@framework';\nimport { Rotation } from '@embedpdf/models';\nimport { TextSelectionStyle, MarqueeSelectionStyle } from '@embedpdf/plugin-selection';\nimport { SelectionSelectionMenuRenderFn } from '../types';\nimport { TextSelection } from './text-selection';\nimport { MarqueeSelection } from './marquee-selection';\n\ntype Props = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /**\n * @deprecated Use `textStyle.background` instead.\n */\n background?: string;\n /** Styling options for text selection highlights */\n textStyle?: TextSelectionStyle;\n /** Styling options for the marquee selection rectangle */\n marqueeStyle?: MarqueeSelectionStyle;\n /** Optional CSS class applied to the marquee rectangle */\n marqueeClassName?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * SelectionLayer is a convenience component that composes both text selection\n * and marquee selection on a single page.\n *\n * For advanced use cases, you can use `TextSelection` and `MarqueeSelection`\n * individually.\n */\nexport function SelectionLayer({\n documentId,\n pageIndex,\n scale,\n rotation,\n background,\n textStyle,\n marqueeStyle,\n marqueeClassName,\n selectionMenu,\n}: Props) {\n return (\n <Fragment>\n <TextSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n background={textStyle?.background ?? background}\n selectionMenu={selectionMenu}\n />\n <MarqueeSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n background={marqueeStyle?.background}\n borderColor={marqueeStyle?.borderColor}\n borderStyle={marqueeStyle?.borderStyle}\n className={marqueeClassName}\n />\n </Fragment>\n );\n}\n"],"names":["useSelectionCapability","useCapability","SelectionPlugin","id","useSelectionPlugin","usePlugin","TextSelection","documentId","pageIndex","scale","scaleOverride","rotation","rotationOverride","background","selectionMenu","plugin","selPlugin","documentState","useDocumentState","page","_b","_a","document","pages","rects","setRects","useState","boundingRect","setBoundingRect","placement","setPlacement","useEffect","registerSelectionOnPage","onRectsChange","onMenuPlacement","newPlacement","actualScale","useMemo","actualRotation","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","MarqueeSelection","className","borderColor","borderStyle","stroke","fill","setRect","resolvedBorderColor","resolvedBackground","registerMarqueeOnPage","onRectChange","border","boxSizing","zIndex","CopyToClipboard","provides","sel","onCopyToClipboard","text","navigator","clipboard","writeText","SelectionPluginPackage","createPluginPackage","BaseSelectionPluginPackage","addUtility","build","textStyle","marqueeStyle","marqueeClassName"],"mappings":"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"}
|
package/dist/react/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../shared-react';
|
package/dist/react/index.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { createPluginPackage } from "@embedpdf/core";
|
|
2
|
-
import { SelectionPlugin, SelectionPluginPackage as SelectionPluginPackage$1 } from "@embedpdf/plugin-selection";
|
|
3
|
-
export * from "@embedpdf/plugin-selection";
|
|
4
|
-
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
5
|
-
import { useState, useEffect, useMemo, Fragment as Fragment$1 } from "react";
|
|
6
|
-
import { useCapability, usePlugin, useDocumentState } from "@embedpdf/core/react";
|
|
7
|
-
import { CounterRotate } from "@embedpdf/utils/react";
|
|
8
|
-
const useSelectionCapability = () => useCapability(SelectionPlugin.id);
|
|
9
|
-
const useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
|
|
10
|
-
function TextSelection({
|
|
11
|
-
documentId,
|
|
12
|
-
pageIndex,
|
|
13
|
-
scale: scaleOverride,
|
|
14
|
-
rotation: rotationOverride,
|
|
15
|
-
background = "rgba(33,150,243)",
|
|
16
|
-
selectionMenu
|
|
17
|
-
}) {
|
|
18
|
-
var _a, _b;
|
|
19
|
-
const { plugin: selPlugin } = useSelectionPlugin();
|
|
20
|
-
const documentState = useDocumentState(documentId);
|
|
21
|
-
const page = (_b = (_a = documentState == null ? void 0 : documentState.document) == null ? void 0 : _a.pages) == null ? void 0 : _b[pageIndex];
|
|
22
|
-
const [rects, setRects] = useState([]);
|
|
23
|
-
const [boundingRect, setBoundingRect] = useState(null);
|
|
24
|
-
const [placement, setPlacement] = useState(null);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
if (!selPlugin || !documentId) return;
|
|
27
|
-
return selPlugin.registerSelectionOnPage({
|
|
28
|
-
documentId,
|
|
29
|
-
pageIndex,
|
|
30
|
-
onRectsChange: ({ rects: rects2, boundingRect: boundingRect2 }) => {
|
|
31
|
-
setRects(rects2);
|
|
32
|
-
setBoundingRect(boundingRect2);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
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
|
-
const pageRotation = (page == null ? void 0 : page.rotation) ?? 0;
|
|
49
|
-
const docRotation = (documentState == null ? void 0 : documentState.rotation) ?? 0;
|
|
50
|
-
return (pageRotation + docRotation) % 4;
|
|
51
|
-
}, [rotationOverride, page == null ? void 0 : page.rotation, documentState == null ? void 0 : documentState.rotation]);
|
|
52
|
-
const shouldRenderMenu = selectionMenu && placement && placement.pageIndex === pageIndex && placement.isVisible;
|
|
53
|
-
if (!boundingRect) return null;
|
|
54
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
55
|
-
/* @__PURE__ */ jsx(
|
|
56
|
-
"div",
|
|
57
|
-
{
|
|
58
|
-
style: {
|
|
59
|
-
position: "absolute",
|
|
60
|
-
left: boundingRect.origin.x * actualScale,
|
|
61
|
-
top: boundingRect.origin.y * actualScale,
|
|
62
|
-
width: boundingRect.size.width * actualScale,
|
|
63
|
-
height: boundingRect.size.height * actualScale,
|
|
64
|
-
mixBlendMode: "multiply",
|
|
65
|
-
isolation: "isolate",
|
|
66
|
-
pointerEvents: "none"
|
|
67
|
-
},
|
|
68
|
-
children: rects.map((b, i) => /* @__PURE__ */ jsx(
|
|
69
|
-
"div",
|
|
70
|
-
{
|
|
71
|
-
style: {
|
|
72
|
-
position: "absolute",
|
|
73
|
-
left: (b.origin.x - boundingRect.origin.x) * actualScale,
|
|
74
|
-
top: (b.origin.y - boundingRect.origin.y) * actualScale,
|
|
75
|
-
width: b.size.width * actualScale,
|
|
76
|
-
height: b.size.height * actualScale,
|
|
77
|
-
background
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
i
|
|
81
|
-
))
|
|
82
|
-
}
|
|
83
|
-
),
|
|
84
|
-
shouldRenderMenu && /* @__PURE__ */ jsx(
|
|
85
|
-
CounterRotate,
|
|
86
|
-
{
|
|
87
|
-
rect: {
|
|
88
|
-
origin: {
|
|
89
|
-
x: placement.rect.origin.x * actualScale,
|
|
90
|
-
y: placement.rect.origin.y * actualScale
|
|
91
|
-
},
|
|
92
|
-
size: {
|
|
93
|
-
width: placement.rect.size.width * actualScale,
|
|
94
|
-
height: placement.rect.size.height * actualScale
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
rotation: actualRotation,
|
|
98
|
-
children: (props) => selectionMenu({
|
|
99
|
-
...props,
|
|
100
|
-
context: {
|
|
101
|
-
type: "selection",
|
|
102
|
-
pageIndex
|
|
103
|
-
},
|
|
104
|
-
selected: true,
|
|
105
|
-
placement
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
)
|
|
109
|
-
] });
|
|
110
|
-
}
|
|
111
|
-
const MarqueeSelection = ({
|
|
112
|
-
documentId,
|
|
113
|
-
pageIndex,
|
|
114
|
-
scale,
|
|
115
|
-
className,
|
|
116
|
-
background,
|
|
117
|
-
borderColor,
|
|
118
|
-
borderStyle = "dashed",
|
|
119
|
-
stroke,
|
|
120
|
-
fill
|
|
121
|
-
}) => {
|
|
122
|
-
const { plugin: selPlugin } = useSelectionPlugin();
|
|
123
|
-
const documentState = useDocumentState(documentId);
|
|
124
|
-
const [rect, setRect] = useState(null);
|
|
125
|
-
const resolvedBorderColor = borderColor ?? stroke ?? "rgba(0,122,204,0.8)";
|
|
126
|
-
const resolvedBackground = background ?? fill ?? "rgba(0,122,204,0.15)";
|
|
127
|
-
const actualScale = useMemo(() => {
|
|
128
|
-
if (scale !== void 0) return scale;
|
|
129
|
-
return (documentState == null ? void 0 : documentState.scale) ?? 1;
|
|
130
|
-
}, [scale, documentState == null ? void 0 : documentState.scale]);
|
|
131
|
-
useEffect(() => {
|
|
132
|
-
if (!selPlugin || !documentId) return;
|
|
133
|
-
return selPlugin.registerMarqueeOnPage({
|
|
134
|
-
documentId,
|
|
135
|
-
pageIndex,
|
|
136
|
-
scale: actualScale,
|
|
137
|
-
onRectChange: setRect
|
|
138
|
-
});
|
|
139
|
-
}, [selPlugin, documentId, pageIndex, actualScale]);
|
|
140
|
-
if (!rect) return null;
|
|
141
|
-
return /* @__PURE__ */ jsx(
|
|
142
|
-
"div",
|
|
143
|
-
{
|
|
144
|
-
style: {
|
|
145
|
-
position: "absolute",
|
|
146
|
-
pointerEvents: "none",
|
|
147
|
-
left: rect.origin.x * actualScale,
|
|
148
|
-
top: rect.origin.y * actualScale,
|
|
149
|
-
width: rect.size.width * actualScale,
|
|
150
|
-
height: rect.size.height * actualScale,
|
|
151
|
-
border: `1px ${borderStyle} ${resolvedBorderColor}`,
|
|
152
|
-
background: resolvedBackground,
|
|
153
|
-
boxSizing: "border-box",
|
|
154
|
-
zIndex: 1e3
|
|
155
|
-
},
|
|
156
|
-
className
|
|
157
|
-
}
|
|
158
|
-
);
|
|
159
|
-
};
|
|
160
|
-
function SelectionLayer({
|
|
161
|
-
documentId,
|
|
162
|
-
pageIndex,
|
|
163
|
-
scale,
|
|
164
|
-
rotation,
|
|
165
|
-
background,
|
|
166
|
-
textStyle,
|
|
167
|
-
marqueeStyle,
|
|
168
|
-
marqueeClassName,
|
|
169
|
-
selectionMenu
|
|
170
|
-
}) {
|
|
171
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
172
|
-
/* @__PURE__ */ jsx(
|
|
173
|
-
TextSelection,
|
|
174
|
-
{
|
|
175
|
-
documentId,
|
|
176
|
-
pageIndex,
|
|
177
|
-
scale,
|
|
178
|
-
rotation,
|
|
179
|
-
background: (textStyle == null ? void 0 : textStyle.background) ?? background,
|
|
180
|
-
selectionMenu
|
|
181
|
-
}
|
|
182
|
-
),
|
|
183
|
-
/* @__PURE__ */ jsx(
|
|
184
|
-
MarqueeSelection,
|
|
185
|
-
{
|
|
186
|
-
documentId,
|
|
187
|
-
pageIndex,
|
|
188
|
-
scale,
|
|
189
|
-
background: marqueeStyle == null ? void 0 : marqueeStyle.background,
|
|
190
|
-
borderColor: marqueeStyle == null ? void 0 : marqueeStyle.borderColor,
|
|
191
|
-
borderStyle: marqueeStyle == null ? void 0 : marqueeStyle.borderStyle,
|
|
192
|
-
className: marqueeClassName
|
|
193
|
-
}
|
|
194
|
-
)
|
|
195
|
-
] });
|
|
196
|
-
}
|
|
197
|
-
function CopyToClipboard() {
|
|
198
|
-
const { provides: sel } = useSelectionCapability();
|
|
199
|
-
useEffect(() => {
|
|
200
|
-
if (!sel) return;
|
|
201
|
-
return sel.onCopyToClipboard(({ text }) => {
|
|
202
|
-
navigator.clipboard.writeText(text);
|
|
203
|
-
});
|
|
204
|
-
}, [sel]);
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
const SelectionPluginPackage = createPluginPackage(SelectionPluginPackage$1).addUtility(CopyToClipboard).build();
|
|
208
|
-
export {
|
|
209
|
-
CopyToClipboard,
|
|
210
|
-
MarqueeSelection,
|
|
211
|
-
SelectionLayer,
|
|
212
|
-
SelectionPluginPackage,
|
|
213
|
-
TextSelection,
|
|
214
|
-
useSelectionCapability,
|
|
215
|
-
useSelectionPlugin
|
|
216
|
-
};
|
|
217
|
-
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-selection.ts","../../src/shared/components/text-selection.tsx","../../src/shared/components/marquee-selection.tsx","../../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 TextSelectionProps = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */\n background?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * TextSelection renders text selection highlight rects and the selection menu.\n * It registers the text selection handler on the page and subscribes to menu\n * placement changes.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport function TextSelection({\n documentId,\n pageIndex,\n scale: scaleOverride,\n rotation: rotationOverride,\n background = 'rgba(33,150,243)',\n selectionMenu,\n}: TextSelectionProps) {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const page = documentState?.document?.pages?.[pageIndex];\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 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 // Combine page intrinsic rotation with document rotation\n const pageRotation = page?.rotation ?? 0;\n const docRotation = documentState?.rotation ?? 0;\n return ((pageRotation + docRotation) % 4) as Rotation;\n }, [rotationOverride, page?.rotation, 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, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useSelectionPlugin } from '../hooks';\n\ninterface MarqueeSelectionProps {\n /** Document ID */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page (optional, defaults to document scale) */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */\n background?: string;\n /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */\n borderColor?: string;\n /** Border style. Default: 'dashed' */\n borderStyle?: 'solid' | 'dashed' | 'dotted';\n /**\n * @deprecated Use `borderColor` instead.\n */\n stroke?: string;\n /**\n * @deprecated Use `background` instead.\n */\n fill?: string;\n}\n\n/**\n * MarqueeSelection renders a selection rectangle when the user drags to select items.\n * It registers the marquee handler on the page.\n *\n * Other plugins (e.g., annotation, form, redaction) can subscribe to `onMarqueeEnd` to\n * determine which objects intersect with the marquee rect.\n *\n * Use this component directly for advanced cases, or use `SelectionLayer`\n * which composes both `TextSelection` and `MarqueeSelection`.\n */\nexport const MarqueeSelection = ({\n documentId,\n pageIndex,\n scale,\n className,\n background,\n borderColor,\n borderStyle = 'dashed',\n stroke,\n fill,\n}: MarqueeSelectionProps) => {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rect, setRect] = useState<Rect | null>(null);\n\n // Resolve deprecated props: new CSS-standard props take precedence\n const resolvedBorderColor = borderColor ?? stroke ?? 'rgba(0,122,204,0.8)';\n const resolvedBackground = background ?? fill ?? 'rgba(0,122,204,0.15)';\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n useEffect(() => {\n if (!selPlugin || !documentId) return;\n\n return selPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale: actualScale,\n onRectChange: setRect,\n });\n }, [selPlugin, documentId, pageIndex, actualScale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * actualScale,\n top: rect.origin.y * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n border: `1px ${borderStyle} ${resolvedBorderColor}`,\n background: resolvedBackground,\n boxSizing: 'border-box',\n zIndex: 1000,\n }}\n className={className}\n />\n );\n};\n","import { Fragment } from '@framework';\nimport { Rotation } from '@embedpdf/models';\nimport { TextSelectionStyle, MarqueeSelectionStyle } from '@embedpdf/plugin-selection';\nimport { SelectionSelectionMenuRenderFn } from '../types';\nimport { TextSelection } from './text-selection';\nimport { MarqueeSelection } from './marquee-selection';\n\ntype Props = {\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: Rotation;\n /**\n * @deprecated Use `textStyle.background` instead.\n */\n background?: string;\n /** Styling options for text selection highlights */\n textStyle?: TextSelectionStyle;\n /** Styling options for the marquee selection rectangle */\n marqueeStyle?: MarqueeSelectionStyle;\n /** Optional CSS class applied to the marquee rectangle */\n marqueeClassName?: string;\n selectionMenu?: SelectionSelectionMenuRenderFn;\n};\n\n/**\n * SelectionLayer is a convenience component that composes both text selection\n * and marquee selection on a single page.\n *\n * For advanced use cases, you can use `TextSelection` and `MarqueeSelection`\n * individually.\n */\nexport function SelectionLayer({\n documentId,\n pageIndex,\n scale,\n rotation,\n background,\n textStyle,\n marqueeStyle,\n marqueeClassName,\n selectionMenu,\n}: Props) {\n return (\n <Fragment>\n <TextSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n background={textStyle?.background ?? background}\n selectionMenu={selectionMenu}\n />\n <MarqueeSelection\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n background={marqueeStyle?.background}\n borderColor={marqueeStyle?.borderColor}\n borderStyle={marqueeStyle?.borderStyle}\n className={marqueeClassName}\n />\n </Fragment>\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","Fragment","BaseSelectionPluginPackage"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@embedpdf/plugin-interaction-manager/react';
|
package/dist/react/utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@embedpdf/utils/react';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function CopyToClipboard(): null;
|