@embedpdf/react 3.0.0-next.10 → 3.0.0-next.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AnnotationListSnapshot-DDxHpJQU-BG32YXxG.d.ts → AnnotationListSnapshot-x6tKulNV-B799rYyi.d.cts} +223 -24
- package/dist/{AnnotationListSnapshot-DDxHpJQU-BG32YXxG.d.cts → AnnotationListSnapshot-x6tKulNV-B799rYyi.d.ts} +223 -24
- package/dist/actions.cjs +42 -0
- package/dist/actions.cjs.map +1 -0
- package/dist/actions.d.cts +18 -0
- package/dist/actions.d.ts +18 -0
- package/dist/actions.js +34 -0
- package/dist/actions.js.map +1 -0
- package/dist/annotation-BCED_p9H.d.cts +160 -0
- package/dist/annotation-anchors-CetwM1g7.js +15 -0
- package/dist/annotation-anchors-CetwM1g7.js.map +1 -0
- package/dist/annotation-anchors-DuYRBJLl.cjs +26 -0
- package/dist/annotation-anchors-DuYRBJLl.cjs.map +1 -0
- package/dist/annotation-hooks-BB5ZhPpf.cjs +16 -0
- package/dist/annotation-hooks-BB5ZhPpf.cjs.map +1 -0
- package/dist/annotation-hooks-Df8EmzDO.js +11 -0
- package/dist/annotation-hooks-Df8EmzDO.js.map +1 -0
- package/dist/annotation-k38KDlIZ.d.ts +160 -0
- package/dist/annotation-menu.cjs +5 -5
- package/dist/annotation-menu.cjs.map +1 -1
- package/dist/annotation-menu.js +2 -2
- package/dist/annotation-menu.js.map +1 -1
- package/dist/annotation.cjs +24 -29
- package/dist/annotation.cjs.map +1 -1
- package/dist/annotation.d.cts +2 -159
- package/dist/annotation.d.ts +2 -159
- package/dist/annotation.js +22 -27
- package/dist/annotation.js.map +1 -1
- package/dist/form-BwrLFpKN.js +805 -0
- package/dist/form-BwrLFpKN.js.map +1 -0
- package/dist/form-D-ZSfGmB.cjs +836 -0
- package/dist/form-D-ZSfGmB.cjs.map +1 -0
- package/dist/form.cjs +8 -551
- package/dist/form.d.cts +4 -21
- package/dist/form.d.ts +4 -21
- package/dist/form.js +3 -544
- package/dist/index.cjs +21 -11
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +9 -6
- package/dist/link.cjs +48 -8
- package/dist/link.cjs.map +1 -1
- package/dist/link.d.cts +2 -2
- package/dist/link.d.ts +2 -2
- package/dist/link.js +49 -9
- package/dist/link.js.map +1 -1
- package/dist/{runtime-Cvi0wQ4d.d.cts → runtime-DE76hlnl.d.ts} +13 -5
- package/dist/{runtime-DXxr8T4L.d.ts → runtime-umHA_xHt.d.cts} +13 -5
- package/dist/runtime.cjs +19 -0
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +19 -1
- package/dist/runtime.js.map +1 -1
- package/dist/scrollbar.cjs +3 -3
- package/dist/scrollbar.cjs.map +1 -1
- package/dist/scrollbar.d.cts +1 -1
- package/dist/scrollbar.d.ts +1 -1
- package/dist/scrollbar.js +1 -1
- package/dist/scrollbar.js.map +1 -1
- package/dist/search.d.cts +1 -1
- package/dist/search.d.ts +1 -1
- package/dist/selection.cjs +2 -2
- package/dist/selection.cjs.map +1 -1
- package/dist/selection.d.cts +1 -1
- package/dist/selection.d.ts +1 -1
- package/dist/selection.js +1 -1
- package/dist/selection.js.map +1 -1
- package/dist/stage.cjs +2 -2
- package/dist/stage.cjs.map +1 -1
- package/dist/stage.d.cts +1 -1
- package/dist/stage.d.ts +1 -1
- package/dist/stage.js +1 -1
- package/dist/stage.js.map +1 -1
- package/dist/stamp.cjs +7 -0
- package/dist/stamp.cjs.map +1 -1
- package/dist/stamp.d.cts +2 -1
- package/dist/stamp.d.ts +2 -1
- package/dist/stamp.js +2 -1
- package/dist/stamp.js.map +1 -1
- package/dist/toolbar.cjs +4 -4
- package/dist/toolbar.cjs.map +1 -1
- package/dist/toolbar.d.cts +1 -1
- package/dist/toolbar.d.ts +1 -1
- package/dist/toolbar.js +1 -1
- package/dist/toolbar.js.map +1 -1
- package/package.json +30 -24
- package/dist/form.cjs.map +0 -1
- package/dist/form.js.map +0 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { d as runtime_d_exports, o as PageContextValue } from "./runtime-umHA_xHt.cjs";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { AnnotationFlags, AnnotationProps, AnnotationProps as AnnotationProps$1, AnnotationPropsPatch, Border, CreationDraftAnchor, CreationDraftAnchor as CreationDraftAnchor$1, Geom, LineEnding, LineEndings, PropKey, PropSpec, Rect, RenderItem, RenderItem as RenderItem$1, Style, TextAlign, TextStyle, Vec } from "@embedpdf/core-annotation";
|
|
4
|
+
import { AnnotationHydration, AnnotationRef, Behavior, CommentThread, CommentsApi, FilePickerProvider, SelectionFlags, SelectionFlags as SelectionFlags$1, SelectionProps, SelectionProps as SelectionProps$1 } from "@embedpdf/plugin-annotation";
|
|
5
|
+
//#region src/annotation-anchors.d.ts
|
|
6
|
+
/** The selection's menu anchor on its primary page, in content space. */
|
|
7
|
+
type SelectionAnchor = {
|
|
8
|
+
pon: number;
|
|
9
|
+
bounds: Rect;
|
|
10
|
+
knob?: Vec;
|
|
11
|
+
};
|
|
12
|
+
declare function sameAnchor(a: SelectionAnchor | null, b: SelectionAnchor | null): boolean;
|
|
13
|
+
declare function sameCreationDraftAnchor(a: CreationDraftAnchor | null, b: CreationDraftAnchor | null): boolean;
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/annotation-hooks.d.ts
|
|
16
|
+
/** The selected annotations as engine DTOs — for selection-aware toolbars/sidebars. */
|
|
17
|
+
declare function useAnnotationSelected(): import("@embedpdf/plugin-annotation").AnnotationDTO[];
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/annotation.d.ts
|
|
20
|
+
/**
|
|
21
|
+
* What an annotation renderer receives: the projected item (its `box` is LIVE —
|
|
22
|
+
* it follows drags), the page context, the engine's baked /AP raster (the
|
|
23
|
+
* "picture"), the default visual (`native` — wrap it or ignore it), and
|
|
24
|
+
* whether this entry currently OWNS the pointer (`interactive`). While not
|
|
25
|
+
* interactive the layer renders your component pointer-locked: the annotation
|
|
26
|
+
* stays a first-class citizen of the annotation plane (select/move/resize).
|
|
27
|
+
*/
|
|
28
|
+
interface AnnotationRendererProps {
|
|
29
|
+
item: RenderItem;
|
|
30
|
+
page: PageContextValue;
|
|
31
|
+
appearance: {
|
|
32
|
+
url: string;
|
|
33
|
+
box: Rect;
|
|
34
|
+
} | null;
|
|
35
|
+
native: React.ReactNode;
|
|
36
|
+
interactive: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* ONE rule: "for THESE annotations, render THIS component, and it owns the
|
|
40
|
+
* pointer WHEN …". The two shapes:
|
|
41
|
+
*
|
|
42
|
+
* - `{ for, component, interactive? }` — your own rule. Without
|
|
43
|
+
* `interactive` it is a pure SKIN: pixels only, mechanically
|
|
44
|
+
* pointer-locked, the annotation plane keeps selection/move/resize. With
|
|
45
|
+
* `interactive` (boolean or live predicate) the layer registers a plugin
|
|
46
|
+
* Behavior for you: while it holds, the annotation plane stands down
|
|
47
|
+
* (hit-test-inert) and your component owns the input.
|
|
48
|
+
* - `{ behavior, component }` — the renderer for a PLUGIN-registered
|
|
49
|
+
* behavior (the form plugin's fill controls via `formWidgetRenderer`);
|
|
50
|
+
* the plugin decides engagement, never the app.
|
|
51
|
+
*
|
|
52
|
+
* Resolution: ownership beats skin — an ENGAGED behavior's component is
|
|
53
|
+
* authoritative; `for` rules apply only to plane-owned annotations, first
|
|
54
|
+
* match wins. Define entries OUTSIDE render (module scope or useMemo): entry
|
|
55
|
+
* identity keys the behavior registration.
|
|
56
|
+
*/
|
|
57
|
+
type AnnotationRenderer = {
|
|
58
|
+
behavior: string;
|
|
59
|
+
component: React.ComponentType<AnnotationRendererProps>;
|
|
60
|
+
} | {
|
|
61
|
+
/** Stable id for the auto-registered behavior (optional; generated). */
|
|
62
|
+
id?: string;
|
|
63
|
+
for: Behavior['matches'];
|
|
64
|
+
component: React.ComponentType<AnnotationRendererProps>;
|
|
65
|
+
interactive?: boolean | (() => boolean);
|
|
66
|
+
};
|
|
67
|
+
interface AnnotationLayerProps {
|
|
68
|
+
/** Annotation renderers — skins and interactive takeovers ({@link AnnotationRenderer}). */
|
|
69
|
+
renderers?: AnnotationRenderer[];
|
|
70
|
+
}
|
|
71
|
+
declare function AnnotationLayer({ renderers }?: AnnotationLayerProps): import("react/jsx-runtime").JSX.Element;
|
|
72
|
+
/**
|
|
73
|
+
* The default file-picker provider: the built-in file dialog (from
|
|
74
|
+
* `@embedpdf/web`), honouring the tool's `accept` filter. This is the ADAPTER
|
|
75
|
+
* fulfilling the plugin's DOM-free port — the dialog lives here, in the
|
|
76
|
+
* framework layer, never in the plugin. A picked `File` carries its own name
|
|
77
|
+
* and mime, so it goes straight through as the engine's file source.
|
|
78
|
+
*/
|
|
79
|
+
declare const filePickerProvider: FilePickerProvider;
|
|
80
|
+
/**
|
|
81
|
+
* Install the file-picker provider for the active document — the ONE port
|
|
82
|
+
* behind every click-then-pick tool (a stamp `'prompt'` source, the file-
|
|
83
|
+
* attachment tool). Call ONCE at a document-scoped spot (not inside
|
|
84
|
+
* `<AnnotationLayer>`, which is per page). Defaults to
|
|
85
|
+
* {@link filePickerProvider}, so a bare `useFilePickerProvider()` makes all of
|
|
86
|
+
* them work out of the box; pass a custom provider (asset library, cloud
|
|
87
|
+
* drive — switch on `req.subtype` / `req.toolId`) or `null` to make
|
|
88
|
+
* click-then-pick tools inert. Cleared on unmount.
|
|
89
|
+
*/
|
|
90
|
+
declare function useFilePickerProvider(provider?: FilePickerProvider | null): void;
|
|
91
|
+
declare function useAnnotation(): import("@embedpdf/plugin-annotation").AnnotationCapability;
|
|
92
|
+
declare function useAnnotationSelection(): string[];
|
|
93
|
+
/**
|
|
94
|
+
* A tool's RESOLVED defaults (base + per-tool override) as a full flat props
|
|
95
|
+
* bag, subscribed so a `setDefaults` re-renders the consumer. Use this — not the
|
|
96
|
+
* imperative `useAnnotation().currentDefaults(id)` — to drive default-editing
|
|
97
|
+
* controls, so they reflect changes live. Pair with `propsForTool(id)` for the
|
|
98
|
+
* specs to render.
|
|
99
|
+
*/
|
|
100
|
+
declare function useAnnotationDefaults(toolId: string): AnnotationProps;
|
|
101
|
+
/**
|
|
102
|
+
* The selection's editable properties — ordered specs shared by every selected
|
|
103
|
+
* kind, current values, and which keys are mixed. THE hook a property sidebar
|
|
104
|
+
* renders from; write back with `useAnnotation().updateSelection({ [key]: v })`.
|
|
105
|
+
* Reference-stable between model changes (the capability memoizes by model
|
|
106
|
+
* identity), so the default equality is enough.
|
|
107
|
+
*/
|
|
108
|
+
declare function useSelectionProps(): SelectionProps;
|
|
109
|
+
/**
|
|
110
|
+
* The selection's `/F` annotation flags — per-flag `true`/`false`, `null` where
|
|
111
|
+
* the selected annotations disagree (render an indeterminate control), `null`
|
|
112
|
+
* overall when nothing is selected. Write back with
|
|
113
|
+
* `useAnnotation().updateSelectionFlags({ locked: true })`. Reference-stable
|
|
114
|
+
* between model changes, like {@link useSelectionProps}.
|
|
115
|
+
*/
|
|
116
|
+
declare function useSelectionFlags(): SelectionFlags | null;
|
|
117
|
+
/**
|
|
118
|
+
* A {@link CommentThread} enriched with its page's live display position —
|
|
119
|
+
* the framework-layer join. Identity stays `pageObjectNumber` (like every
|
|
120
|
+
* annotation surface); these two fields are PRESENTATION, tracking page
|
|
121
|
+
* moves and deletes.
|
|
122
|
+
*/
|
|
123
|
+
interface CommentThreadView extends CommentThread {
|
|
124
|
+
/** Current 0-based display index of the thread's page; `-1` when the page
|
|
125
|
+
* is no longer in the document (one-frame teardown race on delete). */
|
|
126
|
+
pageIndex: number;
|
|
127
|
+
/** The page's `/PageLabels` label when the PDF declares one ("iv", "A-2"),
|
|
128
|
+
* else the 1-based position as a string — print it verbatim. */
|
|
129
|
+
pageLabel: string;
|
|
130
|
+
/**
|
|
131
|
+
* The root annotation's rect in CONTENT space (y-down, crop-relative,
|
|
132
|
+
* unscaled points) — the space `StageCapability.reveal` takes, so a
|
|
133
|
+
* "jump to this comment" is `stage.reveal(pageIndex, { rect: contentRect })`.
|
|
134
|
+
* Null when the page is gone. Identity still travels as `pageObjectNumber`;
|
|
135
|
+
* this, like `pageIndex`, is presentation.
|
|
136
|
+
*/
|
|
137
|
+
contentRect: Rect | null;
|
|
138
|
+
}
|
|
139
|
+
/** Pure join behind {@link useCommentThreads} — exported for tests. */
|
|
140
|
+
declare function enrichCommentThreads(threads: readonly CommentThread[], pages: readonly runtime_d_exports.PageLayout[]): CommentThreadView[];
|
|
141
|
+
/** The comments surface (verbs + `permissionsFor`) — imperative; pair with
|
|
142
|
+
* {@link useCommentThreads} for the subscribed view. */
|
|
143
|
+
declare function useComments(): CommentsApi;
|
|
144
|
+
/**
|
|
145
|
+
* Every comment thread in the document, display-ordered (page position →
|
|
146
|
+
* top of page → creation date) and enriched with `pageIndex`/`pageLabel`.
|
|
147
|
+
* Subscribed to BOTH stores: annotation writes (own, remote, hydration)
|
|
148
|
+
* recompute the threads; page moves/deletes re-run the join. Reference-
|
|
149
|
+
* stable between changes — safe to memo child renders on the array.
|
|
150
|
+
*/
|
|
151
|
+
declare function useCommentThreads(): CommentThreadView[];
|
|
152
|
+
/** The enriched thread containing ANY member ref (root, reply, grouped part,
|
|
153
|
+
* state annotation), or null. */
|
|
154
|
+
declare function useCommentThread(ref: AnnotationRef | null): CommentThreadView | null;
|
|
155
|
+
/** Whole-document hydration status — the comments sidebar's honest loading
|
|
156
|
+
* state (`loading` until `listRawAll` lands, then `complete`/`error`). */
|
|
157
|
+
declare function useCommentsHydration(): AnnotationHydration;
|
|
158
|
+
//#endregion
|
|
159
|
+
export { useCommentsHydration as A, filePickerProvider as C, useCommentThread as D, useAnnotationSelection as E, SelectionAnchor as F, sameAnchor as I, sameCreationDraftAnchor as L, useSelectionFlags as M, useSelectionProps as N, useCommentThreads as O, useAnnotationSelected as P, enrichCommentThreads as S, useAnnotationDefaults as T, SelectionFlags$1 as _, AnnotationPropsPatch as a, TextAlign as b, Border as c, Geom as d, LineEnding as f, RenderItem$1 as g, PropSpec as h, AnnotationProps$1 as i, useFilePickerProvider as j, useComments as k, CommentThreadView as l, PropKey as m, AnnotationLayer as n, AnnotationRenderer as o, LineEndings as p, AnnotationLayerProps as r, AnnotationRendererProps as s, AnnotationFlags as t, CreationDraftAnchor$1 as u, SelectionProps$1 as v, useAnnotation as w, TextStyle as x, Style as y };
|
|
160
|
+
//# sourceMappingURL=annotation-BCED_p9H.d.cts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/annotation-anchors.ts
|
|
2
|
+
function sameAnchor(a, b) {
|
|
3
|
+
if (a === b) return true;
|
|
4
|
+
if (!a || !b) return false;
|
|
5
|
+
return a.pon === b.pon && a.bounds.x === b.bounds.x && a.bounds.y === b.bounds.y && a.bounds.width === b.bounds.width && a.bounds.height === b.bounds.height && a.knob?.x === b.knob?.x && a.knob?.y === b.knob?.y;
|
|
6
|
+
}
|
|
7
|
+
function sameCreationDraftAnchor(a, b) {
|
|
8
|
+
if (a === b) return true;
|
|
9
|
+
if (!a || !b) return false;
|
|
10
|
+
return a.kind === b.kind && a.subtype === b.subtype && a.pon === b.pon && a.pointCount === b.pointCount && a.minPoints === b.minPoints && a.canFinish === b.canFinish && a.bounds.x === b.bounds.x && a.bounds.y === b.bounds.y && a.bounds.width === b.bounds.width && a.bounds.height === b.bounds.height;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { sameCreationDraftAnchor as n, sameAnchor as t };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=annotation-anchors-CetwM1g7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotation-anchors-CetwM1g7.js","names":[],"sources":["../src/annotation-anchors.ts"],"sourcesContent":["import type { CreationDraftAnchor, Rect, Vec } from '@embedpdf/core-annotation';\n\n/** The selection's menu anchor on its primary page, in content space. */\nexport type SelectionAnchor = { pon: number; bounds: Rect; knob?: Vec };\n\nexport function sameAnchor(a: SelectionAnchor | null, b: SelectionAnchor | null): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return (\n a.pon === b.pon &&\n a.bounds.x === b.bounds.x &&\n a.bounds.y === b.bounds.y &&\n a.bounds.width === b.bounds.width &&\n a.bounds.height === b.bounds.height &&\n a.knob?.x === b.knob?.x &&\n a.knob?.y === b.knob?.y\n );\n}\n\nexport function sameCreationDraftAnchor(\n a: CreationDraftAnchor | null,\n b: CreationDraftAnchor | null,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return (\n a.kind === b.kind &&\n a.subtype === b.subtype &&\n a.pon === b.pon &&\n a.pointCount === b.pointCount &&\n a.minPoints === b.minPoints &&\n a.canFinish === b.canFinish &&\n a.bounds.x === b.bounds.x &&\n a.bounds.y === b.bounds.y &&\n a.bounds.width === b.bounds.width &&\n a.bounds.height === b.bounds.height\n );\n}\n"],"mappings":";AAKA,SAAgB,WAAW,GAA2B,GAAoC;CACxF,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;CACrB,OACE,EAAE,QAAQ,EAAE,OACZ,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,UAAU,EAAE,OAAO,SAC5B,EAAE,OAAO,WAAW,EAAE,OAAO,UAC7B,EAAE,MAAM,MAAM,EAAE,MAAM,KACtB,EAAE,MAAM,MAAM,EAAE,MAAM;AAE1B;AAEA,SAAgB,wBACd,GACA,GACS;CACT,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;CACrB,OACE,EAAE,SAAS,EAAE,QACb,EAAE,YAAY,EAAE,WAChB,EAAE,QAAQ,EAAE,OACZ,EAAE,eAAe,EAAE,cACnB,EAAE,cAAc,EAAE,aAClB,EAAE,cAAc,EAAE,aAClB,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,UAAU,EAAE,OAAO,SAC5B,EAAE,OAAO,WAAW,EAAE,OAAO;AAEjC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/annotation-anchors.ts
|
|
2
|
+
function sameAnchor(a, b) {
|
|
3
|
+
if (a === b) return true;
|
|
4
|
+
if (!a || !b) return false;
|
|
5
|
+
return a.pon === b.pon && a.bounds.x === b.bounds.x && a.bounds.y === b.bounds.y && a.bounds.width === b.bounds.width && a.bounds.height === b.bounds.height && a.knob?.x === b.knob?.x && a.knob?.y === b.knob?.y;
|
|
6
|
+
}
|
|
7
|
+
function sameCreationDraftAnchor(a, b) {
|
|
8
|
+
if (a === b) return true;
|
|
9
|
+
if (!a || !b) return false;
|
|
10
|
+
return a.kind === b.kind && a.subtype === b.subtype && a.pon === b.pon && a.pointCount === b.pointCount && a.minPoints === b.minPoints && a.canFinish === b.canFinish && a.bounds.x === b.bounds.x && a.bounds.y === b.bounds.y && a.bounds.width === b.bounds.width && a.bounds.height === b.bounds.height;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
Object.defineProperty(exports, "sameAnchor", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function() {
|
|
16
|
+
return sameAnchor;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "sameCreationDraftAnchor", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function() {
|
|
22
|
+
return sameCreationDraftAnchor;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=annotation-anchors-DuYRBJLl.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotation-anchors-DuYRBJLl.cjs","names":[],"sources":["../src/annotation-anchors.ts"],"sourcesContent":["import type { CreationDraftAnchor, Rect, Vec } from '@embedpdf/core-annotation';\n\n/** The selection's menu anchor on its primary page, in content space. */\nexport type SelectionAnchor = { pon: number; bounds: Rect; knob?: Vec };\n\nexport function sameAnchor(a: SelectionAnchor | null, b: SelectionAnchor | null): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return (\n a.pon === b.pon &&\n a.bounds.x === b.bounds.x &&\n a.bounds.y === b.bounds.y &&\n a.bounds.width === b.bounds.width &&\n a.bounds.height === b.bounds.height &&\n a.knob?.x === b.knob?.x &&\n a.knob?.y === b.knob?.y\n );\n}\n\nexport function sameCreationDraftAnchor(\n a: CreationDraftAnchor | null,\n b: CreationDraftAnchor | null,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return (\n a.kind === b.kind &&\n a.subtype === b.subtype &&\n a.pon === b.pon &&\n a.pointCount === b.pointCount &&\n a.minPoints === b.minPoints &&\n a.canFinish === b.canFinish &&\n a.bounds.x === b.bounds.x &&\n a.bounds.y === b.bounds.y &&\n a.bounds.width === b.bounds.width &&\n a.bounds.height === b.bounds.height\n );\n}\n"],"mappings":";AAKA,SAAgB,WAAW,GAA2B,GAAoC;CACxF,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;CACrB,OACE,EAAE,QAAQ,EAAE,OACZ,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,UAAU,EAAE,OAAO,SAC5B,EAAE,OAAO,WAAW,EAAE,OAAO,UAC7B,EAAE,MAAM,MAAM,EAAE,MAAM,KACtB,EAAE,MAAM,MAAM,EAAE,MAAM;AAE1B;AAEA,SAAgB,wBACd,GACA,GACS;CACT,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;CACrB,OACE,EAAE,SAAS,EAAE,QACb,EAAE,YAAY,EAAE,WAChB,EAAE,QAAQ,EAAE,OACZ,EAAE,eAAe,EAAE,cACnB,EAAE,cAAc,EAAE,aAClB,EAAE,cAAc,EAAE,aAClB,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,MAAM,EAAE,OAAO,KACxB,EAAE,OAAO,UAAU,EAAE,OAAO,SAC5B,EAAE,OAAO,WAAW,EAAE,OAAO;AAEjC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const require_runtime = require("./runtime.cjs");
|
|
2
|
+
let _embedpdf_plugin_annotation_contract = require("@embedpdf/plugin-annotation/contract");
|
|
3
|
+
//#region src/annotation-hooks.ts
|
|
4
|
+
/** The selected annotations as engine DTOs — for selection-aware toolbars/sidebars. */
|
|
5
|
+
function useAnnotationSelected() {
|
|
6
|
+
return require_runtime.useSelector(_embedpdf_plugin_annotation_contract.AnnotationToken, (c) => c.getSelected(), require_runtime.shallowArray);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
Object.defineProperty(exports, "useAnnotationSelected", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function() {
|
|
12
|
+
return useAnnotationSelected;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=annotation-hooks-BB5ZhPpf.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotation-hooks-BB5ZhPpf.cjs","names":["useSelector","AnnotationToken","shallowArray"],"sources":["../src/annotation-hooks.ts"],"sourcesContent":["import { AnnotationToken } from '@embedpdf/plugin-annotation/contract';\n\nimport { shallowArray, useSelector } from './runtime';\n\n/** The selected annotations as engine DTOs — for selection-aware toolbars/sidebars. */\nexport function useAnnotationSelected() {\n return useSelector(AnnotationToken, (c) => c.getSelected(), shallowArray);\n}\n"],"mappings":";;;;AAKA,SAAgB,wBAAwB;CACtC,OAAOA,gBAAAA,YAAYC,qCAAAA,kBAAkB,MAAM,EAAE,YAAY,GAAGC,gBAAAA,YAAY;AAC1E"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { shallowArray, useSelector } from "./runtime.js";
|
|
2
|
+
import { AnnotationToken } from "@embedpdf/plugin-annotation/contract";
|
|
3
|
+
//#region src/annotation-hooks.ts
|
|
4
|
+
/** The selected annotations as engine DTOs — for selection-aware toolbars/sidebars. */
|
|
5
|
+
function useAnnotationSelected() {
|
|
6
|
+
return useSelector(AnnotationToken, (c) => c.getSelected(), shallowArray);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { useAnnotationSelected as t };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=annotation-hooks-Df8EmzDO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotation-hooks-Df8EmzDO.js","names":[],"sources":["../src/annotation-hooks.ts"],"sourcesContent":["import { AnnotationToken } from '@embedpdf/plugin-annotation/contract';\n\nimport { shallowArray, useSelector } from './runtime';\n\n/** The selected annotations as engine DTOs — for selection-aware toolbars/sidebars. */\nexport function useAnnotationSelected() {\n return useSelector(AnnotationToken, (c) => c.getSelected(), shallowArray);\n}\n"],"mappings":";;;;AAKA,SAAgB,wBAAwB;CACtC,OAAO,YAAY,kBAAkB,MAAM,EAAE,YAAY,GAAG,YAAY;AAC1E"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { d as runtime_d_exports, o as PageContextValue } from "./runtime-DE76hlnl.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { AnnotationHydration, AnnotationRef, Behavior, CommentThread, CommentsApi, FilePickerProvider, SelectionFlags, SelectionFlags as SelectionFlags$1, SelectionProps, SelectionProps as SelectionProps$1 } from "@embedpdf/plugin-annotation";
|
|
4
|
+
import { AnnotationFlags, AnnotationProps, AnnotationProps as AnnotationProps$1, AnnotationPropsPatch, Border, CreationDraftAnchor, CreationDraftAnchor as CreationDraftAnchor$1, Geom, LineEnding, LineEndings, PropKey, PropSpec, Rect, RenderItem, RenderItem as RenderItem$1, Style, TextAlign, TextStyle, Vec } from "@embedpdf/core-annotation";
|
|
5
|
+
//#region src/annotation-anchors.d.ts
|
|
6
|
+
/** The selection's menu anchor on its primary page, in content space. */
|
|
7
|
+
type SelectionAnchor = {
|
|
8
|
+
pon: number;
|
|
9
|
+
bounds: Rect;
|
|
10
|
+
knob?: Vec;
|
|
11
|
+
};
|
|
12
|
+
declare function sameAnchor(a: SelectionAnchor | null, b: SelectionAnchor | null): boolean;
|
|
13
|
+
declare function sameCreationDraftAnchor(a: CreationDraftAnchor | null, b: CreationDraftAnchor | null): boolean;
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/annotation-hooks.d.ts
|
|
16
|
+
/** The selected annotations as engine DTOs — for selection-aware toolbars/sidebars. */
|
|
17
|
+
declare function useAnnotationSelected(): import("@embedpdf/plugin-annotation").AnnotationDTO[];
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/annotation.d.ts
|
|
20
|
+
/**
|
|
21
|
+
* What an annotation renderer receives: the projected item (its `box` is LIVE —
|
|
22
|
+
* it follows drags), the page context, the engine's baked /AP raster (the
|
|
23
|
+
* "picture"), the default visual (`native` — wrap it or ignore it), and
|
|
24
|
+
* whether this entry currently OWNS the pointer (`interactive`). While not
|
|
25
|
+
* interactive the layer renders your component pointer-locked: the annotation
|
|
26
|
+
* stays a first-class citizen of the annotation plane (select/move/resize).
|
|
27
|
+
*/
|
|
28
|
+
interface AnnotationRendererProps {
|
|
29
|
+
item: RenderItem;
|
|
30
|
+
page: PageContextValue;
|
|
31
|
+
appearance: {
|
|
32
|
+
url: string;
|
|
33
|
+
box: Rect;
|
|
34
|
+
} | null;
|
|
35
|
+
native: React.ReactNode;
|
|
36
|
+
interactive: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* ONE rule: "for THESE annotations, render THIS component, and it owns the
|
|
40
|
+
* pointer WHEN …". The two shapes:
|
|
41
|
+
*
|
|
42
|
+
* - `{ for, component, interactive? }` — your own rule. Without
|
|
43
|
+
* `interactive` it is a pure SKIN: pixels only, mechanically
|
|
44
|
+
* pointer-locked, the annotation plane keeps selection/move/resize. With
|
|
45
|
+
* `interactive` (boolean or live predicate) the layer registers a plugin
|
|
46
|
+
* Behavior for you: while it holds, the annotation plane stands down
|
|
47
|
+
* (hit-test-inert) and your component owns the input.
|
|
48
|
+
* - `{ behavior, component }` — the renderer for a PLUGIN-registered
|
|
49
|
+
* behavior (the form plugin's fill controls via `formWidgetRenderer`);
|
|
50
|
+
* the plugin decides engagement, never the app.
|
|
51
|
+
*
|
|
52
|
+
* Resolution: ownership beats skin — an ENGAGED behavior's component is
|
|
53
|
+
* authoritative; `for` rules apply only to plane-owned annotations, first
|
|
54
|
+
* match wins. Define entries OUTSIDE render (module scope or useMemo): entry
|
|
55
|
+
* identity keys the behavior registration.
|
|
56
|
+
*/
|
|
57
|
+
type AnnotationRenderer = {
|
|
58
|
+
behavior: string;
|
|
59
|
+
component: React.ComponentType<AnnotationRendererProps>;
|
|
60
|
+
} | {
|
|
61
|
+
/** Stable id for the auto-registered behavior (optional; generated). */
|
|
62
|
+
id?: string;
|
|
63
|
+
for: Behavior['matches'];
|
|
64
|
+
component: React.ComponentType<AnnotationRendererProps>;
|
|
65
|
+
interactive?: boolean | (() => boolean);
|
|
66
|
+
};
|
|
67
|
+
interface AnnotationLayerProps {
|
|
68
|
+
/** Annotation renderers — skins and interactive takeovers ({@link AnnotationRenderer}). */
|
|
69
|
+
renderers?: AnnotationRenderer[];
|
|
70
|
+
}
|
|
71
|
+
declare function AnnotationLayer({ renderers }?: AnnotationLayerProps): import("react/jsx-runtime").JSX.Element;
|
|
72
|
+
/**
|
|
73
|
+
* The default file-picker provider: the built-in file dialog (from
|
|
74
|
+
* `@embedpdf/web`), honouring the tool's `accept` filter. This is the ADAPTER
|
|
75
|
+
* fulfilling the plugin's DOM-free port — the dialog lives here, in the
|
|
76
|
+
* framework layer, never in the plugin. A picked `File` carries its own name
|
|
77
|
+
* and mime, so it goes straight through as the engine's file source.
|
|
78
|
+
*/
|
|
79
|
+
declare const filePickerProvider: FilePickerProvider;
|
|
80
|
+
/**
|
|
81
|
+
* Install the file-picker provider for the active document — the ONE port
|
|
82
|
+
* behind every click-then-pick tool (a stamp `'prompt'` source, the file-
|
|
83
|
+
* attachment tool). Call ONCE at a document-scoped spot (not inside
|
|
84
|
+
* `<AnnotationLayer>`, which is per page). Defaults to
|
|
85
|
+
* {@link filePickerProvider}, so a bare `useFilePickerProvider()` makes all of
|
|
86
|
+
* them work out of the box; pass a custom provider (asset library, cloud
|
|
87
|
+
* drive — switch on `req.subtype` / `req.toolId`) or `null` to make
|
|
88
|
+
* click-then-pick tools inert. Cleared on unmount.
|
|
89
|
+
*/
|
|
90
|
+
declare function useFilePickerProvider(provider?: FilePickerProvider | null): void;
|
|
91
|
+
declare function useAnnotation(): import("@embedpdf/plugin-annotation").AnnotationCapability;
|
|
92
|
+
declare function useAnnotationSelection(): string[];
|
|
93
|
+
/**
|
|
94
|
+
* A tool's RESOLVED defaults (base + per-tool override) as a full flat props
|
|
95
|
+
* bag, subscribed so a `setDefaults` re-renders the consumer. Use this — not the
|
|
96
|
+
* imperative `useAnnotation().currentDefaults(id)` — to drive default-editing
|
|
97
|
+
* controls, so they reflect changes live. Pair with `propsForTool(id)` for the
|
|
98
|
+
* specs to render.
|
|
99
|
+
*/
|
|
100
|
+
declare function useAnnotationDefaults(toolId: string): AnnotationProps;
|
|
101
|
+
/**
|
|
102
|
+
* The selection's editable properties — ordered specs shared by every selected
|
|
103
|
+
* kind, current values, and which keys are mixed. THE hook a property sidebar
|
|
104
|
+
* renders from; write back with `useAnnotation().updateSelection({ [key]: v })`.
|
|
105
|
+
* Reference-stable between model changes (the capability memoizes by model
|
|
106
|
+
* identity), so the default equality is enough.
|
|
107
|
+
*/
|
|
108
|
+
declare function useSelectionProps(): SelectionProps;
|
|
109
|
+
/**
|
|
110
|
+
* The selection's `/F` annotation flags — per-flag `true`/`false`, `null` where
|
|
111
|
+
* the selected annotations disagree (render an indeterminate control), `null`
|
|
112
|
+
* overall when nothing is selected. Write back with
|
|
113
|
+
* `useAnnotation().updateSelectionFlags({ locked: true })`. Reference-stable
|
|
114
|
+
* between model changes, like {@link useSelectionProps}.
|
|
115
|
+
*/
|
|
116
|
+
declare function useSelectionFlags(): SelectionFlags | null;
|
|
117
|
+
/**
|
|
118
|
+
* A {@link CommentThread} enriched with its page's live display position —
|
|
119
|
+
* the framework-layer join. Identity stays `pageObjectNumber` (like every
|
|
120
|
+
* annotation surface); these two fields are PRESENTATION, tracking page
|
|
121
|
+
* moves and deletes.
|
|
122
|
+
*/
|
|
123
|
+
interface CommentThreadView extends CommentThread {
|
|
124
|
+
/** Current 0-based display index of the thread's page; `-1` when the page
|
|
125
|
+
* is no longer in the document (one-frame teardown race on delete). */
|
|
126
|
+
pageIndex: number;
|
|
127
|
+
/** The page's `/PageLabels` label when the PDF declares one ("iv", "A-2"),
|
|
128
|
+
* else the 1-based position as a string — print it verbatim. */
|
|
129
|
+
pageLabel: string;
|
|
130
|
+
/**
|
|
131
|
+
* The root annotation's rect in CONTENT space (y-down, crop-relative,
|
|
132
|
+
* unscaled points) — the space `StageCapability.reveal` takes, so a
|
|
133
|
+
* "jump to this comment" is `stage.reveal(pageIndex, { rect: contentRect })`.
|
|
134
|
+
* Null when the page is gone. Identity still travels as `pageObjectNumber`;
|
|
135
|
+
* this, like `pageIndex`, is presentation.
|
|
136
|
+
*/
|
|
137
|
+
contentRect: Rect | null;
|
|
138
|
+
}
|
|
139
|
+
/** Pure join behind {@link useCommentThreads} — exported for tests. */
|
|
140
|
+
declare function enrichCommentThreads(threads: readonly CommentThread[], pages: readonly runtime_d_exports.PageLayout[]): CommentThreadView[];
|
|
141
|
+
/** The comments surface (verbs + `permissionsFor`) — imperative; pair with
|
|
142
|
+
* {@link useCommentThreads} for the subscribed view. */
|
|
143
|
+
declare function useComments(): CommentsApi;
|
|
144
|
+
/**
|
|
145
|
+
* Every comment thread in the document, display-ordered (page position →
|
|
146
|
+
* top of page → creation date) and enriched with `pageIndex`/`pageLabel`.
|
|
147
|
+
* Subscribed to BOTH stores: annotation writes (own, remote, hydration)
|
|
148
|
+
* recompute the threads; page moves/deletes re-run the join. Reference-
|
|
149
|
+
* stable between changes — safe to memo child renders on the array.
|
|
150
|
+
*/
|
|
151
|
+
declare function useCommentThreads(): CommentThreadView[];
|
|
152
|
+
/** The enriched thread containing ANY member ref (root, reply, grouped part,
|
|
153
|
+
* state annotation), or null. */
|
|
154
|
+
declare function useCommentThread(ref: AnnotationRef | null): CommentThreadView | null;
|
|
155
|
+
/** Whole-document hydration status — the comments sidebar's honest loading
|
|
156
|
+
* state (`loading` until `listRawAll` lands, then `complete`/`error`). */
|
|
157
|
+
declare function useCommentsHydration(): AnnotationHydration;
|
|
158
|
+
//#endregion
|
|
159
|
+
export { useCommentsHydration as A, filePickerProvider as C, useCommentThread as D, useAnnotationSelection as E, SelectionAnchor as F, sameAnchor as I, sameCreationDraftAnchor as L, useSelectionFlags as M, useSelectionProps as N, useCommentThreads as O, useAnnotationSelected as P, enrichCommentThreads as S, useAnnotationDefaults as T, SelectionFlags$1 as _, AnnotationPropsPatch as a, TextAlign as b, Border as c, Geom as d, LineEnding as f, RenderItem$1 as g, PropSpec as h, AnnotationProps$1 as i, useFilePickerProvider as j, useComments as k, CommentThreadView as l, PropKey as m, AnnotationLayer as n, AnnotationRenderer as o, LineEndings as p, AnnotationLayerProps as r, AnnotationRendererProps as s, AnnotationFlags as t, CreationDraftAnchor$1 as u, SelectionProps$1 as v, useAnnotation as w, TextStyle as x, Style as y };
|
|
160
|
+
//# sourceMappingURL=annotation-k38KDlIZ.d.ts.map
|
package/dist/annotation-menu.cjs
CHANGED
|
@@ -2,11 +2,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_rolldown_runtime = require("./rolldown-runtime-DDXJien1.cjs");
|
|
3
3
|
const require_runtime = require("./runtime.cjs");
|
|
4
4
|
const require_anchored = require("./anchored.cjs");
|
|
5
|
-
const
|
|
5
|
+
const require_annotation_anchors = require("./annotation-anchors-DuYRBJLl.cjs");
|
|
6
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
7
|
let react = require("react");
|
|
8
8
|
react = require_rolldown_runtime.__toESM(react, 1);
|
|
9
|
-
let
|
|
9
|
+
let _embedpdf_plugin_annotation_contract_host = require("@embedpdf/plugin-annotation/contract/host");
|
|
10
10
|
//#region src/annotation-menu.tsx
|
|
11
11
|
/**
|
|
12
12
|
* Annotation menus — thin anchor plumbing over the ONE `<Anchored>` primitive.
|
|
@@ -28,12 +28,12 @@ let _embedpdf_plugin_annotation_internal = require("@embedpdf/plugin-annotation/
|
|
|
28
28
|
*/
|
|
29
29
|
function AnnotationMenu({ children, gap = 15, placement = "top" }) {
|
|
30
30
|
const { projector } = require_anchored.useProjectorBinding();
|
|
31
|
-
const anchor = require_runtime.useSelector(
|
|
31
|
+
const anchor = require_runtime.useSelector(_embedpdf_plugin_annotation_contract_host.AnnotationToken, (c) => {
|
|
32
32
|
const a = c.selectionAnchor();
|
|
33
33
|
if (!a) return null;
|
|
34
34
|
const env = projector.viewEnv(a.pon);
|
|
35
35
|
return env ? c.selectionAnchor(env.scale, env.rotation, env.zoom) : a;
|
|
36
|
-
},
|
|
36
|
+
}, require_annotation_anchors.sameAnchor);
|
|
37
37
|
if (!anchor) return null;
|
|
38
38
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_anchored.Anchored, {
|
|
39
39
|
anchor: {
|
|
@@ -48,7 +48,7 @@ function AnnotationMenu({ children, gap = 15, placement = "top" }) {
|
|
|
48
48
|
}
|
|
49
49
|
/** Floats over a live multi-click creation draft (polygon, polyline, …). */
|
|
50
50
|
function AnnotationDraftMenu({ children, gap = 8, placement = "top" }) {
|
|
51
|
-
const anchor = require_runtime.useSelector(
|
|
51
|
+
const anchor = require_runtime.useSelector(_embedpdf_plugin_annotation_contract_host.AnnotationToken, (c) => c.creationDraftAnchor(), require_annotation_anchors.sameCreationDraftAnchor);
|
|
52
52
|
if (!anchor) return null;
|
|
53
53
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_anchored.Anchored, {
|
|
54
54
|
anchor,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotation-menu.cjs","names":["useProjectorBinding","useSelector","AnnotationHostToken","sameAnchor","Anchored","sameCreationDraftAnchor"],"sources":["../src/annotation-menu.tsx"],"sourcesContent":["/**\n * Annotation menus — thin anchor plumbing over the ONE `<Anchored>` primitive.\n *\n * These work identically under `<Stage>` (mount in the overlay slot; the\n * camera projects, no DOM reads) and `<PageView>` (measured + portalled) —\n * the SURFACE provides the projector, the menu doesn't care.\n *\n * No action bags: actions come from the capability hooks (`useAnnotation()`,\n * `useAnnotationSelected()`, …), which subscribe properly and compose across\n * plugins. Render props carry only the ANCHOR'S DATA (the draft menu's\n * progress facts); the annotation-selection menu takes plain children.\n */\nimport * as React from 'react';\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/
|
|
1
|
+
{"version":3,"file":"annotation-menu.cjs","names":["useProjectorBinding","useSelector","AnnotationHostToken","sameAnchor","Anchored","sameCreationDraftAnchor"],"sources":["../src/annotation-menu.tsx"],"sourcesContent":["/**\n * Annotation menus — thin anchor plumbing over the ONE `<Anchored>` primitive.\n *\n * These work identically under `<Stage>` (mount in the overlay slot; the\n * camera projects, no DOM reads) and `<PageView>` (measured + portalled) —\n * the SURFACE provides the projector, the menu doesn't care.\n *\n * No action bags: actions come from the capability hooks (`useAnnotation()`,\n * `useAnnotationSelected()`, …), which subscribe properly and compose across\n * plugins. Render props carry only the ANCHOR'S DATA (the draft menu's\n * progress facts); the annotation-selection menu takes plain children.\n */\nimport * as React from 'react';\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport type { CreationDraftAnchor } from '@embedpdf/core-annotation';\nimport { Anchored, useProjectorBinding, type AnchoredPlacement } from './anchored';\nimport { useSelector } from './runtime';\nimport { sameAnchor, sameCreationDraftAnchor } from './annotation-anchors';\n\nexport interface AnnotationMenuProps {\n children: React.ReactNode;\n /** Gap in screen px between the selection box and the menu (default 15). */\n gap?: number;\n /** Where to place the menu relative to the selection box. Default 'top'. */\n placement?: AnchoredPlacement;\n}\n\n/**\n * Floats over the current annotation selection (one anchor regardless of\n * cross-page selection), dodging the rotate knob. Compose the contents from\n * hooks: `useAnnotation()` for the verbs, `useAnnotationSelected()` /\n * `useSelectionProps()` for the data.\n */\nexport function AnnotationMenu({ children, gap = 15, placement = 'top' }: AnnotationMenuProps) {\n // Reading the binding subscribes this component to projection changes\n // (its identity IS the revision), so the anchor read below re-runs with\n // fresh view facts in the SAME commit as the surface — the knob offset is\n // screen-constant, so its content-space position depends on the page's\n // live view scale.\n const { projector } = useProjectorBinding();\n const anchor = useSelector(\n AnnotationHostToken,\n (c) => {\n const a = c.selectionAnchor();\n if (!a) return null;\n const env = projector.viewEnv(a.pon);\n return env ? c.selectionAnchor(env.scale, env.rotation, env.zoom) : a;\n },\n sameAnchor,\n );\n if (!anchor) return null;\n return (\n <Anchored\n anchor={{\n pon: anchor.pon,\n bounds: anchor.bounds,\n ...(anchor.knob ? { avoid: [anchor.knob] } : {}),\n }}\n placement={placement}\n gap={gap}\n >\n {children}\n </Anchored>\n );\n}\n\nexport interface AnnotationDraftMenuProps {\n /** Render prop receiving the DRAFT ANCHOR'S DATA (subtype, pointCount,\n * minPoints, canFinish, …). The verbs are capability calls:\n * `useAnnotation().finishCreationDraft()` / `.cancelCreationDraft()`. */\n children: (anchor: CreationDraftAnchor) => React.ReactNode;\n /** Gap in screen px between the draft anchor and the menu (default 8). */\n gap?: number;\n /** Where to place the menu relative to the draft anchor. Default 'top'. */\n placement?: AnchoredPlacement;\n}\n\n/** Floats over a live multi-click creation draft (polygon, polyline, …). */\nexport function AnnotationDraftMenu({\n children,\n gap = 8,\n placement = 'top',\n}: AnnotationDraftMenuProps) {\n const anchor = useSelector(\n AnnotationHostToken,\n (c) => c.creationDraftAnchor(),\n sameCreationDraftAnchor,\n );\n if (!anchor) return null;\n return (\n <Anchored anchor={anchor} placement={placement} gap={gap}>\n {children(anchor)}\n </Anchored>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,eAAe,EAAE,UAAU,MAAM,IAAI,YAAY,SAA8B;CAM7F,MAAM,EAAE,cAAcA,iBAAAA,oBAAoB;CAC1C,MAAM,SAASC,gBAAAA,YACbC,0CAAAA,kBACC,MAAM;EACL,MAAM,IAAI,EAAE,gBAAgB;EAC5B,IAAI,CAAC,GAAG,OAAO;EACf,MAAM,MAAM,UAAU,QAAQ,EAAE,GAAG;EACnC,OAAO,MAAM,EAAE,gBAAgB,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,IAAI;CACtE,GACAC,2BAAAA,UACF;CACA,IAAI,CAAC,QAAQ,OAAO;CACpB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,iBAAAA,UAAD;EACE,QAAQ;GACN,KAAK,OAAO;GACZ,QAAQ,OAAO;GACf,GAAI,OAAO,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,IAAI,CAAC;EAChD;EACW;EACN;EAEJ;CACO,CAAA;AAEd;;AAcA,SAAgB,oBAAoB,EAClC,UACA,MAAM,GACN,YAAY,SACe;CAC3B,MAAM,SAASH,gBAAAA,YACbC,0CAAAA,kBACC,MAAM,EAAE,oBAAoB,GAC7BG,2BAAAA,uBACF;CACA,IAAI,CAAC,QAAQ,OAAO;CACpB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACD,iBAAAA,UAAD;EAAkB;EAAmB;EAAgB;EAClD,UAAA,SAAS,MAAM;CACR,CAAA;AAEd"}
|
package/dist/annotation-menu.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useSelector } from "./runtime.js";
|
|
2
2
|
import { Anchored, useProjectorBinding } from "./anchored.js";
|
|
3
|
-
import {
|
|
3
|
+
import { n as sameCreationDraftAnchor, t as sameAnchor } from "./annotation-anchors-CetwM1g7.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import "react";
|
|
6
|
-
import { AnnotationToken } from "@embedpdf/plugin-annotation/
|
|
6
|
+
import { AnnotationToken } from "@embedpdf/plugin-annotation/contract/host";
|
|
7
7
|
//#region src/annotation-menu.tsx
|
|
8
8
|
/**
|
|
9
9
|
* Floats over the current annotation selection (one anchor regardless of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotation-menu.js","names":["AnnotationHostToken"],"sources":["../src/annotation-menu.tsx"],"sourcesContent":["/**\n * Annotation menus — thin anchor plumbing over the ONE `<Anchored>` primitive.\n *\n * These work identically under `<Stage>` (mount in the overlay slot; the\n * camera projects, no DOM reads) and `<PageView>` (measured + portalled) —\n * the SURFACE provides the projector, the menu doesn't care.\n *\n * No action bags: actions come from the capability hooks (`useAnnotation()`,\n * `useAnnotationSelected()`, …), which subscribe properly and compose across\n * plugins. Render props carry only the ANCHOR'S DATA (the draft menu's\n * progress facts); the annotation-selection menu takes plain children.\n */\nimport * as React from 'react';\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/
|
|
1
|
+
{"version":3,"file":"annotation-menu.js","names":["AnnotationHostToken"],"sources":["../src/annotation-menu.tsx"],"sourcesContent":["/**\n * Annotation menus — thin anchor plumbing over the ONE `<Anchored>` primitive.\n *\n * These work identically under `<Stage>` (mount in the overlay slot; the\n * camera projects, no DOM reads) and `<PageView>` (measured + portalled) —\n * the SURFACE provides the projector, the menu doesn't care.\n *\n * No action bags: actions come from the capability hooks (`useAnnotation()`,\n * `useAnnotationSelected()`, …), which subscribe properly and compose across\n * plugins. Render props carry only the ANCHOR'S DATA (the draft menu's\n * progress facts); the annotation-selection menu takes plain children.\n */\nimport * as React from 'react';\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport type { CreationDraftAnchor } from '@embedpdf/core-annotation';\nimport { Anchored, useProjectorBinding, type AnchoredPlacement } from './anchored';\nimport { useSelector } from './runtime';\nimport { sameAnchor, sameCreationDraftAnchor } from './annotation-anchors';\n\nexport interface AnnotationMenuProps {\n children: React.ReactNode;\n /** Gap in screen px between the selection box and the menu (default 15). */\n gap?: number;\n /** Where to place the menu relative to the selection box. Default 'top'. */\n placement?: AnchoredPlacement;\n}\n\n/**\n * Floats over the current annotation selection (one anchor regardless of\n * cross-page selection), dodging the rotate knob. Compose the contents from\n * hooks: `useAnnotation()` for the verbs, `useAnnotationSelected()` /\n * `useSelectionProps()` for the data.\n */\nexport function AnnotationMenu({ children, gap = 15, placement = 'top' }: AnnotationMenuProps) {\n // Reading the binding subscribes this component to projection changes\n // (its identity IS the revision), so the anchor read below re-runs with\n // fresh view facts in the SAME commit as the surface — the knob offset is\n // screen-constant, so its content-space position depends on the page's\n // live view scale.\n const { projector } = useProjectorBinding();\n const anchor = useSelector(\n AnnotationHostToken,\n (c) => {\n const a = c.selectionAnchor();\n if (!a) return null;\n const env = projector.viewEnv(a.pon);\n return env ? c.selectionAnchor(env.scale, env.rotation, env.zoom) : a;\n },\n sameAnchor,\n );\n if (!anchor) return null;\n return (\n <Anchored\n anchor={{\n pon: anchor.pon,\n bounds: anchor.bounds,\n ...(anchor.knob ? { avoid: [anchor.knob] } : {}),\n }}\n placement={placement}\n gap={gap}\n >\n {children}\n </Anchored>\n );\n}\n\nexport interface AnnotationDraftMenuProps {\n /** Render prop receiving the DRAFT ANCHOR'S DATA (subtype, pointCount,\n * minPoints, canFinish, …). The verbs are capability calls:\n * `useAnnotation().finishCreationDraft()` / `.cancelCreationDraft()`. */\n children: (anchor: CreationDraftAnchor) => React.ReactNode;\n /** Gap in screen px between the draft anchor and the menu (default 8). */\n gap?: number;\n /** Where to place the menu relative to the draft anchor. Default 'top'. */\n placement?: AnchoredPlacement;\n}\n\n/** Floats over a live multi-click creation draft (polygon, polyline, …). */\nexport function AnnotationDraftMenu({\n children,\n gap = 8,\n placement = 'top',\n}: AnnotationDraftMenuProps) {\n const anchor = useSelector(\n AnnotationHostToken,\n (c) => c.creationDraftAnchor(),\n sameCreationDraftAnchor,\n );\n if (!anchor) return null;\n return (\n <Anchored anchor={anchor} placement={placement} gap={gap}>\n {children(anchor)}\n </Anchored>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAiCA,SAAgB,eAAe,EAAE,UAAU,MAAM,IAAI,YAAY,SAA8B;CAM7F,MAAM,EAAE,cAAc,oBAAoB;CAC1C,MAAM,SAAS,YACbA,kBACC,MAAM;EACL,MAAM,IAAI,EAAE,gBAAgB;EAC5B,IAAI,CAAC,GAAG,OAAO;EACf,MAAM,MAAM,UAAU,QAAQ,EAAE,GAAG;EACnC,OAAO,MAAM,EAAE,gBAAgB,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,IAAI;CACtE,GACA,UACF;CACA,IAAI,CAAC,QAAQ,OAAO;CACpB,OACE,oBAAC,UAAD;EACE,QAAQ;GACN,KAAK,OAAO;GACZ,QAAQ,OAAO;GACf,GAAI,OAAO,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,IAAI,CAAC;EAChD;EACW;EACN;EAEJ;CACO,CAAA;AAEd;;AAcA,SAAgB,oBAAoB,EAClC,UACA,MAAM,GACN,YAAY,SACe;CAC3B,MAAM,SAAS,YACbA,kBACC,MAAM,EAAE,oBAAoB,GAC7B,uBACF;CACA,IAAI,CAAC,QAAQ,OAAO;CACpB,OACE,oBAAC,UAAD;EAAkB;EAAmB;EAAgB;EAClD,UAAA,SAAS,MAAM;CACR,CAAA;AAEd"}
|
package/dist/annotation.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("./rolldown-runtime-DDXJien1.cjs");
|
|
3
3
|
const require_runtime = require("./runtime.cjs");
|
|
4
|
+
const require_annotation_anchors = require("./annotation-anchors-DuYRBJLl.cjs");
|
|
5
|
+
const require_annotation_hooks = require("./annotation-hooks-BB5ZhPpf.cjs");
|
|
4
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
7
|
let react = require("react");
|
|
6
8
|
react = require_rolldown_runtime.__toESM(react, 1);
|
|
@@ -163,22 +165,31 @@ function ToolGhostImage({ page }) {
|
|
|
163
165
|
const ghost = require_runtime.useSelector(_embedpdf_plugin_annotation_internal.AnnotationToken, (c) => c.toolGhost(page.pon));
|
|
164
166
|
const epoch = require_runtime.useSelector(_embedpdf_plugin_annotation_internal.AnnotationToken, (c) => c.stampArmEpoch());
|
|
165
167
|
const [url, setUrl] = (0, react.useState)(null);
|
|
168
|
+
const bucket = ghost?.kind === "image" ? (0, _embedpdf_plugin_annotation.previewBucket)(ghost.box.width * page.transform.renderScale) : 0;
|
|
166
169
|
(0, react.useEffect)(() => {
|
|
167
|
-
|
|
168
|
-
if (!preview) {
|
|
170
|
+
if (!bucket) {
|
|
169
171
|
setUrl(null);
|
|
170
172
|
return;
|
|
171
173
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
let cancelled = false;
|
|
175
|
+
let obj = null;
|
|
176
|
+
anno.armedStampPreview(bucket).then((preview) => {
|
|
177
|
+
if (cancelled || !preview) return;
|
|
178
|
+
const body = new ArrayBuffer(preview.bytes.byteLength);
|
|
179
|
+
new Uint8Array(body).set(preview.bytes);
|
|
180
|
+
const blob = new Blob([body], preview.mimeType ? { type: preview.mimeType } : {});
|
|
181
|
+
obj = URL.createObjectURL(blob);
|
|
182
|
+
setUrl(obj);
|
|
183
|
+
});
|
|
177
184
|
return () => {
|
|
178
|
-
|
|
179
|
-
|
|
185
|
+
cancelled = true;
|
|
186
|
+
if (obj) URL.revokeObjectURL(obj);
|
|
180
187
|
};
|
|
181
|
-
}, [
|
|
188
|
+
}, [
|
|
189
|
+
anno,
|
|
190
|
+
epoch,
|
|
191
|
+
bucket
|
|
192
|
+
]);
|
|
182
193
|
if (!ghost || ghost.kind !== "image" || !url) return null;
|
|
183
194
|
const b = boxOf(ghost.box, page);
|
|
184
195
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
@@ -635,10 +646,6 @@ function useAnnotation() {
|
|
|
635
646
|
function useAnnotationSelection() {
|
|
636
647
|
return require_runtime.useSelector(_embedpdf_plugin_annotation.AnnotationToken, (c) => c.selection(), require_runtime.shallowArray);
|
|
637
648
|
}
|
|
638
|
-
/** The selected annotations as engine DTOs — for selection-aware toolbars/sidebars. */
|
|
639
|
-
function useAnnotationSelected() {
|
|
640
|
-
return require_runtime.useSelector(_embedpdf_plugin_annotation.AnnotationToken, (c) => c.getSelected(), require_runtime.shallowArray);
|
|
641
|
-
}
|
|
642
649
|
/** Structural equality for a resolved props bag — keeps the subscription from
|
|
643
650
|
* re-rendering on unrelated dispatches, since `currentDefaults` returns a fresh
|
|
644
651
|
* object each call. Small flat objects; JSON compare is exact and cheap here. */
|
|
@@ -720,27 +727,15 @@ function useCommentThread(ref) {
|
|
|
720
727
|
function useCommentsHydration() {
|
|
721
728
|
return require_runtime.useSelector(_embedpdf_plugin_annotation.AnnotationToken, (c) => c.comments.hydration());
|
|
722
729
|
}
|
|
723
|
-
/** Structural equality for the selection anchor — keeps the menu from re-rendering
|
|
724
|
-
* on unrelated dispatches (the capability returns a fresh object each call). */
|
|
725
|
-
function sameAnchor(a, b) {
|
|
726
|
-
if (a === b) return true;
|
|
727
|
-
if (!a || !b) return false;
|
|
728
|
-
return a.pon === b.pon && a.bounds.x === b.bounds.x && a.bounds.y === b.bounds.y && a.bounds.width === b.bounds.width && a.bounds.height === b.bounds.height && a.knob?.x === b.knob?.x && a.knob?.y === b.knob?.y;
|
|
729
|
-
}
|
|
730
|
-
function sameCreationDraftAnchor(a, b) {
|
|
731
|
-
if (a === b) return true;
|
|
732
|
-
if (!a || !b) return false;
|
|
733
|
-
return a.kind === b.kind && a.subtype === b.subtype && a.pon === b.pon && a.pointCount === b.pointCount && a.minPoints === b.minPoints && a.canFinish === b.canFinish && a.bounds.x === b.bounds.x && a.bounds.y === b.bounds.y && a.bounds.width === b.bounds.width && a.bounds.height === b.bounds.height;
|
|
734
|
-
}
|
|
735
730
|
//#endregion
|
|
736
731
|
exports.AnnotationLayer = AnnotationLayer;
|
|
737
732
|
exports.enrichCommentThreads = enrichCommentThreads;
|
|
738
733
|
exports.filePickerProvider = filePickerProvider;
|
|
739
|
-
exports.sameAnchor = sameAnchor;
|
|
740
|
-
exports.sameCreationDraftAnchor = sameCreationDraftAnchor;
|
|
734
|
+
exports.sameAnchor = require_annotation_anchors.sameAnchor;
|
|
735
|
+
exports.sameCreationDraftAnchor = require_annotation_anchors.sameCreationDraftAnchor;
|
|
741
736
|
exports.useAnnotation = useAnnotation;
|
|
742
737
|
exports.useAnnotationDefaults = useAnnotationDefaults;
|
|
743
|
-
exports.useAnnotationSelected = useAnnotationSelected;
|
|
738
|
+
exports.useAnnotationSelected = require_annotation_hooks.useAnnotationSelected;
|
|
744
739
|
exports.useAnnotationSelection = useAnnotationSelection;
|
|
745
740
|
exports.useCommentThread = useCommentThread;
|
|
746
741
|
exports.useCommentThreads = useCommentThreads;
|