@embedpdf/svelte 0.0.0-stage → 3.0.0-next.15

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 (261) hide show
  1. package/LICENSE +192 -0
  2. package/README.md +312 -2
  3. package/dist/actions/readers.svelte.d.ts +29 -0
  4. package/dist/actions/readers.svelte.js +55 -0
  5. package/dist/actions.d.ts +13 -0
  6. package/dist/actions.js +13 -0
  7. package/dist/anchored/Anchored.svelte +24 -0
  8. package/dist/anchored/Anchored.svelte.d.ts +4 -0
  9. package/dist/anchored/PlacedAnchored.svelte +97 -0
  10. package/dist/anchored/PlacedAnchored.svelte.d.ts +4 -0
  11. package/dist/anchored/context.d.ts +31 -0
  12. package/dist/anchored/context.js +36 -0
  13. package/dist/anchored/props.d.ts +29 -0
  14. package/dist/anchored/props.js +1 -0
  15. package/dist/anchored.d.ts +12 -0
  16. package/dist/anchored.js +2 -0
  17. package/dist/annotation/AnnotationChrome.svelte +173 -0
  18. package/dist/annotation/AnnotationChrome.svelte.d.ts +11 -0
  19. package/dist/annotation/AnnotationDraftMenu.svelte +27 -0
  20. package/dist/annotation/AnnotationDraftMenu.svelte.d.ts +4 -0
  21. package/dist/annotation/AnnotationFrame.svelte +46 -0
  22. package/dist/annotation/AnnotationFrame.svelte.d.ts +15 -0
  23. package/dist/annotation/AnnotationLayer.svelte +241 -0
  24. package/dist/annotation/AnnotationLayer.svelte.d.ts +4 -0
  25. package/dist/annotation/AnnotationLook.svelte +67 -0
  26. package/dist/annotation/AnnotationLook.svelte.d.ts +21 -0
  27. package/dist/annotation/AnnotationMenu.svelte +47 -0
  28. package/dist/annotation/AnnotationMenu.svelte.d.ts +4 -0
  29. package/dist/annotation/AnnotationRotationBadge.svelte +52 -0
  30. package/dist/annotation/AnnotationRotationBadge.svelte.d.ts +4 -0
  31. package/dist/annotation/AnnotationScene.svelte +27 -0
  32. package/dist/annotation/AnnotationScene.svelte.d.ts +7 -0
  33. package/dist/annotation/FreeTextBox.svelte +55 -0
  34. package/dist/annotation/FreeTextBox.svelte.d.ts +9 -0
  35. package/dist/annotation/NativeDrawing.svelte +61 -0
  36. package/dist/annotation/NativeDrawing.svelte.d.ts +10 -0
  37. package/dist/annotation/StampGhost.svelte +79 -0
  38. package/dist/annotation/StampGhost.svelte.d.ts +7 -0
  39. package/dist/annotation/chrome-paint.svelte.d.ts +30 -0
  40. package/dist/annotation/chrome-paint.svelte.js +27 -0
  41. package/dist/annotation/props.d.ts +181 -0
  42. package/dist/annotation/props.js +1 -0
  43. package/dist/annotation/readers.svelte.d.ts +59 -0
  44. package/dist/annotation/readers.svelte.js +136 -0
  45. package/dist/annotation/state.d.ts +18 -0
  46. package/dist/annotation/state.js +20 -0
  47. package/dist/annotation/text-box.svelte.d.ts +27 -0
  48. package/dist/annotation/text-box.svelte.js +94 -0
  49. package/dist/annotation.d.ts +32 -0
  50. package/dist/annotation.js +31 -0
  51. package/dist/commands/readers.svelte.d.ts +50 -0
  52. package/dist/commands/readers.svelte.js +83 -0
  53. package/dist/commands.d.ts +9 -0
  54. package/dist/commands.js +9 -0
  55. package/dist/form/ButtonControl.svelte +38 -0
  56. package/dist/form/ButtonControl.svelte.d.ts +11 -0
  57. package/dist/form/ComboControl.svelte +52 -0
  58. package/dist/form/ComboControl.svelte.d.ts +11 -0
  59. package/dist/form/FieldPictures.svelte +145 -0
  60. package/dist/form/FieldPictures.svelte.d.ts +3 -0
  61. package/dist/form/FormFocusRing.svelte +25 -0
  62. package/dist/form/FormFocusRing.svelte.d.ts +8 -0
  63. package/dist/form/FormLayer.svelte +98 -0
  64. package/dist/form/FormLayer.svelte.d.ts +3 -0
  65. package/dist/form/ListControl.svelte +49 -0
  66. package/dist/form/ListControl.svelte.d.ts +11 -0
  67. package/dist/form/NativeListBox.svelte +57 -0
  68. package/dist/form/NativeListBox.svelte.d.ts +4 -0
  69. package/dist/form/SignatureControl.svelte +53 -0
  70. package/dist/form/SignatureControl.svelte.d.ts +11 -0
  71. package/dist/form/TextControl.svelte +107 -0
  72. package/dist/form/TextControl.svelte.d.ts +11 -0
  73. package/dist/form/ToggleControl.svelte +50 -0
  74. package/dist/form/ToggleControl.svelte.d.ts +11 -0
  75. package/dist/form/WidgetBox.svelte +82 -0
  76. package/dist/form/WidgetBox.svelte.d.ts +15 -0
  77. package/dist/form/props.d.ts +21 -0
  78. package/dist/form/props.js +1 -0
  79. package/dist/form/readers.svelte.d.ts +46 -0
  80. package/dist/form/readers.svelte.js +52 -0
  81. package/dist/form/widget.d.ts +16 -0
  82. package/dist/form/widget.js +20 -0
  83. package/dist/form.d.ts +11 -0
  84. package/dist/form.js +12 -0
  85. package/dist/history/readers.d.ts +22 -0
  86. package/dist/history/readers.js +21 -0
  87. package/dist/history.d.ts +10 -0
  88. package/dist/history.js +11 -0
  89. package/dist/i18n/readers.svelte.d.ts +32 -0
  90. package/dist/i18n/readers.svelte.js +30 -0
  91. package/dist/i18n.d.ts +8 -0
  92. package/dist/i18n.js +9 -0
  93. package/dist/index.d.ts +28 -0
  94. package/dist/index.js +28 -0
  95. package/dist/interaction/PagePointerSource.svelte +37 -0
  96. package/dist/interaction/PagePointerSource.svelte.d.ts +3 -0
  97. package/dist/interaction/readers.svelte.d.ts +26 -0
  98. package/dist/interaction/readers.svelte.js +47 -0
  99. package/dist/interaction.d.ts +11 -0
  100. package/dist/interaction.js +13 -0
  101. package/dist/link/LinkLayer.svelte +164 -0
  102. package/dist/link/LinkLayer.svelte.d.ts +4 -0
  103. package/dist/link/props.d.ts +17 -0
  104. package/dist/link/props.js +1 -0
  105. package/dist/link/readers.svelte.d.ts +18 -0
  106. package/dist/link/readers.svelte.js +38 -0
  107. package/dist/link.d.ts +11 -0
  108. package/dist/link.js +11 -0
  109. package/dist/measurement/readers.d.ts +44 -0
  110. package/dist/measurement/readers.js +46 -0
  111. package/dist/measurement.d.ts +12 -0
  112. package/dist/measurement.js +13 -0
  113. package/dist/metadata/readers.d.ts +22 -0
  114. package/dist/metadata/readers.js +22 -0
  115. package/dist/metadata.d.ts +12 -0
  116. package/dist/metadata.js +13 -0
  117. package/dist/page-edit/readers.d.ts +7 -0
  118. package/dist/page-edit/readers.js +11 -0
  119. package/dist/page-edit.d.ts +12 -0
  120. package/dist/page-edit.js +13 -0
  121. package/dist/page-view/PageView.svelte +192 -0
  122. package/dist/page-view/PageView.svelte.d.ts +4 -0
  123. package/dist/page-view/props.d.ts +32 -0
  124. package/dist/page-view/props.js +1 -0
  125. package/dist/page-view.d.ts +8 -0
  126. package/dist/page-view.js +7 -0
  127. package/dist/redaction/readers.d.ts +37 -0
  128. package/dist/redaction/readers.js +38 -0
  129. package/dist/redaction.d.ts +12 -0
  130. package/dist/redaction.js +13 -0
  131. package/dist/render/RenderLayer.svelte +116 -0
  132. package/dist/render/RenderLayer.svelte.d.ts +4 -0
  133. package/dist/render/TileImage.svelte +65 -0
  134. package/dist/render/TileImage.svelte.d.ts +11 -0
  135. package/dist/render/TilePlane.svelte +88 -0
  136. package/dist/render/TilePlane.svelte.d.ts +7 -0
  137. package/dist/render/props.d.ts +16 -0
  138. package/dist/render/props.js +1 -0
  139. package/dist/render/readers.svelte.d.ts +9 -0
  140. package/dist/render/readers.svelte.js +13 -0
  141. package/dist/render.d.ts +10 -0
  142. package/dist/render.js +10 -0
  143. package/dist/runtime/DocumentGate.svelte +26 -0
  144. package/dist/runtime/DocumentGate.svelte.d.ts +4 -0
  145. package/dist/runtime/DocumentScope.svelte +14 -0
  146. package/dist/runtime/DocumentScope.svelte.d.ts +4 -0
  147. package/dist/runtime/KernelProvider.svelte +33 -0
  148. package/dist/runtime/KernelProvider.svelte.d.ts +4 -0
  149. package/dist/runtime/SvgShapes.svelte +30 -0
  150. package/dist/runtime/SvgShapes.svelte.d.ts +8 -0
  151. package/dist/runtime/Viewer.svelte +124 -0
  152. package/dist/runtime/Viewer.svelte.d.ts +4 -0
  153. package/dist/runtime/binding.svelte.d.ts +33 -0
  154. package/dist/runtime/binding.svelte.js +71 -0
  155. package/dist/runtime/capability-handle.d.ts +6 -0
  156. package/dist/runtime/capability-handle.js +71 -0
  157. package/dist/runtime/dev.d.ts +10 -0
  158. package/dist/runtime/dev.js +23 -0
  159. package/dist/runtime/documents.svelte.d.ts +34 -0
  160. package/dist/runtime/documents.svelte.js +49 -0
  161. package/dist/runtime/page-layers.svelte.d.ts +20 -0
  162. package/dist/runtime/page-layers.svelte.js +40 -0
  163. package/dist/runtime/page.d.ts +10 -0
  164. package/dist/runtime/page.js +23 -0
  165. package/dist/runtime/props.d.ts +63 -0
  166. package/dist/runtime/props.js +1 -0
  167. package/dist/runtime/readers.svelte.d.ts +47 -0
  168. package/dist/runtime/readers.svelte.js +122 -0
  169. package/dist/runtime/state.svelte.d.ts +35 -0
  170. package/dist/runtime/state.svelte.js +90 -0
  171. package/dist/runtime/theme.d.ts +12 -0
  172. package/dist/runtime/theme.js +15 -0
  173. package/dist/runtime/values.svelte.d.ts +28 -0
  174. package/dist/runtime/values.svelte.js +51 -0
  175. package/dist/runtime.d.ts +26 -0
  176. package/dist/runtime.js +25 -0
  177. package/dist/search/SearchLayer.svelte +94 -0
  178. package/dist/search/SearchLayer.svelte.d.ts +4 -0
  179. package/dist/search/props.d.ts +11 -0
  180. package/dist/search/props.js +1 -0
  181. package/dist/search/readers.svelte.d.ts +41 -0
  182. package/dist/search/readers.svelte.js +40 -0
  183. package/dist/search.d.ts +11 -0
  184. package/dist/search.js +11 -0
  185. package/dist/selection/SelectionClipboard.svelte +35 -0
  186. package/dist/selection/SelectionClipboard.svelte.d.ts +4 -0
  187. package/dist/selection/SelectionHandles.svelte +192 -0
  188. package/dist/selection/SelectionHandles.svelte.d.ts +4 -0
  189. package/dist/selection/SelectionLayer.svelte +67 -0
  190. package/dist/selection/SelectionLayer.svelte.d.ts +3 -0
  191. package/dist/selection/SelectionMenu.svelte +36 -0
  192. package/dist/selection/SelectionMenu.svelte.d.ts +4 -0
  193. package/dist/selection/props.d.ts +26 -0
  194. package/dist/selection/props.js +1 -0
  195. package/dist/selection/readers.svelte.d.ts +31 -0
  196. package/dist/selection/readers.svelte.js +26 -0
  197. package/dist/selection.d.ts +16 -0
  198. package/dist/selection.js +18 -0
  199. package/dist/shell/readers.svelte.d.ts +40 -0
  200. package/dist/shell/readers.svelte.js +40 -0
  201. package/dist/shell/surface-focus.svelte.d.ts +16 -0
  202. package/dist/shell/surface-focus.svelte.js +33 -0
  203. package/dist/shell.d.ts +12 -0
  204. package/dist/shell.js +11 -0
  205. package/dist/signature/readers.svelte.d.ts +43 -0
  206. package/dist/signature/readers.svelte.js +46 -0
  207. package/dist/signature.d.ts +15 -0
  208. package/dist/signature.js +16 -0
  209. package/dist/stage/PageSurface.svelte +126 -0
  210. package/dist/stage/PageSurface.svelte.d.ts +18 -0
  211. package/dist/stage/Scrollbar.svelte +148 -0
  212. package/dist/stage/Scrollbar.svelte.d.ts +4 -0
  213. package/dist/stage/Stage.svelte +181 -0
  214. package/dist/stage/Stage.svelte.d.ts +4 -0
  215. package/dist/stage/StageScope.svelte +14 -0
  216. package/dist/stage/StageScope.svelte.d.ts +9 -0
  217. package/dist/stage/props.d.ts +71 -0
  218. package/dist/stage/props.js +1 -0
  219. package/dist/stage/readers.svelte.d.ts +39 -0
  220. package/dist/stage/readers.svelte.js +84 -0
  221. package/dist/stage/stage-scope.d.ts +18 -0
  222. package/dist/stage/stage-scope.js +35 -0
  223. package/dist/stage/two-way.svelte.d.ts +13 -0
  224. package/dist/stage/two-way.svelte.js +26 -0
  225. package/dist/stage.d.ts +17 -0
  226. package/dist/stage.js +15 -0
  227. package/dist/stamp/readers.svelte.d.ts +50 -0
  228. package/dist/stamp/readers.svelte.js +76 -0
  229. package/dist/stamp.d.ts +16 -0
  230. package/dist/stamp.js +18 -0
  231. package/dist/toolbar/DefaultCollapsed.svelte +39 -0
  232. package/dist/toolbar/DefaultCollapsed.svelte.d.ts +9 -0
  233. package/dist/toolbar/DefaultCommand.svelte +33 -0
  234. package/dist/toolbar/DefaultCommand.svelte.d.ts +8 -0
  235. package/dist/toolbar/DefaultGroupTrigger.svelte +39 -0
  236. package/dist/toolbar/DefaultGroupTrigger.svelte.d.ts +9 -0
  237. package/dist/toolbar/DefaultOverflowMenu.svelte +106 -0
  238. package/dist/toolbar/DefaultOverflowMenu.svelte.d.ts +9 -0
  239. package/dist/toolbar/DefaultOverflowTrigger.svelte +25 -0
  240. package/dist/toolbar/DefaultOverflowTrigger.svelte.d.ts +7 -0
  241. package/dist/toolbar/Measured.svelte +46 -0
  242. package/dist/toolbar/Measured.svelte.d.ts +11 -0
  243. package/dist/toolbar/NativeSlotSocket.svelte +43 -0
  244. package/dist/toolbar/NativeSlotSocket.svelte.d.ts +11 -0
  245. package/dist/toolbar/Toolbar.svelte +314 -0
  246. package/dist/toolbar/Toolbar.svelte.d.ts +4 -0
  247. package/dist/toolbar/paint.d.ts +3 -0
  248. package/dist/toolbar/paint.js +9 -0
  249. package/dist/toolbar/props.d.ts +48 -0
  250. package/dist/toolbar/props.js +1 -0
  251. package/dist/toolbar/strip.svelte.d.ts +14 -0
  252. package/dist/toolbar/strip.svelte.js +35 -0
  253. package/dist/toolbar/views.d.ts +14 -0
  254. package/dist/toolbar/views.js +1 -0
  255. package/dist/toolbar.d.ts +16 -0
  256. package/dist/toolbar.js +12 -0
  257. package/dist/view-manager/readers.d.ts +19 -0
  258. package/dist/view-manager/readers.js +17 -0
  259. package/dist/view-manager.d.ts +11 -0
  260. package/dist/view-manager.js +12 -0
  261. package/package.json +195 -3
