@embedpdf/plugin-selection 2.5.0 → 2.6.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.
Files changed (45) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +159 -81
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/handlers/marquee-selection.handler.d.ts +9 -7
  6. package/dist/lib/handlers/text-selection.handler.d.ts +8 -6
  7. package/dist/lib/selection-plugin.d.ts +7 -4
  8. package/dist/lib/types.d.ts +71 -2
  9. package/dist/preact/index.cjs +1 -1
  10. package/dist/preact/index.cjs.map +1 -1
  11. package/dist/preact/index.js +59 -16
  12. package/dist/preact/index.js.map +1 -1
  13. package/dist/react/index.cjs +1 -1
  14. package/dist/react/index.cjs.map +1 -1
  15. package/dist/react/index.js +59 -16
  16. package/dist/react/index.js.map +1 -1
  17. package/dist/shared/components/index.d.ts +1 -0
  18. package/dist/shared/components/marquee-selection.d.ts +18 -5
  19. package/dist/shared/components/selection-layer.d.ts +18 -1
  20. package/dist/shared/components/text-selection.d.ts +21 -0
  21. package/dist/shared-preact/components/index.d.ts +1 -0
  22. package/dist/shared-preact/components/marquee-selection.d.ts +18 -5
  23. package/dist/shared-preact/components/selection-layer.d.ts +18 -1
  24. package/dist/shared-preact/components/text-selection.d.ts +21 -0
  25. package/dist/shared-react/components/index.d.ts +1 -0
  26. package/dist/shared-react/components/marquee-selection.d.ts +18 -5
  27. package/dist/shared-react/components/selection-layer.d.ts +18 -1
  28. package/dist/shared-react/components/text-selection.d.ts +21 -0
  29. package/dist/svelte/components/MarqueeSelection.svelte.d.ts +12 -2
  30. package/dist/svelte/components/SelectionLayer.svelte.d.ts +11 -1
  31. package/dist/svelte/components/TextSelection.svelte.d.ts +22 -0
  32. package/dist/svelte/components/index.d.ts +1 -0
  33. package/dist/svelte/index.cjs +1 -1
  34. package/dist/svelte/index.cjs.map +1 -1
  35. package/dist/svelte/index.js +93 -17
  36. package/dist/svelte/index.js.map +1 -1
  37. package/dist/vue/components/index.d.ts +1 -0
  38. package/dist/vue/components/marquee-selection.vue.d.ts +13 -4
  39. package/dist/vue/components/selection-layer.vue.d.ts +15 -5
  40. package/dist/vue/components/text-selection.vue.d.ts +51 -0
  41. package/dist/vue/index.cjs +1 -1
  42. package/dist/vue/index.cjs.map +1 -1
  43. package/dist/vue/index.js +89 -32
  44. package/dist/vue/index.js.map +1 -1
  45. package/package.json +9 -9
@@ -2,12 +2,12 @@ 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
4
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
5
- import { useState, useEffect, useMemo } from "react";
5
+ import { useState, useEffect, useMemo, Fragment as Fragment$1 } from "react";
6
6
  import { useCapability, usePlugin, useDocumentState } from "@embedpdf/core/react";
7
7
  import { CounterRotate } from "@embedpdf/utils/react";
8
8
  const useSelectionCapability = () => useCapability(SelectionPlugin.id);
9
9
  const useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
