@embedpdf/viewer-chrome 3.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +215 -0
- package/README.md +317 -0
- package/dist/chrome.cjs +228 -0
- package/dist/chrome.cjs.map +1 -0
- package/dist/chrome.d.cts +36 -0
- package/dist/chrome.d.ts +36 -0
- package/dist/chrome.js +224 -0
- package/dist/chrome.js.map +1 -0
- package/dist/commands.cjs +497 -0
- package/dist/commands.cjs.map +1 -0
- package/dist/commands.d.cts +22 -0
- package/dist/commands.d.ts +22 -0
- package/dist/commands.js +494 -0
- package/dist/commands.js.map +1 -0
- package/dist/es-C5084JO6.cjs +166 -0
- package/dist/es-C5084JO6.cjs.map +1 -0
- package/dist/es-D0PzYE9Z.js +166 -0
- package/dist/es-D0PzYE9Z.js.map +1 -0
- package/dist/index.cjs +3700 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +121 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.js +3529 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
- package/src/styles.css +132 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let _embedpdf_react_runtime = require("@embedpdf/react/runtime");
|
|
3
|
+
let _embedpdf_react_stage = require("@embedpdf/react/stage");
|
|
4
|
+
let _embedpdf_react_interaction = require("@embedpdf/react/interaction");
|
|
5
|
+
let _embedpdf_react_annotation = require("@embedpdf/react/annotation");
|
|
6
|
+
let _embedpdf_react_form = require("@embedpdf/react/form");
|
|
7
|
+
let _embedpdf_react_link = require("@embedpdf/react/link");
|
|
8
|
+
let _embedpdf_react_shell = require("@embedpdf/react/shell");
|
|
9
|
+
//#region src/config/commands.ts
|
|
10
|
+
const stage = (c) => c.tryGet(_embedpdf_react_stage.StageToken);
|
|
11
|
+
const interaction = (c) => c.tryGet(_embedpdf_react_interaction.InteractionToken);
|
|
12
|
+
const anno = (c) => c.tryGet(_embedpdf_react_annotation.AnnotationToken);
|
|
13
|
+
const hasAnnotationSelection = (c) => (anno(c)?.selection().length ?? 0) > 0;
|
|
14
|
+
/** v2 gated strip items per subtype (comment hidden on links/widgets) — here
|
|
15
|
+
* it's one derivation over the selected DTOs instead of per-command lookups. */
|
|
16
|
+
const selectionSubtypes = (c) => new Set((anno(c)?.getSelected() ?? []).map((a) => a.subtype));
|
|
17
|
+
/**
|
|
18
|
+
* The selection's `link` value: a target, `null` (linkable but none set), or
|
|
19
|
+
* `undefined` when the selection cannot carry a link at all (widgets, mixed
|
|
20
|
+
* link states) — the schema decides, never a subtype blocklist.
|
|
21
|
+
*/
|
|
22
|
+
const selectionLink = (c) => {
|
|
23
|
+
const p = anno(c)?.getSelectionProps();
|
|
24
|
+
if (!p || !p.specs.some((s) => s.key === "link") || p.mixed.includes("link")) return void 0;
|
|
25
|
+
return p.values.link ?? null;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* toolId → the SAME icon + accent definition its toolbar button uses, recorded
|
|
29
|
+
* as a side effect of the `tool()` command definitions below — ONE source of
|
|
30
|
+
* truth, so the tool cursor (ui/tool-cursor.tsx) and the button can never
|
|
31
|
+
* drift apart.
|
|
32
|
+
*/
|
|
33
|
+
const TOOL_ICONS = {};
|
|
34
|
+
const toolAccent = (c, toolId, accent) => {
|
|
35
|
+
if (!accent) return null;
|
|
36
|
+
const anno = c.tryGet(_embedpdf_react_annotation.AnnotationToken);
|
|
37
|
+
if (!anno) return null;
|
|
38
|
+
const d = anno.currentDefaults(toolId);
|
|
39
|
+
return {
|
|
40
|
+
primary: d[accent.primary] ?? void 0,
|
|
41
|
+
secondary: accent.secondary ? d[accent.secondary] ?? void 0 : void 0
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
/** A tool command: activates a real interaction tool; active = it's the tool.
|
|
45
|
+
* The icon previews the tool's current defaults — keyed by the SAME toolId
|
|
46
|
+
* as run/active, so the accent can't drift to another tool's colors. */
|
|
47
|
+
const tool = (id, toolId, labelKey, icon, accent) => {
|
|
48
|
+
TOOL_ICONS[toolId] = {
|
|
49
|
+
icon,
|
|
50
|
+
...accent ? { accent } : {}
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
id,
|
|
54
|
+
labelKey,
|
|
55
|
+
icon,
|
|
56
|
+
categories: ["tool"],
|
|
57
|
+
run: (c) => interaction(c)?.activateTool(toolId),
|
|
58
|
+
active: (c) => interaction(c)?.activeToolId() === toolId,
|
|
59
|
+
enabled: (c) => interaction(c) != null,
|
|
60
|
+
iconAccent: (c) => toolAccent(c, toolId, accent)
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
/** A fixed zoom level (fraction), e.g. 1 = 100%. */
|
|
64
|
+
const zoomLevel = (id, level, label) => ({
|
|
65
|
+
id,
|
|
66
|
+
labelKey: label,
|
|
67
|
+
categories: ["zoom", "zoom-level"],
|
|
68
|
+
run: (c) => stage(c)?.zoomTo({ level }),
|
|
69
|
+
enabled: (c) => stage(c) != null
|
|
70
|
+
});
|
|
71
|
+
const spread = (id, mode, labelKey, icon) => ({
|
|
72
|
+
id,
|
|
73
|
+
labelKey,
|
|
74
|
+
icon,
|
|
75
|
+
categories: ["page", "spread"],
|
|
76
|
+
run: (c) => stage(c)?.setSpread(mode),
|
|
77
|
+
active: (c) => stage(c)?.spread() === mode,
|
|
78
|
+
enabled: (c) => stage(c) != null
|
|
79
|
+
});
|
|
80
|
+
const defaultCommands = [
|
|
81
|
+
{
|
|
82
|
+
id: "zoom:in",
|
|
83
|
+
labelKey: "commands.zoom.in",
|
|
84
|
+
icon: "zoomIn",
|
|
85
|
+
shortcut: ["Mod+=", "Mod+NumpadAdd"],
|
|
86
|
+
categories: ["zoom"],
|
|
87
|
+
run: (c) => stage(c)?.zoomIn(),
|
|
88
|
+
enabled: (c) => stage(c) != null
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "zoom:out",
|
|
92
|
+
labelKey: "commands.zoom.out",
|
|
93
|
+
icon: "zoomOut",
|
|
94
|
+
shortcut: ["Mod+-", "Mod+NumpadSubtract"],
|
|
95
|
+
categories: ["zoom"],
|
|
96
|
+
run: (c) => stage(c)?.zoomOut(),
|
|
97
|
+
enabled: (c) => stage(c) != null
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "zoom:fit-page",
|
|
101
|
+
labelKey: "commands.zoom.fitPage",
|
|
102
|
+
icon: "fitToPage",
|
|
103
|
+
shortcut: "Mod+0",
|
|
104
|
+
categories: ["zoom"],
|
|
105
|
+
run: (c) => stage(c)?.fitPage(),
|
|
106
|
+
active: (c) => stage(c)?.zoomMode() === _embedpdf_react_stage.ZoomMode.FitPage,
|
|
107
|
+
enabled: (c) => stage(c) != null
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "zoom:fit-width",
|
|
111
|
+
labelKey: "commands.zoom.fitWidth",
|
|
112
|
+
icon: "fitToWidth",
|
|
113
|
+
shortcut: "Mod+1",
|
|
114
|
+
categories: ["zoom"],
|
|
115
|
+
run: (c) => stage(c)?.fitWidth(),
|
|
116
|
+
active: (c) => stage(c)?.zoomMode() === _embedpdf_react_stage.ZoomMode.FitWidth,
|
|
117
|
+
enabled: (c) => stage(c) != null
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: "zoom:automatic",
|
|
121
|
+
labelKey: "commands.zoom.automatic",
|
|
122
|
+
categories: ["zoom"],
|
|
123
|
+
run: (c) => stage(c)?.automatic(),
|
|
124
|
+
active: (c) => stage(c)?.zoomMode() === _embedpdf_react_stage.ZoomMode.Automatic,
|
|
125
|
+
enabled: (c) => stage(c) != null
|
|
126
|
+
},
|
|
127
|
+
zoomLevel("zoom:50", .5, "commands.zoom.p50"),
|
|
128
|
+
zoomLevel("zoom:100", 1, "commands.zoom.p100"),
|
|
129
|
+
zoomLevel("zoom:150", 1.5, "commands.zoom.p150"),
|
|
130
|
+
zoomLevel("zoom:200", 2, "commands.zoom.p200"),
|
|
131
|
+
zoomLevel("zoom:400", 4, "commands.zoom.p400"),
|
|
132
|
+
{
|
|
133
|
+
id: "zoom:menu",
|
|
134
|
+
labelKey: "commands.zoom.menu",
|
|
135
|
+
icon: "zoomIn",
|
|
136
|
+
categories: ["zoom"],
|
|
137
|
+
menu: "zoom"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: "pan:toggle",
|
|
141
|
+
labelKey: "commands.pan",
|
|
142
|
+
icon: "hand",
|
|
143
|
+
categories: ["tools"],
|
|
144
|
+
run: (c) => interaction(c)?.activateTool("pan"),
|
|
145
|
+
active: (c) => interaction(c)?.activeToolId() === "pan",
|
|
146
|
+
enabled: (c) => interaction(c) != null
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: "pointer:toggle",
|
|
150
|
+
labelKey: "commands.pointer",
|
|
151
|
+
icon: "pointer",
|
|
152
|
+
categories: ["tools"],
|
|
153
|
+
run: (c) => interaction(c)?.activateTool("pointer"),
|
|
154
|
+
active: (c) => interaction(c)?.activeToolId() === "pointer",
|
|
155
|
+
enabled: (c) => interaction(c) != null
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: "panel:sidebar",
|
|
159
|
+
labelKey: "commands.sidebar",
|
|
160
|
+
icon: "sidebar",
|
|
161
|
+
categories: ["panel"],
|
|
162
|
+
panel: {
|
|
163
|
+
id: "sidebar",
|
|
164
|
+
exclusive: "left"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
id: "panel:search",
|
|
169
|
+
labelKey: "commands.search",
|
|
170
|
+
icon: "search",
|
|
171
|
+
categories: ["panel"],
|
|
172
|
+
panel: {
|
|
173
|
+
id: "search",
|
|
174
|
+
exclusive: "right"
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "panel:comment",
|
|
179
|
+
labelKey: "commands.comment",
|
|
180
|
+
icon: "comment",
|
|
181
|
+
categories: ["panel"],
|
|
182
|
+
panel: {
|
|
183
|
+
id: "comment",
|
|
184
|
+
exclusive: "right"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: "panel:annotation-style",
|
|
189
|
+
labelKey: "commands.style",
|
|
190
|
+
icon: "palette",
|
|
191
|
+
categories: ["panel"],
|
|
192
|
+
panel: {
|
|
193
|
+
id: "annotation-style",
|
|
194
|
+
exclusive: "right"
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: "document:menu",
|
|
199
|
+
labelKey: "commands.menu",
|
|
200
|
+
icon: "menu",
|
|
201
|
+
categories: ["document"],
|
|
202
|
+
menu: "document"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "page:settings",
|
|
206
|
+
labelKey: "commands.viewControls",
|
|
207
|
+
icon: "viewSettings",
|
|
208
|
+
categories: ["page"],
|
|
209
|
+
menu: "page-settings"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
id: "document:download",
|
|
213
|
+
labelKey: "commands.download",
|
|
214
|
+
icon: "download",
|
|
215
|
+
categories: ["document"],
|
|
216
|
+
run: (c) => {
|
|
217
|
+
const id = c.documentId ?? void 0;
|
|
218
|
+
c.tryGet(_embedpdf_react_runtime.DocumentsToken)?.download(id).then((bytes) => {
|
|
219
|
+
const blob = new Blob([bytes], { type: "application/pdf" });
|
|
220
|
+
const url = URL.createObjectURL(blob);
|
|
221
|
+
const a = document.createElement("a");
|
|
222
|
+
a.href = url;
|
|
223
|
+
a.download = "document.pdf";
|
|
224
|
+
a.click();
|
|
225
|
+
URL.revokeObjectURL(url);
|
|
226
|
+
}).catch((e) => console.warn("[snippet-react] download failed", e));
|
|
227
|
+
},
|
|
228
|
+
enabled: (c) => c.tryGet(_embedpdf_react_runtime.DocumentsToken) != null && c.documentId != null
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: "document:print",
|
|
232
|
+
labelKey: "commands.print",
|
|
233
|
+
icon: "print",
|
|
234
|
+
shortcut: "Mod+p",
|
|
235
|
+
categories: ["document"],
|
|
236
|
+
run: () => window.print()
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: "document:fullscreen",
|
|
240
|
+
labelKey: "commands.fullscreen",
|
|
241
|
+
icon: "externalLink",
|
|
242
|
+
categories: ["document"],
|
|
243
|
+
run: () => {
|
|
244
|
+
if (document.fullscreenElement) document.exitFullscreen();
|
|
245
|
+
else document.documentElement.requestFullscreen().catch(() => {});
|
|
246
|
+
},
|
|
247
|
+
active: () => Boolean(document.fullscreenElement)
|
|
248
|
+
},
|
|
249
|
+
spread("spread:none", "none", "commands.spread.none", "singlePage"),
|
|
250
|
+
spread("spread:odd", "odd", "commands.spread.odd", "doublePage"),
|
|
251
|
+
spread("spread:even", "even", "commands.spread.even", "book2"),
|
|
252
|
+
{
|
|
253
|
+
id: "scroll:vertical",
|
|
254
|
+
labelKey: "commands.scroll.vertical",
|
|
255
|
+
icon: "vertical",
|
|
256
|
+
categories: ["page", "scroll"],
|
|
257
|
+
run: (c) => stage(c)?.setLayout("vertical"),
|
|
258
|
+
active: (c) => stage(c)?.layout() === "vertical",
|
|
259
|
+
enabled: (c) => stage(c) != null
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
id: "scroll:horizontal",
|
|
263
|
+
labelKey: "commands.scroll.horizontal",
|
|
264
|
+
icon: "horizontal",
|
|
265
|
+
categories: ["page", "scroll"],
|
|
266
|
+
run: (c) => stage(c)?.setLayout("horizontal"),
|
|
267
|
+
active: (c) => stage(c)?.layout() === "horizontal",
|
|
268
|
+
enabled: (c) => stage(c) != null
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: "rotate:clockwise",
|
|
272
|
+
labelKey: "commands.rotate.clockwise",
|
|
273
|
+
icon: "rotateClockwise",
|
|
274
|
+
categories: ["page", "rotate"],
|
|
275
|
+
run: (c) => stage(c)?.rotateView(90),
|
|
276
|
+
enabled: (c) => stage(c) != null
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
id: "rotate:counter-clockwise",
|
|
280
|
+
labelKey: "commands.rotate.counterclockwise",
|
|
281
|
+
icon: "rotateCounterClockwise",
|
|
282
|
+
categories: ["page", "rotate"],
|
|
283
|
+
run: (c) => stage(c)?.rotateView(-90),
|
|
284
|
+
enabled: (c) => stage(c) != null
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
id: "mode:view",
|
|
288
|
+
labelKey: "commands.mode.view",
|
|
289
|
+
categories: ["mode"],
|
|
290
|
+
run: (c) => {
|
|
291
|
+
const shell = c.tryGet(_embedpdf_react_shell.ShellToken);
|
|
292
|
+
for (const m of MODE_SURFACES) shell?.close(m);
|
|
293
|
+
interaction(c)?.activateTool("pointer");
|
|
294
|
+
},
|
|
295
|
+
active: (c) => {
|
|
296
|
+
const shell = c.tryGet(_embedpdf_react_shell.ShellToken);
|
|
297
|
+
return shell ? MODE_SURFACES.every((m) => !shell.isOpen(m)) : true;
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
modeCommand("mode:annotate", "commands.mode.annotate"),
|
|
301
|
+
modeCommand("mode:shapes", "commands.mode.shapes"),
|
|
302
|
+
modeCommand("mode:insert", "commands.mode.insert"),
|
|
303
|
+
modeCommand("mode:form", "commands.mode.form", "form-edit"),
|
|
304
|
+
modeCommand("mode:redact", "commands.mode.redact"),
|
|
305
|
+
tool("annotation:add-highlight", "highlight", "commands.annotate.highlight", "highlight", { primary: "color" }),
|
|
306
|
+
tool("annotation:add-strikeout", "strikeout", "commands.annotate.strikeout", "strikethrough", { primary: "color" }),
|
|
307
|
+
tool("annotation:add-underline", "underline", "commands.annotate.underline", "underline", { primary: "color" }),
|
|
308
|
+
tool("annotation:add-squiggly", "squiggly", "commands.annotate.squiggly", "squiggly", { primary: "color" }),
|
|
309
|
+
tool("annotation:add-ink", "ink", "commands.annotate.ink", "pencilMarker", { primary: "color" }),
|
|
310
|
+
tool("annotation:add-ink-highlight", "ink-highlight", "commands.annotate.inkHighlight", "inkHighlighter", { primary: "color" }),
|
|
311
|
+
tool("annotation:add-text", "free-text", "commands.annotate.text", "freeText", { primary: "fontColor" }),
|
|
312
|
+
tool("annotation:add-insert-text", "insert-text", "commands.annotate.insertText", "insertText", { primary: "color" }),
|
|
313
|
+
tool("annotation:add-replace-text", "replace-text", "commands.annotate.replaceText", "replaceText", { primary: "color" }),
|
|
314
|
+
tool("annotation:add-callout", "free-text-callout", "commands.annotate.callout", "callout", {
|
|
315
|
+
primary: "color",
|
|
316
|
+
secondary: "interiorColor"
|
|
317
|
+
}),
|
|
318
|
+
tool("annotation:add-note", "note", "commands.annotate.note", "message"),
|
|
319
|
+
tool("annotation:add-link", "link", "commands.annotate.link", "link"),
|
|
320
|
+
tool("annotation:add-rectangle", "square", "commands.shapes.rectangle", "square", {
|
|
321
|
+
primary: "color",
|
|
322
|
+
secondary: "interiorColor"
|
|
323
|
+
}),
|
|
324
|
+
tool("annotation:add-circle", "circle", "commands.shapes.circle", "circle", {
|
|
325
|
+
primary: "color",
|
|
326
|
+
secondary: "interiorColor"
|
|
327
|
+
}),
|
|
328
|
+
tool("annotation:add-line", "line", "commands.shapes.line", "line", { primary: "color" }),
|
|
329
|
+
tool("annotation:add-arrow", "arrow", "commands.shapes.arrow", "lineArrow", { primary: "color" }),
|
|
330
|
+
tool("annotation:add-polygon", "polygon", "commands.shapes.polygon", "polygon", {
|
|
331
|
+
primary: "color",
|
|
332
|
+
secondary: "interiorColor"
|
|
333
|
+
}),
|
|
334
|
+
tool("annotation:add-polyline", "polyline", "commands.shapes.polyline", "zigzag", { primary: "color" }),
|
|
335
|
+
tool("insert:add-stamp", "stamp", "commands.insert.stamp", "rubberStamp"),
|
|
336
|
+
tool("insert:add-attachment", "attachment", "commands.insert.attachment", "paperclip"),
|
|
337
|
+
tool("insert:add-signature", "signature", "commands.insert.signature", "signature"),
|
|
338
|
+
tool("insert:add-image", "image", "commands.insert.image", "photo"),
|
|
339
|
+
tool("form:add-textfield", "form-text", "commands.form.textfield", "formTextfield"),
|
|
340
|
+
tool("form:add-checkbox", "form-checkbox", "commands.form.checkbox", "formCheckbox"),
|
|
341
|
+
tool("form:add-radio", "form-radio", "commands.form.radio", "formRadio"),
|
|
342
|
+
tool("form:add-select", "form-combobox", "commands.form.select", "formSelect"),
|
|
343
|
+
tool("form:add-listbox", "form-listbox", "commands.form.listbox", "formListbox"),
|
|
344
|
+
tool("redaction:redact", "redact", "commands.redact.mark", "redactArea"),
|
|
345
|
+
{
|
|
346
|
+
id: "panel:redaction",
|
|
347
|
+
labelKey: "commands.redact.panel",
|
|
348
|
+
icon: "redactionSidebar",
|
|
349
|
+
categories: ["panel"],
|
|
350
|
+
panel: {
|
|
351
|
+
id: "redaction",
|
|
352
|
+
exclusive: "right"
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
id: "annotation:delete",
|
|
357
|
+
labelKey: "commands.annotate.delete",
|
|
358
|
+
icon: "trash",
|
|
359
|
+
categories: ["annotation"],
|
|
360
|
+
run: (c) => {
|
|
361
|
+
const a = anno(c);
|
|
362
|
+
if (!a) return;
|
|
363
|
+
const form = c.tryGet(_embedpdf_react_form.FormToken);
|
|
364
|
+
const dtos = a.getSelected();
|
|
365
|
+
const widgets = form ? dtos.filter((d) => d.subtype === "widget") : [];
|
|
366
|
+
if (widgets.length === 0) {
|
|
367
|
+
a.deleteSelection();
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const keys = /* @__PURE__ */ new Set();
|
|
371
|
+
for (const w of widgets) {
|
|
372
|
+
const objnum = w.ref.kind === "objectNumber" ? w.ref.annotObjectNumber : 0;
|
|
373
|
+
const field = objnum > 0 ? form.fieldForWidget(objnum) : null;
|
|
374
|
+
if (field) keys.add((0, _embedpdf_react_form.fieldKeyOf)(field));
|
|
375
|
+
}
|
|
376
|
+
for (const key of keys) form.deleteField(key);
|
|
377
|
+
for (const d of dtos) if (d.subtype !== "widget") a.delete(d.ref);
|
|
378
|
+
a.deselect();
|
|
379
|
+
},
|
|
380
|
+
visible: hasAnnotationSelection,
|
|
381
|
+
enabled: (c) => {
|
|
382
|
+
const a = anno(c);
|
|
383
|
+
const refs = a?.getSelection() ?? [];
|
|
384
|
+
return refs.length > 0 && refs.every((r) => a.canDelete(r));
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
id: "annotation:comment",
|
|
389
|
+
labelKey: "commands.comment",
|
|
390
|
+
icon: "comment",
|
|
391
|
+
categories: ["annotation"],
|
|
392
|
+
panel: {
|
|
393
|
+
id: "comment",
|
|
394
|
+
exclusive: "right"
|
|
395
|
+
},
|
|
396
|
+
visible: (c) => hasAnnotationSelection(c) && !selectionSubtypes(c).has("widget")
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
id: "annotation:style",
|
|
400
|
+
labelKey: "commands.style",
|
|
401
|
+
icon: "palette",
|
|
402
|
+
categories: ["annotation"],
|
|
403
|
+
panel: {
|
|
404
|
+
id: "annotation-style",
|
|
405
|
+
exclusive: "right"
|
|
406
|
+
},
|
|
407
|
+
visible: (c) => (anno(c)?.getSelectionProps().specs.length ?? 0) > 0
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
id: "annotation:group",
|
|
411
|
+
labelKey: "commands.annotate.group",
|
|
412
|
+
icon: "group",
|
|
413
|
+
categories: ["annotation"],
|
|
414
|
+
run: (c) => void anno(c)?.group(),
|
|
415
|
+
visible: (c) => anno(c)?.canGroup() ?? false
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
id: "annotation:ungroup",
|
|
419
|
+
labelKey: "commands.annotate.ungroup",
|
|
420
|
+
icon: "ungroup",
|
|
421
|
+
categories: ["annotation"],
|
|
422
|
+
run: (c) => void anno(c)?.ungroup(),
|
|
423
|
+
visible: (c) => anno(c)?.canUngroup() ?? false
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
id: "annotation:link",
|
|
427
|
+
labelKey: "commands.annotate.link",
|
|
428
|
+
icon: "link",
|
|
429
|
+
categories: ["annotation"],
|
|
430
|
+
panel: {
|
|
431
|
+
id: "annotation-style",
|
|
432
|
+
exclusive: "right"
|
|
433
|
+
},
|
|
434
|
+
visible: (c) => selectionLink(c) === null
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
id: "annotation:goto-link",
|
|
438
|
+
labelKey: "commands.annotate.gotoLink",
|
|
439
|
+
icon: "externalLink",
|
|
440
|
+
categories: ["annotation"],
|
|
441
|
+
run: (c) => {
|
|
442
|
+
const target = selectionLink(c);
|
|
443
|
+
if (target) c.tryGet(_embedpdf_react_link.LinkToken)?.activate(target);
|
|
444
|
+
},
|
|
445
|
+
visible: (c) => selectionLink(c) != null
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
id: "annotation:remove-link",
|
|
449
|
+
labelKey: "commands.annotate.removeLink",
|
|
450
|
+
icon: "linkOff",
|
|
451
|
+
categories: ["annotation"],
|
|
452
|
+
run: (c) => anno(c)?.updateSelection({ link: null }),
|
|
453
|
+
visible: (c) => selectionLink(c) != null
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
id: "history:undo",
|
|
457
|
+
labelKey: "commands.undo",
|
|
458
|
+
icon: "arrowBackUp",
|
|
459
|
+
categories: ["history"],
|
|
460
|
+
run: () => {},
|
|
461
|
+
enabled: () => false
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
id: "history:redo",
|
|
465
|
+
labelKey: "commands.redo",
|
|
466
|
+
icon: "arrowForwardUp",
|
|
467
|
+
categories: ["history"],
|
|
468
|
+
run: () => {},
|
|
469
|
+
enabled: () => false
|
|
470
|
+
}
|
|
471
|
+
];
|
|
472
|
+
const MODE_SURFACES = [
|
|
473
|
+
"mode:annotate",
|
|
474
|
+
"mode:shapes",
|
|
475
|
+
"mode:insert",
|
|
476
|
+
"mode:form",
|
|
477
|
+
"mode:redact"
|
|
478
|
+
];
|
|
479
|
+
function modeCommand(id, labelKey, toolId = "pointer") {
|
|
480
|
+
return {
|
|
481
|
+
id,
|
|
482
|
+
labelKey,
|
|
483
|
+
categories: ["mode"],
|
|
484
|
+
run: (c) => {
|
|
485
|
+
const shell = c.tryGet(_embedpdf_react_shell.ShellToken);
|
|
486
|
+
shell?.toggle(id, { exclusive: "mode" });
|
|
487
|
+
interaction(c)?.activateTool(shell?.isOpen(id) ? toolId : "pointer");
|
|
488
|
+
},
|
|
489
|
+
active: (c) => c.tryGet(_embedpdf_react_shell.ShellToken)?.isOpen(id) ?? false
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
//#endregion
|
|
493
|
+
exports.MODE_SURFACES = MODE_SURFACES;
|
|
494
|
+
exports.TOOL_ICONS = TOOL_ICONS;
|
|
495
|
+
exports.defaultCommands = defaultCommands;
|
|
496
|
+
|
|
497
|
+
//# sourceMappingURL=commands.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.cjs","names":["StageToken","InteractionToken","AnnotationToken","ZoomMode","DocumentsToken","ShellToken","FormToken","LinkToken"],"sources":["../src/config/commands.ts"],"sourcesContent":["/**\n * The command vocabulary — the semantic layer. Ported in spirit from the v2\n * snippet's commands.ts, but every command is a pure value: label key, icon,\n * shortcut, derivations, and a `run` (or a declarative surface target). The\n * v2 `registry.getPlugin<T>(id)?.provides()` string-and-cast dance becomes a\n * typed `ctx.get(Token)`.\n *\n * Wiring reality (chrome-parity scope):\n * zoom/pan/pointer/spread/scroll/rotate → real Stage / Interaction / PageEdit\n * modes → shell exclusive surfaces ('mode')\n * panels / menus / modals → declarative shell targets\n * annotate + shape tools → real interaction tools\n * form tools → real form plugin palette (draw-to-place)\n * insert/redact tools → inert interaction tools (demo-tools)\n * history undo/redo → disabled (no history plugin in v3 yet)\n */\nimport type { CommandDef, IconAccent } from '@embedpdf/react/commands';\nimport { DocumentsToken } from '@embedpdf/react/runtime';\nimport { StageToken, ZoomMode } from '@embedpdf/react/stage';\nimport type { SpreadMode } from '@embedpdf/react/stage';\nimport { InteractionToken } from '@embedpdf/react/interaction';\nimport { ShellToken } from '@embedpdf/react/shell';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { fieldKeyOf, FormToken } from '@embedpdf/react/form';\nimport { LinkToken, type PdfLinkTarget } from '@embedpdf/react/link';\n\n// ── helpers ────────────────────────────────────────────────────────────────\ntype Ctx = Parameters<NonNullable<CommandDef['run']>>[0];\n\nconst stage = (c: Ctx) => c.tryGet(StageToken);\nconst interaction = (c: Ctx) => c.tryGet(InteractionToken);\nconst anno = (c: Ctx) => c.tryGet(AnnotationToken);\n\n// ── annotation-selection predicates (drive the floating strip's contents) ────\nconst hasAnnotationSelection = (c: Ctx) => (anno(c)?.selection().length ?? 0) > 0;\n/** v2 gated strip items per subtype (comment hidden on links/widgets) — here\n * it's one derivation over the selected DTOs instead of per-command lookups. */\nconst selectionSubtypes = (c: Ctx) => new Set((anno(c)?.getSelected() ?? []).map((a) => a.subtype));\n/**\n * The selection's `link` value: a target, `null` (linkable but none set), or\n * `undefined` when the selection cannot carry a link at all (widgets, mixed\n * link states) — the schema decides, never a subtype blocklist.\n */\nconst selectionLink = (c: Ctx): PdfLinkTarget | null | undefined => {\n const p = anno(c)?.getSelectionProps();\n if (!p || !p.specs.some((s) => s.key === 'link') || p.mixed.includes('link')) return undefined;\n return (p.values.link ?? null) as PdfLinkTarget | null;\n};\n\n// ── tool icon accents: THIS viewer's design decision ─────────────────────────\n// A tool declares which drawing default each colored part of its glyph previews.\n// This is intentionally explicit at the command definition: property-panel order\n// does not determine icon meaning, and another viewer may make a different choice.\ntype ColorKey = 'color' | 'interiorColor' | 'fontColor';\nexport interface ToolAccentDefinition {\n primary: ColorKey;\n secondary?: ColorKey;\n}\n\n/**\n * toolId → the SAME icon + accent definition its toolbar button uses, recorded\n * as a side effect of the `tool()` command definitions below — ONE source of\n * truth, so the tool cursor (ui/tool-cursor.tsx) and the button can never\n * drift apart.\n */\nexport const TOOL_ICONS: Record<string, { icon: string; accent?: ToolAccentDefinition }> = {};\n\nconst toolAccent = (\n c: Ctx,\n toolId: string,\n accent: ToolAccentDefinition | undefined,\n): IconAccent | null => {\n if (!accent) return null;\n const anno = c.tryGet(AnnotationToken);\n if (!anno) return null;\n const d = anno.currentDefaults(toolId);\n return {\n primary: d[accent.primary] ?? undefined,\n secondary: accent.secondary ? (d[accent.secondary] ?? undefined) : undefined,\n };\n};\n\n/** A tool command: activates a real interaction tool; active = it's the tool.\n * The icon previews the tool's current defaults — keyed by the SAME toolId\n * as run/active, so the accent can't drift to another tool's colors. */\nconst tool = (\n id: string,\n toolId: string,\n labelKey: string,\n icon: string,\n accent?: ToolAccentDefinition,\n): CommandDef => {\n TOOL_ICONS[toolId] = { icon, ...(accent ? { accent } : {}) };\n return {\n id,\n labelKey,\n icon,\n categories: ['tool'],\n run: (c) => interaction(c)?.activateTool(toolId),\n active: (c) => interaction(c)?.activeToolId() === toolId,\n enabled: (c) => interaction(c) != null,\n iconAccent: (c) => toolAccent(c, toolId, accent),\n };\n};\n\n/** A fixed zoom level (fraction), e.g. 1 = 100%. */\nconst zoomLevel = (id: string, level: number, label: string): CommandDef => ({\n id,\n labelKey: label,\n categories: ['zoom', 'zoom-level'],\n run: (c) => stage(c)?.zoomTo({ level }),\n enabled: (c) => stage(c) != null,\n});\n\nconst spread = (id: string, mode: SpreadMode, labelKey: string, icon: string): CommandDef => ({\n id,\n labelKey,\n icon,\n categories: ['page', 'spread'],\n run: (c) => stage(c)?.setSpread(mode),\n active: (c) => stage(c)?.spread() === mode,\n enabled: (c) => stage(c) != null,\n});\n\nexport const defaultCommands: CommandDef[] = [\n // ── zoom ───────────────────────────────────────────────────────────────\n {\n id: 'zoom:in',\n labelKey: 'commands.zoom.in',\n icon: 'zoomIn',\n shortcut: ['Mod+=', 'Mod+NumpadAdd'],\n categories: ['zoom'],\n run: (c) => stage(c)?.zoomIn(),\n enabled: (c) => stage(c) != null,\n },\n {\n id: 'zoom:out',\n labelKey: 'commands.zoom.out',\n icon: 'zoomOut',\n shortcut: ['Mod+-', 'Mod+NumpadSubtract'],\n categories: ['zoom'],\n run: (c) => stage(c)?.zoomOut(),\n enabled: (c) => stage(c) != null,\n },\n {\n id: 'zoom:fit-page',\n labelKey: 'commands.zoom.fitPage',\n icon: 'fitToPage',\n shortcut: 'Mod+0',\n categories: ['zoom'],\n run: (c) => stage(c)?.fitPage(),\n active: (c) => stage(c)?.zoomMode() === ZoomMode.FitPage,\n enabled: (c) => stage(c) != null,\n },\n {\n id: 'zoom:fit-width',\n labelKey: 'commands.zoom.fitWidth',\n icon: 'fitToWidth',\n shortcut: 'Mod+1',\n categories: ['zoom'],\n run: (c) => stage(c)?.fitWidth(),\n active: (c) => stage(c)?.zoomMode() === ZoomMode.FitWidth,\n enabled: (c) => stage(c) != null,\n },\n {\n id: 'zoom:automatic',\n labelKey: 'commands.zoom.automatic',\n categories: ['zoom'],\n run: (c) => stage(c)?.automatic(),\n active: (c) => stage(c)?.zoomMode() === ZoomMode.Automatic,\n enabled: (c) => stage(c) != null,\n },\n zoomLevel('zoom:50', 0.5, 'commands.zoom.p50'),\n zoomLevel('zoom:100', 1, 'commands.zoom.p100'),\n zoomLevel('zoom:150', 1.5, 'commands.zoom.p150'),\n zoomLevel('zoom:200', 2, 'commands.zoom.p200'),\n zoomLevel('zoom:400', 4, 'commands.zoom.p400'),\n {\n id: 'zoom:menu',\n labelKey: 'commands.zoom.menu',\n icon: 'zoomIn',\n categories: ['zoom'],\n menu: 'zoom',\n },\n\n // ── tools ──────────────────────────────────────────────────────────────\n {\n id: 'pan:toggle',\n labelKey: 'commands.pan',\n icon: 'hand',\n categories: ['tools'],\n run: (c) => interaction(c)?.activateTool('pan'),\n active: (c) => interaction(c)?.activeToolId() === 'pan',\n enabled: (c) => interaction(c) != null,\n },\n {\n id: 'pointer:toggle',\n labelKey: 'commands.pointer',\n icon: 'pointer',\n categories: ['tools'],\n run: (c) => interaction(c)?.activateTool('pointer'),\n active: (c) => interaction(c)?.activeToolId() === 'pointer',\n enabled: (c) => interaction(c) != null,\n },\n\n // ── panels (declarative shell targets) ──────────────────────────────────\n {\n id: 'panel:sidebar',\n labelKey: 'commands.sidebar',\n icon: 'sidebar',\n categories: ['panel'],\n panel: { id: 'sidebar', exclusive: 'left' },\n },\n {\n id: 'panel:search',\n labelKey: 'commands.search',\n icon: 'search',\n categories: ['panel'],\n panel: { id: 'search', exclusive: 'right' },\n },\n {\n id: 'panel:comment',\n labelKey: 'commands.comment',\n icon: 'comment',\n categories: ['panel'],\n panel: { id: 'comment', exclusive: 'right' },\n },\n {\n id: 'panel:annotation-style',\n labelKey: 'commands.style',\n icon: 'palette',\n categories: ['panel'],\n panel: { id: 'annotation-style', exclusive: 'right' },\n },\n\n // ── menus (declarative) ─────────────────────────────────────────────────\n {\n id: 'document:menu',\n labelKey: 'commands.menu',\n icon: 'menu',\n categories: ['document'],\n menu: 'document',\n },\n {\n id: 'page:settings',\n labelKey: 'commands.viewControls',\n icon: 'viewSettings',\n categories: ['page'],\n menu: 'page-settings',\n },\n\n // ── document actions ────────────────────────────────────────────────────\n {\n id: 'document:download',\n labelKey: 'commands.download',\n icon: 'download',\n categories: ['document'],\n run: (c) => {\n const id = c.documentId ?? undefined;\n c.tryGet(DocumentsToken)\n ?.download(id)\n .then((bytes) => {\n const blob = new Blob([bytes as BlobPart], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'document.pdf';\n a.click();\n URL.revokeObjectURL(url);\n })\n .catch((e) => console.warn('[snippet-react] download failed', e));\n },\n enabled: (c) => c.tryGet(DocumentsToken) != null && c.documentId != null,\n },\n {\n id: 'document:print',\n labelKey: 'commands.print',\n icon: 'print',\n shortcut: 'Mod+p',\n categories: ['document'],\n run: () => window.print(),\n },\n {\n id: 'document:fullscreen',\n labelKey: 'commands.fullscreen',\n icon: 'externalLink',\n categories: ['document'],\n run: () => {\n if (document.fullscreenElement) document.exitFullscreen();\n else document.documentElement.requestFullscreen().catch(() => {});\n },\n active: () => Boolean(document.fullscreenElement),\n },\n\n // ── page settings (spread / scroll / rotate) ────────────────────────────\n spread('spread:none', 'none', 'commands.spread.none', 'singlePage'),\n spread('spread:odd', 'odd', 'commands.spread.odd', 'doublePage'),\n spread('spread:even', 'even', 'commands.spread.even', 'book2'),\n {\n id: 'scroll:vertical',\n labelKey: 'commands.scroll.vertical',\n icon: 'vertical',\n categories: ['page', 'scroll'],\n run: (c) => stage(c)?.setLayout('vertical'),\n active: (c) => stage(c)?.layout() === 'vertical',\n enabled: (c) => stage(c) != null,\n },\n {\n id: 'scroll:horizontal',\n labelKey: 'commands.scroll.horizontal',\n icon: 'horizontal',\n categories: ['page', 'scroll'],\n run: (c) => stage(c)?.setLayout('horizontal'),\n active: (c) => stage(c)?.layout() === 'horizontal',\n enabled: (c) => stage(c) != null,\n },\n // VIEW rotation (Adobe's \"Rotate View\"): rotates how every page displays in\n // the main stage lens — non-persistent, nothing written to the PDF. The\n // PERMANENT per-page rotation (PageEditToken.rotateBy) belongs in a\n // page-organize surface, not behind the view-settings buttons.\n {\n id: 'rotate:clockwise',\n labelKey: 'commands.rotate.clockwise',\n icon: 'rotateClockwise',\n categories: ['page', 'rotate'],\n run: (c) => stage(c)?.rotateView(90),\n enabled: (c) => stage(c) != null,\n },\n {\n id: 'rotate:counter-clockwise',\n labelKey: 'commands.rotate.counterclockwise',\n icon: 'rotateCounterClockwise',\n categories: ['page', 'rotate'],\n run: (c) => stage(c)?.rotateView(-90),\n enabled: (c) => stage(c) != null,\n },\n\n // ── modes (shell exclusive surfaces, tag 'mode') ────────────────────────\n {\n id: 'mode:view',\n labelKey: 'commands.mode.view',\n categories: ['mode'],\n // View = no mode band. Close any open mode surface and drop to pointer.\n run: (c) => {\n const shell = c.tryGet(ShellToken);\n for (const m of MODE_SURFACES) shell?.close(m);\n interaction(c)?.activateTool('pointer');\n },\n active: (c) => {\n const shell = c.tryGet(ShellToken);\n return shell ? MODE_SURFACES.every((m) => !shell.isOpen(m)) : true;\n },\n },\n modeCommand('mode:annotate', 'commands.mode.annotate'),\n modeCommand('mode:shapes', 'commands.mode.shapes'),\n modeCommand('mode:insert', 'commands.mode.insert'),\n modeCommand('mode:form', 'commands.mode.form', 'form-edit'),\n modeCommand('mode:redact', 'commands.mode.redact'),\n\n // ── annotate tools (real interaction tools) ─────────────────────────────\n tool('annotation:add-highlight', 'highlight', 'commands.annotate.highlight', 'highlight', {\n primary: 'color',\n }),\n tool('annotation:add-strikeout', 'strikeout', 'commands.annotate.strikeout', 'strikethrough', {\n primary: 'color',\n }),\n tool('annotation:add-underline', 'underline', 'commands.annotate.underline', 'underline', {\n primary: 'color',\n }),\n tool('annotation:add-squiggly', 'squiggly', 'commands.annotate.squiggly', 'squiggly', {\n primary: 'color',\n }),\n tool('annotation:add-ink', 'ink', 'commands.annotate.ink', 'pencilMarker', {\n primary: 'color',\n }),\n tool(\n 'annotation:add-ink-highlight',\n 'ink-highlight',\n 'commands.annotate.inkHighlight',\n 'inkHighlighter',\n { primary: 'color' },\n ),\n tool('annotation:add-text', 'free-text', 'commands.annotate.text', 'freeText', {\n primary: 'fontColor',\n }),\n tool('annotation:add-insert-text', 'insert-text', 'commands.annotate.insertText', 'insertText', {\n primary: 'color',\n }),\n tool(\n 'annotation:add-replace-text',\n 'replace-text',\n 'commands.annotate.replaceText',\n 'replaceText',\n { primary: 'color' },\n ),\n tool('annotation:add-callout', 'free-text-callout', 'commands.annotate.callout', 'callout', {\n primary: 'color',\n secondary: 'interiorColor',\n }),\n // Sticky note (\"comment\") — click-to-place; the icon renders from the\n // engine-baked /AP in the tool's current color.\n tool('annotation:add-note', 'note', 'commands.annotate.note', 'message'),\n // Link — drag an invisible hit rectangle, then set the target in the style\n // panel's Link control (create-then-edit). While active, existing links\n // become editable rects instead of navigating.\n tool('annotation:add-link', 'link', 'commands.annotate.link', 'link'),\n\n // ── shape tools (real interaction tools) ────────────────────────────────\n tool('annotation:add-rectangle', 'square', 'commands.shapes.rectangle', 'square', {\n primary: 'color',\n secondary: 'interiorColor',\n }),\n tool('annotation:add-circle', 'circle', 'commands.shapes.circle', 'circle', {\n primary: 'color',\n secondary: 'interiorColor',\n }),\n tool('annotation:add-line', 'line', 'commands.shapes.line', 'line', { primary: 'color' }),\n // The arrow tool is a `line` preset (a line with an arrowhead) — registered by\n // the annotationPlugin `tools` config in App.tsx, activated like any other tool.\n tool('annotation:add-arrow', 'arrow', 'commands.shapes.arrow', 'lineArrow', {\n primary: 'color',\n }),\n tool('annotation:add-polygon', 'polygon', 'commands.shapes.polygon', 'polygon', {\n primary: 'color',\n secondary: 'interiorColor',\n }),\n tool('annotation:add-polyline', 'polyline', 'commands.shapes.polyline', 'zigzag', {\n primary: 'color',\n }),\n\n // ── insert tools (stamp/attachment real; signature/image inert) ─────────\n tool('insert:add-stamp', 'stamp', 'commands.insert.stamp', 'rubberStamp'),\n // File attachment — click the spot, pick the file (the attachment provider).\n tool('insert:add-attachment', 'attachment', 'commands.insert.attachment', 'paperclip'),\n tool('insert:add-signature', 'signature', 'commands.insert.signature', 'signature'),\n tool('insert:add-image', 'image', 'commands.insert.image', 'photo'),\n\n // ── form tools (the form plugin's draw-to-place palette) ────────────────\n tool('form:add-textfield', 'form-text', 'commands.form.textfield', 'formTextfield'),\n tool('form:add-checkbox', 'form-checkbox', 'commands.form.checkbox', 'formCheckbox'),\n tool('form:add-radio', 'form-radio', 'commands.form.radio', 'formRadio'),\n tool('form:add-select', 'form-combobox', 'commands.form.select', 'formSelect'),\n tool('form:add-listbox', 'form-listbox', 'commands.form.listbox', 'formListbox'),\n\n // ── redaction (v2 parity: the toolbar arms the tool; the panel owns the\n // destructive verbs — Apply All / Clear live in the redaction sidebar) ────\n tool('redaction:redact', 'redact', 'commands.redact.mark', 'redactArea'),\n {\n id: 'panel:redaction',\n labelKey: 'commands.redact.panel',\n icon: 'redactionSidebar',\n categories: ['panel'],\n panel: { id: 'redaction', exclusive: 'right' },\n },\n\n // ── annotation selection (the floating strip's verbs) ──────────────────\n {\n id: 'annotation:delete',\n labelKey: 'commands.annotate.delete',\n icon: 'trash',\n categories: ['annotation'],\n run: (c) => {\n const a = anno(c);\n if (!a) return;\n const form = c.tryGet(FormToken);\n const dtos = a.getSelected();\n const widgets = form ? dtos.filter((d) => d.subtype === 'widget') : [];\n if (widgets.length === 0) {\n a.deleteSelection();\n return;\n }\n // Widgets are FIELD-plane citizens: deleting one goes through doc.forms\n // (the field and every widget of it cascade), never the raw annotation —\n // otherwise the /AcroForm entry would be orphaned.\n const keys = new Set<string>();\n for (const w of widgets) {\n const objnum = w.ref.kind === 'objectNumber' ? w.ref.annotObjectNumber : 0;\n const field = objnum > 0 ? form!.fieldForWidget(objnum) : null;\n if (field) keys.add(fieldKeyOf(field));\n }\n for (const key of keys) void form!.deleteField(key);\n for (const d of dtos) if (d.subtype !== 'widget') void a.delete(d.ref);\n a.deselect();\n },\n visible: hasAnnotationSelection,\n // Mirrors the engine's own authorization: locked/unauthorized annotations\n // keep the button visible but disabled (the engine still enforces).\n enabled: (c) => {\n const a = anno(c);\n const refs = a?.getSelection() ?? [];\n return refs.length > 0 && refs.every((r) => a!.canDelete(r));\n },\n },\n {\n id: 'annotation:comment',\n labelKey: 'commands.comment',\n icon: 'comment',\n categories: ['annotation'],\n // Same 'comment' surface panel:comment toggles — `active` derives from it.\n panel: { id: 'comment', exclusive: 'right' },\n visible: (c) => hasAnnotationSelection(c) && !selectionSubtypes(c).has('widget'),\n },\n {\n id: 'annotation:style',\n labelKey: 'commands.style',\n icon: 'palette',\n categories: ['annotation'],\n panel: { id: 'annotation-style', exclusive: 'right' },\n // The kind table decides: no declared editable props → no style button\n // (v2 hardcoded a subtype blocklist for this).\n visible: (c) => (anno(c)?.getSelectionProps().specs.length ?? 0) > 0,\n },\n {\n id: 'annotation:group',\n labelKey: 'commands.annotate.group',\n icon: 'group',\n categories: ['annotation'],\n run: (c) => void anno(c)?.group(),\n visible: (c) => anno(c)?.canGroup() ?? false,\n },\n {\n id: 'annotation:ungroup',\n labelKey: 'commands.annotate.ungroup',\n icon: 'ungroup',\n categories: ['annotation'],\n run: (c) => void anno(c)?.ungroup(),\n visible: (c) => anno(c)?.canUngroup() ?? false,\n },\n\n // ── link strip items (v2's \"Link / Go to link / Remove link\") ───────────\n {\n // Make the selection a link: opens the style panel, whose Link control\n // sets the target (create-then-edit — the plugin materializes the\n // attached child annotations).\n id: 'annotation:link',\n labelKey: 'commands.annotate.link',\n icon: 'link',\n categories: ['annotation'],\n panel: { id: 'annotation-style', exclusive: 'right' },\n visible: (c) => selectionLink(c) === null,\n },\n {\n id: 'annotation:goto-link',\n labelKey: 'commands.annotate.gotoLink',\n icon: 'externalLink',\n categories: ['annotation'],\n run: (c) => {\n const target = selectionLink(c);\n if (target) c.tryGet(LinkToken)?.activate(target);\n },\n visible: (c) => selectionLink(c) != null,\n },\n {\n id: 'annotation:remove-link',\n labelKey: 'commands.annotate.removeLink',\n icon: 'linkOff',\n categories: ['annotation'],\n run: (c) => anno(c)?.updateSelection({ link: null }),\n visible: (c) => selectionLink(c) != null,\n },\n\n // ── history (no plugin yet → disabled, shows the disabled styling) ──────\n {\n id: 'history:undo',\n labelKey: 'commands.undo',\n icon: 'arrowBackUp',\n categories: ['history'],\n run: () => {},\n enabled: () => false,\n },\n {\n id: 'history:redo',\n labelKey: 'commands.redo',\n icon: 'arrowForwardUp',\n categories: ['history'],\n run: () => {},\n enabled: () => false,\n },\n];\n\n// ── mode helpers ─────────────────────────────────────────────────────────────\n// Modes are exclusive shell surfaces tagged 'mode'; the secondary band renders\n// whichever one is open. Kept below the array to keep the list readable.\nexport const MODE_SURFACES = [\n 'mode:annotate',\n 'mode:shapes',\n 'mode:insert',\n 'mode:form',\n 'mode:redact',\n] as const;\n\nfunction modeCommand(\n id: (typeof MODE_SURFACES)[number],\n labelKey: string,\n toolId: string = 'pointer',\n): CommandDef {\n return {\n id,\n labelKey,\n categories: ['mode'],\n // A mode tab is a shell surface AND a tool policy: the Form tab flips the\n // pointer into form design ('form-edit' — widgets select/move/resize like\n // annotations); every other tab (and closing one) drops back to the\n // default pointer, where widgets are fill controls again.\n run: (c) => {\n const shell = c.tryGet(ShellToken);\n shell?.toggle(id, { exclusive: 'mode' });\n interaction(c)?.activateTool(shell?.isOpen(id) ? toolId : 'pointer');\n },\n active: (c) => c.tryGet(ShellToken)?.isOpen(id) ?? false,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CommandDef } from "@embedpdf/react/commands";
|
|
2
|
+
//#region src/config/commands.d.ts
|
|
3
|
+
type ColorKey = 'color' | 'interiorColor' | 'fontColor';
|
|
4
|
+
interface ToolAccentDefinition {
|
|
5
|
+
primary: ColorKey;
|
|
6
|
+
secondary?: ColorKey;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* toolId → the SAME icon + accent definition its toolbar button uses, recorded
|
|
10
|
+
* as a side effect of the `tool()` command definitions below — ONE source of
|
|
11
|
+
* truth, so the tool cursor (ui/tool-cursor.tsx) and the button can never
|
|
12
|
+
* drift apart.
|
|
13
|
+
*/
|
|
14
|
+
declare const TOOL_ICONS: Record<string, {
|
|
15
|
+
icon: string;
|
|
16
|
+
accent?: ToolAccentDefinition;
|
|
17
|
+
}>;
|
|
18
|
+
declare const defaultCommands: CommandDef[];
|
|
19
|
+
declare const MODE_SURFACES: readonly ["mode:annotate", "mode:shapes", "mode:insert", "mode:form", "mode:redact"];
|
|
20
|
+
//#endregion
|
|
21
|
+
export { MODE_SURFACES, TOOL_ICONS, ToolAccentDefinition, defaultCommands };
|
|
22
|
+
//# sourceMappingURL=commands.d.cts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CommandDef } from "@embedpdf/react/commands";
|
|
2
|
+
//#region src/config/commands.d.ts
|
|
3
|
+
type ColorKey = 'color' | 'interiorColor' | 'fontColor';
|
|
4
|
+
interface ToolAccentDefinition {
|
|
5
|
+
primary: ColorKey;
|
|
6
|
+
secondary?: ColorKey;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* toolId → the SAME icon + accent definition its toolbar button uses, recorded
|
|
10
|
+
* as a side effect of the `tool()` command definitions below — ONE source of
|
|
11
|
+
* truth, so the tool cursor (ui/tool-cursor.tsx) and the button can never
|
|
12
|
+
* drift apart.
|
|
13
|
+
*/
|
|
14
|
+
declare const TOOL_ICONS: Record<string, {
|
|
15
|
+
icon: string;
|
|
16
|
+
accent?: ToolAccentDefinition;
|
|
17
|
+
}>;
|
|
18
|
+
declare const defaultCommands: CommandDef[];
|
|
19
|
+
declare const MODE_SURFACES: readonly ["mode:annotate", "mode:shapes", "mode:insert", "mode:form", "mode:redact"];
|
|
20
|
+
//#endregion
|
|
21
|
+
export { MODE_SURFACES, TOOL_ICONS, ToolAccentDefinition, defaultCommands };
|
|
22
|
+
//# sourceMappingURL=commands.d.ts.map
|