superdoc 2.4.0-next.2 → 2.4.0-next.21
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/chunks/{FindReplaceSurface-Dx0llWqP.cjs → FindReplaceSurface-0p7EtMZh.cjs} +4 -4
- package/dist/chunks/{FindReplaceSurface-BEW-1NhM.es.js → FindReplaceSurface-40AnrqWk.es.js} +5 -4
- package/dist/chunks/{PasswordPromptSurface-BUUVC2ee.cjs → PasswordPromptSurface-31lYPcCK.cjs} +4 -3
- package/dist/chunks/{PasswordPromptSurface-BA6HHqEa.es.js → PasswordPromptSurface-CwYeO3iQ.es.js} +4 -2
- package/dist/chunks/{PdfViewer-CNOtyS-I.es.js → PdfViewer-D8h7LRZy.es.js} +103 -19
- package/dist/chunks/{PdfViewer-qpvzwYMz.cjs → PdfViewer-Dug6yDRC.cjs} +105 -20
- package/dist/chunks/_plugin-vue_export-helper-BOaGB7Aw.es.js +8 -0
- package/dist/chunks/_plugin-vue_export-helper-SDR04tiH.cjs +13 -0
- package/dist/chunks/{blank-docx-DP8RUPW-.cjs → blank-docx-BuFAbRjs.cjs} +2 -0
- package/dist/chunks/{blank-docx-XRX6Ker2.es.js → blank-docx-DzQccOlW.es.js} +2 -0
- package/dist/chunks/constants-B6VBlmKp.es.js +4 -0
- package/dist/chunks/constants-DpXuDx_g.cjs +9 -0
- package/dist/chunks/{create-super-doc-ui-D4kk9AjM.es.js → create-super-doc-ui-CFsY0uxw.es.js} +2177 -581
- package/dist/chunks/{create-super-doc-ui-DXdWuTzm.cjs → create-super-doc-ui-jSJQis_0.cjs} +1987 -619
- package/dist/chunks/{eventemitter3-DqY4aSMf.cjs → eventemitter3-C_TAnXOl.cjs} +125 -16
- package/dist/chunks/{eventemitter3-Bt2s0X0a.es.js → eventemitter3-DEIiXiH2.es.js} +124 -16
- package/dist/chunks/jszip-BzJ3CyxR.es.js +4717 -0
- package/dist/chunks/jszip-D8mAFF-r.cjs +4758 -0
- package/dist/chunks/{rolldown-runtime-D7PMmH3s.es.js → rolldown-runtime-0pSA04fp.es.js} +12 -3
- package/dist/chunks/{rolldown-runtime-1Y-nnZJ3.cjs → rolldown-runtime-74VwNCz7.cjs} +11 -2
- package/dist/chunks/{uuid-CFp0WGVU.cjs → uuid-BhG0ngwk.cjs} +10 -6
- package/dist/chunks/{uuid-B2Sqk-3p.es.js → uuid-H0Xcmmhy.es.js} +8 -3
- package/dist/collaboration-upgrade-engine.cjs +34 -9
- package/dist/collaboration-upgrade-engine.es.js +30 -5
- package/dist/document-api/src/comments/comments.types.d.ts +7 -0
- package/dist/document-api/src/types/track-changes.types.d.ts +1 -3
- package/dist/layout-engine/contracts/src/incremental-dependency.d.ts +22 -2
- package/dist/layout-engine/contracts/src/index.d.ts +1 -1
- package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +2 -1
- package/dist/layout-engine/layout-bridge/src/index.d.ts +1 -0
- package/dist/public/ui-react.cjs +66 -2
- package/dist/public/ui-react.es.js +66 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +104 -69
- package/dist/style.layered.css +104 -69
- package/dist/superdoc/src/core/SuperDoc.d.ts +4 -0
- package/dist/superdoc/src/core/types/index.d.ts +505 -42
- package/dist/superdoc/src/helpers/comment-small-screen.d.ts +10 -0
- package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +1 -0
- package/dist/superdoc/src/helpers/v2-review-mutation-reconciler.d.ts +1 -1
- package/dist/superdoc/src/helpers/v2-typing-review-hydration.d.ts +16 -0
- package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButton.vue.d.ts +4 -4
- package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +11 -0
- package/dist/superdoc/src/internal/toolbar/compatibility-catalog.d.ts +1 -1
- package/dist/superdoc/src/public/index.d.cts +22 -0
- package/dist/superdoc/src/public/index.d.ts +11 -0
- package/dist/superdoc/src/public/ui/types.d.ts +25 -1
- package/dist/superdoc/src/stores/comments-store.d.ts +100 -22
- package/dist/superdoc/src/stores/superdoc-store.d.ts +300 -66
- package/dist/superdoc.cjs +6678 -1391
- package/dist/superdoc.es.js +6556 -1268
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +37 -37
- package/package.json +14 -14
- package/dist/chunks/_plugin-vue_export-helper-BTwbGDKw.cjs +0 -11
- package/dist/chunks/_plugin-vue_export-helper-CInC0bKI.es.js +0 -6
- package/dist/chunks/constants-CY3R3_kF.es.js +0 -3
- package/dist/chunks/constants-sbCZ2O_A.cjs +0 -14
- package/dist/chunks/jszip-C8srOKAO.es.js +0 -4650
- package/dist/chunks/jszip-Cs9JBLlJ.cjs +0 -4691
|
@@ -25,8 +25,16 @@ export type { BrowserDocumentApi } from '../../public/browser-document-api.js';
|
|
|
25
25
|
export interface ToolbarDropdownOption {
|
|
26
26
|
/** Row text, and the default command argument when the row is chosen. */
|
|
27
27
|
label?: string;
|
|
28
|
-
/**
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Stable row identity, used for selection state and handed to the command.
|
|
30
|
+
*
|
|
31
|
+
* Numbers included, because the built-in zoom dropdown uses them
|
|
32
|
+
* (`key: 0.5`, `key: 1`) and the runtime passes the value through
|
|
33
|
+
* unchanged. This is what a `command` callback reads as `context.option`,
|
|
34
|
+
* so a string-only declaration here made a numeric key unusable at the far
|
|
35
|
+
* end even once the config side accepted it.
|
|
36
|
+
*/
|
|
37
|
+
key?: string | number;
|
|
30
38
|
/** Attributes spread onto the rendered row. */
|
|
31
39
|
props?: Record<string, unknown>;
|
|
32
40
|
[key: string]: unknown;
|
|
@@ -56,37 +64,350 @@ export interface ToolbarCustomButtonContext extends CustomCommandContext {
|
|
|
56
64
|
argument?: unknown;
|
|
57
65
|
}
|
|
58
66
|
/**
|
|
59
|
-
*
|
|
67
|
+
* What a custom toolbar entry does when activated.
|
|
60
68
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
* A function is registered as a custom command and invoked with
|
|
70
|
+
* {@link ToolbarCustomButtonContext}; a string is read as a canonical V2
|
|
71
|
+
* command id and routed through the shared controller. An unknown id is
|
|
72
|
+
* accepted at compile time and then reported through the toolbar's
|
|
73
|
+
* `exception` event as "Command not handled" -- so the string form stays
|
|
74
|
+
* unnarrowed, but a typo is diagnosed at runtime rather than ignored.
|
|
75
|
+
*/
|
|
76
|
+
export type ToolbarCustomButtonCommand = string | ((context: ToolbarCustomButtonContext) => unknown);
|
|
77
|
+
/** Members every custom toolbar entry carries, whatever its type. */
|
|
78
|
+
interface ToolbarCustomEntryBase {
|
|
79
|
+
/**
|
|
80
|
+
* Unique item name, which also derives the registered command id and the
|
|
81
|
+
* rendered `data-item` attribute.
|
|
82
|
+
*
|
|
83
|
+
* Uniqueness is enforced at construction rather than here: a name that
|
|
84
|
+
* repeats, or that matches a built-in item, used to render a second control
|
|
85
|
+
* under the same `data-item` with neither responding.
|
|
86
|
+
*/
|
|
76
87
|
name: string;
|
|
88
|
+
/** Which toolbar group the entry joins. Defaults to `center`. */
|
|
89
|
+
group?: 'left' | 'center' | 'right' | (string & {});
|
|
90
|
+
/** Hover text. */
|
|
91
|
+
tooltip?: string;
|
|
92
|
+
/** Render the entry as unavailable. Honored: a disabled entry does not run. */
|
|
93
|
+
disabled?: boolean;
|
|
94
|
+
/** Extra DOM hooks. Both are read straight onto the rendered control. */
|
|
95
|
+
attributes?: {
|
|
96
|
+
/**
|
|
97
|
+
* Appended to the item's class list. Any value Vue's `class` binding
|
|
98
|
+
* takes: a string, an array, a condition map, or a nesting of those.
|
|
99
|
+
*
|
|
100
|
+
* AIDEV-NOTE: unconstrained for the same reason as `dropdownStyles`, and
|
|
101
|
+
* verified rather than assumed. This lands inside an array binding --
|
|
102
|
+
* `ToolbarButton` renders `:class="['sd-toolbar-item',
|
|
103
|
+
* attributes.className]"` -- so Vue resolves it, and `string` rejected
|
|
104
|
+
* `['compact', { active: isActive }]`, the ordinary way to write a
|
|
105
|
+
* conditional class. There is also nothing to import or mirror:
|
|
106
|
+
* `@vue/shared` types the input as `normalizeClass(value: unknown)`, so
|
|
107
|
+
* Vue does not name this shape either, and any union written here would
|
|
108
|
+
* be narrower than what Vue accepts. A browser test asserts the array and
|
|
109
|
+
* the condition map both resolve, including that a false branch is
|
|
110
|
+
* dropped rather than stringified.
|
|
111
|
+
*/
|
|
112
|
+
className?: unknown;
|
|
113
|
+
/** Sets `aria-label`, which is otherwise absent on a custom entry. */
|
|
114
|
+
ariaLabel?: string;
|
|
115
|
+
};
|
|
116
|
+
/** Render the control at reduced width. */
|
|
117
|
+
isNarrow?: boolean;
|
|
118
|
+
/** Render the control at increased width. */
|
|
119
|
+
isWide?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* `active` and `activeIcon` are rejected by name because both are dead.
|
|
122
|
+
* `useToolbarItem` hard-codes the initial active state to `false` and
|
|
123
|
+
* discards the option, and nothing in the toolbar reads `activeIcon`. Set
|
|
124
|
+
* the state from the command instead, which does work.
|
|
125
|
+
*/
|
|
126
|
+
active?: never;
|
|
127
|
+
activeIcon?: never;
|
|
128
|
+
/**
|
|
129
|
+
* Open on purpose. `useToolbarItem` accepts 37 fields and forwards them, and
|
|
130
|
+
* closing this list around the ones I could enumerate rejected seven working
|
|
131
|
+
* configurations in review -- `label`, `hasCaret`, `dropdownValueKey`, row
|
|
132
|
+
* `icon`, `attributes`, `splitButton`, `argument` -- each of which renders or
|
|
133
|
+
* is forwarded by code the enumeration missed.
|
|
134
|
+
*
|
|
135
|
+
* So the guarantees here are structural rather than exhaustive: which `type`
|
|
136
|
+
* values render at all, that a button and a dropdown each have something
|
|
137
|
+
* visible, that a dropdown has rows, and that the two dead fields above are
|
|
138
|
+
* refused. A misspelled rare field still compiles, which is the same
|
|
139
|
+
* trade-off `CommentsConfig` makes for the same reason -- the runtime passes
|
|
140
|
+
* the whole bag through, so a closed type would be wrong more often than a
|
|
141
|
+
* typo is.
|
|
142
|
+
*/
|
|
143
|
+
[key: string]: unknown;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* A custom button.
|
|
147
|
+
*
|
|
148
|
+
* `icon` is required, which is stricter than the runtime check and deliberately
|
|
149
|
+
* so. Construction accepts `icon` **or** `defaultLabel`, but only the icon
|
|
150
|
+
* reaches the DOM: a button carrying `defaultLabel` alone builds, mounts, and
|
|
151
|
+
* draws nothing, leaving an empty control in the toolbar. Requiring `icon`
|
|
152
|
+
* keeps this type to shapes that produce something a user can see.
|
|
153
|
+
*
|
|
154
|
+
* `label` is not accepted at all. It is the *live* label a built-in item
|
|
155
|
+
* rewrites as state changes, it does not satisfy the affordance check, and a
|
|
156
|
+
* button carrying only `label` is rejected at construction.
|
|
157
|
+
*
|
|
158
|
+
* AIDEV-NOTE: `defaultLabel` renders nothing for a custom button. The check in
|
|
159
|
+
* `use-toolbar-item.js` treats it as an affordance and `ToolbarButton.vue`
|
|
160
|
+
* never draws it. Widening this type to accept `defaultLabel` alone requires
|
|
161
|
+
* fixing that render first, or it re-admits invisible buttons (#1098).
|
|
162
|
+
*/
|
|
163
|
+
export interface ToolbarCustomButtonItem extends ToolbarCustomEntryBase {
|
|
164
|
+
type: 'button';
|
|
165
|
+
/** Inline SVG or markup. The only thing a custom button actually renders. */
|
|
166
|
+
icon: string;
|
|
77
167
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
168
|
+
* Static label kept for the affordance check and for parity with the legacy
|
|
169
|
+
* spelling. It does not render today; pair it with `icon`, never alone.
|
|
170
|
+
*/
|
|
171
|
+
defaultLabel?: string;
|
|
172
|
+
/**
|
|
173
|
+
* Visible text drawn beside the icon. Unlike `defaultLabel` this really is
|
|
174
|
+
* rendered, but it does not satisfy the affordance check on its own, so it
|
|
175
|
+
* accompanies `icon` rather than replacing it.
|
|
176
|
+
*/
|
|
177
|
+
label?: string;
|
|
178
|
+
/**
|
|
179
|
+
* What the button does. Optional because omitting it renders a control that
|
|
180
|
+
* does nothing rather than failing, which is legal today; an entry meant to
|
|
181
|
+
* be actionable should always carry one.
|
|
182
|
+
*/
|
|
183
|
+
command?: ToolbarCustomButtonCommand;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* One selectable row in a custom dropdown.
|
|
187
|
+
*
|
|
188
|
+
* Both members are required: `key` is what reaches the command through
|
|
189
|
+
* {@link ToolbarCustomButtonContext.option}, and `label` is the only text the
|
|
190
|
+
* row renders, so a row missing either draws blank or selects as `undefined`.
|
|
191
|
+
*/
|
|
192
|
+
interface ToolbarCustomDropdownOptionBase {
|
|
193
|
+
/**
|
|
194
|
+
* Drawn beside the row's label, or a function returning it.
|
|
82
195
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
196
|
+
* Not string-only: `OptionIcon` returns whatever this resolves to straight
|
|
197
|
+
* from a render function, so a Vue VNode works as well as markup.
|
|
198
|
+
*
|
|
199
|
+
* `object` rather than `Record<string, unknown>`, which was the first
|
|
200
|
+
* attempt and admitted only inferred object literals -- a value already
|
|
201
|
+
* typed as Vue's `VNode` has no string index signature and so failed to
|
|
202
|
+
* assign. `object` accepts both without importing Vue's types into the
|
|
203
|
+
* public surface.
|
|
204
|
+
*/
|
|
205
|
+
icon?: string | object | ((option: ToolbarCustomDropdownOption) => unknown);
|
|
206
|
+
/** Render the row as unavailable. */
|
|
207
|
+
disabled?: boolean;
|
|
208
|
+
/** Added to the row's class list. */
|
|
209
|
+
class?: unknown;
|
|
210
|
+
/**
|
|
211
|
+
* Spread onto the rendered row as attributes, and its `class` is merged
|
|
212
|
+
* with the one above. Declared here as well as on `ToolbarDropdownOption`,
|
|
213
|
+
* which it mirrors.
|
|
214
|
+
*/
|
|
215
|
+
props?: Record<string, unknown>;
|
|
216
|
+
/**
|
|
217
|
+
* Open, like the `ToolbarDropdownOption` it mirrors, because
|
|
218
|
+
* `dropdownValueKey` names a member to read dynamically: a row can carry
|
|
219
|
+
* `{ label, key, value }` and send `value` to the command. Closing this
|
|
220
|
+
* would make that shape uncompilable while it still works.
|
|
86
221
|
*/
|
|
87
|
-
command?: string | ((context: ToolbarCustomButtonContext) => unknown);
|
|
88
222
|
[key: string]: unknown;
|
|
89
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* One row in a custom dropdown.
|
|
226
|
+
*
|
|
227
|
+
* A selectable row needs both `label` and `key`: `label` is the only text it
|
|
228
|
+
* renders, and `key` is what reaches the command through
|
|
229
|
+
* {@link ToolbarCustomButtonContext.option}.
|
|
230
|
+
*
|
|
231
|
+
* A `type: 'render'` row is the exception and is why this is a union rather
|
|
232
|
+
* than one interface. `ToolbarDropdown` routes those to its `RenderOption`
|
|
233
|
+
* branch and never reads `label` for them, so requiring it would reject rows
|
|
234
|
+
* the runtime supports -- which the first version of this type did.
|
|
235
|
+
*/
|
|
236
|
+
export type ToolbarCustomDropdownOption = (ToolbarCustomDropdownOptionBase & {
|
|
237
|
+
/**
|
|
238
|
+
* Application metadata. A row carrying `{ type: 'action', label, key }`
|
|
239
|
+
* stays selectable and reaches the command verbatim, so this member is
|
|
240
|
+
* open.
|
|
241
|
+
*
|
|
242
|
+
* AIDEV-NOTE: that openness means `{ type: 'render', label, key }` with
|
|
243
|
+
* no renderer still matches this branch, so the render branch's
|
|
244
|
+
* required `render` does not catch it (#1098). `Exclude<string,
|
|
245
|
+
* 'render'>` does not help -- subtracting a literal from the wide
|
|
246
|
+
* `string` type leaves `string` -- and neither does a branded
|
|
247
|
+
* intersection, because a plain string literal remains assignable to
|
|
248
|
+
* both. Closing this needs a literal union of the metadata values the
|
|
249
|
+
* product supports, which is a contract decision rather than a
|
|
250
|
+
* transcription. The runtime treats such a row as render-only and draws
|
|
251
|
+
* a blank, inert row.
|
|
252
|
+
*/
|
|
253
|
+
type?: string;
|
|
254
|
+
/** Text rendered for the row. */
|
|
255
|
+
label: string;
|
|
256
|
+
/**
|
|
257
|
+
* Value handed to the command when this row is chosen, and the row's
|
|
258
|
+
* Vue key. Numbers are allowed because the built-in zoom dropdown uses
|
|
259
|
+
* them (`key: 0.5`, `key: 1`), and `ButtonGroup` passes the value
|
|
260
|
+
* through to `selectedValue` unchanged.
|
|
261
|
+
*/
|
|
262
|
+
key: string | number;
|
|
263
|
+
}) | (ToolbarCustomDropdownOptionBase & {
|
|
264
|
+
/** Rendered through `RenderOption` rather than as a selectable row. */
|
|
265
|
+
type: 'render';
|
|
266
|
+
/**
|
|
267
|
+
* Required, because `RenderOption` returns `null` unless this is
|
|
268
|
+
* callable. A render row is also excluded from selection, so one
|
|
269
|
+
* without a renderer is a permanently blank row that cannot be clicked.
|
|
270
|
+
*/
|
|
271
|
+
render: () => unknown;
|
|
272
|
+
label?: string;
|
|
273
|
+
key?: string | number;
|
|
274
|
+
});
|
|
275
|
+
/**
|
|
276
|
+
* A custom dropdown.
|
|
277
|
+
*
|
|
278
|
+
* `options` is required and must be non-empty: a dropdown with no rows, or an
|
|
279
|
+
* empty array, renders no trigger at all, so the entry silently disappears
|
|
280
|
+
* rather than drawing something inert.
|
|
281
|
+
*
|
|
282
|
+
* The trigger rule is looser than a button's -- `label` works here as well as
|
|
283
|
+
* `icon` -- because the dropdown draws its own trigger rather than going
|
|
284
|
+
* through the button affordance check.
|
|
285
|
+
*/
|
|
286
|
+
interface ToolbarCustomDropdownBase extends ToolbarCustomEntryBase {
|
|
287
|
+
type: 'dropdown';
|
|
288
|
+
/**
|
|
289
|
+
* Static fallback trigger text. Present for parity with the legacy spelling
|
|
290
|
+
* and does not render, which is why it does not satisfy the trigger
|
|
291
|
+
* requirement below.
|
|
292
|
+
*/
|
|
293
|
+
defaultLabel?: string;
|
|
294
|
+
/**
|
|
295
|
+
* The rows the dropdown offers. Empty is accepted, and is not a mistake on
|
|
296
|
+
* its own: `#updateHighlightColors` assigns `nestedOptions` after the item
|
|
297
|
+
* is built, so a dropdown can construct empty and fill in later. An empty
|
|
298
|
+
* one renders no menu rather than breaking -- `ButtonGroup` guards the
|
|
299
|
+
* branch on `nestedOptions.value.length`.
|
|
300
|
+
*
|
|
301
|
+
* AIDEV-NOTE: this was a nonempty tuple until #1188 review. The tuple did
|
|
302
|
+
* reject `options: []`, and it also rejected every array TypeScript cannot
|
|
303
|
+
* see the length of -- `rows.map(...)`, a `Row[]` variable, a function
|
|
304
|
+
* return. Those are how dropdown rows are normally built; `lineHeight` in
|
|
305
|
+
* `default-items.js` builds its own rows with `.map()`. The obvious escape,
|
|
306
|
+
* `readonly T[] & { 0: T }`, rejects all four (measured, not assumed): an
|
|
307
|
+
* array type carries no index-0 property for the intersection to satisfy.
|
|
308
|
+
* So please do not reintroduce a tuple here -- and note there is no runtime
|
|
309
|
+
* check to fall back on either, deliberately, because an empty dropdown is
|
|
310
|
+
* a legitimate intermediate state.
|
|
311
|
+
*
|
|
312
|
+
* `readonly` so an `as const` array is accepted: the runtime only iterates
|
|
313
|
+
* this and copies the elements into `nestedOptions`, never mutating the
|
|
314
|
+
* consumer's array.
|
|
315
|
+
*/
|
|
316
|
+
options: readonly ToolbarCustomDropdownOption[];
|
|
317
|
+
/** Draw the dropdown caret beside the trigger. Rendered by `ToolbarButton`. */
|
|
318
|
+
hasCaret?: boolean;
|
|
319
|
+
/**
|
|
320
|
+
* Which member of the selected row becomes the command's `argument`.
|
|
321
|
+
*
|
|
322
|
+
* Defaults to `label`, not `key`: `ButtonGroup.handleSelect` reads
|
|
323
|
+
* `option[dropdownValueKey]` and falls back to `option.label` when this is
|
|
324
|
+
* unset. So a dropdown whose display text differs from its value has to set
|
|
325
|
+
* `'key'` explicitly, or the command receives the text a user sees rather
|
|
326
|
+
* than the value it stands for. Any member name works, not just `key`: a row
|
|
327
|
+
* carrying `{ label, key, value }` can send `value`. `context.option` always
|
|
328
|
+
* carries the whole row either way.
|
|
329
|
+
*/
|
|
330
|
+
dropdownValueKey?: string;
|
|
331
|
+
/**
|
|
332
|
+
* Inline styles for the dropdown's own element -- its trigger and wrapper --
|
|
333
|
+
* forwarded unchanged to Vue's `:style` binding.
|
|
334
|
+
*
|
|
335
|
+
* Not the open panel: `ButtonGroup` styles that separately through
|
|
336
|
+
* `menu-props`, which `customButtons` cannot reach. Widths set here size the
|
|
337
|
+
* control in the toolbar, not the menu it opens.
|
|
338
|
+
*
|
|
339
|
+
* AIDEV-NOTE: deliberately unconstrained. Restating Vue's `StyleValue` here
|
|
340
|
+
* was attempted three times and was wrong each time -- string-valued
|
|
341
|
+
* objects rejected `{ padding: 0 }`, object-only rejected
|
|
342
|
+
* `'min-width: 200px'`, and a hand-written union rejected a value already
|
|
343
|
+
* typed as `CSSProperties`, whose index signature a structural restatement
|
|
344
|
+
* does not match. The shape set is Vue's to define and moves with Vue, so
|
|
345
|
+
* mirroring it by hand keeps rejecting working configuration. Importing
|
|
346
|
+
* `StyleValue` would pull a Vue type into the public surface, which this
|
|
347
|
+
* package avoids elsewhere.
|
|
348
|
+
*/
|
|
349
|
+
dropdownStyles?: unknown;
|
|
350
|
+
/**
|
|
351
|
+
* `key` of the row to show as selected before the user picks one. Matches
|
|
352
|
+
* the row `key` type, numbers included.
|
|
353
|
+
*/
|
|
354
|
+
selectedValue?: string | number;
|
|
355
|
+
/** Invoked with the chosen row on {@link ToolbarCustomButtonContext.option}. */
|
|
356
|
+
command?: ToolbarCustomButtonCommand;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* A dropdown needs a trigger a user can see, and it has three ways to draw
|
|
360
|
+
* one. `ToolbarButton` renders `icon` and `label` in its non-split branch and,
|
|
361
|
+
* beside them, `.sd-dropdown-caret` on `v-if="hasCaret"` alone -- so a compact
|
|
362
|
+
* caret-only dropdown is a real control, not an oversight. It renders with a
|
|
363
|
+
* measurable width and opens its rows; only `defaultLabel` draws nothing.
|
|
364
|
+
*
|
|
365
|
+
* Splitting the variant is what makes at-least-one enforceable rather than
|
|
366
|
+
* advisory. Pair a caret-only trigger with `attributes.ariaLabel`, since
|
|
367
|
+
* there is no text for a screen reader to announce.
|
|
368
|
+
*/
|
|
369
|
+
export type ToolbarCustomDropdownItem = (ToolbarCustomDropdownBase & {
|
|
370
|
+
icon: string;
|
|
371
|
+
label?: string;
|
|
372
|
+
hasCaret?: boolean;
|
|
373
|
+
}) | (ToolbarCustomDropdownBase & {
|
|
374
|
+
label: string;
|
|
375
|
+
icon?: string;
|
|
376
|
+
hasCaret?: boolean;
|
|
377
|
+
}) | (ToolbarCustomDropdownBase & {
|
|
378
|
+
hasCaret: true;
|
|
379
|
+
icon?: string;
|
|
380
|
+
label?: string;
|
|
381
|
+
});
|
|
382
|
+
/** A visual divider. Renders on its own and has nothing to run. */
|
|
383
|
+
export interface ToolbarCustomSeparatorItem extends ToolbarCustomEntryBase {
|
|
384
|
+
type: 'separator';
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* A custom entry appended to the built-in toolbar's default item set.
|
|
388
|
+
*
|
|
389
|
+
* What this guarantees is structural, not exhaustive. Each variant fixes the
|
|
390
|
+
* shape of the entry -- which `type` values render at all, that a button and a
|
|
391
|
+
* dropdown each carry something visible, that a dropdown has rows -- while the
|
|
392
|
+
* field list itself stays open, because `useToolbarItem` accepts 37 fields and
|
|
393
|
+
* forwards them. Closing that list rejected eight working configurations
|
|
394
|
+
* during review, and a rejected working config is a worse failure than the
|
|
395
|
+
* autocomplete it buys.
|
|
396
|
+
*
|
|
397
|
+
* Two of the five `useToolbarItem` types are absent because they render
|
|
398
|
+
* nothing: `options` constructs without throwing and `ButtonGroup` has no
|
|
399
|
+
* branch for it, and `overflow` draws only from the separately-built overflow
|
|
400
|
+
* list, which `customButtons` cannot populate.
|
|
401
|
+
*
|
|
402
|
+
* Two fields are refused by name on {@link ToolbarCustomEntryBase} for the
|
|
403
|
+
* same reason: `active` is discarded (`useToolbarItem` hard-codes the initial
|
|
404
|
+
* state to `false`) and `activeIcon` has no toolbar reader at all.
|
|
405
|
+
*
|
|
406
|
+
* Derived from a rendered-behavior survey rather than from the constructor
|
|
407
|
+
* (#1098): construction succeeding proves only that nothing threw, which for
|
|
408
|
+
* this surface was never the same question as whether a control appeared.
|
|
409
|
+
*/
|
|
410
|
+
export type ToolbarCustomButton = ToolbarCustomButtonItem | ToolbarCustomDropdownItem | ToolbarCustomSeparatorItem;
|
|
90
411
|
export type V2AuthoringSelectionCollapse = 'start' | 'end' | null;
|
|
91
412
|
export type V2AuthoringResult = {
|
|
92
413
|
ok: true;
|
|
@@ -843,6 +1164,111 @@ export type LinkPopoverResolution = {
|
|
|
843
1164
|
* default popover.
|
|
844
1165
|
*/
|
|
845
1166
|
export type LinkPopoverResolver = (ctx: LinkPopoverContext) => LinkPopoverResolution | null | undefined;
|
|
1167
|
+
/**
|
|
1168
|
+
* Canonical presentation settings for the built-in comments UI.
|
|
1169
|
+
*
|
|
1170
|
+
* Presentation only, and deliberately not the whole of `modules.comments`.
|
|
1171
|
+
* That block also carries `readOnly` and `allowResolve`, which resolve through
|
|
1172
|
+
* `interaction.comments`, and `permissionResolver`, which is read off
|
|
1173
|
+
* `modules.comments` or the top-level `Config`. All three are stripped from
|
|
1174
|
+
* this bag: policy outlives the built-in UI, so an application drawing its own
|
|
1175
|
+
* comment surface still has to honor it. See the fields themselves, which are
|
|
1176
|
+
* rejected by name with the spelling that applies to each.
|
|
1177
|
+
*
|
|
1178
|
+
* Open on purpose, for the same reason `modules.comments` is: the runtime
|
|
1179
|
+
* merges this bag over that block and spreads the result through the comments
|
|
1180
|
+
* store, which accepts pass-through keys. Closing it would reject working
|
|
1181
|
+
* configurations, which is a worse failure than the missing autocomplete it
|
|
1182
|
+
* would buy. The named fields are the ones the shell reads.
|
|
1183
|
+
*/
|
|
1184
|
+
export type CommentsConfig = {
|
|
1185
|
+
/** How comments present themselves as the surface narrows. */
|
|
1186
|
+
displayMode?: 'auto' | 'sidebar' | 'inline';
|
|
1187
|
+
/** CSS selector for an explicit width measurement target in `auto` mode. */
|
|
1188
|
+
compactMeasurementSelector?: string;
|
|
1189
|
+
/** Fixed compact-mode breakpoint override, in pixels. */
|
|
1190
|
+
compactBreakpointPx?: number;
|
|
1191
|
+
/** Comment highlight colors (internal/external and active overrides). */
|
|
1192
|
+
highlightColors?: {
|
|
1193
|
+
/** Base highlight color for internal comments. */
|
|
1194
|
+
internal?: string;
|
|
1195
|
+
/** Base highlight color for external comments. */
|
|
1196
|
+
external?: string;
|
|
1197
|
+
/** Active highlight color override for internal comments. */
|
|
1198
|
+
activeInternal?: string;
|
|
1199
|
+
/** Active highlight color override for external comments. */
|
|
1200
|
+
activeExternal?: string;
|
|
1201
|
+
};
|
|
1202
|
+
/** Comment highlight opacity, active and inactive. */
|
|
1203
|
+
highlightOpacity?: {
|
|
1204
|
+
/** Opacity for the active comment highlight. */
|
|
1205
|
+
active?: number;
|
|
1206
|
+
/** Opacity for inactive comment highlights. */
|
|
1207
|
+
inactive?: number;
|
|
1208
|
+
};
|
|
1209
|
+
/** Highlight color used while hovering a comment. */
|
|
1210
|
+
highlightHoverColor?: string;
|
|
1211
|
+
/** Tracked-change highlight colors. */
|
|
1212
|
+
trackChangeHighlightColors?: TrackChangeHighlightColors;
|
|
1213
|
+
/** Active tracked-change highlight colors (defaults to the above). */
|
|
1214
|
+
trackChangeActiveHighlightColors?: TrackChangeHighlightColors;
|
|
1215
|
+
/**
|
|
1216
|
+
* Policy, not presentation. `normalizeUiConfig` strips all three from this
|
|
1217
|
+
* bag before anything reads it, so accepting them here would advertise a
|
|
1218
|
+
* setting that is silently discarded.
|
|
1219
|
+
*
|
|
1220
|
+
* `readOnly` and `allowResolve` belong on `interaction.comments`, where they
|
|
1221
|
+
* resolve and keep applying to an application drawing its own comment
|
|
1222
|
+
* surface.
|
|
1223
|
+
*
|
|
1224
|
+
* `permissionResolver` is collaboration wiring rather than policy, and has
|
|
1225
|
+
* no `ui` spelling at all. `pickResolver` takes the first of
|
|
1226
|
+
* `modules.comments.permissionResolver` and the top-level
|
|
1227
|
+
* `Config.permissionResolver`, in that order, so either works and the
|
|
1228
|
+
* comments-scoped one wins.
|
|
1229
|
+
*/
|
|
1230
|
+
readOnly?: never;
|
|
1231
|
+
allowResolve?: never;
|
|
1232
|
+
permissionResolver?: never;
|
|
1233
|
+
} & Record<string, unknown>;
|
|
1234
|
+
/** Border and background colors for one tracked-change highlight state. */
|
|
1235
|
+
export interface TrackChangeHighlightColors {
|
|
1236
|
+
/** Border color for inserted text. */
|
|
1237
|
+
insertBorder?: string;
|
|
1238
|
+
/** Background color for inserted text. */
|
|
1239
|
+
insertBackground?: string;
|
|
1240
|
+
/** Border color for deleted text. */
|
|
1241
|
+
deleteBorder?: string;
|
|
1242
|
+
/** Background color for deleted text. */
|
|
1243
|
+
deleteBackground?: string;
|
|
1244
|
+
/** Border color for a format change. */
|
|
1245
|
+
formatBorder?: string;
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Canonical configuration for the chrome drawn around content controls.
|
|
1249
|
+
*
|
|
1250
|
+
* `chrome` is the whole option bag this surface has. `'default'` and `'none'`
|
|
1251
|
+
* are the only values the painter and the v2 host accept; anything else is
|
|
1252
|
+
* coerced back to `'default'`.
|
|
1253
|
+
*/
|
|
1254
|
+
export interface ContentControlsConfig {
|
|
1255
|
+
/** Whether SuperDoc draws its own chrome around each content control. */
|
|
1256
|
+
chrome?: 'default' | 'none';
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Canonical configuration for the built-in link popover.
|
|
1260
|
+
*
|
|
1261
|
+
* `popoverResolver` supersedes `modules.links.popoverResolver`, which stays
|
|
1262
|
+
* supported for all of v2. Setting both keeps the canonical one; the legacy
|
|
1263
|
+
* spelling only applies when the canonical one is absent.
|
|
1264
|
+
*/
|
|
1265
|
+
export interface LinkPopoverConfig {
|
|
1266
|
+
/**
|
|
1267
|
+
* Called when a user clicks a link, to decide which popover to show.
|
|
1268
|
+
* Returning `null` or `undefined` falls back to the built-in popover.
|
|
1269
|
+
*/
|
|
1270
|
+
popoverResolver?: LinkPopoverResolver;
|
|
1271
|
+
}
|
|
846
1272
|
/** Context object passed to context menu callbacks (showWhen, render, action, menuProvider). */
|
|
847
1273
|
export interface ContextMenuContext {
|
|
848
1274
|
/** The editor instance. */
|
|
@@ -1650,6 +2076,17 @@ export interface FindReplaceConfig {
|
|
|
1650
2076
|
width?: number | string;
|
|
1651
2077
|
maxWidth?: number | string;
|
|
1652
2078
|
maxHeight?: number | string;
|
|
2079
|
+
/**
|
|
2080
|
+
* Focus the find input when the surface opens. Defaults to `true`; set
|
|
2081
|
+
* `false` to leave focus wherever the user had it.
|
|
2082
|
+
*
|
|
2083
|
+
* Honored but undeclared until #1094: `useFindReplace` spreads this whole
|
|
2084
|
+
* bag into the surface request, and `SurfaceManager` applies it last, over
|
|
2085
|
+
* the `modules.surfaces.floating` defaults.
|
|
2086
|
+
*/
|
|
2087
|
+
autoFocus?: boolean;
|
|
2088
|
+
/** Close the surface on a pointer press outside it. Defaults to `false`. */
|
|
2089
|
+
closeOnOutsidePointerDown?: boolean;
|
|
1653
2090
|
};
|
|
1654
2091
|
}
|
|
1655
2092
|
/**
|
|
@@ -2439,18 +2876,36 @@ export interface SuperDocExceptionEditorPayload {
|
|
|
2439
2876
|
code?: string;
|
|
2440
2877
|
documentId?: string | null;
|
|
2441
2878
|
}
|
|
2879
|
+
/**
|
|
2880
|
+
* Exception payload raised by the built-in toolbar.
|
|
2881
|
+
*
|
|
2882
|
+
* Emitted for a command that failed and for a custom entry the toolbar could
|
|
2883
|
+
* not build, in which case `itemName` is the entry that was skipped and the
|
|
2884
|
+
* message names the field that would fix it. Reaches the host as well as the
|
|
2885
|
+
* toolbar, because entries are built inside the toolbar constructor and
|
|
2886
|
+
* nothing can have subscribed to the toolbar yet.
|
|
2887
|
+
*/
|
|
2888
|
+
export interface SuperDocExceptionToolbarPayload {
|
|
2889
|
+
error: Error;
|
|
2890
|
+
/** The value originally thrown, before it was normalized to an `Error`. */
|
|
2891
|
+
originalError: unknown;
|
|
2892
|
+
/** The toolbar item involved, or `null` when the entry had no usable name. */
|
|
2893
|
+
itemName: string | null;
|
|
2894
|
+
editor?: Editor | null;
|
|
2895
|
+
}
|
|
2442
2896
|
/**
|
|
2443
2897
|
* Union of all `exception` event payloads SuperDoc emits at runtime.
|
|
2444
|
-
* Consumers can narrow with `'stage' in payload` (store init)
|
|
2445
|
-
* `'code' in payload` (editor lifecycle)
|
|
2898
|
+
* Consumers can narrow with `'stage' in payload` (store init),
|
|
2899
|
+
* `'code' in payload` (editor lifecycle), or `'itemName' in payload`
|
|
2900
|
+
* (built-in toolbar).
|
|
2446
2901
|
*
|
|
2447
|
-
* The union exists today because
|
|
2448
|
-
* (`initializeDocuments`, the restore path,
|
|
2449
|
-
* pre-date a shared error contract. Normalizing them to a
|
|
2450
|
-
* payload shape is a separate follow-up; consumers can narrow with
|
|
2902
|
+
* The union exists today because four independent emit sites
|
|
2903
|
+
* (`initializeDocuments`, the restore path, the editor lifecycle, and the
|
|
2904
|
+
* built-in toolbar) pre-date a shared error contract. Normalizing them to a
|
|
2905
|
+
* single payload shape is a separate follow-up; consumers can narrow with
|
|
2451
2906
|
* the `in` checks above in the meantime.
|
|
2452
2907
|
*/
|
|
2453
|
-
export type SuperDocExceptionPayload = SuperDocExceptionStorePayload | SuperDocExceptionRestorePayload | SuperDocExceptionEditorPayload;
|
|
2908
|
+
export type SuperDocExceptionPayload = SuperDocExceptionStorePayload | SuperDocExceptionRestorePayload | SuperDocExceptionEditorPayload | SuperDocExceptionToolbarPayload;
|
|
2454
2909
|
/**
|
|
2455
2910
|
* Zoom mode. `manual` holds whatever value was last set; `fit-width`
|
|
2456
2911
|
* continuously recomputes the zoom that fits the page width into the
|
|
@@ -2638,12 +3093,16 @@ export interface UIConfig {
|
|
|
2638
3093
|
*/
|
|
2639
3094
|
fonts?: ToolbarFontOption[];
|
|
2640
3095
|
/**
|
|
2641
|
-
* Custom toolbar
|
|
3096
|
+
* Custom toolbar entries appended to the default item set. See
|
|
3097
|
+
* `ToolbarCustomButton` for which shapes render.
|
|
2642
3098
|
*
|
|
2643
|
-
* `
|
|
2644
|
-
*
|
|
3099
|
+
* `readonly` so an `as const` array is accepted. Without it the array
|
|
3100
|
+
* built in a separate variable had no way through: widening turns each
|
|
3101
|
+
* `type` into `string`, `as const` is the documented answer to that,
|
|
3102
|
+
* and a mutable field then rejected the result. The toolbar only reads
|
|
3103
|
+
* this.
|
|
2645
3104
|
*/
|
|
2646
|
-
customButtons?: ToolbarCustomButton[];
|
|
3105
|
+
customButtons?: readonly ToolbarCustomButton[];
|
|
2647
3106
|
/**
|
|
2648
3107
|
* Show the formatting marks (pilcrow) button in the toolbar. Off by
|
|
2649
3108
|
* default. Distinct from `layoutEngineOptions.showFormattingMarks`, which
|
|
@@ -2654,7 +3113,7 @@ export interface UIConfig {
|
|
|
2654
3113
|
showTableOfContentsButton?: boolean;
|
|
2655
3114
|
};
|
|
2656
3115
|
/** Built-in comments UI. Enabled by default. */
|
|
2657
|
-
comments?: boolean |
|
|
3116
|
+
comments?: boolean | CommentsConfig;
|
|
2658
3117
|
/** Built-in right-click and slash context menu. Enabled by default. */
|
|
2659
3118
|
contextMenu?: boolean | ContextMenuConfig;
|
|
2660
3119
|
/**
|
|
@@ -2662,16 +3121,20 @@ export interface UIConfig {
|
|
|
2662
3121
|
* SuperDoc intercept Cmd+F / Ctrl+F; `editor.ui.search` stays available to
|
|
2663
3122
|
* custom UI either way.
|
|
2664
3123
|
*/
|
|
2665
|
-
search?: boolean |
|
|
2666
|
-
/**
|
|
2667
|
-
|
|
3124
|
+
search?: boolean | FindReplaceConfig;
|
|
3125
|
+
/**
|
|
3126
|
+
* Built-in popover shown when a link is clicked. It renders by default;
|
|
3127
|
+
* pass `false` (or `ui: false`) to suppress it. Supplying a
|
|
3128
|
+
* {@link LinkPopoverConfig.popoverResolver} replaces it with your own UI.
|
|
3129
|
+
*/
|
|
3130
|
+
linkPopover?: boolean | LinkPopoverConfig;
|
|
2668
3131
|
/** Built-in ruler. Disabled by default. */
|
|
2669
3132
|
ruler?: boolean | {
|
|
2670
3133
|
/** Element or selector to render the ruler into. */
|
|
2671
3134
|
container?: string | HTMLElement;
|
|
2672
3135
|
};
|
|
2673
3136
|
/** Built-in chrome drawn around content controls. Enabled by default. */
|
|
2674
|
-
contentControls?: boolean |
|
|
3137
|
+
contentControls?: boolean | ContentControlsConfig;
|
|
2675
3138
|
}
|
|
2676
3139
|
/**
|
|
2677
3140
|
* What the user is permitted to do, as distinct from what SuperDoc draws.
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a context-menu event landed inside the tracked-change carrier that
|
|
3
|
+
* is already visually active. The review visual owner maintains this marker,
|
|
4
|
+
* so the right-click path can stay synchronous and avoid a catalog lookup or
|
|
5
|
+
* document-wide DOM query.
|
|
6
|
+
*
|
|
7
|
+
* @param {EventTarget | null} target
|
|
8
|
+
* @returns {boolean}
|
|
9
|
+
*/
|
|
10
|
+
export function isActiveTrackedChangeContextMenuTarget(target: EventTarget | null): boolean;
|
|
1
11
|
/**
|
|
2
12
|
* Normalize adaptive comments UI policy fields.
|
|
3
13
|
*
|
|
@@ -12,7 +12,7 @@ export function createV2ReviewMutationReconciler({ getContext, reconcile, hydrat
|
|
|
12
12
|
onReconciled: any;
|
|
13
13
|
}): {
|
|
14
14
|
enqueue: (impact: any) => void;
|
|
15
|
-
enqueueAfterPaint(impact: any, waitForPaint: any):
|
|
15
|
+
enqueueAfterPaint(impact: any, waitForPaint: any): Promise<any>;
|
|
16
16
|
onRender: (supersedesInFlight?: boolean) => void;
|
|
17
17
|
reset(): void;
|
|
18
18
|
getPendingIds(): Set<any>;
|