@embedpdf/viewer-chrome 3.0.0-next.13 → 3.0.0-next.14
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/chrome.cjs +22 -1
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.d.cts +1 -0
- package/dist/chrome.d.ts +1 -0
- package/dist/chrome.js +22 -1
- package/dist/chrome.js.map +1 -1
- package/dist/commands.cjs +55 -1
- package/dist/commands.cjs.map +1 -1
- package/dist/commands.d.cts +1 -1
- package/dist/commands.d.ts +1 -1
- package/dist/commands.js +55 -1
- package/dist/commands.js.map +1 -1
- package/dist/{es-DYwzfxyt.cjs → es-BXLlBo2b.cjs} +29 -1
- package/dist/es-BXLlBo2b.cjs.map +1 -0
- package/dist/{es-sN6uqBgD.js → es-CLgTsFDS.js} +29 -1
- package/dist/es-CLgTsFDS.js.map +1 -0
- package/dist/index.cjs +428 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +423 -8
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/es-DYwzfxyt.cjs.map +0 -1
- package/dist/es-sN6uqBgD.js.map +0 -1
package/dist/chrome.cjs
CHANGED
|
@@ -53,6 +53,10 @@ const mainBar = {
|
|
|
53
53
|
(0, _embedpdf_react_toolbar.item)("mode:redact", {
|
|
54
54
|
variants: ["label"],
|
|
55
55
|
importance: 1
|
|
56
|
+
}),
|
|
57
|
+
(0, _embedpdf_react_toolbar.item)("mode:measure", {
|
|
58
|
+
variants: ["label"],
|
|
59
|
+
importance: 1
|
|
56
60
|
})
|
|
57
61
|
]
|
|
58
62
|
})],
|
|
@@ -124,6 +128,22 @@ const formBar = {
|
|
|
124
128
|
history
|
|
125
129
|
] }
|
|
126
130
|
};
|
|
131
|
+
const measureBar = {
|
|
132
|
+
id: "measure",
|
|
133
|
+
sections: { center: [
|
|
134
|
+
(0, _embedpdf_react_toolbar.group)("measure", { importance: 5 }, [
|
|
135
|
+
"measurement:distance",
|
|
136
|
+
"measurement:perimeter",
|
|
137
|
+
"measurement:area",
|
|
138
|
+
"measurement:calibrate"
|
|
139
|
+
]),
|
|
140
|
+
(0, _embedpdf_react_toolbar.group)("scale", { importance: 4 }, [(0, _embedpdf_react_toolbar.custom)("measurement-scale", {
|
|
141
|
+
variants: ["inline"],
|
|
142
|
+
terminal: "panel:measurement"
|
|
143
|
+
})]),
|
|
144
|
+
style
|
|
145
|
+
] }
|
|
146
|
+
};
|
|
127
147
|
const redactBar = {
|
|
128
148
|
id: "redact",
|
|
129
149
|
sections: { center: [
|
|
@@ -208,7 +228,8 @@ const defaultChrome = (0, _embedpdf_react_toolbar.defineChrome)({
|
|
|
208
228
|
"mode:shapes": shapesBar,
|
|
209
229
|
"mode:insert": insertBar,
|
|
210
230
|
"mode:form": formBar,
|
|
211
|
-
"mode:redact": redactBar
|
|
231
|
+
"mode:redact": redactBar,
|
|
232
|
+
"mode:measure": measureBar
|
|
212
233
|
},
|
|
213
234
|
menus: {
|
|
214
235
|
document: documentMenu,
|
package/dist/chrome.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chrome.cjs","names":[],"sources":["../src/config/chrome.ts"],"sourcesContent":["/**\n * The chrome — structure only. No breakpoints, no show/hide lists, no locale\n * overrides, no dividers/spacers, no hand-written overflow menus. What fits is\n * measured and solved at runtime (@embedpdf/core-ui); the overflow menu is\n * derived. Compare to the v2 snippet's 1,950-line ui-schema.ts.\n *\n * `importance` (1 sheds first … 5 pinned) is the only responsive knob.\n */\nimport {\n defineChrome,\n group,\n item,\n custom,\n type BarSchema,\n type ChromeSchema,\n type MenuSchema,\n} from '@embedpdf/react/toolbar';\n\n// Reused across every mode band — plain values, so composition is just a const.\nconst style = group('style', { importance: 4 }, [item('panel:annotation-style')]);\nconst history = group('history', { importance: 3 }, ['history:undo', 'history:redo']);\n\n// ── main toolbar ─────────────────────────────────────────────────────────────\nconst mainBar: BarSchema = {\n id: 'main',\n sections: {\n // v2 layout: everything before the first spacer sits LEFT-aligned —\n // document menu, workspace, zoom strip, pan/pointer. Only the mode tabs\n // are truly centered.\n start: [\n group('document', { importance: 5 }, [item('document:menu')]),\n group('workspace', { importance: 4 }, [\n item('panel:sidebar', { importance: 5 }),\n item('page:settings'),\n ]),\n // The inline zoom strip; when it can't fit it renders its 'button'\n // variant, and in the overflow menu it projects through zoom:menu.\n group('zoom', { importance: 4 }, [\n custom('zoom-controls', { variants: ['inline', 'button'], terminal: 'zoom:menu' }),\n ]),\n group('tools', { importance: 2 }, ['pan:toggle', 'pointer:toggle']),\n ],\n center: [\n group('modes', {\n role: 'tabs',\n // The group ladder: full strip → trailing tabs shed behind a derived\n // in-strip chevron (v2's overflow-tabs-button) → select (v2's\n // mode-select-button) → global overflow. Tab items at importance 1 so\n // the strip is the FIRST thing to compact; the group at 4 so its\n // compact forms survive long.\n shed: true,\n collapse: 'select',\n importance: 4,\n labelKey: 'commands.mode.group',\n items: [\n item('mode:view', { variants: ['label'], importance: 1 }),\n item('mode:annotate', { variants: ['label'], importance: 1 }),\n item('mode:shapes', { variants: ['label'], importance: 1 }),\n item('mode:insert', { variants: ['label'], importance: 1 }),\n item('mode:form', { variants: ['label'], importance: 1 }),\n item('mode:redact', { variants: ['label'], importance: 1 }),\n ],\n }),\n ],\n end: [group('panels', { importance: 5 }, ['panel:search', 'panel:comment'])],\n },\n};\n\n// ── secondary bands (one per mode; which shows is derived from shell) ────────\nconst annotateBar: BarSchema = {\n id: 'annotate',\n sections: {\n center: [\n group('comment', { importance: 4 }, ['annotation:add-note', 'annotation:add-link']),\n group('markup', { importance: 4 }, [\n 'annotation:add-highlight',\n 'annotation:add-strikeout',\n 'annotation:add-underline',\n 'annotation:add-squiggly',\n ]),\n group('draw', { importance: 3 }, ['annotation:add-ink', 'annotation:add-ink-highlight']),\n group('text', { importance: 2 }, [\n 'annotation:add-text',\n 'annotation:add-insert-text',\n 'annotation:add-replace-text',\n 'annotation:add-callout',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst shapesBar: BarSchema = {\n id: 'shapes',\n sections: {\n center: [\n group('shapes', { importance: 4 }, [\n 'annotation:add-rectangle',\n 'annotation:add-circle',\n 'annotation:add-line',\n 'annotation:add-arrow',\n ]),\n group('polygons', { importance: 2 }, ['annotation:add-polygon', 'annotation:add-polyline']),\n style,\n history,\n ],\n },\n};\n\nconst insertBar: BarSchema = {\n id: 'insert',\n sections: {\n center: [\n group('stamps', { importance: 4 }, [\n 'insert:add-stamp',\n // Quick marks (`stamps.toolbar`): thumbnails that arm on click; in a\n // menu the stamps panel stands in for them.\n custom('quick-stamps', { terminal: 'insert:add-stamp', importance: 3 }),\n 'insert:add-attachment',\n 'insert:add-signature',\n 'insert:add-image',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst formBar: BarSchema = {\n id: 'form',\n sections: {\n center: [\n group('fields', { importance: 4 }, [\n 'form:add-textfield',\n 'form:add-checkbox',\n 'form:add-radio',\n ]),\n group('choice-fields', { importance: 2 }, ['form:add-select', 'form:add-listbox']),\n group('signature-fields', { importance: 2 }, ['form:add-signature']),\n history,\n ],\n },\n};\n\nconst redactBar: BarSchema = {\n id: 'redact',\n sections: {\n center: [\n group('redact', { importance: 4 }, ['redaction:redact', 'panel:redaction']),\n style,\n history,\n ],\n },\n};\n\n// ── menus (command trees; separators derive between sections) ────────────────\nconst documentMenu: MenuSchema = {\n id: 'document',\n sections: [\n { items: ['document:download', 'document:print'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\nconst zoomMenu: MenuSchema = {\n id: 'zoom',\n sections: [\n {\n labelKey: 'commands.zoom.level',\n items: ['zoom:50', 'zoom:100', 'zoom:150', 'zoom:200', 'zoom:400'],\n },\n { items: ['zoom:in', 'zoom:out'] },\n { items: ['zoom:fit-page', 'zoom:fit-width', 'zoom:automatic'] },\n ],\n};\n\nconst pageSettingsMenu: MenuSchema = {\n id: 'page-settings',\n sections: [\n { labelKey: 'commands.spread.group', items: ['spread:none', 'spread:odd', 'spread:even'] },\n { labelKey: 'commands.scroll.group', items: ['scroll:vertical', 'scroll:horizontal'] },\n { labelKey: 'commands.rotate.group', items: ['rotate:clockwise', 'rotate:counter-clockwise'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\n// ── contextual strips (anchored to selections; same BarSchema vocabulary) ────\n// WHICH commands actually show is each command's `visible` derivation (group\n// only when groupable, style only when the kind declares editable props…), so\n// one strip serves single AND multi selection — v2 needed two schemas for that.\nconst annotationStrip: BarSchema = {\n id: 'annotation-strip',\n sections: {\n center: [\n group('annotation-actions', { importance: 4 }, [\n 'annotation:comment',\n 'annotation:style',\n 'annotation:stamp-from-selection',\n 'annotation:link',\n 'annotation:goto-link',\n 'annotation:remove-link',\n 'annotation:group',\n 'annotation:ungroup',\n ]),\n // Its own group → a derived separator; delete stands apart.\n group('annotation-danger', { importance: 5 }, ['annotation:delete']),\n ],\n },\n};\n\n// The text-selection strip: appears when a text selection SETTLES (the menu\n// component gates on `isSelecting()`). One command today; \"Highlight\" et al.\n// are one more id here + one command — no component changes.\nconst selectionStrip: BarSchema = {\n id: 'selection-strip',\n sections: {\n center: [group('selection-actions', { importance: 4 }, ['selection:copy'])],\n },\n};\n\n/**\n * The DEFAULT chrome — exported as a VALUE, which is the whole customization\n * model: consumers pass nothing and track this, transform it, or write their\n * own. It is never merged with anything.\n */\nexport const defaultChrome = defineChrome({\n bars: { main: mainBar },\n modeBars: {\n 'mode:annotate': annotateBar,\n 'mode:shapes': shapesBar,\n 'mode:insert': insertBar,\n 'mode:form': formBar,\n 'mode:redact': redactBar,\n },\n menus: { document: documentMenu, zoom: zoomMenu, 'page-settings': pageSettingsMenu },\n strips: { annotation: annotationStrip, selection: selectionStrip },\n});\n\n// Lookups take the RESOLVED schema (the host may have replaced the default) —\n// the typed literal widens to arbitrary string keys here, once.\n\n/** Menu lookup by id (arbitrary string). */\nexport function getMenu(schema: ChromeSchema, id: string): MenuSchema | undefined {\n return (schema.menus as Record<string, MenuSchema> | undefined)?.[id];\n}\n\n/** Secondary band lookup by mode-surface id. */\nexport function getModeBar(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.modeBars as Record<string, BarSchema> | undefined)?.[id];\n}\n\n/** Contextual strip lookup by context id ('annotation', …). */\nexport function getStrip(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.strips as Record<string, BarSchema> | undefined)?.[id];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chrome.cjs","names":[],"sources":["../src/config/chrome.ts"],"sourcesContent":["/**\n * The chrome — structure only. No breakpoints, no show/hide lists, no locale\n * overrides, no dividers/spacers, no hand-written overflow menus. What fits is\n * measured and solved at runtime (@embedpdf/core-ui); the overflow menu is\n * derived. Compare to the v2 snippet's 1,950-line ui-schema.ts.\n *\n * `importance` (1 sheds first … 5 pinned) is the only responsive knob.\n */\nimport {\n defineChrome,\n group,\n item,\n custom,\n type BarSchema,\n type ChromeSchema,\n type MenuSchema,\n} from '@embedpdf/react/toolbar';\n\n// Reused across every mode band — plain values, so composition is just a const.\nconst style = group('style', { importance: 4 }, [item('panel:annotation-style')]);\nconst history = group('history', { importance: 3 }, ['history:undo', 'history:redo']);\n\n// ── main toolbar ─────────────────────────────────────────────────────────────\nconst mainBar: BarSchema = {\n id: 'main',\n sections: {\n // v2 layout: everything before the first spacer sits LEFT-aligned —\n // document menu, workspace, zoom strip, pan/pointer. Only the mode tabs\n // are truly centered.\n start: [\n group('document', { importance: 5 }, [item('document:menu')]),\n group('workspace', { importance: 4 }, [\n item('panel:sidebar', { importance: 5 }),\n item('page:settings'),\n ]),\n // The inline zoom strip; when it can't fit it renders its 'button'\n // variant, and in the overflow menu it projects through zoom:menu.\n group('zoom', { importance: 4 }, [\n custom('zoom-controls', { variants: ['inline', 'button'], terminal: 'zoom:menu' }),\n ]),\n group('tools', { importance: 2 }, ['pan:toggle', 'pointer:toggle']),\n ],\n center: [\n group('modes', {\n role: 'tabs',\n // The group ladder: full strip → trailing tabs shed behind a derived\n // in-strip chevron (v2's overflow-tabs-button) → select (v2's\n // mode-select-button) → global overflow. Tab items at importance 1 so\n // the strip is the FIRST thing to compact; the group at 4 so its\n // compact forms survive long.\n shed: true,\n collapse: 'select',\n importance: 4,\n labelKey: 'commands.mode.group',\n items: [\n item('mode:view', { variants: ['label'], importance: 1 }),\n item('mode:annotate', { variants: ['label'], importance: 1 }),\n item('mode:shapes', { variants: ['label'], importance: 1 }),\n item('mode:insert', { variants: ['label'], importance: 1 }),\n item('mode:form', { variants: ['label'], importance: 1 }),\n item('mode:redact', { variants: ['label'], importance: 1 }),\n item('mode:measure', { variants: ['label'], importance: 1 }),\n ],\n }),\n ],\n end: [group('panels', { importance: 5 }, ['panel:search', 'panel:comment'])],\n },\n};\n\n// ── secondary bands (one per mode; which shows is derived from shell) ────────\nconst annotateBar: BarSchema = {\n id: 'annotate',\n sections: {\n center: [\n group('comment', { importance: 4 }, ['annotation:add-note', 'annotation:add-link']),\n group('markup', { importance: 4 }, [\n 'annotation:add-highlight',\n 'annotation:add-strikeout',\n 'annotation:add-underline',\n 'annotation:add-squiggly',\n ]),\n group('draw', { importance: 3 }, ['annotation:add-ink', 'annotation:add-ink-highlight']),\n group('text', { importance: 2 }, [\n 'annotation:add-text',\n 'annotation:add-insert-text',\n 'annotation:add-replace-text',\n 'annotation:add-callout',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst shapesBar: BarSchema = {\n id: 'shapes',\n sections: {\n center: [\n group('shapes', { importance: 4 }, [\n 'annotation:add-rectangle',\n 'annotation:add-circle',\n 'annotation:add-line',\n 'annotation:add-arrow',\n ]),\n group('polygons', { importance: 2 }, ['annotation:add-polygon', 'annotation:add-polyline']),\n style,\n history,\n ],\n },\n};\n\nconst insertBar: BarSchema = {\n id: 'insert',\n sections: {\n center: [\n group('stamps', { importance: 4 }, [\n 'insert:add-stamp',\n // Quick marks (`stamps.toolbar`): thumbnails that arm on click; in a\n // menu the stamps panel stands in for them.\n custom('quick-stamps', { terminal: 'insert:add-stamp', importance: 3 }),\n 'insert:add-attachment',\n 'insert:add-signature',\n 'insert:add-image',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst formBar: BarSchema = {\n id: 'form',\n sections: {\n center: [\n group('fields', { importance: 4 }, [\n 'form:add-textfield',\n 'form:add-checkbox',\n 'form:add-radio',\n ]),\n group('choice-fields', { importance: 2 }, ['form:add-select', 'form:add-listbox']),\n group('signature-fields', { importance: 2 }, ['form:add-signature']),\n history,\n ],\n },\n};\n\nconst measureBar: BarSchema = {\n id: 'measure',\n sections: {\n center: [\n group('measure', { importance: 5 }, [\n 'measurement:distance',\n 'measurement:perimeter',\n 'measurement:area',\n 'measurement:calibrate',\n ]),\n group('scale', { importance: 4 }, [\n custom('measurement-scale', { variants: ['inline'], terminal: 'panel:measurement' }),\n ]),\n style,\n ],\n },\n};\n\nconst redactBar: BarSchema = {\n id: 'redact',\n sections: {\n center: [\n group('redact', { importance: 4 }, ['redaction:redact', 'panel:redaction']),\n style,\n history,\n ],\n },\n};\n\n// ── menus (command trees; separators derive between sections) ────────────────\nconst documentMenu: MenuSchema = {\n id: 'document',\n sections: [\n { items: ['document:download', 'document:print'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\nconst zoomMenu: MenuSchema = {\n id: 'zoom',\n sections: [\n {\n labelKey: 'commands.zoom.level',\n items: ['zoom:50', 'zoom:100', 'zoom:150', 'zoom:200', 'zoom:400'],\n },\n { items: ['zoom:in', 'zoom:out'] },\n { items: ['zoom:fit-page', 'zoom:fit-width', 'zoom:automatic'] },\n ],\n};\n\nconst pageSettingsMenu: MenuSchema = {\n id: 'page-settings',\n sections: [\n { labelKey: 'commands.spread.group', items: ['spread:none', 'spread:odd', 'spread:even'] },\n { labelKey: 'commands.scroll.group', items: ['scroll:vertical', 'scroll:horizontal'] },\n { labelKey: 'commands.rotate.group', items: ['rotate:clockwise', 'rotate:counter-clockwise'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\n// ── contextual strips (anchored to selections; same BarSchema vocabulary) ────\n// WHICH commands actually show is each command's `visible` derivation (group\n// only when groupable, style only when the kind declares editable props…), so\n// one strip serves single AND multi selection — v2 needed two schemas for that.\nconst annotationStrip: BarSchema = {\n id: 'annotation-strip',\n sections: {\n center: [\n group('annotation-actions', { importance: 4 }, [\n 'annotation:comment',\n 'annotation:style',\n 'annotation:stamp-from-selection',\n 'annotation:link',\n 'annotation:goto-link',\n 'annotation:remove-link',\n 'annotation:group',\n 'annotation:ungroup',\n ]),\n // Its own group → a derived separator; delete stands apart.\n group('annotation-danger', { importance: 5 }, ['annotation:delete']),\n ],\n },\n};\n\n// The text-selection strip: appears when a text selection SETTLES (the menu\n// component gates on `isSelecting()`). One command today; \"Highlight\" et al.\n// are one more id here + one command — no component changes.\nconst selectionStrip: BarSchema = {\n id: 'selection-strip',\n sections: {\n center: [group('selection-actions', { importance: 4 }, ['selection:copy'])],\n },\n};\n\n/**\n * The DEFAULT chrome — exported as a VALUE, which is the whole customization\n * model: consumers pass nothing and track this, transform it, or write their\n * own. It is never merged with anything.\n */\nexport const defaultChrome = defineChrome({\n bars: { main: mainBar },\n modeBars: {\n 'mode:annotate': annotateBar,\n 'mode:shapes': shapesBar,\n 'mode:insert': insertBar,\n 'mode:form': formBar,\n 'mode:redact': redactBar,\n 'mode:measure': measureBar,\n },\n menus: { document: documentMenu, zoom: zoomMenu, 'page-settings': pageSettingsMenu },\n strips: { annotation: annotationStrip, selection: selectionStrip },\n});\n\n// Lookups take the RESOLVED schema (the host may have replaced the default) —\n// the typed literal widens to arbitrary string keys here, once.\n\n/** Menu lookup by id (arbitrary string). */\nexport function getMenu(schema: ChromeSchema, id: string): MenuSchema | undefined {\n return (schema.menus as Record<string, MenuSchema> | undefined)?.[id];\n}\n\n/** Secondary band lookup by mode-surface id. */\nexport function getModeBar(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.modeBars as Record<string, BarSchema> | undefined)?.[id];\n}\n\n/** Contextual strip lookup by context id ('annotation', …). */\nexport function getStrip(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.strips as Record<string, BarSchema> | undefined)?.[id];\n}\n"],"mappings":"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"}
|
package/dist/chrome.d.cts
CHANGED
package/dist/chrome.d.ts
CHANGED
package/dist/chrome.js
CHANGED
|
@@ -52,6 +52,10 @@ const mainBar = {
|
|
|
52
52
|
item("mode:redact", {
|
|
53
53
|
variants: ["label"],
|
|
54
54
|
importance: 1
|
|
55
|
+
}),
|
|
56
|
+
item("mode:measure", {
|
|
57
|
+
variants: ["label"],
|
|
58
|
+
importance: 1
|
|
55
59
|
})
|
|
56
60
|
]
|
|
57
61
|
})],
|
|
@@ -123,6 +127,22 @@ const formBar = {
|
|
|
123
127
|
history
|
|
124
128
|
] }
|
|
125
129
|
};
|
|
130
|
+
const measureBar = {
|
|
131
|
+
id: "measure",
|
|
132
|
+
sections: { center: [
|
|
133
|
+
group("measure", { importance: 5 }, [
|
|
134
|
+
"measurement:distance",
|
|
135
|
+
"measurement:perimeter",
|
|
136
|
+
"measurement:area",
|
|
137
|
+
"measurement:calibrate"
|
|
138
|
+
]),
|
|
139
|
+
group("scale", { importance: 4 }, [custom("measurement-scale", {
|
|
140
|
+
variants: ["inline"],
|
|
141
|
+
terminal: "panel:measurement"
|
|
142
|
+
})]),
|
|
143
|
+
style
|
|
144
|
+
] }
|
|
145
|
+
};
|
|
126
146
|
const redactBar = {
|
|
127
147
|
id: "redact",
|
|
128
148
|
sections: { center: [
|
|
@@ -207,7 +227,8 @@ const defaultChrome = defineChrome({
|
|
|
207
227
|
"mode:shapes": shapesBar,
|
|
208
228
|
"mode:insert": insertBar,
|
|
209
229
|
"mode:form": formBar,
|
|
210
|
-
"mode:redact": redactBar
|
|
230
|
+
"mode:redact": redactBar,
|
|
231
|
+
"mode:measure": measureBar
|
|
211
232
|
},
|
|
212
233
|
menus: {
|
|
213
234
|
document: documentMenu,
|
package/dist/chrome.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chrome.js","names":[],"sources":["../src/config/chrome.ts"],"sourcesContent":["/**\n * The chrome — structure only. No breakpoints, no show/hide lists, no locale\n * overrides, no dividers/spacers, no hand-written overflow menus. What fits is\n * measured and solved at runtime (@embedpdf/core-ui); the overflow menu is\n * derived. Compare to the v2 snippet's 1,950-line ui-schema.ts.\n *\n * `importance` (1 sheds first … 5 pinned) is the only responsive knob.\n */\nimport {\n defineChrome,\n group,\n item,\n custom,\n type BarSchema,\n type ChromeSchema,\n type MenuSchema,\n} from '@embedpdf/react/toolbar';\n\n// Reused across every mode band — plain values, so composition is just a const.\nconst style = group('style', { importance: 4 }, [item('panel:annotation-style')]);\nconst history = group('history', { importance: 3 }, ['history:undo', 'history:redo']);\n\n// ── main toolbar ─────────────────────────────────────────────────────────────\nconst mainBar: BarSchema = {\n id: 'main',\n sections: {\n // v2 layout: everything before the first spacer sits LEFT-aligned —\n // document menu, workspace, zoom strip, pan/pointer. Only the mode tabs\n // are truly centered.\n start: [\n group('document', { importance: 5 }, [item('document:menu')]),\n group('workspace', { importance: 4 }, [\n item('panel:sidebar', { importance: 5 }),\n item('page:settings'),\n ]),\n // The inline zoom strip; when it can't fit it renders its 'button'\n // variant, and in the overflow menu it projects through zoom:menu.\n group('zoom', { importance: 4 }, [\n custom('zoom-controls', { variants: ['inline', 'button'], terminal: 'zoom:menu' }),\n ]),\n group('tools', { importance: 2 }, ['pan:toggle', 'pointer:toggle']),\n ],\n center: [\n group('modes', {\n role: 'tabs',\n // The group ladder: full strip → trailing tabs shed behind a derived\n // in-strip chevron (v2's overflow-tabs-button) → select (v2's\n // mode-select-button) → global overflow. Tab items at importance 1 so\n // the strip is the FIRST thing to compact; the group at 4 so its\n // compact forms survive long.\n shed: true,\n collapse: 'select',\n importance: 4,\n labelKey: 'commands.mode.group',\n items: [\n item('mode:view', { variants: ['label'], importance: 1 }),\n item('mode:annotate', { variants: ['label'], importance: 1 }),\n item('mode:shapes', { variants: ['label'], importance: 1 }),\n item('mode:insert', { variants: ['label'], importance: 1 }),\n item('mode:form', { variants: ['label'], importance: 1 }),\n item('mode:redact', { variants: ['label'], importance: 1 }),\n ],\n }),\n ],\n end: [group('panels', { importance: 5 }, ['panel:search', 'panel:comment'])],\n },\n};\n\n// ── secondary bands (one per mode; which shows is derived from shell) ────────\nconst annotateBar: BarSchema = {\n id: 'annotate',\n sections: {\n center: [\n group('comment', { importance: 4 }, ['annotation:add-note', 'annotation:add-link']),\n group('markup', { importance: 4 }, [\n 'annotation:add-highlight',\n 'annotation:add-strikeout',\n 'annotation:add-underline',\n 'annotation:add-squiggly',\n ]),\n group('draw', { importance: 3 }, ['annotation:add-ink', 'annotation:add-ink-highlight']),\n group('text', { importance: 2 }, [\n 'annotation:add-text',\n 'annotation:add-insert-text',\n 'annotation:add-replace-text',\n 'annotation:add-callout',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst shapesBar: BarSchema = {\n id: 'shapes',\n sections: {\n center: [\n group('shapes', { importance: 4 }, [\n 'annotation:add-rectangle',\n 'annotation:add-circle',\n 'annotation:add-line',\n 'annotation:add-arrow',\n ]),\n group('polygons', { importance: 2 }, ['annotation:add-polygon', 'annotation:add-polyline']),\n style,\n history,\n ],\n },\n};\n\nconst insertBar: BarSchema = {\n id: 'insert',\n sections: {\n center: [\n group('stamps', { importance: 4 }, [\n 'insert:add-stamp',\n // Quick marks (`stamps.toolbar`): thumbnails that arm on click; in a\n // menu the stamps panel stands in for them.\n custom('quick-stamps', { terminal: 'insert:add-stamp', importance: 3 }),\n 'insert:add-attachment',\n 'insert:add-signature',\n 'insert:add-image',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst formBar: BarSchema = {\n id: 'form',\n sections: {\n center: [\n group('fields', { importance: 4 }, [\n 'form:add-textfield',\n 'form:add-checkbox',\n 'form:add-radio',\n ]),\n group('choice-fields', { importance: 2 }, ['form:add-select', 'form:add-listbox']),\n group('signature-fields', { importance: 2 }, ['form:add-signature']),\n history,\n ],\n },\n};\n\nconst redactBar: BarSchema = {\n id: 'redact',\n sections: {\n center: [\n group('redact', { importance: 4 }, ['redaction:redact', 'panel:redaction']),\n style,\n history,\n ],\n },\n};\n\n// ── menus (command trees; separators derive between sections) ────────────────\nconst documentMenu: MenuSchema = {\n id: 'document',\n sections: [\n { items: ['document:download', 'document:print'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\nconst zoomMenu: MenuSchema = {\n id: 'zoom',\n sections: [\n {\n labelKey: 'commands.zoom.level',\n items: ['zoom:50', 'zoom:100', 'zoom:150', 'zoom:200', 'zoom:400'],\n },\n { items: ['zoom:in', 'zoom:out'] },\n { items: ['zoom:fit-page', 'zoom:fit-width', 'zoom:automatic'] },\n ],\n};\n\nconst pageSettingsMenu: MenuSchema = {\n id: 'page-settings',\n sections: [\n { labelKey: 'commands.spread.group', items: ['spread:none', 'spread:odd', 'spread:even'] },\n { labelKey: 'commands.scroll.group', items: ['scroll:vertical', 'scroll:horizontal'] },\n { labelKey: 'commands.rotate.group', items: ['rotate:clockwise', 'rotate:counter-clockwise'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\n// ── contextual strips (anchored to selections; same BarSchema vocabulary) ────\n// WHICH commands actually show is each command's `visible` derivation (group\n// only when groupable, style only when the kind declares editable props…), so\n// one strip serves single AND multi selection — v2 needed two schemas for that.\nconst annotationStrip: BarSchema = {\n id: 'annotation-strip',\n sections: {\n center: [\n group('annotation-actions', { importance: 4 }, [\n 'annotation:comment',\n 'annotation:style',\n 'annotation:stamp-from-selection',\n 'annotation:link',\n 'annotation:goto-link',\n 'annotation:remove-link',\n 'annotation:group',\n 'annotation:ungroup',\n ]),\n // Its own group → a derived separator; delete stands apart.\n group('annotation-danger', { importance: 5 }, ['annotation:delete']),\n ],\n },\n};\n\n// The text-selection strip: appears when a text selection SETTLES (the menu\n// component gates on `isSelecting()`). One command today; \"Highlight\" et al.\n// are one more id here + one command — no component changes.\nconst selectionStrip: BarSchema = {\n id: 'selection-strip',\n sections: {\n center: [group('selection-actions', { importance: 4 }, ['selection:copy'])],\n },\n};\n\n/**\n * The DEFAULT chrome — exported as a VALUE, which is the whole customization\n * model: consumers pass nothing and track this, transform it, or write their\n * own. It is never merged with anything.\n */\nexport const defaultChrome = defineChrome({\n bars: { main: mainBar },\n modeBars: {\n 'mode:annotate': annotateBar,\n 'mode:shapes': shapesBar,\n 'mode:insert': insertBar,\n 'mode:form': formBar,\n 'mode:redact': redactBar,\n },\n menus: { document: documentMenu, zoom: zoomMenu, 'page-settings': pageSettingsMenu },\n strips: { annotation: annotationStrip, selection: selectionStrip },\n});\n\n// Lookups take the RESOLVED schema (the host may have replaced the default) —\n// the typed literal widens to arbitrary string keys here, once.\n\n/** Menu lookup by id (arbitrary string). */\nexport function getMenu(schema: ChromeSchema, id: string): MenuSchema | undefined {\n return (schema.menus as Record<string, MenuSchema> | undefined)?.[id];\n}\n\n/** Secondary band lookup by mode-surface id. */\nexport function getModeBar(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.modeBars as Record<string, BarSchema> | undefined)?.[id];\n}\n\n/** Contextual strip lookup by context id ('annotation', …). */\nexport function getStrip(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.strips as Record<string, BarSchema> | undefined)?.[id];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chrome.js","names":[],"sources":["../src/config/chrome.ts"],"sourcesContent":["/**\n * The chrome — structure only. No breakpoints, no show/hide lists, no locale\n * overrides, no dividers/spacers, no hand-written overflow menus. What fits is\n * measured and solved at runtime (@embedpdf/core-ui); the overflow menu is\n * derived. Compare to the v2 snippet's 1,950-line ui-schema.ts.\n *\n * `importance` (1 sheds first … 5 pinned) is the only responsive knob.\n */\nimport {\n defineChrome,\n group,\n item,\n custom,\n type BarSchema,\n type ChromeSchema,\n type MenuSchema,\n} from '@embedpdf/react/toolbar';\n\n// Reused across every mode band — plain values, so composition is just a const.\nconst style = group('style', { importance: 4 }, [item('panel:annotation-style')]);\nconst history = group('history', { importance: 3 }, ['history:undo', 'history:redo']);\n\n// ── main toolbar ─────────────────────────────────────────────────────────────\nconst mainBar: BarSchema = {\n id: 'main',\n sections: {\n // v2 layout: everything before the first spacer sits LEFT-aligned —\n // document menu, workspace, zoom strip, pan/pointer. Only the mode tabs\n // are truly centered.\n start: [\n group('document', { importance: 5 }, [item('document:menu')]),\n group('workspace', { importance: 4 }, [\n item('panel:sidebar', { importance: 5 }),\n item('page:settings'),\n ]),\n // The inline zoom strip; when it can't fit it renders its 'button'\n // variant, and in the overflow menu it projects through zoom:menu.\n group('zoom', { importance: 4 }, [\n custom('zoom-controls', { variants: ['inline', 'button'], terminal: 'zoom:menu' }),\n ]),\n group('tools', { importance: 2 }, ['pan:toggle', 'pointer:toggle']),\n ],\n center: [\n group('modes', {\n role: 'tabs',\n // The group ladder: full strip → trailing tabs shed behind a derived\n // in-strip chevron (v2's overflow-tabs-button) → select (v2's\n // mode-select-button) → global overflow. Tab items at importance 1 so\n // the strip is the FIRST thing to compact; the group at 4 so its\n // compact forms survive long.\n shed: true,\n collapse: 'select',\n importance: 4,\n labelKey: 'commands.mode.group',\n items: [\n item('mode:view', { variants: ['label'], importance: 1 }),\n item('mode:annotate', { variants: ['label'], importance: 1 }),\n item('mode:shapes', { variants: ['label'], importance: 1 }),\n item('mode:insert', { variants: ['label'], importance: 1 }),\n item('mode:form', { variants: ['label'], importance: 1 }),\n item('mode:redact', { variants: ['label'], importance: 1 }),\n item('mode:measure', { variants: ['label'], importance: 1 }),\n ],\n }),\n ],\n end: [group('panels', { importance: 5 }, ['panel:search', 'panel:comment'])],\n },\n};\n\n// ── secondary bands (one per mode; which shows is derived from shell) ────────\nconst annotateBar: BarSchema = {\n id: 'annotate',\n sections: {\n center: [\n group('comment', { importance: 4 }, ['annotation:add-note', 'annotation:add-link']),\n group('markup', { importance: 4 }, [\n 'annotation:add-highlight',\n 'annotation:add-strikeout',\n 'annotation:add-underline',\n 'annotation:add-squiggly',\n ]),\n group('draw', { importance: 3 }, ['annotation:add-ink', 'annotation:add-ink-highlight']),\n group('text', { importance: 2 }, [\n 'annotation:add-text',\n 'annotation:add-insert-text',\n 'annotation:add-replace-text',\n 'annotation:add-callout',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst shapesBar: BarSchema = {\n id: 'shapes',\n sections: {\n center: [\n group('shapes', { importance: 4 }, [\n 'annotation:add-rectangle',\n 'annotation:add-circle',\n 'annotation:add-line',\n 'annotation:add-arrow',\n ]),\n group('polygons', { importance: 2 }, ['annotation:add-polygon', 'annotation:add-polyline']),\n style,\n history,\n ],\n },\n};\n\nconst insertBar: BarSchema = {\n id: 'insert',\n sections: {\n center: [\n group('stamps', { importance: 4 }, [\n 'insert:add-stamp',\n // Quick marks (`stamps.toolbar`): thumbnails that arm on click; in a\n // menu the stamps panel stands in for them.\n custom('quick-stamps', { terminal: 'insert:add-stamp', importance: 3 }),\n 'insert:add-attachment',\n 'insert:add-signature',\n 'insert:add-image',\n ]),\n style,\n history,\n ],\n },\n};\n\nconst formBar: BarSchema = {\n id: 'form',\n sections: {\n center: [\n group('fields', { importance: 4 }, [\n 'form:add-textfield',\n 'form:add-checkbox',\n 'form:add-radio',\n ]),\n group('choice-fields', { importance: 2 }, ['form:add-select', 'form:add-listbox']),\n group('signature-fields', { importance: 2 }, ['form:add-signature']),\n history,\n ],\n },\n};\n\nconst measureBar: BarSchema = {\n id: 'measure',\n sections: {\n center: [\n group('measure', { importance: 5 }, [\n 'measurement:distance',\n 'measurement:perimeter',\n 'measurement:area',\n 'measurement:calibrate',\n ]),\n group('scale', { importance: 4 }, [\n custom('measurement-scale', { variants: ['inline'], terminal: 'panel:measurement' }),\n ]),\n style,\n ],\n },\n};\n\nconst redactBar: BarSchema = {\n id: 'redact',\n sections: {\n center: [\n group('redact', { importance: 4 }, ['redaction:redact', 'panel:redaction']),\n style,\n history,\n ],\n },\n};\n\n// ── menus (command trees; separators derive between sections) ────────────────\nconst documentMenu: MenuSchema = {\n id: 'document',\n sections: [\n { items: ['document:download', 'document:print'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\nconst zoomMenu: MenuSchema = {\n id: 'zoom',\n sections: [\n {\n labelKey: 'commands.zoom.level',\n items: ['zoom:50', 'zoom:100', 'zoom:150', 'zoom:200', 'zoom:400'],\n },\n { items: ['zoom:in', 'zoom:out'] },\n { items: ['zoom:fit-page', 'zoom:fit-width', 'zoom:automatic'] },\n ],\n};\n\nconst pageSettingsMenu: MenuSchema = {\n id: 'page-settings',\n sections: [\n { labelKey: 'commands.spread.group', items: ['spread:none', 'spread:odd', 'spread:even'] },\n { labelKey: 'commands.scroll.group', items: ['scroll:vertical', 'scroll:horizontal'] },\n { labelKey: 'commands.rotate.group', items: ['rotate:clockwise', 'rotate:counter-clockwise'] },\n { items: ['document:fullscreen'] },\n ],\n};\n\n// ── contextual strips (anchored to selections; same BarSchema vocabulary) ────\n// WHICH commands actually show is each command's `visible` derivation (group\n// only when groupable, style only when the kind declares editable props…), so\n// one strip serves single AND multi selection — v2 needed two schemas for that.\nconst annotationStrip: BarSchema = {\n id: 'annotation-strip',\n sections: {\n center: [\n group('annotation-actions', { importance: 4 }, [\n 'annotation:comment',\n 'annotation:style',\n 'annotation:stamp-from-selection',\n 'annotation:link',\n 'annotation:goto-link',\n 'annotation:remove-link',\n 'annotation:group',\n 'annotation:ungroup',\n ]),\n // Its own group → a derived separator; delete stands apart.\n group('annotation-danger', { importance: 5 }, ['annotation:delete']),\n ],\n },\n};\n\n// The text-selection strip: appears when a text selection SETTLES (the menu\n// component gates on `isSelecting()`). One command today; \"Highlight\" et al.\n// are one more id here + one command — no component changes.\nconst selectionStrip: BarSchema = {\n id: 'selection-strip',\n sections: {\n center: [group('selection-actions', { importance: 4 }, ['selection:copy'])],\n },\n};\n\n/**\n * The DEFAULT chrome — exported as a VALUE, which is the whole customization\n * model: consumers pass nothing and track this, transform it, or write their\n * own. It is never merged with anything.\n */\nexport const defaultChrome = defineChrome({\n bars: { main: mainBar },\n modeBars: {\n 'mode:annotate': annotateBar,\n 'mode:shapes': shapesBar,\n 'mode:insert': insertBar,\n 'mode:form': formBar,\n 'mode:redact': redactBar,\n 'mode:measure': measureBar,\n },\n menus: { document: documentMenu, zoom: zoomMenu, 'page-settings': pageSettingsMenu },\n strips: { annotation: annotationStrip, selection: selectionStrip },\n});\n\n// Lookups take the RESOLVED schema (the host may have replaced the default) —\n// the typed literal widens to arbitrary string keys here, once.\n\n/** Menu lookup by id (arbitrary string). */\nexport function getMenu(schema: ChromeSchema, id: string): MenuSchema | undefined {\n return (schema.menus as Record<string, MenuSchema> | undefined)?.[id];\n}\n\n/** Secondary band lookup by mode-surface id. */\nexport function getModeBar(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.modeBars as Record<string, BarSchema> | undefined)?.[id];\n}\n\n/** Contextual strip lookup by context id ('annotation', …). */\nexport function getStrip(schema: ChromeSchema, id: string): BarSchema | undefined {\n return (schema.strips as Record<string, BarSchema> | undefined)?.[id];\n}\n"],"mappings":";;;;;;;;;;AAmBA,MAAM,QAAQ,MAAM,SAAS,EAAE,YAAY,EAAE,GAAG,CAAC,KAAK,wBAAwB,CAAC,CAAC;AAChF,MAAM,UAAU,MAAM,WAAW,EAAE,YAAY,EAAE,GAAG,CAAC,gBAAgB,cAAc,CAAC;AAGpF,MAAM,UAAqB;CACzB,IAAI;CACJ,UAAU;EAIR,OAAO;GACL,MAAM,YAAY,EAAE,YAAY,EAAE,GAAG,CAAC,KAAK,eAAe,CAAC,CAAC;GAC5D,MAAM,aAAa,EAAE,YAAY,EAAE,GAAG,CACpC,KAAK,iBAAiB,EAAE,YAAY,EAAE,CAAC,GACvC,KAAK,eAAe,CACtB,CAAC;GAGD,MAAM,QAAQ,EAAE,YAAY,EAAE,GAAG,CAC/B,OAAO,iBAAiB;IAAE,UAAU,CAAC,UAAU,QAAQ;IAAG,UAAU;GAAY,CAAC,CACnF,CAAC;GACD,MAAM,SAAS,EAAE,YAAY,EAAE,GAAG,CAAC,cAAc,gBAAgB,CAAC;EACpE;EACA,QAAQ,CACN,MAAM,SAAS;GACb,MAAM;GAMN,MAAM;GACN,UAAU;GACV,YAAY;GACZ,UAAU;GACV,OAAO;IACL,KAAK,aAAa;KAAE,UAAU,CAAC,OAAO;KAAG,YAAY;IAAE,CAAC;IACxD,KAAK,iBAAiB;KAAE,UAAU,CAAC,OAAO;KAAG,YAAY;IAAE,CAAC;IAC5D,KAAK,eAAe;KAAE,UAAU,CAAC,OAAO;KAAG,YAAY;IAAE,CAAC;IAC1D,KAAK,eAAe;KAAE,UAAU,CAAC,OAAO;KAAG,YAAY;IAAE,CAAC;IAC1D,KAAK,aAAa;KAAE,UAAU,CAAC,OAAO;KAAG,YAAY;IAAE,CAAC;IACxD,KAAK,eAAe;KAAE,UAAU,CAAC,OAAO;KAAG,YAAY;IAAE,CAAC;IAC1D,KAAK,gBAAgB;KAAE,UAAU,CAAC,OAAO;KAAG,YAAY;IAAE,CAAC;GAC7D;EACF,CAAC,CACH;EACA,KAAK,CAAC,MAAM,UAAU,EAAE,YAAY,EAAE,GAAG,CAAC,gBAAgB,eAAe,CAAC,CAAC;CAC7E;AACF;AAGA,MAAM,cAAyB;CAC7B,IAAI;CACJ,UAAU,EACR,QAAQ;EACN,MAAM,WAAW,EAAE,YAAY,EAAE,GAAG,CAAC,uBAAuB,qBAAqB,CAAC;EAClF,MAAM,UAAU,EAAE,YAAY,EAAE,GAAG;GACjC;GACA;GACA;GACA;EACF,CAAC;EACD,MAAM,QAAQ,EAAE,YAAY,EAAE,GAAG,CAAC,sBAAsB,8BAA8B,CAAC;EACvF,MAAM,QAAQ,EAAE,YAAY,EAAE,GAAG;GAC/B;GACA;GACA;GACA;EACF,CAAC;EACD;EACA;CACF,EACF;AACF;AAEA,MAAM,YAAuB;CAC3B,IAAI;CACJ,UAAU,EACR,QAAQ;EACN,MAAM,UAAU,EAAE,YAAY,EAAE,GAAG;GACjC;GACA;GACA;GACA;EACF,CAAC;EACD,MAAM,YAAY,EAAE,YAAY,EAAE,GAAG,CAAC,0BAA0B,yBAAyB,CAAC;EAC1F;EACA;CACF,EACF;AACF;AAEA,MAAM,YAAuB;CAC3B,IAAI;CACJ,UAAU,EACR,QAAQ;EACN,MAAM,UAAU,EAAE,YAAY,EAAE,GAAG;GACjC;GAGA,OAAO,gBAAgB;IAAE,UAAU;IAAoB,YAAY;GAAE,CAAC;GACtE;GACA;GACA;EACF,CAAC;EACD;EACA;CACF,EACF;AACF;AAEA,MAAM,UAAqB;CACzB,IAAI;CACJ,UAAU,EACR,QAAQ;EACN,MAAM,UAAU,EAAE,YAAY,EAAE,GAAG;GACjC;GACA;GACA;EACF,CAAC;EACD,MAAM,iBAAiB,EAAE,YAAY,EAAE,GAAG,CAAC,mBAAmB,kBAAkB,CAAC;EACjF,MAAM,oBAAoB,EAAE,YAAY,EAAE,GAAG,CAAC,oBAAoB,CAAC;EACnE;CACF,EACF;AACF;AAEA,MAAM,aAAwB;CAC5B,IAAI;CACJ,UAAU,EACR,QAAQ;EACN,MAAM,WAAW,EAAE,YAAY,EAAE,GAAG;GAClC;GACA;GACA;GACA;EACF,CAAC;EACD,MAAM,SAAS,EAAE,YAAY,EAAE,GAAG,CAChC,OAAO,qBAAqB;GAAE,UAAU,CAAC,QAAQ;GAAG,UAAU;EAAoB,CAAC,CACrF,CAAC;EACD;CACF,EACF;AACF;AAEA,MAAM,YAAuB;CAC3B,IAAI;CACJ,UAAU,EACR,QAAQ;EACN,MAAM,UAAU,EAAE,YAAY,EAAE,GAAG,CAAC,oBAAoB,iBAAiB,CAAC;EAC1E;EACA;CACF,EACF;AACF;AAGA,MAAM,eAA2B;CAC/B,IAAI;CACJ,UAAU,CACR,EAAE,OAAO,CAAC,qBAAqB,gBAAgB,EAAE,GACjD,EAAE,OAAO,CAAC,qBAAqB,EAAE,CACnC;AACF;AAEA,MAAM,WAAuB;CAC3B,IAAI;CACJ,UAAU;EACR;GACE,UAAU;GACV,OAAO;IAAC;IAAW;IAAY;IAAY;IAAY;GAAU;EACnE;EACA,EAAE,OAAO,CAAC,WAAW,UAAU,EAAE;EACjC,EAAE,OAAO;GAAC;GAAiB;GAAkB;EAAgB,EAAE;CACjE;AACF;AAEA,MAAM,mBAA+B;CACnC,IAAI;CACJ,UAAU;EACR;GAAE,UAAU;GAAyB,OAAO;IAAC;IAAe;IAAc;GAAa;EAAE;EACzF;GAAE,UAAU;GAAyB,OAAO,CAAC,mBAAmB,mBAAmB;EAAE;EACrF;GAAE,UAAU;GAAyB,OAAO,CAAC,oBAAoB,0BAA0B;EAAE;EAC7F,EAAE,OAAO,CAAC,qBAAqB,EAAE;CACnC;AACF;AAMA,MAAM,kBAA6B;CACjC,IAAI;CACJ,UAAU,EACR,QAAQ,CACN,MAAM,sBAAsB,EAAE,YAAY,EAAE,GAAG;EAC7C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAED,MAAM,qBAAqB,EAAE,YAAY,EAAE,GAAG,CAAC,mBAAmB,CAAC,CACrE,EACF;AACF;AAKA,MAAM,iBAA4B;CAChC,IAAI;CACJ,UAAU,EACR,QAAQ,CAAC,MAAM,qBAAqB,EAAE,YAAY,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC,EAC5E;AACF;;;;;;AAOA,MAAa,gBAAgB,aAAa;CACxC,MAAM,EAAE,MAAM,QAAQ;CACtB,UAAU;EACR,iBAAiB;EACjB,eAAe;EACf,eAAe;EACf,aAAa;EACb,eAAe;EACf,gBAAgB;CAClB;CACA,OAAO;EAAE,UAAU;EAAc,MAAM;EAAU,iBAAiB;CAAiB;CACnF,QAAQ;EAAE,YAAY;EAAiB,WAAW;CAAe;AACnE,CAAC;;AAMD,SAAgB,QAAQ,QAAsB,IAAoC;CAChF,OAAQ,OAAO,QAAmD;AACpE;;AAGA,SAAgB,WAAW,QAAsB,IAAmC;CAClF,OAAQ,OAAO,WAAqD;AACtE;;AAGA,SAAgB,SAAS,QAAsB,IAAmC;CAChF,OAAQ,OAAO,SAAmD;AACpE"}
|
package/dist/commands.cjs
CHANGED
|
@@ -5,6 +5,7 @@ let _embedpdf_react_interaction = require("@embedpdf/react/interaction");
|
|
|
5
5
|
let _embedpdf_react_selection = require("@embedpdf/react/selection");
|
|
6
6
|
let _embedpdf_react_annotation = require("@embedpdf/react/annotation");
|
|
7
7
|
let _embedpdf_react_stamp = require("@embedpdf/react/stamp");
|
|
8
|
+
let _embedpdf_react_measurement = require("@embedpdf/react/measurement");
|
|
8
9
|
let _embedpdf_react_redaction = require("@embedpdf/react/redaction");
|
|
9
10
|
let _embedpdf_react_actions = require("@embedpdf/react/actions");
|
|
10
11
|
let _embedpdf_react_form = require("@embedpdf/react/form");
|
|
@@ -326,6 +327,7 @@ const defaultCommands = [
|
|
|
326
327
|
modeCommand("mode:insert", "commands.mode.insert"),
|
|
327
328
|
modeCommand("mode:form", "commands.mode.form", "form-edit"),
|
|
328
329
|
modeCommand("mode:redact", "commands.mode.redact"),
|
|
330
|
+
modeCommand("mode:measure", "commands.mode.measure"),
|
|
329
331
|
tool("annotation:add-highlight", "highlight", "commands.annotate.highlight", "highlight", { primary: "color" }),
|
|
330
332
|
tool("annotation:add-strikeout", "strikeout", "commands.annotate.strikeout", "strikethrough", { primary: "color" }),
|
|
331
333
|
tool("annotation:add-underline", "underline", "commands.annotate.underline", "underline", { primary: "color" }),
|
|
@@ -403,6 +405,57 @@ const defaultCommands = [
|
|
|
403
405
|
exclusive: "right"
|
|
404
406
|
}
|
|
405
407
|
},
|
|
408
|
+
{
|
|
409
|
+
...tool("measurement:distance", "distance", "measurement.distance", "distance", { primary: "color" }),
|
|
410
|
+
enabled: (c) => {
|
|
411
|
+
const s = stage(c);
|
|
412
|
+
const pon = s?.pages()[s.currentPage()]?.pon;
|
|
413
|
+
return pon != null && (c.tryGet(_embedpdf_react_measurement.MeasurementToken)?.canMeasure(pon) ?? false);
|
|
414
|
+
}
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
...tool("measurement:perimeter", "perimeter", "measurement.perimeter", "perimeter", { primary: "color" }),
|
|
418
|
+
enabled: (c) => {
|
|
419
|
+
const s = stage(c);
|
|
420
|
+
const pon = s?.pages()[s.currentPage()]?.pon;
|
|
421
|
+
return pon != null && (c.tryGet(_embedpdf_react_measurement.MeasurementToken)?.canMeasure(pon) ?? false);
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
...tool("measurement:area", "area", "measurement.area", "area", { primary: "color" }),
|
|
426
|
+
enabled: (c) => {
|
|
427
|
+
const s = stage(c);
|
|
428
|
+
const pon = s?.pages()[s.currentPage()]?.pon;
|
|
429
|
+
return pon != null && (c.tryGet(_embedpdf_react_measurement.MeasurementToken)?.canMeasure(pon) ?? false);
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
id: "measurement:calibrate",
|
|
434
|
+
labelKey: "measurement.calibrate",
|
|
435
|
+
icon: "calibrate",
|
|
436
|
+
categories: ["tool"],
|
|
437
|
+
enabled: (c) => c.tryGet(_embedpdf_react_measurement.MeasurementToken)?.canCalibrate() ?? false,
|
|
438
|
+
active: (c) => interaction(c)?.activeToolId() === "calibrate",
|
|
439
|
+
run: (c) => c.tryGet(_embedpdf_react_measurement.MeasurementToken)?.startCalibration()
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: "panel:measurement",
|
|
443
|
+
labelKey: "measurement.title",
|
|
444
|
+
icon: "updateScale",
|
|
445
|
+
categories: ["panel"],
|
|
446
|
+
panel: {
|
|
447
|
+
id: "measurement",
|
|
448
|
+
exclusive: "right"
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
id: "annotation:cancel-creation",
|
|
453
|
+
labelKey: "commands.annotate.cancelCreation",
|
|
454
|
+
categories: ["annotation"],
|
|
455
|
+
shortcut: "Escape",
|
|
456
|
+
enabled: (c) => anno(c)?.hasCreationDraft() ?? false,
|
|
457
|
+
run: (c) => anno(c)?.cancelCreationDraft()
|
|
458
|
+
},
|
|
406
459
|
{
|
|
407
460
|
id: "annotation:delete",
|
|
408
461
|
labelKey: "commands.annotate.delete",
|
|
@@ -573,7 +626,8 @@ const MODE_SURFACES = [
|
|
|
573
626
|
"mode:shapes",
|
|
574
627
|
"mode:insert",
|
|
575
628
|
"mode:form",
|
|
576
|
-
"mode:redact"
|
|
629
|
+
"mode:redact",
|
|
630
|
+
"mode:measure"
|
|
577
631
|
];
|
|
578
632
|
function modeCommand(id, labelKey, toolId = "pointer") {
|
|
579
633
|
return {
|
package/dist/commands.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.cjs","names":["StageToken","InteractionToken","AnnotationToken","SelectionToken","FormToken","RedactionToken","ZoomMode","SearchToken","DocumentsToken","ActionsToken","ShellToken","StampToken","SignatureToken","I18nToken","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 tools → real stamp library panel + image/\n * attachment click-then-pick (signature\n * still inert, via 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 { copySelection, SelectionToken, type TextRange } from '@embedpdf/react/selection';\nimport { fieldKeyOf, FormToken } from '@embedpdf/react/form';\nimport { ActionsToken } from '@embedpdf/react/actions';\nimport { LinkToken, openLinkTarget, type PdfLinkTarget } from '@embedpdf/react/link';\nimport { SearchToken } from '@embedpdf/react/search';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { StampToken } from '@embedpdf/react/stamp';\nimport { SignatureToken } from '@embedpdf/react/signature';\nimport { I18nToken } from '@embedpdf/react/i18n';\n\n// ── helpers ────────────────────────────────────────────────────────────────\ntype Ctx = Parameters<NonNullable<CommandDef['run']>>[0];\n\n/** Where selection-made stamps go: the user's own library, persisted. */\nconst CUSTOM_LIBRARY_ID = 'embedpdf-custom';\n\nconst stage = (c: Ctx) => c.tryGet(StageToken);\nconst interaction = (c: Ctx) => c.tryGet(InteractionToken);\nconst anno = (c: Ctx) => c.tryGet(AnnotationToken);\nconst textSelection = (c: Ctx) => c.tryGet(SelectionToken);\nconst sameTextRange = (a: TextRange | null, b: TextRange | null): boolean =>\n a === b ||\n (!!a &&\n !!b &&\n a.start.pon === b.start.pon &&\n a.start.index === b.start.index &&\n a.end.pon === b.end.pon &&\n a.end.index === b.end.index);\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\n// The `stamp` tool has no toolbar button of its own: it is ARMED by the stamps\n// panel (picking a library asset), never activated directly — so its cursor\n// skin is recorded here rather than as a side effect of a `tool()` definition.\nTOOL_ICONS['stamp'] = { icon: 'rubberStamp' };\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 // Authoring tools grey out without their family's authority — the SAME\n // twin the owning plugin's gesture gate consults (permissions.md), so a\n // button can never offer a doomed paint: annotation/insert tools ask\n // annotation create authority, form-design tools ask `form.canDesign()`,\n // the redact marker asks `redaction.canMark()`. Absent plugin → ungated\n // (a build without the plugin has no authority question to ask).\n const authority: ((c: Ctx) => boolean) | null =\n id.startsWith('annotation:add') || id.startsWith('insert:add')\n ? (c) => anno(c)?.canCreate() ?? true\n : id.startsWith('form:add')\n ? (c) => c.tryGet(FormToken)?.canDesign() ?? true\n : id === 'redaction:redact'\n ? (c) => c.tryGet(RedactionToken)?.canMark() ?? true\n : null;\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 && (authority?.(c) ?? true),\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 // No doc.text.search → every query would 403; the panel has no job.\n visible: (c) => c.tryGet(SearchToken)?.canSearch() ?? true,\n categories: ['panel'],\n panel: { id: 'search', exclusive: 'right' },\n },\n {\n id: 'panel:comment',\n labelKey: 'commands.comment',\n icon: 'comment',\n // No doc.annotate.read → there is nothing this panel could show.\n visible: (c) => anno(c)?.canRead() ?? true,\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 const documents = c.tryGet(DocumentsToken);\n if (!documents) return;\n const pull = () => documents.download(id);\n // The Phase-4 verb-owner contract: WS → serialize → DS as ONE queued\n // operation, so the WillSave mutations are IN the downloaded bytes\n // and two rapid saves can never interleave. Without the actions\n // plugin this degrades to a plain download.\n const actions = c.tryGet(ActionsToken);\n (actions ? actions.runDocumentVerb('save', pull) : pull())\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 // The permissions.md chrome exception: a kernel verb with a 1:1\n // capability reads the kernel's `allows` directly — no owning plugin.\n enabled: (c) =>\n c.documentId != null && (c.tryGet(DocumentsToken)?.allows('doc.download') ?? false),\n },\n {\n id: 'document:print',\n labelKey: 'commands.print',\n icon: 'print',\n shortcut: 'Mod+p',\n categories: ['document'],\n // WP → window.print() → DP through the one serialized verb op (the\n // latch suppresses any nested script print); documentless chrome (or\n // no actions plugin) keeps today's direct dialog.\n run: (c) => {\n const actions = c.documentId != null ? c.tryGet(ActionsToken) : null;\n if (actions) void actions.runDocumentVerb('print', () => window.print());\n else window.print();\n },\n // Same exception; documentless chrome (no doc open) keeps print enabled\n // for whatever the host page shows.\n enabled: (c) => c.documentId == null || (c.tryGet(DocumentsToken)?.allows('doc.print') ?? true),\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/image/attachment real; signature inert) ─────────\n // Stamps open a LIBRARY, they are not a file dialog: the panel lists the\n // reusable named assets the stamp plugin holds, and picking one arms the\n // annotation plugin's stamp tool with that asset's bytes (stamps-panel.tsx).\n // Arbitrary image bytes are `insert:add-image` below — a different gesture,\n // so a different button.\n {\n id: 'insert:add-stamp',\n labelKey: 'commands.insert.stamp',\n icon: 'rubberStamp',\n // No stamp plugin → no library to show. No create authority → nothing the\n // picker could place (the same twin every insert tool's button asks).\n visible: (c) => c.tryGet(StampToken) != null,\n enabled: (c) => anno(c)?.canCreate() ?? true,\n categories: ['panel'],\n panel: { id: 'stamps', exclusive: 'right' },\n },\n // File attachment — click the spot, pick the file (the attachment provider).\n tool('insert:add-attachment', 'attachment', 'commands.insert.attachment', 'paperclip'),\n // Signatures open the PEOPLE panel (libraries of kind 'signatures'): pick a\n // mark → with a target field it signs (or fills) it, else it arms — a click\n // on a signature field signs, anywhere else drops a stamp (Preview).\n {\n id: 'insert:add-signature',\n labelKey: 'commands.insert.signature',\n icon: 'signature',\n visible: (c) => c.tryGet(StampToken) != null && c.tryGet(SignatureToken) != null,\n enabled: (c) => anno(c)?.canCreate() ?? true,\n categories: ['panel'],\n panel: { id: 'signatures', exclusive: 'right' },\n },\n // Image — the click-then-pick placement: click the spot, the file dialog\n // opens (narrowed to rasters), the picture lands where you clicked. The\n // tool itself is a `stamp` preset registered in viewer.tsx.\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 tool('form:add-signature', 'form-signature', 'commands.form.signature', 'signature'),\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 // Useful to a session that can propose marks OR apply them; with neither\n // power the panel could only display other people's pending marks.\n visible: (c) => {\n const r = c.tryGet(RedactionToken);\n return r ? r.canMark() || r.canApply() : true;\n },\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 // The selection becomes a reusable stamp: the engine flattens the\n // selected appearances into one page (vector, positions kept) and the\n // stamp plugin files it under the user's own library — persisted like\n // any library, exportable as a PDF Acrobat reads.\n id: 'annotation:stamp-from-selection',\n labelKey: 'commands.annotate.stampFromSelection',\n icon: 'rubberStampPlus',\n categories: ['annotation'],\n run: (c) => {\n const a = anno(c);\n const stamp = c.tryGet(StampToken);\n const documentId = c.documentId;\n if (!a || !stamp || documentId == null) return;\n const dtos = a.getSelected();\n const pon = dtos[0]?.ref.pageObjectNumber;\n if (pon === undefined) return;\n const i18n = c.tryGet(I18nToken);\n const label = i18n?.t('demo.stampsCustomLabel') ?? 'Custom stamp';\n const libraryName = i18n?.t('demo.stampsCustomLibrary') ?? 'My stamps';\n const libraryId = CUSTOM_LIBRARY_ID;\n const ensureLibrary = stamp.library(libraryId)\n ? Promise.resolve(libraryId)\n : stamp.createLibrary(libraryName, { id: libraryId, categories: ['custom'] });\n ensureLibrary\n .then((id) =>\n stamp.addAssetFromAnnotations(\n documentId,\n pon,\n dtos.map((d) => d.ref),\n { libraryId: id, label: `${label} ${stamp.assets(id).length + 1}` },\n ),\n )\n // v2 jumped the sidebar to the custom library; the panel reads the\n // surface's open props for its picker.\n .then(() =>\n c.tryGet(ShellToken)?.open('stamps', {\n exclusive: 'right',\n props: { libraryId },\n }),\n )\n .catch((e) => console.warn('[embedpdf] stamp from selection failed', e));\n },\n // One page, no widgets (a form field is not artwork), no pending\n // redaction marks, and a library to put it in. The engine refuses hidden\n // or appearance-less annotations itself — all-or-nothing, never a stamp\n // missing a part.\n visible: (c) =>\n c.tryGet(StampToken) != null &&\n hasAnnotationSelection(c) &&\n !selectionSubtypes(c).has('widget') &&\n !selectionSubtypes(c).has('redact') &&\n new Set((anno(c)?.getSelected() ?? []).map((d) => d.ref.pageObjectNumber)).size === 1,\n enabled: (c) => c.tryGet(DocumentsToken)?.allows('doc.download') ?? true,\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 // ── text selection (the selection strip's verbs) ────────────────────────\n {\n id: 'selection:copy',\n labelKey: 'commands.selection.copy',\n icon: 'copy',\n categories: ['selection'],\n // The permission story rides `visible`: a deployment denying\n // doc.text.copy shows no Copy at all — and with zero visible commands\n // the strip renders nothing, so there is never an empty bubble.\n visible: (c) => {\n const s = textSelection(c);\n return !!s && s.hasSelection() && s.canCopy();\n },\n // Async Clipboard write inside the click's activation window; instant\n // when <SelectionClipboard>'s commit prefetch already fetched the text.\n // A successful copy consumes the selection, which also dismisses its strip.\n run: (c) => {\n const s = textSelection(c);\n if (!s) return;\n const copiedRange = s.snapshot().range;\n void copySelection(s).then(\n (text) => {\n // Clipboard writes can outlive the click. Never let an older copy\n // completion clear a newer selection the user made in the meantime.\n if (text !== '' && sameTextRange(s.snapshot().range, copiedRange)) s.clear();\n },\n () => {}, // Copy failed: preserve the selection so the user can retry.\n );\n },\n },\n\n // ── link strip items (v2's \"Link / Go to link / Remove link\") ───────────\n {\n // Make the selection a link: opens the anchored POPOVER (v2's popup —\n // a link is a verb on the selection, not a style), whose editor sets\n // the target through `updateSelection({ link })`; the plugin's\n // reconciler materializes the attached child annotations.\n id: 'annotation:link',\n labelKey: 'commands.annotate.link',\n icon: 'link',\n categories: ['annotation'],\n run: (c) => c.tryGet(ShellToken)?.toggle('link-editor'),\n active: (c) => c.tryGet(ShellToken)?.isOpen('link-editor') ?? false,\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 const link = c.tryGet(LinkToken);\n // The opener PERFORMS the uri outcome (window.open) — bare `activate`\n // resolves but opens nothing for URL targets.\n if (target && link) openLinkTarget(link, 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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"}
|
|
1
|
+
{"version":3,"file":"commands.cjs","names":["StageToken","InteractionToken","AnnotationToken","SelectionToken","FormToken","RedactionToken","ZoomMode","SearchToken","DocumentsToken","ActionsToken","ShellToken","StampToken","SignatureToken","MeasurementToken","I18nToken","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 tools → real stamp library panel + image/\n * attachment click-then-pick (signature\n * still inert, via 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 { copySelection, SelectionToken, type TextRange } from '@embedpdf/react/selection';\nimport { fieldKeyOf, FormToken } from '@embedpdf/react/form';\nimport { ActionsToken } from '@embedpdf/react/actions';\nimport { LinkToken, openLinkTarget, type PdfLinkTarget } from '@embedpdf/react/link';\nimport { SearchToken } from '@embedpdf/react/search';\nimport { MeasurementToken } from '@embedpdf/react/measurement';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { StampToken } from '@embedpdf/react/stamp';\nimport { SignatureToken } from '@embedpdf/react/signature';\nimport { I18nToken } from '@embedpdf/react/i18n';\n\n// ── helpers ────────────────────────────────────────────────────────────────\ntype Ctx = Parameters<NonNullable<CommandDef['run']>>[0];\n\n/** Where selection-made stamps go: the user's own library, persisted. */\nconst CUSTOM_LIBRARY_ID = 'embedpdf-custom';\n\nconst stage = (c: Ctx) => c.tryGet(StageToken);\nconst interaction = (c: Ctx) => c.tryGet(InteractionToken);\nconst anno = (c: Ctx) => c.tryGet(AnnotationToken);\nconst textSelection = (c: Ctx) => c.tryGet(SelectionToken);\nconst sameTextRange = (a: TextRange | null, b: TextRange | null): boolean =>\n a === b ||\n (!!a &&\n !!b &&\n a.start.pon === b.start.pon &&\n a.start.index === b.start.index &&\n a.end.pon === b.end.pon &&\n a.end.index === b.end.index);\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\n// The `stamp` tool has no toolbar button of its own: it is ARMED by the stamps\n// panel (picking a library asset), never activated directly — so its cursor\n// skin is recorded here rather than as a side effect of a `tool()` definition.\nTOOL_ICONS['stamp'] = { icon: 'rubberStamp' };\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 // Authoring tools grey out without their family's authority — the SAME\n // twin the owning plugin's gesture gate consults (permissions.md), so a\n // button can never offer a doomed paint: annotation/insert tools ask\n // annotation create authority, form-design tools ask `form.canDesign()`,\n // the redact marker asks `redaction.canMark()`. Absent plugin → ungated\n // (a build without the plugin has no authority question to ask).\n const authority: ((c: Ctx) => boolean) | null =\n id.startsWith('annotation:add') || id.startsWith('insert:add')\n ? (c) => anno(c)?.canCreate() ?? true\n : id.startsWith('form:add')\n ? (c) => c.tryGet(FormToken)?.canDesign() ?? true\n : id === 'redaction:redact'\n ? (c) => c.tryGet(RedactionToken)?.canMark() ?? true\n : null;\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 && (authority?.(c) ?? true),\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 // No doc.text.search → every query would 403; the panel has no job.\n visible: (c) => c.tryGet(SearchToken)?.canSearch() ?? true,\n categories: ['panel'],\n panel: { id: 'search', exclusive: 'right' },\n },\n {\n id: 'panel:comment',\n labelKey: 'commands.comment',\n icon: 'comment',\n // No doc.annotate.read → there is nothing this panel could show.\n visible: (c) => anno(c)?.canRead() ?? true,\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 const documents = c.tryGet(DocumentsToken);\n if (!documents) return;\n const pull = () => documents.download(id);\n // The Phase-4 verb-owner contract: WS → serialize → DS as ONE queued\n // operation, so the WillSave mutations are IN the downloaded bytes\n // and two rapid saves can never interleave. Without the actions\n // plugin this degrades to a plain download.\n const actions = c.tryGet(ActionsToken);\n (actions ? actions.runDocumentVerb('save', pull) : pull())\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 // The permissions.md chrome exception: a kernel verb with a 1:1\n // capability reads the kernel's `allows` directly — no owning plugin.\n enabled: (c) =>\n c.documentId != null && (c.tryGet(DocumentsToken)?.allows('doc.download') ?? false),\n },\n {\n id: 'document:print',\n labelKey: 'commands.print',\n icon: 'print',\n shortcut: 'Mod+p',\n categories: ['document'],\n // WP → window.print() → DP through the one serialized verb op (the\n // latch suppresses any nested script print); documentless chrome (or\n // no actions plugin) keeps today's direct dialog.\n run: (c) => {\n const actions = c.documentId != null ? c.tryGet(ActionsToken) : null;\n if (actions) void actions.runDocumentVerb('print', () => window.print());\n else window.print();\n },\n // Same exception; documentless chrome (no doc open) keeps print enabled\n // for whatever the host page shows.\n enabled: (c) => c.documentId == null || (c.tryGet(DocumentsToken)?.allows('doc.print') ?? true),\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 modeCommand('mode:measure', 'commands.mode.measure'),\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/image/attachment real; signature inert) ─────────\n // Stamps open a LIBRARY, they are not a file dialog: the panel lists the\n // reusable named assets the stamp plugin holds, and picking one arms the\n // annotation plugin's stamp tool with that asset's bytes (stamps-panel.tsx).\n // Arbitrary image bytes are `insert:add-image` below — a different gesture,\n // so a different button.\n {\n id: 'insert:add-stamp',\n labelKey: 'commands.insert.stamp',\n icon: 'rubberStamp',\n // No stamp plugin → no library to show. No create authority → nothing the\n // picker could place (the same twin every insert tool's button asks).\n visible: (c) => c.tryGet(StampToken) != null,\n enabled: (c) => anno(c)?.canCreate() ?? true,\n categories: ['panel'],\n panel: { id: 'stamps', exclusive: 'right' },\n },\n // File attachment — click the spot, pick the file (the attachment provider).\n tool('insert:add-attachment', 'attachment', 'commands.insert.attachment', 'paperclip'),\n // Signatures open the PEOPLE panel (libraries of kind 'signatures'): pick a\n // mark → with a target field it signs (or fills) it, else it arms — a click\n // on a signature field signs, anywhere else drops a stamp (Preview).\n {\n id: 'insert:add-signature',\n labelKey: 'commands.insert.signature',\n icon: 'signature',\n visible: (c) => c.tryGet(StampToken) != null && c.tryGet(SignatureToken) != null,\n enabled: (c) => anno(c)?.canCreate() ?? true,\n categories: ['panel'],\n panel: { id: 'signatures', exclusive: 'right' },\n },\n // Image — the click-then-pick placement: click the spot, the file dialog\n // opens (narrowed to rasters), the picture lands where you clicked. The\n // tool itself is a `stamp` preset registered in viewer.tsx.\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 tool('form:add-signature', 'form-signature', 'commands.form.signature', 'signature'),\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 // Useful to a session that can propose marks OR apply them; with neither\n // power the panel could only display other people's pending marks.\n visible: (c) => {\n const r = c.tryGet(RedactionToken);\n return r ? r.canMark() || r.canApply() : true;\n },\n categories: ['panel'],\n panel: { id: 'redaction', exclusive: 'right' },\n },\n\n {\n ...tool('measurement:distance', 'distance', 'measurement.distance', 'distance', {\n primary: 'color',\n }),\n enabled: (c) => {\n const s = stage(c);\n const pon = s?.pages()[s.currentPage()]?.pon;\n return pon != null && (c.tryGet(MeasurementToken)?.canMeasure(pon) ?? false);\n },\n },\n {\n ...tool('measurement:perimeter', 'perimeter', 'measurement.perimeter', 'perimeter', {\n primary: 'color',\n }),\n enabled: (c) => {\n const s = stage(c);\n const pon = s?.pages()[s.currentPage()]?.pon;\n return pon != null && (c.tryGet(MeasurementToken)?.canMeasure(pon) ?? false);\n },\n },\n {\n ...tool('measurement:area', 'area', 'measurement.area', 'area', {\n primary: 'color',\n }),\n enabled: (c) => {\n const s = stage(c);\n const pon = s?.pages()[s.currentPage()]?.pon;\n return pon != null && (c.tryGet(MeasurementToken)?.canMeasure(pon) ?? false);\n },\n },\n {\n id: 'measurement:calibrate',\n labelKey: 'measurement.calibrate',\n icon: 'calibrate',\n categories: ['tool'],\n enabled: (c) => c.tryGet(MeasurementToken)?.canCalibrate() ?? false,\n active: (c) => interaction(c)?.activeToolId() === 'calibrate',\n run: (c) => c.tryGet(MeasurementToken)?.startCalibration(),\n },\n {\n id: 'panel:measurement',\n labelKey: 'measurement.title',\n icon: 'updateScale',\n categories: ['panel'],\n panel: { id: 'measurement', exclusive: 'right' },\n },\n\n // ── annotation selection (the floating strip's verbs) ──────────────────\n {\n id: 'annotation:cancel-creation',\n labelKey: 'commands.annotate.cancelCreation',\n categories: ['annotation'],\n shortcut: 'Escape',\n enabled: (c) => anno(c)?.hasCreationDraft() ?? false,\n run: (c) => anno(c)?.cancelCreationDraft(),\n },\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 // The selection becomes a reusable stamp: the engine flattens the\n // selected appearances into one page (vector, positions kept) and the\n // stamp plugin files it under the user's own library — persisted like\n // any library, exportable as a PDF Acrobat reads.\n id: 'annotation:stamp-from-selection',\n labelKey: 'commands.annotate.stampFromSelection',\n icon: 'rubberStampPlus',\n categories: ['annotation'],\n run: (c) => {\n const a = anno(c);\n const stamp = c.tryGet(StampToken);\n const documentId = c.documentId;\n if (!a || !stamp || documentId == null) return;\n const dtos = a.getSelected();\n const pon = dtos[0]?.ref.pageObjectNumber;\n if (pon === undefined) return;\n const i18n = c.tryGet(I18nToken);\n const label = i18n?.t('demo.stampsCustomLabel') ?? 'Custom stamp';\n const libraryName = i18n?.t('demo.stampsCustomLibrary') ?? 'My stamps';\n const libraryId = CUSTOM_LIBRARY_ID;\n const ensureLibrary = stamp.library(libraryId)\n ? Promise.resolve(libraryId)\n : stamp.createLibrary(libraryName, { id: libraryId, categories: ['custom'] });\n ensureLibrary\n .then((id) =>\n stamp.addAssetFromAnnotations(\n documentId,\n pon,\n dtos.map((d) => d.ref),\n { libraryId: id, label: `${label} ${stamp.assets(id).length + 1}` },\n ),\n )\n // v2 jumped the sidebar to the custom library; the panel reads the\n // surface's open props for its picker.\n .then(() =>\n c.tryGet(ShellToken)?.open('stamps', {\n exclusive: 'right',\n props: { libraryId },\n }),\n )\n .catch((e) => console.warn('[embedpdf] stamp from selection failed', e));\n },\n // One page, no widgets (a form field is not artwork), no pending\n // redaction marks, and a library to put it in. The engine refuses hidden\n // or appearance-less annotations itself — all-or-nothing, never a stamp\n // missing a part.\n visible: (c) =>\n c.tryGet(StampToken) != null &&\n hasAnnotationSelection(c) &&\n !selectionSubtypes(c).has('widget') &&\n !selectionSubtypes(c).has('redact') &&\n new Set((anno(c)?.getSelected() ?? []).map((d) => d.ref.pageObjectNumber)).size === 1,\n enabled: (c) => c.tryGet(DocumentsToken)?.allows('doc.download') ?? true,\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 // ── text selection (the selection strip's verbs) ────────────────────────\n {\n id: 'selection:copy',\n labelKey: 'commands.selection.copy',\n icon: 'copy',\n categories: ['selection'],\n // The permission story rides `visible`: a deployment denying\n // doc.text.copy shows no Copy at all — and with zero visible commands\n // the strip renders nothing, so there is never an empty bubble.\n visible: (c) => {\n const s = textSelection(c);\n return !!s && s.hasSelection() && s.canCopy();\n },\n // Async Clipboard write inside the click's activation window; instant\n // when <SelectionClipboard>'s commit prefetch already fetched the text.\n // A successful copy consumes the selection, which also dismisses its strip.\n run: (c) => {\n const s = textSelection(c);\n if (!s) return;\n const copiedRange = s.snapshot().range;\n void copySelection(s).then(\n (text) => {\n // Clipboard writes can outlive the click. Never let an older copy\n // completion clear a newer selection the user made in the meantime.\n if (text !== '' && sameTextRange(s.snapshot().range, copiedRange)) s.clear();\n },\n () => {}, // Copy failed: preserve the selection so the user can retry.\n );\n },\n },\n\n // ── link strip items (v2's \"Link / Go to link / Remove link\") ───────────\n {\n // Make the selection a link: opens the anchored POPOVER (v2's popup —\n // a link is a verb on the selection, not a style), whose editor sets\n // the target through `updateSelection({ link })`; the plugin's\n // reconciler materializes the attached child annotations.\n id: 'annotation:link',\n labelKey: 'commands.annotate.link',\n icon: 'link',\n categories: ['annotation'],\n run: (c) => c.tryGet(ShellToken)?.toggle('link-editor'),\n active: (c) => c.tryGet(ShellToken)?.isOpen('link-editor') ?? false,\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 const link = c.tryGet(LinkToken);\n // The opener PERFORMS the uri outcome (window.open) — bare `activate`\n // resolves but opens nothing for URL targets.\n if (target && link) openLinkTarget(link, 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 'mode:measure',\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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"}
|
package/dist/commands.d.cts
CHANGED
|
@@ -16,7 +16,7 @@ declare const TOOL_ICONS: Record<string, {
|
|
|
16
16
|
accent?: ToolAccentDefinition;
|
|
17
17
|
}>;
|
|
18
18
|
declare const defaultCommands: CommandDef[];
|
|
19
|
-
declare const MODE_SURFACES: readonly ["mode:annotate", "mode:shapes", "mode:insert", "mode:form", "mode:redact"];
|
|
19
|
+
declare const MODE_SURFACES: readonly ["mode:annotate", "mode:shapes", "mode:insert", "mode:form", "mode:redact", "mode:measure"];
|
|
20
20
|
//#endregion
|
|
21
21
|
export { MODE_SURFACES, TOOL_ICONS, ToolAccentDefinition, defaultCommands };
|
|
22
22
|
//# sourceMappingURL=commands.d.cts.map
|
package/dist/commands.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ declare const TOOL_ICONS: Record<string, {
|
|
|
16
16
|
accent?: ToolAccentDefinition;
|
|
17
17
|
}>;
|
|
18
18
|
declare const defaultCommands: CommandDef[];
|
|
19
|
-
declare const MODE_SURFACES: readonly ["mode:annotate", "mode:shapes", "mode:insert", "mode:form", "mode:redact"];
|
|
19
|
+
declare const MODE_SURFACES: readonly ["mode:annotate", "mode:shapes", "mode:insert", "mode:form", "mode:redact", "mode:measure"];
|
|
20
20
|
//#endregion
|
|
21
21
|
export { MODE_SURFACES, TOOL_ICONS, ToolAccentDefinition, defaultCommands };
|
|
22
22
|
//# sourceMappingURL=commands.d.ts.map
|