@@ -0,0 +1,35 @@
1
+ <!--
2
+ Copying selected text with the keyboard and the browser's Copy menu. Mount it once per viewer:
3
+ it fetches the selected text when the selection settles, answers the native `copy` event at
4
+ once, and falls back to the async Clipboard API for Ctrl+C / Cmd+C when the page has no DOM
5
+ selection. A selection the user may not copy isn't copied, and `onRefused` is called. It
6
+ draws nothing, and wires nothing until a document is ready. A Copy button calls
7
+ `copySelection(useSelection())` from its click instead.
8
+ -->
9
+ <script lang="ts">
10
+ import { untrack } from 'svelte';
11
+ import { SelectionToken } from '@embedpdf/plugin-selection';
12
+ import { wireSelectionClipboard } from '@embedpdf/web';
13
+ import { useOptionalCapability } from '../runtime/readers.svelte.js';
14
+ import { valueOf } from '../runtime/values.svelte.js';
15
+ import type { SelectionClipboardProps } from './props.js';
16
+
17
+ let { prefetch, onRefused, target }: SelectionClipboardProps = $props();
18
+
19
+ // The capability itself, not a handle: the clipboard wiring keeps it and subscribes to it.
20
+ const selection = useOptionalCapability(SelectionToken);
21
+
22
+ $effect(() => {
23
+ const current = selection.current;
24
+ const element = valueOf(target);
25
+ // Read at the moment of the refusal, so a new callback needs no new wiring.
26
+ const options = {
27
+ ...(prefetch === undefined ? {} : { prefetch }),
28
+ ...(element ? { target: element } : {}),
29
+ onRefused: () => untrack(() => onRefused)?.(),
30
+ };
31
+ // A target that hasn't mounted yet wires nothing; this runs again once it has.
32
+ if (!current || (target !== undefined && !element)) return;
33
+ return untrack(() => wireSelectionClipboard(current, options));
34
+ });
35
+ </script>
@@ -0,0 +1,4 @@
1
+ import type { SelectionClipboardProps } from './props.js';
2
+ declare const SelectionClipboard: import("svelte").Component<SelectionClipboardProps, {}, "">;
3
+ type SelectionClipboard = ReturnType<typeof SelectionClipboard>;
4
+ export default SelectionClipboard;
@@ -0,0 +1,192 @@
1
+ <!--
2
+ Draggable selection handles, the way phones draw them: a thin caret bar that is the selection's
3
+ own start or end edge (the boundary glyph's edge, so turned text and turned pages carry the
4
+ handle with them), capped by a circle that keeps its size on screen, above the first line at
5
+ the start and below the last line at the end.
6
+
7
+ On touch, where nothing can drag a caret, the handles grow or shrink a selection: a long press
8
+ selects a word, then each handle extends from the opposite end, snapping to glyphs and crossing
9
+ pages like a pointer drag. A handle drag is the same selection gesture, so the highlight, the
10
+ menu and the commit events behave the same.
11
+
12
+ Mount it in a `<Stage>`'s overlay, next to `<SelectionMenu>`. Outside a Stage it draws nothing
13
+ (a `<PageView>` has no camera to project the handles through). A press on a handle never pans
14
+ the Stage. Painted in the plugin's `handles` setting, which the `--epdf-text-selection-handle`
15
+ and `--epdf-text-selection-handle-shadow` CSS variables win over.
16
+
17
+ The policy is shared: the view over the Stage, the endpoints, the geometry and the armed drag
18
+ come from the selection plugin's `handles` module, the listener mechanics from
19
+ `@embedpdf/web`'s `attachSelectionHandle`. This file keeps the subscriptions and the markup.
20
+ -->
21
+ <script lang="ts">
22
+ import {
23
+ HANDLE_BAR,
24
+ HANDLE_HEAD,
25
+ HANDLE_PAD,
26
+ armSelectionHandle,
27
+ selectionHandleEndpointsOf,
28
+ selectionHandleGeom,
29
+ selectionHandleViewOf,
30
+ type SelectionHandleGeom,
31
+ } from '@embedpdf/plugin-selection';
32
+ import { SelectionToken } from '@embedpdf/plugin-selection/contract/host';
33
+ import { attachSelectionHandle, paint, sameSelectionEndpoints } from '@embedpdf/web';
34
+ import { useOptionalProjectorBinding } from '../anchored/context.js';
35
+ import { devWarn } from '../runtime/dev.js';
36
+ import { useViewerSettings } from '../runtime/documents.svelte.js';
37
+ import {
38
+ useCapability,
39
+ useKernelValue,
40
+ useOptionalCapability,
41
+ useOptionalSelector,
42
+ } from '../runtime/readers.svelte.js';
43
+ import { stageTokenOf } from '../stage/stage-scope.js';
44
+ import type { SelectionHandlesProps } from './props.js';
45
+ import { useSelectionSettings, useSelectionState } from './readers.svelte.js';
46
+
47
+ type Role = 'start' | 'end';
48
+
49
+ let { token }: SelectionHandlesProps = $props();
50
+
51
+ const host = useCapability(SelectionToken);
52
+ const stage = useOptionalCapability(stageTokenOf(() => token));
53
+
54
+ // Outside a Stage there is no camera to project through: say so instead of drawing nothing
55
+ // without a word.
56
+ const surface = useOptionalProjectorBinding();
57
+ if (!surface || surface().projector.space !== 'overlay') {
58
+ devWarn(
59
+ 'selection-handles-outside-stage',
60
+ '<SelectionHandles> draws nothing here: put it in the <Stage> overlay snippet ' +
61
+ '(a <PageView> has no camera to project the handles through).',
62
+ );
63
+ }
64
+
65
+ const selecting = useSelectionState((selectionState) => selectionState.isSelecting);
66
+ const visible = useOptionalSelector(SelectionToken, (lens) => lens.isHighlightVisible(), false);
67
+ const handles = useSelectionSettings((settings) => settings.handles);
68
+ const accent = useViewerSettings((settings) => settings.accent);
69
+ const endpoints = useOptionalSelector(
70
+ SelectionToken,
71
+ (lens) => selectionHandleEndpointsOf(lens.getSnapshot()),
72
+ null,
73
+ sameSelectionEndpoints,
74
+ );
75
+ // The handles are placed by projecting the endpoints through the camera, so they move whenever
76
+ // it does: the visible pages are the Stage's value for exactly that, the same one its pages
77
+ // move on, so handle and highlight move in one frame.
78
+ const camera = useKernelValue(() => stage.current?.listVisiblePages() ?? null);
79
+
80
+ const geometry = $derived.by((): Record<Role, SelectionHandleGeom | null> | null => {
81
+ void camera.current;
82
+ const lens = stage.current;
83
+ const ends = endpoints.current;
84
+ if (!lens || !ends) return null;
85
+ const view = selectionHandleViewOf(lens);
86
+ return {
87
+ start: selectionHandleGeom(view, ends.start, 'start'),
88
+ end: selectionHandleGeom(view, ends.end, 'end'),
89
+ };
90
+ });
91
+
92
+ // The handle being dragged: it keeps its handles shown while the selection is mid-gesture.
93
+ let dragging = $state<Role | null>(null);
94
+
95
+ /**
96
+ * Arm a drag at the press. It reads the stage and the endpoints as they are now, not as they
97
+ * were when the listener was attached.
98
+ */
99
+ function arm(role: Role) {
100
+ const lens = stage.current;
101
+ const ends = endpoints.current;
102
+ if (!lens || !ends) return null;
103
+ const armed = armSelectionHandle(host, selectionHandleViewOf(lens), ends, role);
104
+ if (!armed) return null;
105
+ dragging = role;
106
+ return {
107
+ // The point the user grabbed: the bar's midpoint.
108
+ base: armed.base,
109
+ session: {
110
+ move: armed.drag.move,
111
+ end: () => {
112
+ armed.drag.end(); // settles the selection: the menu shows again, onCommitted fires
113
+ dragging = null;
114
+ },
115
+ },
116
+ };
117
+ }
118
+
119
+ /** The handle's listeners, as an attachment: a native press listener, so the Stage never sees it. */
120
+ const bindHandle = (role: Role) => (element: HTMLElement) =>
121
+ attachSelectionHandle(element, { arm: () => arm(role) });
122
+
123
+ // Each is its CSS variable first, then the setting; an unset color is the accent.
124
+ const color = $derived(paint('text-selection-handle', handles.current.color ?? accent.current));
125
+ const shadow = $derived(paint('text-selection-handle-shadow', handles.current.shadow));
126
+
127
+ // Hidden while a pointer drag selects (like the menu), but a handle drag is itself a selection
128
+ // gesture, so it keeps its handles.
129
+ const shown = $derived(
130
+ stage.current !== null &&
131
+ endpoints.current !== null &&
132
+ visible.current &&
133
+ (!selecting.current || dragging !== null),
134
+ );
135
+ </script>
136
+
137
+ <!--
138
+ One handle, laid out upright in its own frame (a bar as long as the edge, the head above it at
139
+ the start or below it at the end), then turned onto the projected edge. The pivot is the bar's
140
+ ascent-side tip, the one point that must land exactly on the glyph's corner. Upright text
141
+ carries no transform.
142
+ -->
143
+ {#snippet handle(role: Role, at: SelectionHandleGeom)}
144
+ {@const barTop = HANDLE_PAD + (role === 'start' ? HANDLE_HEAD : 0)}
145
+ {@const pivotX = HANDLE_PAD + HANDLE_BAR / 2}
146
+ <div
147
+ {@attach bindHandle(role)}
148
+ style:position="absolute"
149
+ style:left="{at.bar.from.x - pivotX}px"
150
+ style:top="{at.bar.from.y - barTop}px"
151
+ style:width="{HANDLE_BAR + 2 * HANDLE_PAD}px"
152
+ style:height="{at.length + HANDLE_HEAD + 2 * HANDLE_PAD}px"
153
+ style:transform={at.upright ? undefined : `rotate(${at.rotation}deg)`}
154
+ style:transform-origin={at.upright ? undefined : `${pivotX}px ${barTop}px`}
155
+ style:touch-action="none"
156
+ style:cursor="grab"
157
+ style:pointer-events="auto"
158
+ >
159
+ <!-- The caret bar: the selection's own edge, as tall as the glyph's ink, at any tilt. -->
160
+ <div
161
+ style:position="absolute"
162
+ style:left="{HANDLE_PAD}px"
163
+ style:top="{barTop}px"
164
+ style:width="{HANDLE_BAR}px"
165
+ style:height="{at.length}px"
166
+ style:background={color}
167
+ style:border-radius="{HANDLE_BAR / 2}px"
168
+ ></div>
169
+ <!-- The head, against the bar: past the ascent at the start, past the baseline at the end,
170
+ in the text's frame. -->
171
+ <div
172
+ style:position="absolute"
173
+ style:left="{pivotX - HANDLE_HEAD / 2}px"
174
+ style:top="{role === 'start' ? HANDLE_PAD : HANDLE_PAD + at.length}px"
175
+ style:width="{HANDLE_HEAD}px"
176
+ style:height="{HANDLE_HEAD}px"
177
+ style:border-radius="50%"
178
+ style:background={color}
179
+ style:box-shadow={shadow}
180
+ ></div>
181
+ </div>
182
+ {/snippet}
183
+
184
+ {#if shown && geometry}
185
+ <!-- A handle whose page isn't laid out right now draws nothing. -->
186
+ {#if geometry.start}
187
+ {@render handle('start', geometry.start)}
188
+ {/if}
189
+ {#if geometry.end}
190
+ {@render handle('end', geometry.end)}
191
+ {/if}
192
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { SelectionHandlesProps } from './props.js';
2
+ declare const SelectionHandles: import("svelte").Component<SelectionHandlesProps, {}, "">;
3
+ type SelectionHandles = ReturnType<typeof SelectionHandles>;
4
+ export default SelectionHandles;
@@ -0,0 +1,67 @@
1
+ <!--
2
+ The highlight of the selected text on one page. It only paints: it warms the page's text
3
+ geometry when it mounts, reads the page-space highlight from the plugin and maps each piece
4
+ through the page's transform, in the plugin's `color` setting, which the
5
+ `--epdf-text-selection` CSS variable wins over. Pointer input is `<PagePointerSource>`'s.
6
+
7
+ It reads the host lens (`/contract/host`: geometry warming, the highlight handshake), which
8
+ exists for exactly this; app code gets the public lens from `useSelection()`.
9
+ -->
10
+ <script lang="ts">
11
+ import { SelectionToken } from '@embedpdf/plugin-selection/contract/host';
12
+ import type { SelectionSegment } from '@embedpdf/plugin-selection';
13
+ import { mixAccent, paint, quadInPixels, svgPoints } from '@embedpdf/web';
14
+ import { useViewerSettings } from '../runtime/documents.svelte.js';
15
+ import { usePage } from '../runtime/page.js';
16
+ import {
17
+ shallowArray,
18
+ useOptionalCapability,
19
+ useOptionalSelector,
20
+ } from '../runtime/readers.svelte.js';
21
+ import { useSelectionSettings } from './readers.svelte.js';
22
+
23
+ const NO_SEGMENTS: readonly SelectionSegment[] = Object.freeze([]);
24
+
25
+ const page = usePage();
26
+ const selection = useOptionalCapability(SelectionToken);
27
+ const segments = useOptionalSelector(
28
+ SelectionToken,
29
+ (lens) => lens.listSegments(page.ref),
30
+ NO_SEGMENTS,
31
+ shallowArray,
32
+ );
33
+ // Code that draws its own selection (a markup tool's preview) can take the highlight over;
34
+ // then this draws nothing, so the two never overlap.
35
+ const visible = useOptionalSelector(SelectionToken, (lens) => lens.isHighlightVisible(), false);
36
+ // Settings need no document; without the selection plugin this throws now, with the fix.
37
+ const color = useSelectionSettings((settings) => settings.color);
38
+ // An unset color follows the viewer's accent, behind the `--epdf-accent` variable.
39
+ const accent = useViewerSettings((settings) => settings.accent);
40
+
41
+ // Warm this page's text geometry as soon as it's on screen, so the first press can hit-test
42
+ // without waiting for the engine. Nothing warms without the `doc.text.select` permission.
43
+ $effect(() => {
44
+ const lens = selection.current;
45
+ const ref = page.ref;
46
+ if (!lens) return;
47
+ void lens.ensureLoaded(ref);
48
+ });
49
+
50
+ // Unset, the color is the accent at 35%, the accent variables included.
51
+ const fill = $derived(
52
+ paint('text-selection', color.current ?? mixAccent('text-selection', accent.current)),
53
+ );
54
+ </script>
55
+
56
+ {#if visible.current}
57
+ <svg
58
+ style="position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none"
59
+ >
60
+ {#each segments.current as segment, index (index)}
61
+ <!-- Page space to the page layer's pixels, which turn with the page: mapping the four
62
+ corners is exact, for turned text too. The fill is in `style`: an SVG attribute
63
+ doesn't read var(). -->
64
+ <polygon points={svgPoints(quadInPixels(segment.quad, page.transform))} style:fill />
65
+ {/each}
66
+ </svg>
67
+ {/if}
@@ -0,0 +1,3 @@
1
+ declare const SelectionLayer: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type SelectionLayer = ReturnType<typeof SelectionLayer>;
3
+ export default SelectionLayer;
@@ -0,0 +1,36 @@
1
+ <!--
2
+ A menu over the text selection, once the selection settles. One anchor for the whole
3
+ selection, even across pages: it sits on the page the gesture ended on. Hidden while the user
4
+ is still dragging, it appears when the pointer lifts; a selection made from code shows it at
5
+ once. It works in a `<Stage>`'s overlay and in a `<PageView>` alike: the surface gives the
6
+ projection.
7
+
8
+ For UI that follows the selection during the drag, use `<Anchored>` with
9
+ `useSelection().getAnchor()` yourself: this component is that, plus the hiding.
10
+ -->
11
+ <script lang="ts">
12
+ import { SelectionToken } from '@embedpdf/plugin-selection';
13
+ import { samePageBounds } from '@embedpdf/web';
14
+ import Anchored from '../anchored/Anchored.svelte';
15
+ import { useOptionalSelector } from '../runtime/readers.svelte.js';
16
+ import type { SelectionMenuProps } from './props.js';
17
+ import { useSelectionState } from './readers.svelte.js';
18
+
19
+ let { children, gap = 8, placement = 'top' }: SelectionMenuProps = $props();
20
+
21
+ const selecting = useSelectionState((selectionState) => selectionState.isSelecting);
22
+ // Every read gives a new anchor: compared by page and box, so the menu moves only when the
23
+ // selection did.
24
+ const anchor = useOptionalSelector(
25
+ SelectionToken,
26
+ (selection) => selection.getAnchor(),
27
+ null,
28
+ samePageBounds,
29
+ );
30
+ </script>
31
+
32
+ {#if !selecting.current && anchor.current}
33
+ <Anchored anchor={anchor.current} {placement} {gap}>
34
+ {@render children()}
35
+ </Anchored>
36
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { SelectionMenuProps } from './props.js';
2
+ declare const SelectionMenu: import("svelte").Component<SelectionMenuProps, {}, "">;
3
+ type SelectionMenu = ReturnType<typeof SelectionMenu>;
4
+ export default SelectionMenu;
@@ -0,0 +1,26 @@
1
+ /** The props of the selection components. */
2
+ import type { Snippet } from 'svelte';
3
+ import type { AnchoredPlacement, SelectionClipboardOptions } from '@embedpdf/web';
4
+ import type { MaybeGetter } from '../runtime/values.svelte.js';
5
+ import type { StageTokenProp } from '../stage/stage-scope.js';
6
+ export interface SelectionMenuProps {
7
+ /** The menu: buttons that call `useSelection()`, `copySelection()`, an annotation's markup. */
8
+ children: Snippet;
9
+ /** The gap in screen pixels between the selection and the menu. Default 8. */
10
+ gap?: number;
11
+ /** Where the menu sits next to the selection. Default `'top'`. */
12
+ placement?: AnchoredPlacement;
13
+ }
14
+ export interface SelectionHandlesProps {
15
+ /** The stage lens this overlay is on: the enclosing `<Stage>`'s by default. */
16
+ token?: StageTokenProp;
17
+ }
18
+ /** The props of `<SelectionClipboard>`. */
19
+ export interface SelectionClipboardProps extends Pick<SelectionClipboardOptions, 'prefetch' | 'onRefused'> {
20
+ /**
21
+ * Copy only while focus is inside this element, for a page with more than one viewer. Pass a
22
+ * function (`() => area`, with `bind:this={area}`): copying works once the element has mounted.
23
+ * Default: anywhere on the page.
24
+ */
25
+ target?: MaybeGetter<HTMLElement | null | undefined>;
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The selection plugin's readers: `useSelection()` (the API), `useSelectionState()`,
3
+ * `useSelectionSettings()` and `useSelectionEvent()`. App code gets the public lens; the layers
4
+ * in this folder read the host lens themselves.
5
+ */
6
+ import type { EventHook } from '@embedpdf/core';
7
+ import type { SelectionCapability } from '@embedpdf/plugin-selection';
8
+ /**
9
+ * The public selection API (`select()`, `readText()`, `canCopy()`, …) for app chrome: toolbars,
10
+ * context menus, automation. A handle, always the capability of the document in scope.
11
+ */
12
+ export declare function useSelection(): SelectionCapability;
13
+ /**
14
+ * The selection's state: whether anything is selected, whether the user is still selecting, the
15
+ * character range and the pages it's on (declared once in `selectionState`), as a reactive object
16
+ * (`state.hasSelection`). With a selector, the value it picks as `{ current }`. Empty without a
17
+ * document.
18
+ */
19
+ export declare const useSelectionState: import("../index.js").StateReader<{
20
+ hasSelection: boolean;
21
+ isSelecting: boolean;
22
+ range: import("@embedpdf/plugin-selection").TextRange | null;
23
+ pages: readonly import("@embedpdf/core").PageRef[];
24
+ }>;
25
+ /** The selection settings (`dragThreshold`, `color`, `handles`), with or without a document. */
26
+ export declare const useSelectionSettings: import("../index.js").SettingsReader<import("@embedpdf/plugin-selection").SelectionSettings & object>;
27
+ /**
28
+ * Subscribe to one selection event while the component lives:
29
+ * `useSelectionEvent((selection) => selection.onCommitted, handler)`.
30
+ */
31
+ export declare function useSelectionEvent<T>(select: (selection: SelectionCapability) => EventHook<T>, handler: (event: T) => void): void;
@@ -0,0 +1,26 @@
1
+ import { SelectionToken, selectionState } from '@embedpdf/plugin-selection';
2
+ import { useCapability, useCapabilityEvent } from '../runtime/readers.svelte.js';
3
+ import { settingsReader, stateReader } from '../runtime/state.svelte.js';
4
+ /**
5
+ * The public selection API (`select()`, `readText()`, `canCopy()`, …) for app chrome: toolbars,
6
+ * context menus, automation. A handle, always the capability of the document in scope.
7
+ */
8
+ export function useSelection() {
9
+ return useCapability(SelectionToken);
10
+ }
11
+ /**
12
+ * The selection's state: whether anything is selected, whether the user is still selecting, the
13
+ * character range and the pages it's on (declared once in `selectionState`), as a reactive object
14
+ * (`state.hasSelection`). With a selector, the value it picks as `{ current }`. Empty without a
15
+ * document.
16
+ */
17
+ export const useSelectionState = stateReader(selectionState);
18
+ /** The selection settings (`dragThreshold`, `color`, `handles`), with or without a document. */
19
+ export const useSelectionSettings = settingsReader(SelectionToken);
20
+ /**
21
+ * Subscribe to one selection event while the component lives:
22
+ * `useSelectionEvent((selection) => selection.onCommitted, handler)`.
23
+ */
24
+ export function useSelectionEvent(select, handler) {
25
+ useCapabilityEvent(SelectionToken, select, handler);
26
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @embedpdf/svelte/selection — text selection.
3
+ *
4
+ * `<SelectionLayer>` paints the highlight on each page; `<SelectionMenu>` floats over a settled
5
+ * selection; `<SelectionHandles>` are the touch handles in a Stage's overlay;
6
+ * `<SelectionClipboard>` wires Ctrl+C / Cmd+C. The readers are the plugin's four:
7
+ * `useSelection()`, `useSelectionState()`, `useSelectionSettings()` and `useSelectionEvent()`.
8
+ */
9
+ export * from '@embedpdf/plugin-selection';
10
+ export { copySelection } from '@embedpdf/web';
11
+ export { default as SelectionLayer } from './selection/SelectionLayer.svelte';
12
+ export { default as SelectionMenu } from './selection/SelectionMenu.svelte';
13
+ export { default as SelectionHandles } from './selection/SelectionHandles.svelte';
14
+ export { default as SelectionClipboard } from './selection/SelectionClipboard.svelte';
15
+ export type { SelectionClipboardProps, SelectionHandlesProps, SelectionMenuProps, } from './selection/props.js';
16
+ export { useSelection, useSelectionEvent, useSelectionSettings, useSelectionState, } from './selection/readers.svelte.js';
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @embedpdf/svelte/selection — text selection.
3
+ *
4
+ * `<SelectionLayer>` paints the highlight on each page; `<SelectionMenu>` floats over a settled
5
+ * selection; `<SelectionHandles>` are the touch handles in a Stage's overlay;
6
+ * `<SelectionClipboard>` wires Ctrl+C / Cmd+C. The readers are the plugin's four:
7
+ * `useSelection()`, `useSelectionState()`, `useSelectionSettings()` and `useSelectionEvent()`.
8
+ */
9
+ // Registration travels with the UI.
10
+ export * from '@embedpdf/plugin-selection';
11
+ // The clipboard write lives in @embedpdf/web (the plugin has no DOM); it's here too, so app code
12
+ // has one import for the feature.
13
+ export { copySelection } from '@embedpdf/web';
14
+ export { default as SelectionLayer } from './selection/SelectionLayer.svelte';
15
+ export { default as SelectionMenu } from './selection/SelectionMenu.svelte';
16
+ export { default as SelectionHandles } from './selection/SelectionHandles.svelte';
17
+ export { default as SelectionClipboard } from './selection/SelectionClipboard.svelte';
18
+ export { useSelection, useSelectionEvent, useSelectionSettings, useSelectionState, } from './selection/readers.svelte.js';
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The shell plugin's readers. The app owns every surface's DOM; these bind its open and closed
3
+ * state to the kernel, so commands can drive it and an app can restore it.
4
+ *
5
+ * They work without a document: shell state is a document's, and chrome that uses it (panel
6
+ * buttons, menu anchors) stays mounted while none is open. With no document every surface reads
7
+ * as closed, no menu as open, and `useSurface`'s verbs do nothing; `useShell()` then reaches the
8
+ * stand-in, whose calls refuse with `not-ready`.
9
+ */
10
+ import type { EventHook } from '@embedpdf/core';
11
+ import type { OpenSurfaceOptions, ShellCapability, SurfaceProps } from '@embedpdf/plugin-shell';
12
+ import { type MaybeGetter } from '../runtime/values.svelte.js';
13
+ /** The shell API: open and close panels, dialogs and menus. Without a document its calls refuse with `not-ready`. */
14
+ export declare function useShell(): ShellCapability;
15
+ /** Subscribe to one shell event while the component lives: `useShellEvent((shell) => shell.onSurfaceOpened, handler)`. */
16
+ export declare function useShellEvent<T>(select: (shell: ShellCapability) => EventHook<T>, handler: (event: T) => void): void;
17
+ /**
18
+ * Which panels, dialogs and menus are open (declared once in `shellState`), as a reactive object
19
+ * (`useShellState().openMenus`). Takes a selector. Without a document nothing is open.
20
+ */
21
+ export declare const useShellState: import("../index.js").StateReader<{
22
+ openSurfaces: readonly import("@embedpdf/plugin-shell").SurfaceState[];
23
+ openMenus: readonly string[];
24
+ }>;
25
+ /** One surface: whether it's open and its props, read live, and the calls that change it. */
26
+ export interface SurfaceHandle {
27
+ readonly isOpen: boolean;
28
+ /** The props the surface was opened with, or updated to; empty when it has none. */
29
+ readonly props: SurfaceProps;
30
+ open(options?: OpenSurfaceOptions): void;
31
+ close(): void;
32
+ toggle(options?: OpenSurfaceOptions): void;
33
+ }
34
+ /**
35
+ * One named surface (panel, dialog, overlay) of this component's document: `panel.isOpen` and
36
+ * `panel.props` update in a template, and `open`, `close` and `toggle` can be passed as handlers
37
+ * (`onclick={panel.close}`). Pass the id as a function to follow a prop. It reads as closed, and
38
+ * its calls do nothing, while no document is open.
39
+ */
40
+ export declare function useSurface(id: MaybeGetter<string>): SurfaceHandle;
@@ -0,0 +1,40 @@
1
+ import { ShellToken, shellState } from '@embedpdf/plugin-shell';
2
+ import { useCapability, useCapabilityEvent, useOptionalCapability, useOptionalSelector, } from '../runtime/readers.svelte.js';
3
+ import { stateReader } from '../runtime/state.svelte.js';
4
+ import { valueOf } from '../runtime/values.svelte.js';
5
+ /** The shell API: open and close panels, dialogs and menus. Without a document its calls refuse with `not-ready`. */
6
+ export function useShell() {
7
+ return useCapability(ShellToken);
8
+ }
9
+ /** Subscribe to one shell event while the component lives: `useShellEvent((shell) => shell.onSurfaceOpened, handler)`. */
10
+ export function useShellEvent(select, handler) {
11
+ useCapabilityEvent(ShellToken, select, handler);
12
+ }
13
+ /**
14
+ * Which panels, dialogs and menus are open (declared once in `shellState`), as a reactive object
15
+ * (`useShellState().openMenus`). Takes a selector. Without a document nothing is open.
16
+ */
17
+ export const useShellState = stateReader(shellState);
18
+ const NO_PROPS = Object.freeze({});
19
+ /**
20
+ * One named surface (panel, dialog, overlay) of this component's document: `panel.isOpen` and
21
+ * `panel.props` update in a template, and `open`, `close` and `toggle` can be passed as handlers
22
+ * (`onclick={panel.close}`). Pass the id as a function to follow a prop. It reads as closed, and
23
+ * its calls do nothing, while no document is open.
24
+ */
25
+ export function useSurface(id) {
26
+ const shell = useOptionalCapability(ShellToken);
27
+ const isOpen = useOptionalSelector(ShellToken, (shell) => shell.isOpen(valueOf(id)), false);
28
+ const props = useOptionalSelector(ShellToken, (shell) => shell.getSurface(valueOf(id))?.props ?? NO_PROPS, NO_PROPS);
29
+ return {
30
+ get isOpen() {
31
+ return isOpen.current;
32
+ },
33
+ get props() {
34
+ return props.current;
35
+ },
36
+ open: (options) => shell.current?.open(valueOf(id), options),
37
+ close: () => shell.current?.close(valueOf(id)),
38
+ toggle: (options) => shell.current?.toggle(valueOf(id), options),
39
+ };
40
+ }
@@ -0,0 +1,16 @@
1
+ import type { Attachment } from 'svelte/attachments';
2
+ import { type SurfaceFocusOptions } from '@embedpdf/web';
3
+ import { type MaybeGetter } from '../runtime/values.svelte.js';
4
+ export type { SurfaceFocusOptions };
5
+ /**
6
+ * An attachment that puts the cursor in its element when the surface `id` asks for it: on every
7
+ * `open(id, { focus: true })`, a command whose panel says `focus` among them, and when the
8
+ * element mounts while the request is up (the panel opened, or its code loaded, because of it).
9
+ * A plain open never moves it. `select` selects an input's text, so typing replaces it. It reads
10
+ * the surface of this component's document; pass the id as a function to follow a prop.
11
+ *
12
+ * ```svelte
13
+ * <input {@attach surfaceFocus('search', { select: true })} bind:value={query} />
14
+ * ```
15
+ */
16
+ export declare function surfaceFocus(id: MaybeGetter<string>, options?: SurfaceFocusOptions): Attachment<HTMLElement>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Putting the cursor in an element when its panel asks for it. `@embedpdf/web`'s surface focus
3
+ * follower owns the rule (a new request moves the cursor in, and so does mounting while one is
4
+ * up); this binds it to Svelte as an attachment.
5
+ */
6
+ import { untrack } from 'svelte';
7
+ import { ShellToken } from '@embedpdf/plugin-shell';
8
+ import { createSurfaceFocusFollower } from '@embedpdf/web';
9
+ import { useOptionalCapability, useOptionalSelector } from '../runtime/readers.svelte.js';
10
+ import { valueOf } from '../runtime/values.svelte.js';
11
+ /**
12
+ * An attachment that puts the cursor in its element when the surface `id` asks for it: on every
13
+ * `open(id, { focus: true })`, a command whose panel says `focus` among them, and when the
14
+ * element mounts while the request is up (the panel opened, or its code loaded, because of it).
15
+ * A plain open never moves it. `select` selects an input's text, so typing replaces it. It reads
16
+ * the surface of this component's document; pass the id as a function to follow a prop.
17
+ *
18
+ * ```svelte
19
+ * <input {@attach surfaceFocus('search', { select: true })} bind:value={query} />
20
+ * ```
21
+ */
22
+ export function surfaceFocus(id, options = {}) {
23
+ const shell = useOptionalCapability(ShellToken);
24
+ const request = useOptionalSelector(ShellToken, (current) => current.getSurface(valueOf(id))?.focusRequest ?? 0, 0);
25
+ return (element) => {
26
+ const follower = createSurfaceFocusFollower();
27
+ $effect(() => {
28
+ const current = shell.current;
29
+ const value = request.current;
30
+ untrack(() => follower.follow(element, current, value, options));
31
+ });
32
+ };
33
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @embedpdf/svelte/shell — panels, dialogs and menus.
3
+ *
4
+ * Your app draws every surface; the readers bind whether each one is open (and its props) to the
5
+ * kernel, so commands can open them and a layout can be saved and restored. `surfaceFocus` puts
6
+ * the cursor in a panel's element when the panel asks for it.
7
+ */
8
+ export * from '@embedpdf/plugin-shell';
9
+ export { useShell, useShellEvent, useShellState, useSurface } from './shell/readers.svelte.js';
10
+ export type { SurfaceHandle } from './shell/readers.svelte.js';
11
+ export { surfaceFocus } from './shell/surface-focus.svelte.js';
12
+ export type { SurfaceFocusOptions } from './shell/surface-focus.svelte.js';
package/dist/shell.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @embedpdf/svelte/shell — panels, dialogs and menus.
3
+ *
4
+ * Your app draws every surface; the readers bind whether each one is open (and its props) to the
5
+ * kernel, so commands can open them and a layout can be saved and restored. `surfaceFocus` puts
6
+ * the cursor in a panel's element when the panel asks for it.
7
+ */
8
+ // Registration travels with the UI.
9
+ export * from '@embedpdf/plugin-shell';
10
+ export { useShell, useShellEvent, useShellState, useSurface } from './shell/readers.svelte.js';
11
+ export { surfaceFocus } from './shell/surface-focus.svelte.js';