10
- function SelectionLayer({
10
+ function TextSelection({
11
11
  documentId,
12
12
  pageIndex,
13
13
  scale: scaleOverride,
@@ -108,27 +108,22 @@ function SelectionLayer({
108
108
  )
109
109
  ] });
110
110
  }
111
- function CopyToClipboard() {
112
- const { provides: sel } = useSelectionCapability();
113
- useEffect(() => {
114
- if (!sel) return;
115
- return sel.onCopyToClipboard(({ text }) => {
116
- navigator.clipboard.writeText(text);
117
- });
118
- }, [sel]);
119
- return null;
120
- }
121
111
  const MarqueeSelection = ({
122
112
  documentId,
123
113
  pageIndex,
124
114
  scale,
125
115
  className,
126
- stroke = "rgba(0,122,204,0.8)",
127
- fill = "rgba(0,122,204,0.15)"
116
+ background,
117
+ borderColor,
118
+ borderStyle = "dashed",
119
+ stroke,
120
+ fill
128
121
  }) => {
129
122
  const { plugin: selPlugin } = useSelectionPlugin();
130
123
  const documentState = useDocumentState(documentId);
131
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)";
132
127
  const actualScale = useMemo(() => {
133
128
  if (scale !== void 0) return scale;
134
129
  return (documentState == null ? void 0 : documentState.scale) ?? 1;
@@ -153,8 +148,8 @@ const MarqueeSelection = ({
153
148
  top: rect.origin.y * actualScale,
154
149
  width: rect.size.width * actualScale,
155
150
  height: rect.size.height * actualScale,
156
- border: `1px dashed ${stroke}`,
157
- background: fill,
151
+ border: `1px ${borderStyle} ${resolvedBorderColor}`,
152
+ background: resolvedBackground,
158
153
  boxSizing: "border-box",
159
154
  zIndex: 1e3
160
155
  },
@@ -162,12 +157,60 @@ const MarqueeSelection = ({
162
157
  }
163
158
  );
164
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
+ }
165
207
  const SelectionPluginPackage = createPluginPackage(SelectionPluginPackage$1).addUtility(CopyToClipboard).build();
166
208
  export {
167
209
  CopyToClipboard,
168
210
  MarqueeSelection,
169
211
  SelectionLayer,
170
212
  SelectionPluginPackage,
213
+ TextSelection,
171
214
  useSelectionCapability,
172
215
  useSelectionPlugin
173
216
  };
@@ -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/components/marquee-selection.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 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 // 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 // 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 } 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 { 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 /** Stroke colour (default: 'rgba(0,122,204,0.8)') */\n stroke?: string;\n /** Fill colour (default: 'rgba(0,122,204,0.15)') */\n fill?: string;\n}\n\n/**\n * MarqueeSelection renders a selection rectangle when the user drags to select items.\n * Place this component on each page where you want marquee selection to work.\n *\n * Other plugins (e.g., annotation, form) can subscribe to `onMarqueeEnd` to\n * determine which objects intersect with the marquee rect.\n */\nexport const MarqueeSelection = ({\n documentId,\n pageIndex,\n scale,\n className,\n stroke = 'rgba(0,122,204,0.8)',\n fill = 'rgba(0,122,204,0.15)',\n}: MarqueeSelectionProps) => {\n const { plugin: selPlugin } = useSelectionPlugin();\n const documentState = useDocumentState(documentId);\n const [rect, setRect] = useState<Rect | null>(null);\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 dashed ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n zIndex: 1000,\n }}\n className={className}\n />\n );\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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"}
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":";;;;;;;AAGO,MAAM,yBAAyB,MAAM,cAA+B,gBAAgB,EAAE;AACtF,MAAM,qBAAqB,MAAM,UAA2B,gBAAgB,EAAE;ACsB9E,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,aAAa;AAAA,EACb;AACF,GAAuB;;AACrB,QAAM,EAAE,QAAQ,UAAA,IAAc,mBAAA;AAC9B,QAAM,gBAAgB,iBAAiB,UAAU;AACjD,QAAM,QAAO,0DAAe,aAAf,mBAAyB,UAAzB,mBAAiC;AAC9C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAC7C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAsB,IAAI;AAGlE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwC,IAAI;AAE9E,YAAU,MAAM;AACd,QAAI,CAAC,aAAa,CAAC,WAAY;AAE/B,WAAO,UAAU,wBAAwB;AAAA,MACvC;AAAA,MACA;AAAA,MACA,eAAe,CAAC,EAAE,OAAAA,QAAO,cAAAC,oBAAmB;AAC1C,iBAASD,MAAK;AACd,wBAAgBC,aAAY;AAAA,MAC9B;AAAA,IAAA,CACD;AAAA,EACH,GAAG,CAAC,WAAW,YAAY,SAAS,CAAC;AAErC,YAAU,MAAM;AACd,QAAI,CAAC,aAAa,CAAC,WAAY;AAG/B,WAAO,UAAU,gBAAgB,YAAY,CAAC,iBAAiB;AAC7D,mBAAa,YAAY;AAAA,IAC3B,CAAC;AAAA,EACH,GAAG,CAAC,WAAW,UAAU,CAAC;AAE1B,QAAM,cAAc,QAAQ,MAAM;AAChC,QAAI,kBAAkB,OAAW,QAAO;AACxC,YAAO,+CAAe,UAAS;AAAA,EACjC,GAAG,CAAC,eAAe,+CAAe,KAAK,CAAC;AAExC,QAAM,iBAAiB,QAAQ,MAAM;AACnC,QAAI,qBAAqB,OAAW,QAAO;AAE3C,UAAM,gBAAe,6BAAM,aAAY;AACvC,UAAM,eAAc,+CAAe,aAAY;AAC/C,YAAS,eAAe,eAAe;AAAA,EACzC,GAAG,CAAC,kBAAkB,6BAAM,UAAU,+CAAe,QAAQ,CAAC;AAE9D,QAAM,mBACJ,iBAAiB,aAAa,UAAU,cAAc,aAAa,UAAU;AAE/E,MAAI,CAAC,aAAc,QAAO;AAE1B,SACE,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,MAAM,aAAa,OAAO,IAAI;AAAA,UAC9B,KAAK,aAAa,OAAO,IAAI;AAAA,UAC7B,OAAO,aAAa,KAAK,QAAQ;AAAA,UACjC,QAAQ,aAAa,KAAK,SAAS;AAAA,UACnC,cAAc;AAAA,UACd,WAAW;AAAA,UACX,eAAe;AAAA,QAAA;AAAA,QAGhB,UAAA,MAAM,IAAI,CAAC,GAAG,MACb;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO,EAAE,OAAO,IAAI,aAAa,OAAO,KAAK;AAAA,cAC7C,MAAM,EAAE,OAAO,IAAI,aAAa,OAAO,KAAK;AAAA,cAC5C,OAAO,EAAE,KAAK,QAAQ;AAAA,cACtB,QAAQ,EAAE,KAAK,SAAS;AAAA,cACxB;AAAA,YAAA;AAAA,UACF;AAAA,UARK;AAAA,QAAA,CAUR;AAAA,MAAA;AAAA,IAAA;AAAA,IAEF,oBACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,UACJ,QAAQ;AAAA,YACN,GAAG,UAAU,KAAK,OAAO,IAAI;AAAA,YAC7B,GAAG,UAAU,KAAK,OAAO,IAAI;AAAA,UAAA;AAAA,UAE/B,MAAM;AAAA,YACJ,OAAO,UAAU,KAAK,KAAK,QAAQ;AAAA,YACnC,QAAQ,UAAU,KAAK,KAAK,SAAS;AAAA,UAAA;AAAA,QACvC;AAAA,QAEF,UAAU;AAAA,QAET,UAAA,CAAC,UACA,cAAc;AAAA,UACZ,GAAG;AAAA,UACH,SAAS;AAAA,YACP,MAAM;AAAA,YACN;AAAA,UAAA;AAAA,UAEF,UAAU;AAAA,UACV;AAAA,QAAA,CACD;AAAA,MAAA;AAAA,IAAA;AAAA,EAEL,GAEJ;AAEJ;ACnGO,MAAM,mBAAmB,CAAC;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AACF,MAA6B;AAC3B,QAAM,EAAE,QAAQ,UAAA,IAAc,mBAAA;AAC9B,QAAM,gBAAgB,iBAAiB,UAAU;AACjD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAsB,IAAI;AAGlD,QAAM,sBAAsB,eAAe,UAAU;AACrD,QAAM,qBAAqB,cAAc,QAAQ;AAEjD,QAAM,cAAc,QAAQ,MAAM;AAChC,QAAI,UAAU,OAAW,QAAO;AAChC,YAAO,+CAAe,UAAS;AAAA,EACjC,GAAG,CAAC,OAAO,+CAAe,KAAK,CAAC;AAEhC,YAAU,MAAM;AACd,QAAI,CAAC,aAAa,CAAC,WAAY;AAE/B,WAAO,UAAU,sBAAsB;AAAA,MACrC;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,cAAc;AAAA,IAAA,CACf;AAAA,EACH,GAAG,CAAC,WAAW,YAAY,WAAW,WAAW,CAAC;AAElD,MAAI,CAAC,KAAM,QAAO;AAElB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,eAAe;AAAA,QACf,MAAM,KAAK,OAAO,IAAI;AAAA,QACtB,KAAK,KAAK,OAAO,IAAI;AAAA,QACrB,OAAO,KAAK,KAAK,QAAQ;AAAA,QACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,QAC3B,QAAQ,OAAO,WAAW,IAAI,mBAAmB;AAAA,QACjD,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,QAAQ;AAAA,MAAA;AAAA,MAEV;AAAA,IAAA;AAAA,EAAA;AAGN;AC/DO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAU;AACR,8BACGC,YAAA,EACC,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAY,uCAAW,eAAc;AAAA,QACrC;AAAA,MAAA;AAAA,IAAA;AAAA,IAEF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY,6CAAc;AAAA,QAC1B,aAAa,6CAAc;AAAA,QAC3B,aAAa,6CAAc;AAAA,QAC3B,WAAW;AAAA,MAAA;AAAA,IAAA;AAAA,EACb,GACF;AAEJ;AC5DO,SAAS,kBAAkB;AAChC,QAAM,EAAE,UAAU,IAAA,IAAQ,uBAAA;AAE1B,YAAU,MAAM;AACd,QAAI,CAAC,IAAK;AACV,WAAO,IAAI,kBAAkB,CAAC,EAAE,WAAW;AACzC,gBAAU,UAAU,UAAU,IAAI;AAAA,IACpC,CAAC;AAAA,EACH,GAAG,CAAC,GAAG,CAAC;AAER,SAAO;AACT;ACLO,MAAM,yBAAyB,oBAAoBC,wBAA0B,EACjF,WAAW,eAAe,EAC1B,MAAA;"}
@@ -1,3 +1,4 @@
1
1
  export * from './selection-layer';
2
+ export * from './text-selection';
2
3
  export * from './copy-to-clipboard';
3
4
  export * from './marquee-selection';
@@ -7,17 +7,30 @@ interface MarqueeSelectionProps {
7
7
  scale?: number;
8
8
  /** Optional CSS class applied to the marquee rectangle */
9
9
  className?: string;
10
- /** Stroke colour (default: 'rgba(0,122,204,0.8)') */
10
+ /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */
11
+ background?: string;
12
+ /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */
13
+ borderColor?: string;
14
+ /** Border style. Default: 'dashed' */
15
+ borderStyle?: 'solid' | 'dashed' | 'dotted';
16
+ /**
17
+ * @deprecated Use `borderColor` instead.
18
+ */
11
19
  stroke?: string;
12
- /** Fill colour (default: 'rgba(0,122,204,0.15)') */
20
+ /**
21
+ * @deprecated Use `background` instead.
22
+ */
13
23
  fill?: string;
14
24
  }
15
25
  /**
16
26
  * MarqueeSelection renders a selection rectangle when the user drags to select items.
17
- * Place this component on each page where you want marquee selection to work.
27
+ * It registers the marquee handler on the page.
18
28
  *
19
- * Other plugins (e.g., annotation, form) can subscribe to `onMarqueeEnd` to
29
+ * Other plugins (e.g., annotation, form, redaction) can subscribe to `onMarqueeEnd` to
20
30
  * determine which objects intersect with the marquee rect.
31
+ *
32
+ * Use this component directly for advanced cases, or use `SelectionLayer`
33
+ * which composes both `TextSelection` and `MarqueeSelection`.
21
34
  */
22
- export declare const MarqueeSelection: ({ documentId, pageIndex, scale, className, stroke, fill, }: MarqueeSelectionProps) => import("react/jsx-runtime").JSX.Element | null;
35
+ export declare const MarqueeSelection: ({ documentId, pageIndex, scale, className, background, borderColor, borderStyle, stroke, fill, }: MarqueeSelectionProps) => import("react/jsx-runtime").JSX.Element | null;
23
36
  export {};
@@ -1,12 +1,29 @@
1
1
  import { Rotation } from '@embedpdf/models';
2
+ import { TextSelectionStyle, MarqueeSelectionStyle } from '../../index.ts';
2
3
  import { SelectionSelectionMenuRenderFn } from '../types';
3
4
  type Props = {
4
5
  documentId: string;
5
6
  pageIndex: number;
6
7
  scale?: number;
7
8
  rotation?: Rotation;
9
+ /**
10
+ * @deprecated Use `textStyle.background` instead.
11
+ */
8
12
  background?: string;
13
+ /** Styling options for text selection highlights */
14
+ textStyle?: TextSelectionStyle;
15
+ /** Styling options for the marquee selection rectangle */
16
+ marqueeStyle?: MarqueeSelectionStyle;
17
+ /** Optional CSS class applied to the marquee rectangle */
18
+ marqueeClassName?: string;
9
19
  selectionMenu?: SelectionSelectionMenuRenderFn;
10
20
  };
11
- export declare function SelectionLayer({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: Props): import("react/jsx-runtime").JSX.Element | null;
21
+ /**
22
+ * SelectionLayer is a convenience component that composes both text selection
23
+ * and marquee selection on a single page.
24
+ *
25
+ * For advanced use cases, you can use `TextSelection` and `MarqueeSelection`
26
+ * individually.
27
+ */
28
+ export declare function SelectionLayer({ documentId, pageIndex, scale, rotation, background, textStyle, marqueeStyle, marqueeClassName, selectionMenu, }: Props): import("react/jsx-runtime").JSX.Element;
12
29
  export {};
@@ -0,0 +1,21 @@
1
+ import { Rotation } from '@embedpdf/models';
2
+ import { SelectionSelectionMenuRenderFn } from '../types';
3
+ type TextSelectionProps = {
4
+ documentId: string;
5
+ pageIndex: number;
6
+ scale?: number;
7
+ rotation?: Rotation;
8
+ /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */
9
+ background?: string;
10
+ selectionMenu?: SelectionSelectionMenuRenderFn;
11
+ };
12
+ /**
13
+ * TextSelection renders text selection highlight rects and the selection menu.
14
+ * It registers the text selection handler on the page and subscribes to menu
15
+ * placement changes.
16
+ *
17
+ * Use this component directly for advanced cases, or use `SelectionLayer`
18
+ * which composes both `TextSelection` and `MarqueeSelection`.
19
+ */
20
+ export declare function TextSelection({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: TextSelectionProps): import("react/jsx-runtime").JSX.Element | null;
21
+ export {};
@@ -1,3 +1,4 @@
1
1
  export * from './selection-layer';
2
+ export * from './text-selection';
2
3
  export * from './copy-to-clipboard';
3
4
  export * from './marquee-selection';
@@ -7,17 +7,30 @@ interface MarqueeSelectionProps {
7
7
  scale?: number;
8
8
  /** Optional CSS class applied to the marquee rectangle */
9
9
  className?: string;
10
- /** Stroke colour (default: 'rgba(0,122,204,0.8)') */
10
+ /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */
11
+ background?: string;
12
+ /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */
13
+ borderColor?: string;
14
+ /** Border style. Default: 'dashed' */
15
+ borderStyle?: 'solid' | 'dashed' | 'dotted';
16
+ /**
17
+ * @deprecated Use `borderColor` instead.
18
+ */
11
19
  stroke?: string;
12
- /** Fill colour (default: 'rgba(0,122,204,0.15)') */
20
+ /**
21
+ * @deprecated Use `background` instead.
22
+ */
13
23
  fill?: string;
14
24
  }
15
25
  /**
16
26
  * MarqueeSelection renders a selection rectangle when the user drags to select items.
17
- * Place this component on each page where you want marquee selection to work.
27
+ * It registers the marquee handler on the page.
18
28
  *
19
- * Other plugins (e.g., annotation, form) can subscribe to `onMarqueeEnd` to
29
+ * Other plugins (e.g., annotation, form, redaction) can subscribe to `onMarqueeEnd` to
20
30
  * determine which objects intersect with the marquee rect.
31
+ *
32
+ * Use this component directly for advanced cases, or use `SelectionLayer`
33
+ * which composes both `TextSelection` and `MarqueeSelection`.
21
34
  */
22
- export declare const MarqueeSelection: ({ documentId, pageIndex, scale, className, stroke, fill, }: MarqueeSelectionProps) => import("preact").JSX.Element | null;
35
+ export declare const MarqueeSelection: ({ documentId, pageIndex, scale, className, background, borderColor, borderStyle, stroke, fill, }: MarqueeSelectionProps) => import("preact").JSX.Element | null;
23
36
  export {};
@@ -1,12 +1,29 @@
1
1
  import { Rotation } from '@embedpdf/models';
2
+ import { TextSelectionStyle, MarqueeSelectionStyle } from '../../lib/index.ts';
2
3
  import { SelectionSelectionMenuRenderFn } from '../types';
3
4
  type Props = {
4
5
  documentId: string;
5
6
  pageIndex: number;
6
7
  scale?: number;
7
8
  rotation?: Rotation;
9
+ /**
10
+ * @deprecated Use `textStyle.background` instead.
11
+ */
8
12
  background?: string;
13
+ /** Styling options for text selection highlights */
14
+ textStyle?: TextSelectionStyle;
15
+ /** Styling options for the marquee selection rectangle */
16
+ marqueeStyle?: MarqueeSelectionStyle;
17
+ /** Optional CSS class applied to the marquee rectangle */
18
+ marqueeClassName?: string;
9
19
  selectionMenu?: SelectionSelectionMenuRenderFn;
10
20
  };
11
- export declare function SelectionLayer({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: Props): import("preact").JSX.Element | null;
21
+ /**
22
+ * SelectionLayer is a convenience component that composes both text selection
23
+ * and marquee selection on a single page.
24
+ *
25
+ * For advanced use cases, you can use `TextSelection` and `MarqueeSelection`
26
+ * individually.
27
+ */
28
+ export declare function SelectionLayer({ documentId, pageIndex, scale, rotation, background, textStyle, marqueeStyle, marqueeClassName, selectionMenu, }: Props): import("preact").JSX.Element;
12
29
  export {};
@@ -0,0 +1,21 @@
1
+ import { Rotation } from '@embedpdf/models';
2
+ import { SelectionSelectionMenuRenderFn } from '../types';
3
+ type TextSelectionProps = {
4
+ documentId: string;
5
+ pageIndex: number;
6
+ scale?: number;
7
+ rotation?: Rotation;
8
+ /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */
9
+ background?: string;
10
+ selectionMenu?: SelectionSelectionMenuRenderFn;
11
+ };
12
+ /**
13
+ * TextSelection renders text selection highlight rects and the selection menu.
14
+ * It registers the text selection handler on the page and subscribes to menu
15
+ * placement changes.
16
+ *
17
+ * Use this component directly for advanced cases, or use `SelectionLayer`
18
+ * which composes both `TextSelection` and `MarqueeSelection`.
19
+ */
20
+ export declare function TextSelection({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: TextSelectionProps): import("preact").JSX.Element | null;
21
+ export {};
@@ -1,3 +1,4 @@
1
1
  export * from './selection-layer';
2
+ export * from './text-selection';
2
3
  export * from './copy-to-clipboard';
3
4
  export * from './marquee-selection';
@@ -7,17 +7,30 @@ interface MarqueeSelectionProps {
7
7
  scale?: number;
8
8
  /** Optional CSS class applied to the marquee rectangle */
9
9
  className?: string;
10
- /** Stroke colour (default: 'rgba(0,122,204,0.8)') */
10
+ /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */
11
+ background?: string;
12
+ /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */
13
+ borderColor?: string;
14
+ /** Border style. Default: 'dashed' */
15
+ borderStyle?: 'solid' | 'dashed' | 'dotted';
16
+ /**
17
+ * @deprecated Use `borderColor` instead.
18
+ */
11
19
  stroke?: string;
12
- /** Fill colour (default: 'rgba(0,122,204,0.15)') */
20
+ /**
21
+ * @deprecated Use `background` instead.
22
+ */
13
23
  fill?: string;
14
24
  }
15
25
  /**
16
26
  * MarqueeSelection renders a selection rectangle when the user drags to select items.
17
- * Place this component on each page where you want marquee selection to work.
27
+ * It registers the marquee handler on the page.
18
28
  *
19
- * Other plugins (e.g., annotation, form) can subscribe to `onMarqueeEnd` to
29
+ * Other plugins (e.g., annotation, form, redaction) can subscribe to `onMarqueeEnd` to
20
30
  * determine which objects intersect with the marquee rect.
31
+ *
32
+ * Use this component directly for advanced cases, or use `SelectionLayer`
33
+ * which composes both `TextSelection` and `MarqueeSelection`.
21
34
  */
22
- export declare const MarqueeSelection: ({ documentId, pageIndex, scale, className, stroke, fill, }: MarqueeSelectionProps) => import("react/jsx-runtime").JSX.Element | null;
35
+ export declare const MarqueeSelection: ({ documentId, pageIndex, scale, className, background, borderColor, borderStyle, stroke, fill, }: MarqueeSelectionProps) => import("react/jsx-runtime").JSX.Element | null;
23
36
  export {};
@@ -1,12 +1,29 @@
1
1
  import { Rotation } from '@embedpdf/models';
2
+ import { TextSelectionStyle, MarqueeSelectionStyle } from '../../lib/index.ts';
2
3
  import { SelectionSelectionMenuRenderFn } from '../types';
3
4
  type Props = {
4
5
  documentId: string;
5
6
  pageIndex: number;
6
7
  scale?: number;
7
8
  rotation?: Rotation;
9
+ /**
10
+ * @deprecated Use `textStyle.background` instead.
11
+ */
8
12
  background?: string;
13
+ /** Styling options for text selection highlights */
14
+ textStyle?: TextSelectionStyle;
15
+ /** Styling options for the marquee selection rectangle */
16
+ marqueeStyle?: MarqueeSelectionStyle;
17
+ /** Optional CSS class applied to the marquee rectangle */
18
+ marqueeClassName?: string;
9
19
  selectionMenu?: SelectionSelectionMenuRenderFn;
10
20
  };
11
- export declare function SelectionLayer({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: Props): import("react/jsx-runtime").JSX.Element | null;
21
+ /**
22
+ * SelectionLayer is a convenience component that composes both text selection
23
+ * and marquee selection on a single page.
24
+ *
25
+ * For advanced use cases, you can use `TextSelection` and `MarqueeSelection`
26
+ * individually.
27
+ */
28
+ export declare function SelectionLayer({ documentId, pageIndex, scale, rotation, background, textStyle, marqueeStyle, marqueeClassName, selectionMenu, }: Props): import("react/jsx-runtime").JSX.Element;
12
29
  export {};
@@ -0,0 +1,21 @@
1
+ import { Rotation } from '@embedpdf/models';
2
+ import { SelectionSelectionMenuRenderFn } from '../types';
3
+ type TextSelectionProps = {
4
+ documentId: string;
5
+ pageIndex: number;
6
+ scale?: number;
7
+ rotation?: Rotation;
8
+ /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */
9
+ background?: string;
10
+ selectionMenu?: SelectionSelectionMenuRenderFn;
11
+ };
12
+ /**
13
+ * TextSelection renders text selection highlight rects and the selection menu.
14
+ * It registers the text selection handler on the page and subscribes to menu
15
+ * placement changes.
16
+ *
17
+ * Use this component directly for advanced cases, or use `SelectionLayer`
18
+ * which composes both `TextSelection` and `MarqueeSelection`.
19
+ */
20
+ export declare function TextSelection({ documentId, pageIndex, scale: scaleOverride, rotation: rotationOverride, background, selectionMenu, }: TextSelectionProps): import("react/jsx-runtime").JSX.Element | null;
21
+ export {};
@@ -7,9 +7,19 @@ interface MarqueeSelectionProps {
7
7
  scale?: number;
8
8
  /** Optional CSS class applied to the marquee rectangle */
9
9
  class?: string;
10
- /** Stroke colour (default: 'rgba(0,122,204,0.8)') */
10
+ /** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */
11
+ background?: string;
12
+ /** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */
13
+ borderColor?: string;
14
+ /** Border style. Default: 'dashed' */
15
+ borderStyle?: 'solid' | 'dashed' | 'dotted';
16
+ /**
17
+ * @deprecated Use `borderColor` instead.
18
+ */
11
19
  stroke?: string;
12
- /** Fill colour (default: 'rgba(0,122,204,0.15)') */
20
+ /**
21
+ * @deprecated Use `background` instead.
22
+ */
13
23
  fill?: string;
14
24
  }
15
25
  declare const MarqueeSelection: import('svelte', { with: { "resolution-mode": "import" } }).Component<MarqueeSelectionProps, {}, "">;
@@ -1,5 +1,6 @@
1
1
  import { Snippet } from 'svelte';
2
2
  import { Rotation } from '@embedpdf/models';
3
+ import { TextSelectionStyle, MarqueeSelectionStyle } from '../../lib/index.ts';
3
4
  import { SelectionSelectionMenuRenderFn, SelectionSelectionMenuProps } from '../types';
4
5
  interface SelectionLayerProps {
5
6
  /** Document ID */
@@ -10,8 +11,17 @@ interface SelectionLayerProps {
10
11
  scale?: number;
11
12
  /** Rotation of the page (optional, defaults to document rotation) */
12
13
  rotation?: Rotation;
13
- /** Background color for selection rectangles */
14
+ /**
15
+ * @deprecated Use `textStyle.background` instead.
16
+ * Background color for selection rectangles.
17
+ */
14
18
  background?: string;
19
+ /** Styling options for text selection highlights */
20
+ textStyle?: TextSelectionStyle;
21
+ /** Styling options for the marquee selection rectangle */
22
+ marqueeStyle?: MarqueeSelectionStyle;
23
+ /** Optional CSS class applied to the marquee rectangle */
24
+ marqueeClass?: string;
15
25
  /** Render function for selection menu (schema-driven approach) */
16
26
  selectionMenu?: SelectionSelectionMenuRenderFn;
17
27
  /** Snippet for custom selection menu (slot-based approach) */
@@ -0,0 +1,22 @@
1
+ import { Snippet } from 'svelte';
2
+ import { Rotation } from '@embedpdf/models';
3
+ import { SelectionSelectionMenuRenderFn, SelectionSelectionMenuProps } from '../types';
4
+ interface TextSelectionProps {
5
+ /** Document ID */
6
+ documentId: string;
7
+ /** Index of the page this layer lives on */
8
+ pageIndex: 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;
13
+ /** Background color for text selection highlights. Default: 'rgba(33,150,243)' */
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]>;
19
+ }
20
+ declare const TextSelection: import('svelte', { with: { "resolution-mode": "import" } }).Component<TextSelectionProps, {}, "">;
21
+ type TextSelection = ReturnType<typeof TextSelection>;
22
+ export default TextSelection;
@@ -1,3 +1,4 @@
1
1
  export { default as SelectionLayer } from './SelectionLayer.svelte';
2
+ export { default as TextSelection } from './TextSelection.svelte';
2
3
  export { default as CopyToClipboard } from './CopyToClipboard.svelte';
3
4
  export { default as MarqueeSelection } from './MarqueeSelection.svelte';
@@ -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 n=require("svelte/internal/client");require("@embedpdf/models");const i=require("@embedpdf/core/svelte"),o=require("@embedpdf/utils/svelte");function r(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,i.get?i:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const l=r(n),s=()=>i.useCapability(t.SelectionPlugin.id),p=()=>i.usePlugin(t.SelectionPlugin.id);var d=l.from_html("<div></div>"),c=l.from_html("<div></div> <!>",1);function g(e,t){l.push(t,!0);const n=s();l.user_effect(()=>{if(n.provides)return n.provides.onCopyToClipboard(({text:e})=>{navigator.clipboard.writeText(e).catch(e=>{console.error("Failed to copy text to clipboard:",e)})})}),l.pop()}var a=l.from_html("<div></div>");const u=e.createPluginPackage(t.SelectionPluginPackage).addUtility(g).build();exports.CopyToClipboard=g,exports.MarqueeSelection=function(e,t){l.push(t,!0);let n=l.prop(t,"stroke",3,"rgba(0,122,204,0.8)"),o=l.prop(t,"fill",3,"rgba(0,122,204,0.15)");const r=p(),s=i.useDocumentState(()=>t.documentId);let d=l.state(null);const c=l.derived(()=>{var e;return void 0!==t.scale?t.scale:(null==(e=s.current)?void 0:e.scale)??1});l.user_effect(()=>{if(l.set(d,null),r.plugin)return r.plugin.registerMarqueeOnPage({documentId:t.documentId,pageIndex:t.pageIndex,scale:l.get(c),onRectChange:e=>{l.set(d,e,!0)}})});var g=l.comment(),u=l.first_child(g),v=e=>{var i=a();let r;l.template_effect(()=>{l.set_class(i,1,l.clsx(t.class)),r=l.set_style(i,"",r,{position:"absolute","pointer-events":"none",left:l.get(d).origin.x*l.get(c)+"px",top:l.get(d).origin.y*l.get(c)+"px",width:l.get(d).size.width*l.get(c)+"px",height:l.get(d).size.height*l.get(c)+"px",border:`1px dashed ${n()}`,background:o(),"box-sizing":"border-box","z-index":"1000"})}),l.append(e,i)};l.if(u,e=>{l.get(d)&&e(v)}),l.append(e,g),l.pop()},exports.SelectionLayer=function(e,t){l.push(t,!0);let n=l.prop(t,"background",3,"rgba(33,150,243)");const r=p(),s=i.useDocumentState(()=>t.documentId),g=l.derived(()=>{var e,n,i;return null==(i=null==(n=null==(e=s.current)?void 0:e.document)?void 0:n.pages)?void 0:i[t.pageIndex]});let a=l.state(l.proxy([])),u=l.state(null),v=l.state(null);const f=l.derived(()=>{var e;return void 0!==t.scale?t.scale:(null==(e=s.current)?void 0:e.scale)??1}),m=l.derived(()=>{var e,n;if(void 0!==t.rotation)return t.rotation;return(((null==(e=l.get(g))?void 0:e.rotation)??0)+((null==(n=s.current)?void 0:n.rotation)??0))%4}),x=l.derived(()=>Boolean(l.get(v)&&l.get(v).pageIndex===t.pageIndex&&l.get(v).isVisible&&(t.selectionMenu||t.selectionMenuSnippet)));l.user_effect(()=>r.plugin&&t.documentId?r.plugin.registerSelectionOnPage({documentId:t.documentId,pageIndex:t.pageIndex,onRectsChange:({rects:e,boundingRect:t})=>{l.set(a,e,!0),l.set(u,t,!0)}}):(l.set(a,[],!0),void l.set(u,null))),l.user_effect(()=>{if(r.plugin&&t.documentId)return r.plugin.onMenuPlacement(t.documentId,e=>{l.set(v,e,!0)});l.set(v,null)});var h=l.comment(),b=l.first_child(h),y=e=>{var i=c(),r=l.first_child(i);let s;l.each(r,21,()=>l.get(a),l.index,(e,t)=>{var i=d();let o;l.template_effect(()=>o=l.set_style(i,"",o,{position:"absolute",left:(l.get(t).origin.x-l.get(u).origin.x)*l.get(f)+"px",top:(l.get(t).origin.y-l.get(u).origin.y)*l.get(f)+"px",width:l.get(t).size.width*l.get(f)+"px",height:l.get(t).size.height*l.get(f)+"px",background:n(),"pointer-events":"none"})),l.append(e,i)}),l.reset(r);var p=l.sibling(r,2),g=e=>{{const n=(e,n)=>{const i=l.derived(()=>function(e,n){return{context:{type:"selection",pageIndex:t.pageIndex},selected:!0,rect:e,placement:{suggestTop:(null==(i=l.get(v))?void 0:i.suggestTop)??!1,spaceAbove:(null==(o=l.get(v))?void 0:o.spaceAbove)??0,spaceBelow:(null==(r=l.get(v))?void 0:r.spaceBelow)??0},menuWrapperProps:n};var i,o,r}(null==n?void 0:n().rect,null==n?void 0:n().menuWrapperProps));var o=l.comment(),r=l.first_child(o),s=e=>{const n=l.derived(()=>t.selectionMenu(l.get(i)));var o=l.comment(),r=l.first_child(o),s=e=>{var t=l.comment(),i=l.first_child(t);l.component(i,()=>l.get(n).component,(e,t)=>{t(e,l.spread_props(()=>l.get(n).props))}),l.append(e,t)};l.if(r,e=>{l.get(n)&&e(s)}),l.append(e,o)},p=e=>{var n=l.comment(),o=l.first_child(n),r=e=>{var n=l.comment(),o=l.first_child(n);l.snippet(o,()=>t.selectionMenuSnippet,()=>l.get(i)),l.append(e,n)};l.if(o,e=>{t.selectionMenuSnippet&&e(r)},!0),l.append(e,n)};l.if(r,e=>{t.selectionMenu?e(s):e(p,!1)}),l.append(e,o)};let i=l.derived(()=>({origin:{x:l.get(v).rect.origin.x*l.get(f),y:l.get(v).rect.origin.y*l.get(f)},size:{width:l.get(v).rect.size.width*l.get(f),height:l.get(v).rect.size.height*l.get(f)}}));o.CounterRotate(e,{get rect(){return l.get(i)},get rotation(){return l.get(m)},children:n,$$slots:{default:!0}})}};l.if(p,e=>{l.get(x)&&l.get(v)&&e(g)}),l.template_effect(()=>s=l.set_style(r,"",s,{position:"absolute",left:l.get(u).origin.x*l.get(f)+"px",top:l.get(u).origin.y*l.get(f)+"px",width:l.get(u).size.width*l.get(f)+"px",height:l.get(u).size.height*l.get(f)+"px","mix-blend-mode":"multiply",isolation:"isolate","pointer-events":"none"})),l.append(e,i)};l.if(b,e=>{l.get(u)&&e(y)}),l.append(e,h),l.pop()},exports.SelectionPluginPackage=u,exports.useSelectionCapability=s,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]})});
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 n=require("svelte/internal/client");require("@embedpdf/models");const r=require("@embedpdf/core/svelte"),o=require("@embedpdf/utils/svelte");function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const l=i(n),d=()=>r.useCapability(t.SelectionPlugin.id),s=()=>r.usePlugin(t.SelectionPlugin.id);var u=l.from_html("<div></div>"),c=l.from_html("<div></div> <!>",1);function g(e,t){l.push(t,!0);let n=l.prop(t,"background",3,"rgba(33,150,243)");const i=s(),d=r.useDocumentState(()=>t.documentId),g=l.derived(()=>{var e,n,r;return null==(r=null==(n=null==(e=d.current)?void 0:e.document)?void 0:n.pages)?void 0:r[t.pageIndex]});let a=l.state(l.proxy([])),p=l.state(null),v=l.state(null);const f=l.derived(()=>{var e;return void 0!==t.scale?t.scale:(null==(e=d.current)?void 0:e.scale)??1}),m=l.derived(()=>{var e,n;if(void 0!==t.rotation)return t.rotation;return(((null==(e=l.get(g))?void 0:e.rotation)??0)+((null==(n=d.current)?void 0:n.rotation)??0))%4}),b=l.derived(()=>Boolean(l.get(v)&&l.get(v).pageIndex===t.pageIndex&&l.get(v).isVisible&&(t.selectionMenu||t.selectionMenuSnippet)));l.user_effect(()=>i.plugin&&t.documentId?i.plugin.registerSelectionOnPage({documentId:t.documentId,pageIndex:t.pageIndex,onRectsChange:({rects:e,boundingRect:t})=>{l.set(a,e,!0),l.set(p,t,!0)}}):(l.set(a,[],!0),void l.set(p,null))),l.user_effect(()=>{if(i.plugin&&t.documentId)return i.plugin.onMenuPlacement(t.documentId,e=>{l.set(v,e,!0)});l.set(v,null)});var x=l.comment(),h=l.first_child(x),y=e=>{var r=c(),i=l.first_child(r);let d;l.each(i,21,()=>l.get(a),l.index,(e,t)=>{var r=u();let o;l.template_effect(()=>o=l.set_style(r,"",o,{position:"absolute",left:(l.get(t).origin.x-l.get(p).origin.x)*l.get(f)+"px",top:(l.get(t).origin.y-l.get(p).origin.y)*l.get(f)+"px",width:l.get(t).size.width*l.get(f)+"px",height:l.get(t).size.height*l.get(f)+"px",background:n(),"pointer-events":"none"})),l.append(e,r)}),l.reset(i);var s=l.sibling(i,2),g=e=>{{const n=(e,n)=>{const r=l.derived(()=>function(e,n){return{context:{type:"selection",pageIndex:t.pageIndex},selected:!0,rect:e,placement:{suggestTop:(null==(r=l.get(v))?void 0:r.suggestTop)??!1,spaceAbove:(null==(o=l.get(v))?void 0:o.spaceAbove)??0,spaceBelow:(null==(i=l.get(v))?void 0:i.spaceBelow)??0},menuWrapperProps:n};var r,o,i}(null==n?void 0:n().rect,null==n?void 0:n().menuWrapperProps));var o=l.comment(),i=l.first_child(o),d=e=>{const n=l.derived(()=>t.selectionMenu(l.get(r)));var o=l.comment(),i=l.first_child(o),d=e=>{var t=l.comment(),r=l.first_child(t);l.component(r,()=>l.get(n).component,(e,t)=>{t(e,l.spread_props(()=>l.get(n).props))}),l.append(e,t)};l.if(i,e=>{l.get(n)&&e(d)}),l.append(e,o)},s=e=>{var n=l.comment(),o=l.first_child(n),i=e=>{var n=l.comment(),o=l.first_child(n);l.snippet(o,()=>t.selectionMenuSnippet,()=>l.get(r)),l.append(e,n)};l.if(o,e=>{t.selectionMenuSnippet&&e(i)},!0),l.append(e,n)};l.if(i,e=>{t.selectionMenu?e(d):e(s,!1)}),l.append(e,o)};let r=l.derived(()=>({origin:{x:l.get(v).rect.origin.x*l.get(f),y:l.get(v).rect.origin.y*l.get(f)},size:{width:l.get(v).rect.size.width*l.get(f),height:l.get(v).rect.size.height*l.get(f)}}));o.CounterRotate(e,{get rect(){return l.get(r)},get rotation(){return l.get(m)},children:n,$$slots:{default:!0}})}};l.if(s,e=>{l.get(b)&&l.get(v)&&e(g)}),l.template_effect(()=>d=l.set_style(i,"",d,{position:"absolute",left:l.get(p).origin.x*l.get(f)+"px",top:l.get(p).origin.y*l.get(f)+"px",width:l.get(p).size.width*l.get(f)+"px",height:l.get(p).size.height*l.get(f)+"px","mix-blend-mode":"multiply",isolation:"isolate","pointer-events":"none"})),l.append(e,r)};l.if(h,e=>{l.get(p)&&e(y)}),l.append(e,x),l.pop()}var a=l.from_html("<div></div>");function p(e,t){l.push(t,!0);let n=l.prop(t,"borderStyle",3,"dashed");const o=s(),i=r.useDocumentState(()=>t.documentId),d=l.derived(()=>t.borderColor??t.stroke??"rgba(0,122,204,0.8)"),u=l.derived(()=>t.background??t.fill??"rgba(0,122,204,0.15)");let c=l.state(null);const g=l.derived(()=>{var e;return void 0!==t.scale?t.scale:(null==(e=i.current)?void 0:e.scale)??1});l.user_effect(()=>{if(l.set(c,null),o.plugin)return o.plugin.registerMarqueeOnPage({documentId:t.documentId,pageIndex:t.pageIndex,scale:l.get(g),onRectChange:e=>{l.set(c,e,!0)}})});var p=l.comment(),v=l.first_child(p),f=e=>{var r=a();let o;l.template_effect(()=>{l.set_class(r,1,l.clsx(t.class)),o=l.set_style(r,"",o,{position:"absolute","pointer-events":"none",left:l.get(c).origin.x*l.get(g)+"px",top:l.get(c).origin.y*l.get(g)+"px",width:l.get(c).size.width*l.get(g)+"px",height:l.get(c).size.height*l.get(g)+"px",border:`1px ${n()} ${l.get(d)}`,background:l.get(u),"box-sizing":"border-box","z-index":"1000"})}),l.append(e,r)};l.if(v,e=>{l.get(c)&&e(f)}),l.append(e,p),l.pop()}var v=l.from_html("<!> <!>",1);function f(e,t){l.push(t,!0);const n=d();l.user_effect(()=>{if(n.provides)return n.provides.onCopyToClipboard(({text:e})=>{navigator.clipboard.writeText(e).catch(e=>{console.error("Failed to copy text to clipboard:",e)})})}),l.pop()}const m=e.createPluginPackage(t.SelectionPluginPackage).addUtility(f).build();exports.CopyToClipboard=f,exports.MarqueeSelection=p,exports.SelectionLayer=function(e,t){l.push(t,!0);const n=l.derived(()=>{var e;return(null==(e=t.textStyle)?void 0:e.background)??t.background});var r=v(),o=l.first_child(r);g(o,{get documentId(){return t.documentId},get pageIndex(){return t.pageIndex},get scale(){return t.scale},get rotation(){return t.rotation},get background(){return l.get(n)},get selectionMenu(){return t.selectionMenu},get selectionMenuSnippet(){return t.selectionMenuSnippet}});var i=l.sibling(o,2);{let e=l.derived(()=>{var e;return null==(e=t.marqueeStyle)?void 0:e.background}),n=l.derived(()=>{var e;return null==(e=t.marqueeStyle)?void 0:e.borderColor}),r=l.derived(()=>{var e;return null==(e=t.marqueeStyle)?void 0:e.borderStyle});p(i,{get documentId(){return t.documentId},get pageIndex(){return t.pageIndex},get scale(){return t.scale},get background(){return l.get(e)},get borderColor(){return l.get(n)},get borderStyle(){return l.get(r)},get class(){return t.marqueeClass}})}l.append(e,r),l.pop()},exports.SelectionPluginPackage=m,exports.TextSelection=g,exports.useSelectionCapability=d,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]})});
2
2
  //# sourceMappingURL=index.cjs.map