@docx-editor.dev/react 0.0.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +137 -2
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/dist/index.d.mts +3263 -0
- package/dist/index.d.ts +3263 -0
- package/dist/index.js +18 -0
- package/dist/index.mjs +18 -0
- package/package.json +61 -5
- package/index.js +0 -1
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,3263 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import react__default, { CSSProperties, ReactNode, ReactElement, ForwardRefExoticComponent, RefAttributes, HTMLAttributes, Ref } from 'react';
|
|
3
|
+
import { DocumentSource, FontConfiguration, Editor, DocumentChange, EditorFontError, TextMatch, ViewScope, DocumentHandle, EditorCommand, EditorScope, ExecResult, EditorSnapshot, EditorEvents, PageSetup, IndentFormatting, ColorValue, Theme } from '@docx-editor.dev/core/contracts/editor';
|
|
4
|
+
export { Editor, EditorCommand, EditorFontError, EditorFontErrorCode, EditorQuery, EditorScope, EditorSnapshot, FontConfiguration, FontFaceRequest, FontSource, FontSourceSubstitution, PageSetup } from '@docx-editor.dev/core/contracts/editor';
|
|
5
|
+
import { FontConfigurationFragment, FontResolver, EditorModule, ImageDecodePort, ChromeSlotId, SupportedImageMime, TableChromeSlotId, ChromeMenuId, ChromeMenuEntry, DocxEditorInstance, SurfaceHyperlink, ImageWrapTarget, TextMeasurer, PaginatedSurfaceState, NavigationCommand, SurfaceFormatting, SectionProperties, RulerIndent } from '@docx-editor.dev/core/editor';
|
|
6
|
+
export { CHROME_GROUPS, CHROME_MENUS, ChromeMenu, ChromeMenuEntry, ChromeMenuId, ChromeMenuItemEntry, ChromeMenuSeparatorEntry, ChromeMenuSubmenuEntry, ChromeSlotId, FontConfigurationBase, FontConfigurationFragment, FontLoadFailure, FontLoadFailureReason, FontResolutionRequest, FontResolver, FontUrlSource, ImageWrapTarget, LoadFontsRequest, LoadFontsResult, MAX_RESOLVER_FAMILIES, PX_PER_CM, PX_PER_INCH, RulerTick, RulerUnit, ToolbarCommandState, WORD_DEFAULT_FONT, chromeMenuSlots, commandForSlot, composeFontConfiguration, createFontSource, generateRulerTicks, loadFonts, rulerPageBox, runToolbarCommand, toolbarCommandState } from '@docx-editor.dev/core/editor';
|
|
7
|
+
import { TFunction, Translations } from '@docx-editor.dev/i18n';
|
|
8
|
+
import { ContentControlType, ContentControlSummary } from '@docx-editor.dev/core';
|
|
9
|
+
export { DocxDocument } from '@docx-editor.dev/core/contracts/types';
|
|
10
|
+
|
|
11
|
+
/** Props for `DocxEditor.Content`. @public */
|
|
12
|
+
interface DocxEditorContentProps {
|
|
13
|
+
/** Appended after the load-bearing `docx-paginated-surface` class. */
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The element the engine paints pages into. Must render inside a
|
|
18
|
+
* `DocxEditor.Viewport`; the facade attaches here and detaches on unmount (stashing
|
|
19
|
+
* the live document bytes, so remounting elsewhere restores the content).
|
|
20
|
+
*
|
|
21
|
+
* Its centring margin lives in the STYLESHEET, not in an inline style here, and behind
|
|
22
|
+
* `:where()` so it carries no specificity: a host that places the page itself — inside its
|
|
23
|
+
* own stage, beside its own art — overrides it with a plain class and no `!important`. An
|
|
24
|
+
* inline style could not be beaten by a class at all, which is exactly the trap that makes
|
|
25
|
+
* a library feel like something to fight.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
declare function DocxEditorContent({ className }: DocxEditorContentProps): react.JSX.Element;
|
|
30
|
+
|
|
31
|
+
/** Props for `DocxEditor.Loading`. @public */
|
|
32
|
+
interface DocxEditorLoadingProps {
|
|
33
|
+
/**
|
|
34
|
+
* An extra host-owned condition, OR-ed with the editor's own. OPTIONAL: the default
|
|
35
|
+
* already holds the screen up while the editor has nothing painted, including a
|
|
36
|
+
* `DocxEditor.Root` mounted before its document arrives. Pass this for state the
|
|
37
|
+
* editor cannot see — bytes still downloading, fonts not settled — when you mount the
|
|
38
|
+
* provider only after those resolve.
|
|
39
|
+
*/
|
|
40
|
+
when?: boolean;
|
|
41
|
+
/** Appended after the load-bearing `ep-root docx-editor__loading` classes. */
|
|
42
|
+
className?: string;
|
|
43
|
+
/** Inline styles for the loading container, as on `DocxEditor.Viewport`. */
|
|
44
|
+
style?: CSSProperties;
|
|
45
|
+
/**
|
|
46
|
+
* The loading screen. Omitted, a neutral spinner rendered from the `--doc-*` tokens is
|
|
47
|
+
* used, so the batteries-included path has something to show. Compose your own around
|
|
48
|
+
* `DocxEditor.Loading.Spinner` to keep the packaged indicator beside your own copy.
|
|
49
|
+
*/
|
|
50
|
+
children?: ReactNode;
|
|
51
|
+
}
|
|
52
|
+
/** Props for `DocxEditor.Loading.Spinner`. @public */
|
|
53
|
+
interface DocxEditorLoadingSpinnerProps {
|
|
54
|
+
/** Appended after the load-bearing `docx-editor__loading-spinner` class. */
|
|
55
|
+
className?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The packaged spinner, on its own. Exposed because `children` replaces the default
|
|
59
|
+
* screen wholesale — a host that wants "spinner plus my own label" would otherwise have
|
|
60
|
+
* to hand-copy an internal class name.
|
|
61
|
+
*
|
|
62
|
+
* Decorative: it carries `aria-hidden`, so the surrounding live region needs its own
|
|
63
|
+
* text. `DocxEditor.Loading` supplies a translated one when you pass no children.
|
|
64
|
+
*
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
declare function DocxEditorLoadingSpinner({ className }: DocxEditorLoadingSpinnerProps): react.JSX.Element;
|
|
68
|
+
/**
|
|
69
|
+
* The loading part with the packaged spinner attached as a static.
|
|
70
|
+
*
|
|
71
|
+
* @public
|
|
72
|
+
*/
|
|
73
|
+
interface DocxEditorLoadingComponent {
|
|
74
|
+
/** Renders the loading screen, or nothing once a document is available. */
|
|
75
|
+
(props: DocxEditorLoadingProps): ReactNode;
|
|
76
|
+
/** The packaged indicator, for composing into custom children. */
|
|
77
|
+
readonly Spinner: typeof DocxEditorLoadingSpinner;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Renders its children while the editor is still waiting for a document, and nothing
|
|
81
|
+
* once one is available. No condition to wire up in the common case:
|
|
82
|
+
*
|
|
83
|
+
* ```tsx
|
|
84
|
+
* <DocxEditor.Root document={bytes}>
|
|
85
|
+
* <DocxEditor.Loading>
|
|
86
|
+
* <MySpinner />
|
|
87
|
+
* </DocxEditor.Loading>
|
|
88
|
+
* <DocxEditor.Viewport>
|
|
89
|
+
* <DocxEditor.Content />
|
|
90
|
+
* </DocxEditor.Viewport>
|
|
91
|
+
* </DocxEditor.Root>
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* It clears as soon as bytes are handed over — NOT when pages finish painting — so it is
|
|
95
|
+
* safe to gate a `DocxEditor.Content` on, and an unmounted viewport does not bring it
|
|
96
|
+
* back. A parse failure clears it too, so a broken document never spins forever; report
|
|
97
|
+
* that from `snapshot().parseError` or the `error` event. Add `when` only for async the
|
|
98
|
+
* editor cannot observe, typically a host that mounts the provider after its own fetch.
|
|
99
|
+
*
|
|
100
|
+
* Rendered OUTSIDE a `DocxEditor.Root` it always shows, because there is no editor to
|
|
101
|
+
* report otherwise — the same rule `useEditorState` documents for a null editor. Place
|
|
102
|
+
* it inside the provider unless a permanently-visible placeholder is what you want.
|
|
103
|
+
*
|
|
104
|
+
* Carries its own `ep-root`, so the theme tokens resolve wherever it is composed.
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
declare const DocxEditorLoading: DocxEditorLoadingComponent;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Props for `DocxEditor.Root`. Creation parameters (`document`, `fonts`, `author`,
|
|
112
|
+
* `locale`, and the initial `mode`/`zoom`) are sampled when the instance is created;
|
|
113
|
+
* only `document` and `fonts` identity remount it. Later `mode` and `zoom` changes flow through
|
|
114
|
+
* `Editor.setZoom` so edits, the caret, and the undo history survive.
|
|
115
|
+
*
|
|
116
|
+
* @public
|
|
117
|
+
*/
|
|
118
|
+
interface DocxEditorRootProps {
|
|
119
|
+
/** A document to load: DOCX bytes or an existing handle. Identity change remounts. */
|
|
120
|
+
document?: DocumentSource;
|
|
121
|
+
/**
|
|
122
|
+
* Font bytes for Word-accurate (HarfBuzz-shaped) wrap and pagination. Omitted, layout
|
|
123
|
+
* uses a fixed-width estimate; fonts embedded in the document are wired automatically
|
|
124
|
+
* either way. Pass `await loadDefaultFonts()` from `@docx-editor.dev/fonts` for
|
|
125
|
+
* Word's default faces — a bare fragment is accepted — or compose several origins
|
|
126
|
+
* with `composeFontConfiguration`. Sampled at mount; identity change remounts;
|
|
127
|
+
* failures degrade to the fixed measurer and report through `onFontError`.
|
|
128
|
+
*/
|
|
129
|
+
fonts?: FontConfiguration | FontConfigurationFragment | FontResolver;
|
|
130
|
+
author?: string;
|
|
131
|
+
locale?: string;
|
|
132
|
+
/** Drawing refusal labels for painted placeholders; defaults to the active locale catalogue. */
|
|
133
|
+
translate?: (key: string, params?: Record<string, string | number>) => string;
|
|
134
|
+
/**
|
|
135
|
+
* Capability modules to register (`@docx-editor.dev/pro`'s review module,
|
|
136
|
+
* custom nodes). Sampled at mount only, like `mode`: module registration is
|
|
137
|
+
* construction-time in the engine.
|
|
138
|
+
*/
|
|
139
|
+
modules?: readonly EditorModule[];
|
|
140
|
+
/** `'edit'` (default) or `'view'` (read-only). Sampled at mount only. */
|
|
141
|
+
mode?: 'edit' | 'view';
|
|
142
|
+
zoom?: number;
|
|
143
|
+
/** Fired once per instance, after it is published to the tree (and after any
|
|
144
|
+
* `DocxEditor.Content` in the same commit has attached its mount point). */
|
|
145
|
+
onReady?: (editor: Editor) => void;
|
|
146
|
+
/** Fired when the document changes (revision + identity deltas, not bytes). */
|
|
147
|
+
onChange?: (change: DocumentChange) => void;
|
|
148
|
+
/** Fired with the typed font failure when the shaped-font pipeline rejects. */
|
|
149
|
+
onFontError?: (error: EditorFontError) => void;
|
|
150
|
+
/**
|
|
151
|
+
* Localized labels for table insertion furniture. When omitted, core falls back to
|
|
152
|
+
* bundled English through {@link defaultTableLabel}.
|
|
153
|
+
*/
|
|
154
|
+
tableInteractionLabel?: (key: 'table.insertRowBelow' | 'table.insertColumnRight') => string;
|
|
155
|
+
/** Optional decode port for embedded image insertion and paint in tests or custom hosts. */
|
|
156
|
+
imageDecodePort?: ImageDecodePort;
|
|
157
|
+
children?: ReactNode;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Creates and owns a `DocxEditorInstance` and provides it to the subtree. Renders no
|
|
161
|
+
* DOM — compose it with `DocxEditor.Viewport` + `DocxEditor.Content` for the painted
|
|
162
|
+
* pages, and any hook-built chrome anywhere inside.
|
|
163
|
+
*
|
|
164
|
+
* @public
|
|
165
|
+
*/
|
|
166
|
+
declare function DocxEditorRoot(props: DocxEditorRootProps): react.JSX.Element;
|
|
167
|
+
|
|
168
|
+
/** Props for `DocxEditor.Viewport`. @public */
|
|
169
|
+
interface DocxEditorViewportProps {
|
|
170
|
+
/** Appended after the load-bearing viewport classes (e.g. `dark` for chrome theming). */
|
|
171
|
+
className?: string;
|
|
172
|
+
style?: CSSProperties;
|
|
173
|
+
children?: ReactNode;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The sole scroll container for the painted document. Put `DocxEditor.Content` inside
|
|
177
|
+
* it; the engine discovers this element by class and manages scrolling against it.
|
|
178
|
+
*
|
|
179
|
+
* @public
|
|
180
|
+
*/
|
|
181
|
+
declare function DocxEditorViewport({ className, style, children }: DocxEditorViewportProps): react.JSX.Element;
|
|
182
|
+
|
|
183
|
+
/** Resolves an i18n key to display text. @public */
|
|
184
|
+
type ToolbarTranslate = (key: string) => string;
|
|
185
|
+
|
|
186
|
+
/** Props for `DocxEditorToolbar.Button`. @public */
|
|
187
|
+
interface ToolbarButtonProps$1 {
|
|
188
|
+
/** The chrome slot this button drives (`'text.bold'`, `'history.undo'`, ...). */
|
|
189
|
+
slot: ChromeSlotId;
|
|
190
|
+
/** Icon override; falls back to `children`, then to the registry's icon paths. */
|
|
191
|
+
icon?: ReactNode;
|
|
192
|
+
/** Merge the button's behavior into the single child element instead of a <button>. */
|
|
193
|
+
asChild?: boolean;
|
|
194
|
+
className?: string;
|
|
195
|
+
children?: ReactNode;
|
|
196
|
+
/** Render nothing — inside the default arrangement this removes the slot. */
|
|
197
|
+
hidden?: boolean;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* One chrome slot as a live toolbar button: enabled/active from the engine's
|
|
201
|
+
* can-before-exec answer, labelled from the registry's i18n key, `data-active` /
|
|
202
|
+
* `data-disabled` presence attributes for styling, `aria-pressed` on toggles.
|
|
203
|
+
*
|
|
204
|
+
* @public
|
|
205
|
+
*/
|
|
206
|
+
declare function ToolbarButton$1(props: ToolbarButtonProps$1): react.JSX.Element | null;
|
|
207
|
+
declare namespace ToolbarButton$1 {
|
|
208
|
+
var docxToolbarPart: true;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
interface ImageInsertProviderProps {
|
|
212
|
+
children: ReactNode;
|
|
213
|
+
}
|
|
214
|
+
declare function ImageInsertProvider({ children }: ImageInsertProviderProps): react.JSX.Element;
|
|
215
|
+
/** Props for the toolbar/menu insert trigger. @public */
|
|
216
|
+
interface ImageInsertTriggerProps {
|
|
217
|
+
className?: string;
|
|
218
|
+
hidden?: boolean;
|
|
219
|
+
asChild?: boolean;
|
|
220
|
+
children?: ReactNode;
|
|
221
|
+
}
|
|
222
|
+
/** Toolbar insert-image control — opens the shared file picker. @public */
|
|
223
|
+
declare function ImageInsertTrigger({ className, hidden, asChild, children, }: ImageInsertTriggerProps): react.JSX.Element | null;
|
|
224
|
+
declare namespace ImageInsertTrigger {
|
|
225
|
+
var docxSlot: "image.insert";
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Props for `DocxEditorToolbar.ImageWrap`. @public */
|
|
229
|
+
interface ImageWrapProps {
|
|
230
|
+
className?: string;
|
|
231
|
+
hidden?: boolean;
|
|
232
|
+
asChild?: boolean;
|
|
233
|
+
children?: ReactNode;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Wrap-text dropdown presenting all nine Word choices.
|
|
237
|
+
*
|
|
238
|
+
* @public
|
|
239
|
+
*/
|
|
240
|
+
declare function ImageWrap({ className, hidden, asChild, children }: ImageWrapProps): react.JSX.Element | null;
|
|
241
|
+
declare namespace ImageWrap {
|
|
242
|
+
var docxSlot: "image.wrap";
|
|
243
|
+
}
|
|
244
|
+
/** @public */
|
|
245
|
+
interface ImageWrapPartComponent {
|
|
246
|
+
(props: ImageWrapProps): ReactElement | null;
|
|
247
|
+
readonly docxSlot: 'image.wrap';
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Props for `DocxEditorToolbar.ImageAltText`. @public */
|
|
251
|
+
interface ImageAltTextProps {
|
|
252
|
+
className?: string;
|
|
253
|
+
hidden?: boolean;
|
|
254
|
+
asChild?: boolean;
|
|
255
|
+
children?: ReactNode;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Opens a small panel to edit image description (and optional title).
|
|
259
|
+
*
|
|
260
|
+
* @public
|
|
261
|
+
*/
|
|
262
|
+
declare function ImageAltText({ className, hidden, asChild, children }: ImageAltTextProps): react.JSX.Element | null;
|
|
263
|
+
declare namespace ImageAltText {
|
|
264
|
+
var docxSlot: "image.altText";
|
|
265
|
+
}
|
|
266
|
+
/** @public */
|
|
267
|
+
interface ImageAltTextPartComponent {
|
|
268
|
+
(props: ImageAltTextProps): ReactElement | null;
|
|
269
|
+
readonly docxSlot: 'image.altText';
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Props for `DocxEditor.ImagePropertiesDialog`. @public */
|
|
273
|
+
interface DocxEditorImagePropertiesDialogProps {
|
|
274
|
+
open: boolean;
|
|
275
|
+
onClose: () => void;
|
|
276
|
+
className?: string;
|
|
277
|
+
triggerRef?: React.RefObject<HTMLElement | null>;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Properties dialog for the selected picture.
|
|
281
|
+
*
|
|
282
|
+
* @public
|
|
283
|
+
*/
|
|
284
|
+
declare function DocxEditorImagePropertiesDialog({ open, onClose, className, triggerRef, }: DocxEditorImagePropertiesDialogProps): react.JSX.Element | null;
|
|
285
|
+
/** Props for the toolbar properties trigger. @public */
|
|
286
|
+
interface ImagePropertiesTriggerProps {
|
|
287
|
+
className?: string;
|
|
288
|
+
hidden?: boolean;
|
|
289
|
+
asChild?: boolean;
|
|
290
|
+
children?: react.ReactNode;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Opens the image properties dialog for the selected drawing.
|
|
294
|
+
*
|
|
295
|
+
* @public
|
|
296
|
+
*/
|
|
297
|
+
declare function ImagePropertiesTrigger({ className, hidden, asChild, children, }: ImagePropertiesTriggerProps): react.JSX.Element | null;
|
|
298
|
+
declare namespace ImagePropertiesTrigger {
|
|
299
|
+
var docxSlot: "image.properties";
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
type NormalizedImagePayload = {
|
|
303
|
+
readonly ok: true;
|
|
304
|
+
readonly bytes: Uint8Array;
|
|
305
|
+
readonly mime: SupportedImageMime;
|
|
306
|
+
readonly widthPoints: number;
|
|
307
|
+
readonly heightPoints: number;
|
|
308
|
+
} | {
|
|
309
|
+
readonly ok: false;
|
|
310
|
+
/** i18n key under `imageInsert.errors.*` suitable for `t()`. */
|
|
311
|
+
readonly reasonKey: string;
|
|
312
|
+
};
|
|
313
|
+
/** Preflight raster bytes for insert/replace. Never allocates from file-supplied dimensions alone. */
|
|
314
|
+
declare function normalizeImageBytes(bytes: Uint8Array): NormalizedImagePayload;
|
|
315
|
+
|
|
316
|
+
/** Props for the named parts (`DocxEditorToolbar.Bold`, ...): the slot is pinned. @public */
|
|
317
|
+
type ToolbarPartProps = Omit<ToolbarButtonProps$1, 'slot'>;
|
|
318
|
+
interface ToolbarPartComponent {
|
|
319
|
+
(props: ToolbarPartProps): ReturnType<typeof ToolbarButton$1>;
|
|
320
|
+
readonly docxSlot: ChromeSlotId;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Props for the non-button parts (pickers, steppers, color splits, save). @public
|
|
324
|
+
*/
|
|
325
|
+
interface ToolbarSlotPartProps {
|
|
326
|
+
className?: string;
|
|
327
|
+
/** Render nothing — inside the default arrangement this removes the slot. */
|
|
328
|
+
hidden?: boolean;
|
|
329
|
+
}
|
|
330
|
+
/** A non-button part pinned to one slot. @public */
|
|
331
|
+
interface ToolbarSlotPartComponent {
|
|
332
|
+
(props: ToolbarSlotPartProps): ReturnType<typeof ToolbarButton$1>;
|
|
333
|
+
readonly docxSlot: ChromeSlotId;
|
|
334
|
+
}
|
|
335
|
+
/** Props for `DocxEditorToolbar.Separator`. @public */
|
|
336
|
+
interface ToolbarSeparatorProps {
|
|
337
|
+
className?: string;
|
|
338
|
+
}
|
|
339
|
+
/** A vertical rule between toolbar groups. @public */
|
|
340
|
+
declare function ToolbarSeparator({ className }: ToolbarSeparatorProps): react.JSX.Element;
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Props for the split colour controls. @public
|
|
344
|
+
*
|
|
345
|
+
* The one addition over a plain slot part is `icon`, and it belongs here rather than on
|
|
346
|
+
* `ToolbarSlotPartProps`: the other slot parts are steppers and pickers with no single glyph
|
|
347
|
+
* to replace, so an icon prop on the shared type would be a promise three of them could not
|
|
348
|
+
* keep.
|
|
349
|
+
*/
|
|
350
|
+
interface ToolbarColorSplitProps extends ToolbarSlotPartProps {
|
|
351
|
+
/**
|
|
352
|
+
* Replaces the glyph above the colour bar — the registry's red "A" or highlighter pen.
|
|
353
|
+
*
|
|
354
|
+
* The BAR is not replaceable and still paints the live value, so a host swapping the glyph
|
|
355
|
+
* keeps the thing that makes this control readable at a glance.
|
|
356
|
+
*/
|
|
357
|
+
icon?: ReactNode;
|
|
358
|
+
}
|
|
359
|
+
/** A split colour control pinned to one slot. @public */
|
|
360
|
+
interface ToolbarColorSplitComponent {
|
|
361
|
+
(props: ToolbarColorSplitProps): ReturnType<typeof ToolbarButton$1>;
|
|
362
|
+
readonly docxSlot: ChromeSlotId;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** The merged part is keyed by its GROUP id — it stands in for all four slots. */
|
|
366
|
+
interface ToolbarAlignmentComponent {
|
|
367
|
+
(props: ToolbarSlotPartProps): ReturnType<typeof ToolbarAlignmentImpl>;
|
|
368
|
+
readonly docxSlot: 'alignment';
|
|
369
|
+
}
|
|
370
|
+
declare function ToolbarAlignmentImpl({ className, hidden }: ToolbarSlotPartProps): react.JSX.Element | null;
|
|
371
|
+
|
|
372
|
+
/** Props for `DocxEditorToolbar.Action`. @public */
|
|
373
|
+
interface ToolbarActionProps {
|
|
374
|
+
/**
|
|
375
|
+
* Accessible name and tooltip. A resolved STRING, not an i18n key: the label belongs to
|
|
376
|
+
* the host's own action, so the host's own catalogue resolves it. (Registry controls go
|
|
377
|
+
* the other way — they carry keys and the toolbar's `t` resolves them.)
|
|
378
|
+
*/
|
|
379
|
+
label: string;
|
|
380
|
+
/** Icon content. Inline SVG sized ~18px matches the packaged controls. */
|
|
381
|
+
icon?: ReactNode;
|
|
382
|
+
/** Pressed state, for an action that toggles. Sets `aria-pressed` and `data-active`. */
|
|
383
|
+
active?: boolean;
|
|
384
|
+
disabled?: boolean;
|
|
385
|
+
/** Tooltip when disabled — say why, the way the engine's controls do. */
|
|
386
|
+
disabledReason?: string;
|
|
387
|
+
onSelect?: () => void;
|
|
388
|
+
/** Merge the behavior onto the single child element instead of rendering a `<button>`. */
|
|
389
|
+
asChild?: boolean;
|
|
390
|
+
className?: string;
|
|
391
|
+
children?: ReactNode;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* A host-owned toolbar action, styled and behaved like the packaged controls.
|
|
395
|
+
*
|
|
396
|
+
* Renders inside `<DocxEditor.Toolbar>` after the default arrangement (it drives no slot,
|
|
397
|
+
* so it is an appended child), or anywhere under `preset={false}`.
|
|
398
|
+
*
|
|
399
|
+
* @public
|
|
400
|
+
*/
|
|
401
|
+
declare function ToolbarAction(props: ToolbarActionProps): react.JSX.Element;
|
|
402
|
+
|
|
403
|
+
/** What `useFontFamily` answers. @public */
|
|
404
|
+
interface UseFontFamilyResult {
|
|
405
|
+
/** The selection's agreed family, or null (mixed selection, or no document). */
|
|
406
|
+
readonly value: string | null;
|
|
407
|
+
/** Apply a family through the can-before-exec path; a refusal is a safe no-op. */
|
|
408
|
+
readonly setValue: (family: string) => void;
|
|
409
|
+
/**
|
|
410
|
+
* The offerable font catalog (validated, deduplicated, sorted): the editor's
|
|
411
|
+
* configured families merged with the document's declared ones.
|
|
412
|
+
*/
|
|
413
|
+
readonly options: readonly string[];
|
|
414
|
+
/** Whether the engine would honour a font change right now. */
|
|
415
|
+
readonly isEnabled: boolean;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* The font-family picker's behavior, UI-free.
|
|
419
|
+
*
|
|
420
|
+
* @public
|
|
421
|
+
*/
|
|
422
|
+
declare function useFontFamily(): UseFontFamilyResult;
|
|
423
|
+
/** Props for `DocxEditorToolbar.FontFamily` and its sub-parts. @public */
|
|
424
|
+
interface FontFamilyPartProps {
|
|
425
|
+
asChild?: boolean;
|
|
426
|
+
className?: string;
|
|
427
|
+
children?: ReactNode;
|
|
428
|
+
}
|
|
429
|
+
/** Props for the compound root. @public */
|
|
430
|
+
interface FontFamilyProps extends FontFamilyPartProps {
|
|
431
|
+
/** Render nothing — inside the default arrangement this removes the slot. */
|
|
432
|
+
hidden?: boolean;
|
|
433
|
+
}
|
|
434
|
+
/** Props for `FontFamily.Item`. @public */
|
|
435
|
+
interface FontFamilyItemProps extends FontFamilyPartProps {
|
|
436
|
+
/** The family this item applies. */
|
|
437
|
+
value: string;
|
|
438
|
+
}
|
|
439
|
+
declare function FontFamilyTrigger({ asChild, className, children }: FontFamilyPartProps): react.JSX.Element | null;
|
|
440
|
+
declare namespace FontFamilyTrigger {
|
|
441
|
+
var docxToolbarPart: true;
|
|
442
|
+
}
|
|
443
|
+
declare function FontFamilyContent({ asChild, className, children }: FontFamilyPartProps): react.JSX.Element | null;
|
|
444
|
+
declare function FontFamilyItem({ value, asChild, className, children }: FontFamilyItemProps): react.JSX.Element | null;
|
|
445
|
+
/** The compound part with its sub-parts attached as statics. @public */
|
|
446
|
+
interface FontFamilyNamespace {
|
|
447
|
+
(props: FontFamilyProps): ReactNode;
|
|
448
|
+
readonly docxSlot: 'font.family';
|
|
449
|
+
readonly Trigger: typeof FontFamilyTrigger;
|
|
450
|
+
readonly Content: typeof FontFamilyContent;
|
|
451
|
+
readonly Item: typeof FontFamilyItem;
|
|
452
|
+
}
|
|
453
|
+
declare const FontFamily: FontFamilyNamespace;
|
|
454
|
+
|
|
455
|
+
/** One pickable paragraph style, as the document defines it. @public */
|
|
456
|
+
interface ParagraphStyleOption {
|
|
457
|
+
readonly styleId: string;
|
|
458
|
+
readonly name: string;
|
|
459
|
+
/**
|
|
460
|
+
* How the style looks, for rendering the row in its own face. Every value arrives
|
|
461
|
+
* already bounded by the engine's derivation (family against the CSS-sink shape, colour
|
|
462
|
+
* against six hex digits), which is what makes it safe to put in a style object.
|
|
463
|
+
*/
|
|
464
|
+
readonly preview: {
|
|
465
|
+
readonly fontFamily: string | null;
|
|
466
|
+
readonly fontSizePt: number | null;
|
|
467
|
+
readonly bold: boolean;
|
|
468
|
+
readonly italic: boolean;
|
|
469
|
+
readonly color: string | null;
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
/** What `useParagraphStyle` answers. @public */
|
|
473
|
+
interface UseParagraphStyleResult {
|
|
474
|
+
/** The selection's agreed paragraph styleId, or null (unstyled/default, or mixed). */
|
|
475
|
+
readonly value: string | null;
|
|
476
|
+
/** Apply a paragraph style through the can-before-exec path; a refusal is a safe no-op. */
|
|
477
|
+
readonly setValue: (styleId: string) => void;
|
|
478
|
+
/**
|
|
479
|
+
* The document's paragraph styles — validated ids and display names, in the engine's
|
|
480
|
+
* Word-gallery order (Normal, Title, Subtitle, the headings, then everything else in
|
|
481
|
+
* document order), NOT the order `styles.xml` happens to list them in.
|
|
482
|
+
*/
|
|
483
|
+
readonly options: readonly ParagraphStyleOption[];
|
|
484
|
+
/** Whether the engine would honour a style change right now. */
|
|
485
|
+
readonly isEnabled: boolean;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* The paragraph-style picker's behavior, UI-free.
|
|
489
|
+
*
|
|
490
|
+
* @public
|
|
491
|
+
*/
|
|
492
|
+
declare function useParagraphStyle(): UseParagraphStyleResult;
|
|
493
|
+
/** Props for `DocxEditorToolbar.StylePicker` and its sub-parts. @public */
|
|
494
|
+
interface ParagraphStylePartProps {
|
|
495
|
+
asChild?: boolean;
|
|
496
|
+
className?: string;
|
|
497
|
+
children?: ReactNode;
|
|
498
|
+
}
|
|
499
|
+
/** Props for the compound root. @public */
|
|
500
|
+
interface ParagraphStyleProps extends ParagraphStylePartProps {
|
|
501
|
+
/** Render nothing — inside the default arrangement this removes the slot. */
|
|
502
|
+
hidden?: boolean;
|
|
503
|
+
}
|
|
504
|
+
/** Props for `ParagraphStyle.Item`. @public */
|
|
505
|
+
interface ParagraphStyleItemProps extends ParagraphStylePartProps {
|
|
506
|
+
/** The styleId this item applies. */
|
|
507
|
+
value: string;
|
|
508
|
+
}
|
|
509
|
+
declare function ParagraphStyleTrigger({ asChild, className, children }: ParagraphStylePartProps): react.JSX.Element | null;
|
|
510
|
+
declare namespace ParagraphStyleTrigger {
|
|
511
|
+
var docxToolbarPart: true;
|
|
512
|
+
}
|
|
513
|
+
declare function ParagraphStyleContent({ asChild, className, children }: ParagraphStylePartProps): react.JSX.Element | null;
|
|
514
|
+
declare function ParagraphStyleItem({ value, asChild, className, children }: ParagraphStyleItemProps): react.JSX.Element | null;
|
|
515
|
+
/** The compound part with its sub-parts attached as statics. @public */
|
|
516
|
+
interface ParagraphStyleNamespace {
|
|
517
|
+
(props: ParagraphStyleProps): ReactNode;
|
|
518
|
+
readonly docxSlot: 'styles.style';
|
|
519
|
+
readonly Trigger: typeof ParagraphStyleTrigger;
|
|
520
|
+
readonly Content: typeof ParagraphStyleContent;
|
|
521
|
+
readonly Item: typeof ParagraphStyleItem;
|
|
522
|
+
}
|
|
523
|
+
declare const ParagraphStyle: ParagraphStyleNamespace;
|
|
524
|
+
|
|
525
|
+
/** Props shared by contextual table toolbar compound parts. @public */
|
|
526
|
+
interface TableChromePartProps {
|
|
527
|
+
/** Appended to the part root class list. */
|
|
528
|
+
className?: string;
|
|
529
|
+
/** When true, the part renders nothing. */
|
|
530
|
+
hidden?: boolean;
|
|
531
|
+
/** Merge props onto the single child element instead of rendering a default host node. */
|
|
532
|
+
asChild?: boolean;
|
|
533
|
+
/** Custom panel body or trigger label; defaults to the packaged control chrome. */
|
|
534
|
+
children?: ReactNode;
|
|
535
|
+
}
|
|
536
|
+
/** Props for a value-driven row or swatch inside a table compound menu. @public */
|
|
537
|
+
interface TableChromeItemProps extends TableChromePartProps {
|
|
538
|
+
/** The pick value this item dispatches (target id, style name, width size, or hex without `#`). */
|
|
539
|
+
value: string;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Shared compound contract for menu-style table chrome parts
|
|
543
|
+
* ({@link TableBorderTargetNamespace}, {@link TableBorderStyleNamespace}, {@link TableBorderWidthNamespace}).
|
|
544
|
+
*
|
|
545
|
+
* @public
|
|
546
|
+
*/
|
|
547
|
+
interface TableChromePartComponent extends ToolbarSlotPartComponent {
|
|
548
|
+
/** The chrome slot this compound drives. */
|
|
549
|
+
readonly docxSlot: TableChromeSlotId;
|
|
550
|
+
/** Opens the picker menu or dialog. */
|
|
551
|
+
readonly Trigger: (props: TableChromePartProps) => ReactNode;
|
|
552
|
+
/** The open menu or dialog panel; omit to use the default item list. */
|
|
553
|
+
readonly Content: (props: TableChromePartProps) => ReactNode;
|
|
554
|
+
/** One selectable value row or swatch inside {@link Content}. */
|
|
555
|
+
readonly Item: (props: TableChromeItemProps) => ReactNode;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Border-target picker compound (`DocxEditor.Toolbar.TableBorderTarget`).
|
|
559
|
+
*
|
|
560
|
+
* @public
|
|
561
|
+
*/
|
|
562
|
+
interface TableBorderTargetNamespace extends TableChromePartComponent {
|
|
563
|
+
/** Chrome slot id: `table.borderTarget`. */
|
|
564
|
+
readonly docxSlot: 'table.borderTarget';
|
|
565
|
+
/** Button that opens the border-edge target menu. */
|
|
566
|
+
readonly Trigger: (props: TableChromePartProps) => ReactNode;
|
|
567
|
+
/** Open menu listing edge scopes and clear. */
|
|
568
|
+
readonly Content: (props: TableChromePartProps) => ReactNode;
|
|
569
|
+
/** One edge scope or clear row inside the target menu. */
|
|
570
|
+
readonly Item: (props: TableChromeItemProps) => ReactNode;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Border-colour split compound with a quick-apply main button and swatch dialog
|
|
574
|
+
* (`DocxEditor.Toolbar.TableBorderColor`).
|
|
575
|
+
*
|
|
576
|
+
* @public
|
|
577
|
+
*/
|
|
578
|
+
interface TableBorderColorNamespace extends TableChromePartComponent {
|
|
579
|
+
/** Chrome slot id: `table.borderColor`. */
|
|
580
|
+
readonly docxSlot: 'table.borderColor';
|
|
581
|
+
/** Applies the last swatch without opening the dialog. */
|
|
582
|
+
readonly Main: (props: TableChromePartProps) => ReactNode;
|
|
583
|
+
/** Button that opens the border-colour swatch dialog. */
|
|
584
|
+
readonly Trigger: (props: TableChromePartProps) => ReactNode;
|
|
585
|
+
/** Open swatch dialog for the active border target. */
|
|
586
|
+
readonly Content: (props: TableChromePartProps) => ReactNode;
|
|
587
|
+
/** One colour swatch inside the border-colour dialog. */
|
|
588
|
+
readonly Item: (props: TableChromeItemProps) => ReactNode;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Cell-fill split compound (`DocxEditor.Toolbar.TableCellFill`).
|
|
592
|
+
*
|
|
593
|
+
* @public
|
|
594
|
+
*/
|
|
595
|
+
interface TableCellFillNamespace extends TableChromePartComponent {
|
|
596
|
+
/** Chrome slot id: `table.cellFill`. */
|
|
597
|
+
readonly docxSlot: 'table.cellFill';
|
|
598
|
+
/** Applies the last swatch without opening the dialog. */
|
|
599
|
+
readonly Main: (props: TableChromePartProps) => ReactNode;
|
|
600
|
+
/** Button that opens the cell-fill swatch dialog. */
|
|
601
|
+
readonly Trigger: (props: TableChromePartProps) => ReactNode;
|
|
602
|
+
/** Open swatch dialog for the selected cell(s). */
|
|
603
|
+
readonly Content: (props: TableChromePartProps) => ReactNode;
|
|
604
|
+
/** One fill swatch inside the cell-fill dialog. */
|
|
605
|
+
readonly Item: (props: TableChromeItemProps) => ReactNode;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Border-style menu compound (`DocxEditor.Toolbar.TableBorderStyle`).
|
|
609
|
+
*
|
|
610
|
+
* @public
|
|
611
|
+
*/
|
|
612
|
+
interface TableBorderStyleNamespace extends TableChromePartComponent {
|
|
613
|
+
/** Chrome slot id: `table.borderStyle`. */
|
|
614
|
+
readonly docxSlot: 'table.borderStyle';
|
|
615
|
+
/** Button that opens the border line-style menu. */
|
|
616
|
+
readonly Trigger: (props: TableChromePartProps) => ReactNode;
|
|
617
|
+
/** Open menu listing line styles for the active target. */
|
|
618
|
+
readonly Content: (props: TableChromePartProps) => ReactNode;
|
|
619
|
+
/** One line-style row inside the style menu. */
|
|
620
|
+
readonly Item: (props: TableChromeItemProps) => ReactNode;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Border-width menu compound (`DocxEditor.Toolbar.TableBorderWidth`).
|
|
624
|
+
*
|
|
625
|
+
* @public
|
|
626
|
+
*/
|
|
627
|
+
interface TableBorderWidthNamespace extends TableChromePartComponent {
|
|
628
|
+
/** Chrome slot id: `table.borderWidth`. */
|
|
629
|
+
readonly docxSlot: 'table.borderWidth';
|
|
630
|
+
/** Button that opens the border width menu. */
|
|
631
|
+
readonly Trigger: (props: TableChromePartProps) => ReactNode;
|
|
632
|
+
/** Open menu listing width presets for the active target. */
|
|
633
|
+
readonly Content: (props: TableChromePartProps) => ReactNode;
|
|
634
|
+
/** One width preset row inside the width menu. */
|
|
635
|
+
readonly Item: (props: TableChromeItemProps) => ReactNode;
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Resolved label for the active border target in the shared draft.
|
|
639
|
+
*
|
|
640
|
+
* For custom table chrome that shows the current target name outside the packaged picker.
|
|
641
|
+
*
|
|
642
|
+
* @public
|
|
643
|
+
*/
|
|
644
|
+
declare function useTableBorderTargetLabel(): string;
|
|
645
|
+
|
|
646
|
+
/** Props for `DocxEditor.Toolbar`. @public */
|
|
647
|
+
interface DocxEditorToolbarProps {
|
|
648
|
+
/** Appended after the base `docx-toolbar` class. */
|
|
649
|
+
className?: string;
|
|
650
|
+
/** i18n resolver for control labels; without it the raw keys show (never English). */
|
|
651
|
+
t?: ToolbarTranslate;
|
|
652
|
+
/**
|
|
653
|
+
* Handler for the `file.save` control. Save is not an engine command (`Editor.save()`
|
|
654
|
+
* returns bytes the host must deliver), so without a handler the control renders
|
|
655
|
+
* disabled — same contract as the Vue toolbar's `onSave`.
|
|
656
|
+
*/
|
|
657
|
+
onSave?: () => void;
|
|
658
|
+
/**
|
|
659
|
+
* `false` renders children verbatim with no default arrangement. Default `true`:
|
|
660
|
+
* part children override their slots in place, others append.
|
|
661
|
+
*/
|
|
662
|
+
preset?: boolean;
|
|
663
|
+
/**
|
|
664
|
+
* `false` lets the bar WRAP to more rows instead of collapsing groups into the "⋯"
|
|
665
|
+
* menu when it runs out of width. Default `true`.
|
|
666
|
+
*/
|
|
667
|
+
overflow?: boolean;
|
|
668
|
+
children?: ReactNode;
|
|
669
|
+
}
|
|
670
|
+
/** The toolbar with its parts attached as statics. @public */
|
|
671
|
+
interface DocxEditorToolbarNamespace {
|
|
672
|
+
(props: DocxEditorToolbarProps): ReactNode;
|
|
673
|
+
readonly Button: typeof ToolbarButton$1;
|
|
674
|
+
/** A host-owned action the chrome registry does not describe. */
|
|
675
|
+
readonly Action: typeof ToolbarAction;
|
|
676
|
+
readonly Separator: typeof ToolbarSeparator;
|
|
677
|
+
readonly Undo: ToolbarPartComponent;
|
|
678
|
+
readonly Redo: ToolbarPartComponent;
|
|
679
|
+
readonly Bold: ToolbarPartComponent;
|
|
680
|
+
readonly Italic: ToolbarPartComponent;
|
|
681
|
+
readonly Underline: ToolbarPartComponent;
|
|
682
|
+
readonly Strike: ToolbarPartComponent;
|
|
683
|
+
readonly Link: ToolbarPartComponent;
|
|
684
|
+
readonly ClearFormatting: ToolbarPartComponent;
|
|
685
|
+
readonly Superscript: ToolbarPartComponent;
|
|
686
|
+
readonly Subscript: ToolbarPartComponent;
|
|
687
|
+
readonly Alignment: ToolbarAlignmentComponent;
|
|
688
|
+
readonly AlignLeft: ToolbarPartComponent;
|
|
689
|
+
readonly AlignCenter: ToolbarPartComponent;
|
|
690
|
+
readonly AlignRight: ToolbarPartComponent;
|
|
691
|
+
readonly AlignJustify: ToolbarPartComponent;
|
|
692
|
+
readonly LineSpacing: ToolbarSlotPartComponent;
|
|
693
|
+
readonly BulletList: ToolbarPartComponent;
|
|
694
|
+
readonly NumberedList: ToolbarPartComponent;
|
|
695
|
+
readonly Outdent: ToolbarPartComponent;
|
|
696
|
+
readonly Indent: ToolbarPartComponent;
|
|
697
|
+
readonly ImageInsert: ToolbarPartComponent;
|
|
698
|
+
readonly ImageProperties: ToolbarPartComponent;
|
|
699
|
+
readonly ImageWrap: ImageWrapPartComponent;
|
|
700
|
+
readonly ImageAltText: ImageAltTextPartComponent;
|
|
701
|
+
readonly TableInsert: ToolbarPartComponent;
|
|
702
|
+
/** Border-edge target picker compound for contextual table chrome. */
|
|
703
|
+
readonly TableBorderTarget: TableBorderTargetNamespace;
|
|
704
|
+
/** Border-colour split compound (quick-apply main + swatch dialog). */
|
|
705
|
+
readonly TableBorderColor: TableBorderColorNamespace;
|
|
706
|
+
/** Border line-style menu compound. */
|
|
707
|
+
readonly TableBorderStyle: TableBorderStyleNamespace;
|
|
708
|
+
/** Border width menu compound. */
|
|
709
|
+
readonly TableBorderWidth: TableBorderWidthNamespace;
|
|
710
|
+
/** Cell background fill split compound (quick-apply main + swatch dialog). */
|
|
711
|
+
readonly TableCellFill: TableCellFillNamespace;
|
|
712
|
+
readonly Comments: ToolbarPartComponent;
|
|
713
|
+
readonly FontFamily: typeof FontFamily;
|
|
714
|
+
readonly FontSize: ToolbarSlotPartComponent;
|
|
715
|
+
readonly FontColor: ToolbarColorSplitComponent;
|
|
716
|
+
readonly Highlight: ToolbarColorSplitComponent;
|
|
717
|
+
readonly Zoom: ToolbarSlotPartComponent;
|
|
718
|
+
readonly StylePicker: typeof ParagraphStyle;
|
|
719
|
+
readonly EditingMode: ToolbarSlotPartComponent;
|
|
720
|
+
readonly Save: ToolbarSlotPartComponent;
|
|
721
|
+
readonly ContentControlShowAll: ToolbarPartComponent;
|
|
722
|
+
readonly ContentControlFormFill: ToolbarPartComponent;
|
|
723
|
+
readonly ContentControlInspector: ToolbarPartComponent;
|
|
724
|
+
readonly ContentControlRemove: ToolbarPartComponent;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* The compound toolbar: `<DocxEditor.Toolbar/>` for the full working chrome, parts as
|
|
728
|
+
* statics for composition (`<DocxEditor.Toolbar><DocxEditor.Toolbar.Bold/>...`).
|
|
729
|
+
*
|
|
730
|
+
* @public
|
|
731
|
+
*/
|
|
732
|
+
declare const DocxEditorToolbar: DocxEditorToolbarNamespace;
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* A menu's identity: one of the registry's four, or a HOST'S OWN.
|
|
736
|
+
*
|
|
737
|
+
* The `(string & {})` arm keeps the registry ids as editor autocomplete while accepting
|
|
738
|
+
* any other string, so a product can add "Review" or "Clauses" without the library having
|
|
739
|
+
* to know about it. Lives here rather than in `parts` because the bar's open/active state
|
|
740
|
+
* is keyed on it and both modules read that state.
|
|
741
|
+
*
|
|
742
|
+
* @public
|
|
743
|
+
*/
|
|
744
|
+
type MenuId = ChromeMenuId | (string & {});
|
|
745
|
+
|
|
746
|
+
/** Props for `DocxEditor.Menu.Row`: one presentational menu row. @public */
|
|
747
|
+
interface MenuRowProps {
|
|
748
|
+
/** Material Symbols paths, rendered as inline SVG in the row's icon column. */
|
|
749
|
+
icon?: ReactNode;
|
|
750
|
+
/** Right-aligned shortcut text (already resolved). */
|
|
751
|
+
shortcut?: string;
|
|
752
|
+
disabled?: boolean;
|
|
753
|
+
/**
|
|
754
|
+
* Tooltip. Set it for the ENGINE's disabled reason and nothing else — a menu row's text
|
|
755
|
+
* is already visible, so a tooltip repeating it is noise, and inventing a reason for a
|
|
756
|
+
* refusal the engine explained is the thing this codebase does not do.
|
|
757
|
+
*/
|
|
758
|
+
title?: string;
|
|
759
|
+
/**
|
|
760
|
+
* Checked state, for a row that TOGGLES (bold on bold text). Leave undefined on a row
|
|
761
|
+
* that just acts: `menuitemcheckbox` with `aria-checked="false"` announces "not
|
|
762
|
+
* selected" on a Page break row, which is a claim about state it does not have.
|
|
763
|
+
*/
|
|
764
|
+
active?: boolean;
|
|
765
|
+
/**
|
|
766
|
+
* Present on a row belonging to a MUTUALLY EXCLUSIVE set (the four alignments), which
|
|
767
|
+
* makes it `menuitemradio` rather than `menuitemcheckbox`. Four independent checkboxes
|
|
768
|
+
* is a different claim from one-of-four, and a screen reader reads it as such.
|
|
769
|
+
*/
|
|
770
|
+
selected?: true;
|
|
771
|
+
/** Stable marker for hosts, tests and e2e. */
|
|
772
|
+
slot?: string;
|
|
773
|
+
onSelect?: () => void;
|
|
774
|
+
className?: string;
|
|
775
|
+
children?: ReactNode;
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* One menu row: icon column, label, shortcut column.
|
|
779
|
+
*
|
|
780
|
+
* The icon column is reserved even when a row has no icon, so labels line up down the
|
|
781
|
+
* panel the way Word's and Docs' menus do.
|
|
782
|
+
*
|
|
783
|
+
* @public
|
|
784
|
+
*/
|
|
785
|
+
declare function MenuRow(props: MenuRowProps): react.JSX.Element;
|
|
786
|
+
/** Props for `DocxEditor.Menu.Group`: a titled section of rows. @public */
|
|
787
|
+
interface MenuGroupProps {
|
|
788
|
+
/** Literal heading, already resolved. Wins over {@link labelKey}. */
|
|
789
|
+
label?: string;
|
|
790
|
+
/** i18n key of the heading. */
|
|
791
|
+
labelKey?: string;
|
|
792
|
+
className?: string;
|
|
793
|
+
hidden?: boolean;
|
|
794
|
+
children?: ReactNode;
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* A named section inside a panel: a visible heading and the rows under it.
|
|
798
|
+
*
|
|
799
|
+
* A separator says rows are apart; a group says what they are, which is what a panel needs
|
|
800
|
+
* once a product adds rows beside the packaged ones. `role="group"` nests legally inside a
|
|
801
|
+
* menu, keeps its rows owned by it, and takes the heading as its accessible name — so the
|
|
802
|
+
* visible heading is decoration and is hidden from the tree.
|
|
803
|
+
*
|
|
804
|
+
* @public
|
|
805
|
+
*/
|
|
806
|
+
declare function MenuGroup({ label: literal, labelKey, className, hidden, children, }: MenuGroupProps): react.JSX.Element | null;
|
|
807
|
+
/** Props for `DocxEditor.Menu.Item`: one chrome slot as a menu row. @public */
|
|
808
|
+
interface MenuItemProps {
|
|
809
|
+
/** The chrome slot this row drives (`'text.bold'`, `'insert.pageBreak'`, …). */
|
|
810
|
+
slot: ChromeSlotId;
|
|
811
|
+
/** Plain-label i18n key, overriding the slot's tooltip-shaped one. */
|
|
812
|
+
labelKey?: string;
|
|
813
|
+
/** i18n key of the shortcut shown in the right column. */
|
|
814
|
+
shortcutKey?: string;
|
|
815
|
+
className?: string;
|
|
816
|
+
/** Render nothing — inside a packaged menu this removes the row. */
|
|
817
|
+
hidden?: boolean;
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* One chrome slot as a live menu row: enabled and active from the engine's
|
|
821
|
+
* can-before-exec answer, labelled and iconed from the registry. Selecting it runs the
|
|
822
|
+
* slot's command and closes the menu.
|
|
823
|
+
*
|
|
824
|
+
* @public
|
|
825
|
+
*/
|
|
826
|
+
declare function MenuItem({ slot, labelKey, shortcutKey, className, hidden }: MenuItemProps): react.JSX.Element | null;
|
|
827
|
+
declare namespace MenuItem {
|
|
828
|
+
var docxMenuRow: true;
|
|
829
|
+
}
|
|
830
|
+
/** Props for the pinned File rows. @public */
|
|
831
|
+
interface MenuActionProps {
|
|
832
|
+
className?: string;
|
|
833
|
+
hidden?: boolean;
|
|
834
|
+
}
|
|
835
|
+
declare const MenuOpen: (({ className, hidden }: MenuActionProps) => react.JSX.Element | null) & {
|
|
836
|
+
docxSlot: ChromeSlotId;
|
|
837
|
+
};
|
|
838
|
+
declare const MenuSave: (({ className, hidden }: MenuActionProps) => react.JSX.Element | null) & {
|
|
839
|
+
docxSlot: ChromeSlotId;
|
|
840
|
+
};
|
|
841
|
+
/**
|
|
842
|
+
* Page setup. Unlike open and save, the ENGINE has an opinion here — `setPageSetup` is a
|
|
843
|
+
* real command, it just needs the dialog's values — so the row asks through the slot's
|
|
844
|
+
* probe and is disabled with the engine's own words on a document it cannot rewrite.
|
|
845
|
+
*/
|
|
846
|
+
declare function MenuPageSetupImpl({ className, hidden }: MenuActionProps): react.JSX.Element | null;
|
|
847
|
+
declare const MenuPageSetup: typeof MenuPageSetupImpl & {
|
|
848
|
+
docxSlot: ChromeSlotId;
|
|
849
|
+
};
|
|
850
|
+
interface MenuSubmenuProps {
|
|
851
|
+
/** i18n key of the parent row's label. */
|
|
852
|
+
labelKey: string;
|
|
853
|
+
/** Material Symbols paths for the parent row's icon. */
|
|
854
|
+
paths?: readonly string[] | null;
|
|
855
|
+
className?: string;
|
|
856
|
+
children?: ReactNode;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* A row that opens a nested panel to its right (Insert › Break).
|
|
860
|
+
*
|
|
861
|
+
* The parent row runs nothing — disclosure is not a command — so it stays interactive
|
|
862
|
+
* regardless of what its children can do, and each child answers for itself. Opening on
|
|
863
|
+
* hover AND on click is what both Word and Docs do; keyboard users get the same panel
|
|
864
|
+
* through focus.
|
|
865
|
+
*
|
|
866
|
+
* @public
|
|
867
|
+
*/
|
|
868
|
+
declare function MenuSubmenu({ labelKey, paths, className, children }: MenuSubmenuProps): react.JSX.Element;
|
|
869
|
+
/** Props for `DocxEditor.Menu.TableGrid`. @public */
|
|
870
|
+
interface MenuTableGridProps {
|
|
871
|
+
/** The slot the picked size dispatches through. Defaults to `table.insert`. */
|
|
872
|
+
slot?: ChromeSlotId;
|
|
873
|
+
className?: string;
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Word's insert-table size picker: a 6×6 grid that highlights as the pointer sweeps it
|
|
877
|
+
* and reads back the size underneath.
|
|
878
|
+
*
|
|
879
|
+
* Rendered only when the engine will honour an insert (see `MenuTablePicker`). A panel
|
|
880
|
+
* that opens onto a grid nothing can be picked from is worse than no panel: the row
|
|
881
|
+
* cannot act, so it should not disclose — it should look disabled, like every other row
|
|
882
|
+
* the engine refuses.
|
|
883
|
+
*
|
|
884
|
+
* @public
|
|
885
|
+
*/
|
|
886
|
+
declare function MenuTableGrid({ slot, className }: MenuTableGridProps): react.JSX.Element;
|
|
887
|
+
/** Props for `DocxEditor.Menu.Separator`. @public */
|
|
888
|
+
interface MenuSeparatorProps {
|
|
889
|
+
className?: string;
|
|
890
|
+
}
|
|
891
|
+
/** A horizontal rule between groups of rows. @public */
|
|
892
|
+
declare function MenuSeparator({ className }: MenuSeparatorProps): react.JSX.Element;
|
|
893
|
+
/**
|
|
894
|
+
* One registry entry as its row.
|
|
895
|
+
*
|
|
896
|
+
* The three host-boundary slots route to their pinned parts rather than to the generic
|
|
897
|
+
* `MenuItem`, because a command-driven row would render them permanently disabled — the
|
|
898
|
+
* engine reports, correctly, that neither open nor save is a command.
|
|
899
|
+
*/
|
|
900
|
+
declare function MenuEntry({ entry }: {
|
|
901
|
+
entry: ChromeMenuEntry;
|
|
902
|
+
}): react.JSX.Element;
|
|
903
|
+
/** Props for `DocxEditor.Menu.Menu` and the four pinned menu parts. @public */
|
|
904
|
+
interface MenuProps {
|
|
905
|
+
/** Which menu this is. Only one panel in the bar is open at a time, keyed on this. */
|
|
906
|
+
id: MenuId;
|
|
907
|
+
/** i18n key of the trigger label. Defaults to the registry's. */
|
|
908
|
+
labelKey?: string;
|
|
909
|
+
/**
|
|
910
|
+
* Literal trigger label, already resolved. Wins over `labelKey`, and is what a
|
|
911
|
+
* host-defined menu uses — its name is not in our catalogue and never will be.
|
|
912
|
+
*/
|
|
913
|
+
label?: string;
|
|
914
|
+
/**
|
|
915
|
+
* Icon shown before the trigger's label.
|
|
916
|
+
*
|
|
917
|
+
* OPT-IN and unset by default, because neither Word nor Docs puts icons on a menu bar and
|
|
918
|
+
* the packaged bar should look like the thing it is imitating. It exists because every
|
|
919
|
+
* other control in this library takes one — toolbar parts, menu rows — and a product with
|
|
920
|
+
* its own visual language should not have to rebuild the trigger to add a glyph to it.
|
|
921
|
+
*
|
|
922
|
+
* Decorative: the label is the accessible name, so the icon is hidden from assistive tech.
|
|
923
|
+
*/
|
|
924
|
+
icon?: ReactNode;
|
|
925
|
+
className?: string;
|
|
926
|
+
/** Render nothing — inside the default bar this removes the menu. */
|
|
927
|
+
hidden?: boolean;
|
|
928
|
+
/**
|
|
929
|
+
* `false` renders `children` verbatim as the whole panel. Default `true`: the panel is
|
|
930
|
+
* the registry's rows for this menu, with a row child REPLACING the row it names in
|
|
931
|
+
* place (`hidden` removes it) and any other child appended. Use `false` when the order
|
|
932
|
+
* matters and you want to state it yourself.
|
|
933
|
+
*/
|
|
934
|
+
preset?: boolean;
|
|
935
|
+
/** Panel content. */
|
|
936
|
+
children?: ReactNode;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* One menu of the bar: a trigger and the panel it opens.
|
|
940
|
+
*
|
|
941
|
+
* Bar behaviour is Docs': a click opens, a second click closes, and while ANY menu is
|
|
942
|
+
* open, moving the pointer over a different trigger switches to it without a click.
|
|
943
|
+
*
|
|
944
|
+
* @public
|
|
945
|
+
*/
|
|
946
|
+
declare function Menu({ id, labelKey, label: literal, icon, className, hidden, preset, children, }: MenuProps): react.JSX.Element | null;
|
|
947
|
+
/** A menu pinned to one registry id, for `DocxEditor.Menu.File` and friends. @public */
|
|
948
|
+
interface MenuPartComponent {
|
|
949
|
+
(props: Omit<MenuProps, 'id'>): ReactNode;
|
|
950
|
+
readonly docxMenu: ChromeMenuId;
|
|
951
|
+
}
|
|
952
|
+
/** Props for `DocxEditor.Menu.ReportIssue`. @public */
|
|
953
|
+
interface MenuReportIssueProps {
|
|
954
|
+
className?: string;
|
|
955
|
+
/** Render nothing — inside the packaged Help menu this removes the row. */
|
|
956
|
+
hidden?: boolean;
|
|
957
|
+
/** Replaces the packaged handler. Falls back to the menu's `onReportIssue`, then to
|
|
958
|
+
* this project's own tracker. */
|
|
959
|
+
onSelect?: () => void;
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Help › Report issue.
|
|
963
|
+
*
|
|
964
|
+
* A NAMED part rather than anonymous markup inside the Help menu, because it is the one
|
|
965
|
+
* packaged row that reaches OUTSIDE the host's product: it opens this project's issue
|
|
966
|
+
* tracker with the current page URL and user agent prefilled. A host embedding the editor
|
|
967
|
+
* in its own app has every reason to point that somewhere else or drop it, and it should
|
|
968
|
+
* not have to rebuild the menu to do either — `reportIssue={false}` removes it,
|
|
969
|
+
* `onReportIssue` redirects it, and this part composes it back by name.
|
|
970
|
+
*
|
|
971
|
+
* @public
|
|
972
|
+
*/
|
|
973
|
+
declare function MenuReportIssueImpl({ className, hidden, onSelect }: MenuReportIssueProps): react.JSX.Element | null;
|
|
974
|
+
/**
|
|
975
|
+
* The report-issue row, with its row-identity marker.
|
|
976
|
+
*
|
|
977
|
+
* The key is NOT a `ChromeSlotId` — the row is React's, not the shared registry's — but the
|
|
978
|
+
* merge only needs a stable string, and using one here is what lets a host write
|
|
979
|
+
* `<Menu.ReportIssue hidden/>` and have it REPLACE the packaged row rather than render a
|
|
980
|
+
* second, invisible one beside it.
|
|
981
|
+
*
|
|
982
|
+
* @public
|
|
983
|
+
*/
|
|
984
|
+
declare const MenuReportIssue: typeof MenuReportIssueImpl & {
|
|
985
|
+
docxSlot: string;
|
|
986
|
+
};
|
|
987
|
+
|
|
988
|
+
/** Props for `DocxEditor.Menu`. @public */
|
|
989
|
+
interface DocxEditorMenuProps {
|
|
990
|
+
/** Appended after the base `docx-menubar` class. */
|
|
991
|
+
className?: string;
|
|
992
|
+
/** i18n resolver for row labels; without it the raw keys show (never English). */
|
|
993
|
+
t?: ToolbarTranslate;
|
|
994
|
+
/**
|
|
995
|
+
* Name for the file the packaged Save writes, without the extension. Ignored when
|
|
996
|
+
* `onSave` is given.
|
|
997
|
+
*/
|
|
998
|
+
fileName?: string;
|
|
999
|
+
/**
|
|
1000
|
+
* Replaces File › Open. The default opens a file picker and hands the bytes to
|
|
1001
|
+
* `Editor.load` — a user-driven file READ, never a fetch.
|
|
1002
|
+
*/
|
|
1003
|
+
onOpen?: () => void;
|
|
1004
|
+
/**
|
|
1005
|
+
* Fired when the packaged Open reads a file, before its bytes are loaded — so a host can
|
|
1006
|
+
* reflect the file's name in its own title chrome. Not fired when `onOpen` replaced the
|
|
1007
|
+
* packaged picker: the host is reading the file itself and already holds the name.
|
|
1008
|
+
*/
|
|
1009
|
+
onOpenFile?: (file: File) => void;
|
|
1010
|
+
/** Replaces File › Save. The default runs `Editor.save()` and downloads the bytes. */
|
|
1011
|
+
onSave?: () => void;
|
|
1012
|
+
/** Replaces File › Page setup. The default opens the packaged Page Setup dialog. */
|
|
1013
|
+
onPageSetup?: () => void;
|
|
1014
|
+
/**
|
|
1015
|
+
* Replaces Help › Report issue. The default opens THIS project's issue tracker,
|
|
1016
|
+
* prefilled with the current page URL and user agent — so a host embedding the editor
|
|
1017
|
+
* in its own product should point this at its own support channel, or drop the row with
|
|
1018
|
+
* `reportIssue={false}`.
|
|
1019
|
+
*/
|
|
1020
|
+
onReportIssue?: () => void;
|
|
1021
|
+
/** `false` removes Help › Report issue, and the Help menu with it. Default `true`. */
|
|
1022
|
+
reportIssue?: boolean;
|
|
1023
|
+
/**
|
|
1024
|
+
* `false` renders children verbatim with no default arrangement. Default `true`: menu
|
|
1025
|
+
* children override their menu in place, others append.
|
|
1026
|
+
*/
|
|
1027
|
+
preset?: boolean;
|
|
1028
|
+
children?: ReactNode;
|
|
1029
|
+
}
|
|
1030
|
+
/** The menu bar with its parts attached as statics. @public */
|
|
1031
|
+
interface DocxEditorMenuNamespace {
|
|
1032
|
+
(props: DocxEditorMenuProps): ReactNode;
|
|
1033
|
+
/** A menu of the bar, addressed by registry id. */
|
|
1034
|
+
readonly Menu: typeof Menu;
|
|
1035
|
+
readonly File: MenuPartComponent;
|
|
1036
|
+
readonly Format: MenuPartComponent;
|
|
1037
|
+
readonly Insert: MenuPartComponent;
|
|
1038
|
+
readonly Help: MenuPartComponent;
|
|
1039
|
+
/** One chrome slot as a live row. */
|
|
1040
|
+
readonly Item: typeof MenuItem;
|
|
1041
|
+
/** A presentational row, for a host action that is not a chrome slot. */
|
|
1042
|
+
readonly Row: typeof MenuRow;
|
|
1043
|
+
/** A named section of rows: a visible heading plus a real ARIA group. */
|
|
1044
|
+
readonly Group: typeof MenuGroup;
|
|
1045
|
+
readonly Separator: typeof MenuSeparator;
|
|
1046
|
+
readonly Submenu: typeof MenuSubmenu;
|
|
1047
|
+
/** Word's 6×6 insert-table size picker. */
|
|
1048
|
+
readonly TableGrid: typeof MenuTableGrid;
|
|
1049
|
+
/** One registry entry as its row, for a host arranging registry data itself. */
|
|
1050
|
+
readonly Entry: typeof MenuEntry;
|
|
1051
|
+
readonly Open: typeof MenuOpen;
|
|
1052
|
+
readonly Save: typeof MenuSave;
|
|
1053
|
+
readonly PageSetup: typeof MenuPageSetup;
|
|
1054
|
+
/** Help › Report issue, so a host can drop it or point it elsewhere by name. */
|
|
1055
|
+
readonly ReportIssue: typeof MenuReportIssue;
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* The compound menu bar: `<DocxEditor.Menu/>` for File · Format · Insert · Help, parts as
|
|
1059
|
+
* statics for composition.
|
|
1060
|
+
*
|
|
1061
|
+
* Every actionable row is a chrome slot, so a row and its toolbar twin share one label,
|
|
1062
|
+
* one icon, one command and one enabled state. Rows the engine cannot honour yet render
|
|
1063
|
+
* present and disabled, carrying the engine's own reason.
|
|
1064
|
+
*
|
|
1065
|
+
* @public
|
|
1066
|
+
*/
|
|
1067
|
+
declare const DocxEditorMenu: DocxEditorMenuNamespace;
|
|
1068
|
+
|
|
1069
|
+
/** Props for the context-fed ruler parts. @public */
|
|
1070
|
+
interface DocxEditorRulerProps {
|
|
1071
|
+
/** Measurement unit for tick labels. Defaults to inches. */
|
|
1072
|
+
unit?: 'inch' | 'cm';
|
|
1073
|
+
className?: string;
|
|
1074
|
+
style?: CSSProperties;
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* The horizontal ruler as a context-fed part (`DocxEditor.HorizontalRuler`): page
|
|
1078
|
+
* width, margins and zoom straight from the editor. Left/right margin handles are
|
|
1079
|
+
* draggable when the engine supports page-setup writes; the drag previews locally and
|
|
1080
|
+
* commits one undoable step on release.
|
|
1081
|
+
*
|
|
1082
|
+
* @public
|
|
1083
|
+
*/
|
|
1084
|
+
declare function DocxEditorHorizontalRuler(props: DocxEditorRulerProps): ReactElement;
|
|
1085
|
+
/**
|
|
1086
|
+
* The vertical ruler as a context-fed part (`DocxEditor.VerticalRuler`): page height,
|
|
1087
|
+
* margins and zoom straight from the editor. Top/bottom margin handles are draggable
|
|
1088
|
+
* when the engine supports page-setup writes, committing one undoable step on release.
|
|
1089
|
+
*
|
|
1090
|
+
* @public
|
|
1091
|
+
*/
|
|
1092
|
+
declare function DocxEditorVerticalRuler(props: DocxEditorRulerProps): ReactElement;
|
|
1093
|
+
|
|
1094
|
+
/** Props for the context-fed outline part. @public */
|
|
1095
|
+
interface DocxEditorDocumentOutlineProps {
|
|
1096
|
+
/** Close-button handler; without one the panel simply stays open. */
|
|
1097
|
+
onClose?: () => void;
|
|
1098
|
+
/** Vertical offset (px) inside the panel's positioning container. */
|
|
1099
|
+
topOffset?: number;
|
|
1100
|
+
/** Left anchor (px) inside the panel's positioning container. */
|
|
1101
|
+
leftOffset?: number;
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* The document outline as a context-fed part (`DocxEditor.DocumentOutline`): headings
|
|
1105
|
+
* from `Editor.getOutline()`, in document order; clicking one moves the caret to that
|
|
1106
|
+
* heading. The panel positions absolutely — give it a `position: relative` container.
|
|
1107
|
+
*
|
|
1108
|
+
* @public
|
|
1109
|
+
*/
|
|
1110
|
+
declare function DocxEditorDocumentOutline(props: DocxEditorDocumentOutlineProps): ReactElement;
|
|
1111
|
+
|
|
1112
|
+
/** The pane's tabs. Word's Replace tab is a later slice; nothing here pretends it exists. */
|
|
1113
|
+
type NavigationTab$1 = 'headings' | 'find';
|
|
1114
|
+
/** How `useNavigationPane` is configured. @public */
|
|
1115
|
+
interface UseNavigationPaneOptions {
|
|
1116
|
+
/** Open state for the first render when the pane is uncontrolled. Defaults to closed. */
|
|
1117
|
+
defaultOpen?: boolean;
|
|
1118
|
+
/** Controlled open state. Pair with `onOpenChange`. */
|
|
1119
|
+
open?: boolean;
|
|
1120
|
+
onOpenChange?: (open: boolean) => void;
|
|
1121
|
+
/** Tab shown first when uncontrolled. Defaults to `'headings'`. */
|
|
1122
|
+
defaultTab?: NavigationTab$1;
|
|
1123
|
+
/** Controlled tab. Pair with `onTabChange`. */
|
|
1124
|
+
tab?: NavigationTab$1;
|
|
1125
|
+
onTabChange?: (tab: NavigationTab$1) => void;
|
|
1126
|
+
/** Panel width in px. Defaults to {@link NAVIGATION_PANE_WIDTH}. */
|
|
1127
|
+
paneWidth?: number;
|
|
1128
|
+
}
|
|
1129
|
+
/** What `useNavigationPane` answers. @public */
|
|
1130
|
+
interface UseNavigationPaneResult {
|
|
1131
|
+
readonly open: boolean;
|
|
1132
|
+
readonly setOpen: (open: boolean) => void;
|
|
1133
|
+
readonly toggle: () => void;
|
|
1134
|
+
readonly tab: NavigationTab$1;
|
|
1135
|
+
readonly setTab: (tab: NavigationTab$1) => void;
|
|
1136
|
+
readonly paneWidth: number;
|
|
1137
|
+
/**
|
|
1138
|
+
* Px the chrome is displaced by, right now. `0` while the pane is closed AND whenever
|
|
1139
|
+
* the left gutter was already wide enough to hold it — which is the point.
|
|
1140
|
+
*/
|
|
1141
|
+
readonly shift: number;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* The navigation pane's behavior, with no UI attached: open state, the active tab, and
|
|
1145
|
+
* the document displacement an open pane is entitled to.
|
|
1146
|
+
*
|
|
1147
|
+
* `DocxEditor.Navigation` calls this and shares the result with its parts. Call it
|
|
1148
|
+
* directly to drive a pane of your own.
|
|
1149
|
+
*
|
|
1150
|
+
* @public
|
|
1151
|
+
*/
|
|
1152
|
+
declare function useNavigationPane(options?: UseNavigationPaneOptions): UseNavigationPaneResult;
|
|
1153
|
+
|
|
1154
|
+
/** Shared props for the pane's structural parts. @public */
|
|
1155
|
+
interface NavigationPartProps {
|
|
1156
|
+
className?: string;
|
|
1157
|
+
style?: CSSProperties;
|
|
1158
|
+
children?: ReactNode;
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* The pane's title row. With no children it renders the close arrow and the title.
|
|
1162
|
+
*
|
|
1163
|
+
* @public
|
|
1164
|
+
*/
|
|
1165
|
+
declare function NavigationHeader({ className, style, children, }: NavigationPartProps): ReactElement;
|
|
1166
|
+
/** The back arrow that closes the pane. @public */
|
|
1167
|
+
declare function NavigationClose({ className, style, children }: NavigationPartProps): ReactElement;
|
|
1168
|
+
/** The pane's heading text. @public */
|
|
1169
|
+
declare function NavigationTitle({ className, style, children }: NavigationPartProps): ReactElement;
|
|
1170
|
+
/**
|
|
1171
|
+
* The tab strip. With no children it renders one `Tab` per tab the pane supports.
|
|
1172
|
+
*
|
|
1173
|
+
* A real `role="tablist"`, so arrow keys move between tabs and a screen reader announces
|
|
1174
|
+
* the panel each one controls.
|
|
1175
|
+
*
|
|
1176
|
+
* @public
|
|
1177
|
+
*/
|
|
1178
|
+
declare function NavigationTabs({ className, style, children }: NavigationPartProps): ReactElement;
|
|
1179
|
+
/** Props for one tab. @public */
|
|
1180
|
+
interface NavigationTabProps extends NavigationPartProps {
|
|
1181
|
+
value: NavigationTab$1;
|
|
1182
|
+
}
|
|
1183
|
+
/** One tab button. Children replace the label. @public */
|
|
1184
|
+
declare function NavigationTab({ value, className, style, children, }: NavigationTabProps): ReactElement;
|
|
1185
|
+
/**
|
|
1186
|
+
* The heading list, indented by outline depth. Clicking a row moves the caret to that
|
|
1187
|
+
* heading and brings it into view.
|
|
1188
|
+
*
|
|
1189
|
+
* The filter box narrows the list CLIENT-SIDE — it hides rows whose text does not contain
|
|
1190
|
+
* what you typed. It is deliberately not the document search: filtering an outline and
|
|
1191
|
+
* searching a document are different questions, and the Find tab answers the second one.
|
|
1192
|
+
*
|
|
1193
|
+
* @public
|
|
1194
|
+
*/
|
|
1195
|
+
declare function NavigationHeadings({ className, style }: NavigationPartProps): ReactElement;
|
|
1196
|
+
/**
|
|
1197
|
+
* The find panel: a query box, a result counter with previous/next, the match-case and
|
|
1198
|
+
* whole-word toggles, and the result list. Selecting a result moves the caret onto the
|
|
1199
|
+
* match and reveals its page.
|
|
1200
|
+
*
|
|
1201
|
+
* @public
|
|
1202
|
+
*/
|
|
1203
|
+
declare function NavigationFind({ className, style }: NavigationPartProps): ReactElement;
|
|
1204
|
+
/**
|
|
1205
|
+
* The collapsed pane's disc button. `DocxEditor.Navigation` renders one for you while the
|
|
1206
|
+
* pane is closed; place it yourself (a toolbar, a menu) with `toggle={false}` on the root.
|
|
1207
|
+
*
|
|
1208
|
+
* @public
|
|
1209
|
+
*/
|
|
1210
|
+
declare function NavigationToggle({ className, style, children, }: NavigationPartProps): ReactElement;
|
|
1211
|
+
|
|
1212
|
+
/** Props for `DocxEditor.Navigation`. @public */
|
|
1213
|
+
interface DocxEditorNavigationProps extends UseNavigationPaneOptions {
|
|
1214
|
+
/**
|
|
1215
|
+
* Label resolver. Defaults to the active `LocaleContext` catalogue (bundled English
|
|
1216
|
+
* unless a provider swapped it), matching `<DocxEditor>`'s own default.
|
|
1217
|
+
*/
|
|
1218
|
+
t?: (key: string, params?: Record<string, string | number>) => string;
|
|
1219
|
+
/**
|
|
1220
|
+
* The collapsed disc button. `false` removes it; an OBJECT is props for the packaged one,
|
|
1221
|
+
* so a host can give it a class without restyling the library's.
|
|
1222
|
+
*
|
|
1223
|
+
* It is a prop rather than something you compose through `children` because the disc is
|
|
1224
|
+
* rendered OUTSIDE the panel: the panel is `inert` while the pane is shut, which is
|
|
1225
|
+
* exactly when the disc has to be clickable.
|
|
1226
|
+
*/
|
|
1227
|
+
toggle?: boolean | NavigationPartProps;
|
|
1228
|
+
className?: string;
|
|
1229
|
+
style?: CSSProperties;
|
|
1230
|
+
/** Replaces the default composition (header, tabs, both panels). */
|
|
1231
|
+
children?: ReactNode;
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* The document navigation pane — headings and find — over the left gutter.
|
|
1235
|
+
*
|
|
1236
|
+
* @public
|
|
1237
|
+
*/
|
|
1238
|
+
declare function DocxEditorNavigation(props: DocxEditorNavigationProps): ReactElement;
|
|
1239
|
+
/**
|
|
1240
|
+
* `DocxEditor.Navigation` with its parts attached as statics.
|
|
1241
|
+
*
|
|
1242
|
+
* @public
|
|
1243
|
+
*/
|
|
1244
|
+
interface DocxEditorNavigationNamespace {
|
|
1245
|
+
(props: DocxEditorNavigationProps): ReactElement;
|
|
1246
|
+
readonly Header: typeof NavigationHeader;
|
|
1247
|
+
readonly Close: typeof NavigationClose;
|
|
1248
|
+
readonly Title: typeof NavigationTitle;
|
|
1249
|
+
readonly Tabs: typeof NavigationTabs;
|
|
1250
|
+
readonly Tab: typeof NavigationTab;
|
|
1251
|
+
readonly Headings: typeof NavigationHeadings;
|
|
1252
|
+
readonly Find: typeof NavigationFind;
|
|
1253
|
+
readonly Toggle: typeof NavigationToggle;
|
|
1254
|
+
}
|
|
1255
|
+
declare const Navigation: DocxEditorNavigationNamespace;
|
|
1256
|
+
|
|
1257
|
+
/**
|
|
1258
|
+
* One heading of the engine's outline: text, 0-based level, and the block id
|
|
1259
|
+
* `Editor.scrollToBlock` accepts.
|
|
1260
|
+
*
|
|
1261
|
+
* @public
|
|
1262
|
+
*/
|
|
1263
|
+
type OutlineHeading$1 = ReturnType<Editor['getOutline']>[number];
|
|
1264
|
+
/** A heading plus how deep to indent it in a rendered list. @public */
|
|
1265
|
+
interface OutlineHeadingItem {
|
|
1266
|
+
readonly heading: OutlineHeading$1;
|
|
1267
|
+
/**
|
|
1268
|
+
* Indent depth RELATIVE to the shallowest heading present, not the absolute level. A
|
|
1269
|
+
* memo whose top sections are Heading 2 should left-align them at the base instead of
|
|
1270
|
+
* carrying a phantom first-level indent.
|
|
1271
|
+
*/
|
|
1272
|
+
readonly depth: number;
|
|
1273
|
+
}
|
|
1274
|
+
/** What `useDocumentOutline` answers. @public */
|
|
1275
|
+
interface UseDocumentOutlineResult {
|
|
1276
|
+
/** The document's headings, in document order. Empty when it has none. */
|
|
1277
|
+
readonly headings: readonly OutlineHeading$1[];
|
|
1278
|
+
/** The same headings with their rendering depth resolved. */
|
|
1279
|
+
readonly items: readonly OutlineHeadingItem[];
|
|
1280
|
+
/**
|
|
1281
|
+
* The heading this pane last navigated to, so a list can show it as current. Tracks the
|
|
1282
|
+
* PANE's navigation, not the caret: following the caret would mean walking the document
|
|
1283
|
+
* on every selection change, and the engine has no derivation for it yet.
|
|
1284
|
+
*/
|
|
1285
|
+
readonly selectedBlockId: string | null;
|
|
1286
|
+
/** Move the caret to a heading and bring it into view. Unknown ids are a safe no-op. */
|
|
1287
|
+
readonly goTo: (blockId: string) => void;
|
|
1288
|
+
readonly isEmpty: boolean;
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* The document outline's behavior, with no UI attached: the headings, their nesting
|
|
1292
|
+
* depth, and the jump. `DocxEditor.Navigation.Headings` is this hook plus rows; a host
|
|
1293
|
+
* that wants a different list takes the hook and renders its own.
|
|
1294
|
+
*
|
|
1295
|
+
* @public
|
|
1296
|
+
*/
|
|
1297
|
+
declare function useDocumentOutline(): UseDocumentOutlineResult;
|
|
1298
|
+
|
|
1299
|
+
/** Milliseconds of quiet before a typed query is run against the document. */
|
|
1300
|
+
declare const SEARCH_DEBOUNCE_MS = 150;
|
|
1301
|
+
/**
|
|
1302
|
+
* The engine's cap on one search. A full result array means "at least this many"; the
|
|
1303
|
+
* hook reports that as {@link UseDocumentSearchResult.truncated}.
|
|
1304
|
+
*/
|
|
1305
|
+
declare const SEARCH_MATCH_LIMIT = 2000;
|
|
1306
|
+
/** What `useDocumentSearch` answers. @public */
|
|
1307
|
+
interface UseDocumentSearchResult {
|
|
1308
|
+
/** The text in the search box, updated synchronously as the user types. */
|
|
1309
|
+
readonly query: string;
|
|
1310
|
+
readonly setQuery: (query: string) => void;
|
|
1311
|
+
readonly matchCase: boolean;
|
|
1312
|
+
readonly setMatchCase: (value: boolean) => void;
|
|
1313
|
+
readonly wholeWord: boolean;
|
|
1314
|
+
readonly setWholeWord: (value: boolean) => void;
|
|
1315
|
+
/** Matches for the last RUN query, in document order. */
|
|
1316
|
+
readonly matches: readonly TextMatch[];
|
|
1317
|
+
/**
|
|
1318
|
+
* Whether the engine stopped at its cap with matches still ahead of it, so a count
|
|
1319
|
+
* should read "2000+" rather than an exact total. A search that lands on exactly the cap
|
|
1320
|
+
* reports true; over-reporting by one is the honest direction.
|
|
1321
|
+
*/
|
|
1322
|
+
readonly truncated: boolean;
|
|
1323
|
+
/** Index of the match the caret was last sent to, or `-1` before any navigation. */
|
|
1324
|
+
readonly activeIndex: number;
|
|
1325
|
+
/** Select a match by index and bring its page into view. Out-of-range is a no-op. */
|
|
1326
|
+
readonly goTo: (index: number) => void;
|
|
1327
|
+
/** Next / previous match, wrapping at the ends the way Word's arrows do. */
|
|
1328
|
+
readonly next: () => void;
|
|
1329
|
+
readonly previous: () => void;
|
|
1330
|
+
/** Empty the box and drop the results, without touching the selection. */
|
|
1331
|
+
readonly clear: () => void;
|
|
1332
|
+
/** Whether a typed query is waiting for its debounce to elapse. */
|
|
1333
|
+
readonly isPending: boolean;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* The find panel's behavior, with no UI attached.
|
|
1337
|
+
*
|
|
1338
|
+
* @public
|
|
1339
|
+
*/
|
|
1340
|
+
declare function useDocumentSearch(): UseDocumentSearchResult;
|
|
1341
|
+
|
|
1342
|
+
/** Panel width, in px, when the host does not choose one. */
|
|
1343
|
+
declare const NAVIGATION_PANE_WIDTH = 280;
|
|
1344
|
+
/**
|
|
1345
|
+
* Gap between the viewport's left edge and the panel.
|
|
1346
|
+
*
|
|
1347
|
+
* Clears a vertical ruler: `RULER_WIDTH` is 20px pinned at the viewport's left edge, so
|
|
1348
|
+
* anything less puts the panel and its collapsed disc on top of the tick marks.
|
|
1349
|
+
*/
|
|
1350
|
+
declare const NAVIGATION_PANE_INSET = 32;
|
|
1351
|
+
/** Clearance kept between the panel's right edge and the page. */
|
|
1352
|
+
declare const NAVIGATION_PANE_GAP = 16;
|
|
1353
|
+
/** Total left space an open pane needs before the page may start. */
|
|
1354
|
+
declare function navigationPaneReservation(paneWidth?: number): number;
|
|
1355
|
+
interface NavigationShiftInput {
|
|
1356
|
+
/** Client width of the scroll container. */
|
|
1357
|
+
readonly viewportWidth: number;
|
|
1358
|
+
/** Rendered width of one page, zoom applied. */
|
|
1359
|
+
readonly pageWidthPx: number;
|
|
1360
|
+
/** Space the open pane needs, from {@link navigationPaneReservation}. */
|
|
1361
|
+
readonly reservation: number;
|
|
1362
|
+
/** Padding already reserved at the inline end, for example by the review rail. */
|
|
1363
|
+
readonly inlineEndReservation?: number;
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* The viewport's left padding, in px, that puts the page's left edge exactly at
|
|
1367
|
+
* `reservation` — and `0` whenever the gutter is already wide enough.
|
|
1368
|
+
*
|
|
1369
|
+
* Returns 0 for a degenerate measurement (a viewport that has not been laid out yet, a
|
|
1370
|
+
* document with no page setup) rather than guessing: shifting on a zero measurement would
|
|
1371
|
+
* make the pane jump on the first frame and settle on the second.
|
|
1372
|
+
*/
|
|
1373
|
+
declare function navigationShift({ viewportWidth, pageWidthPx, reservation, inlineEndReservation, }: NavigationShiftInput): number;
|
|
1374
|
+
|
|
1375
|
+
/**
|
|
1376
|
+
* The px the chrome is currently displaced by an open navigation pane. `0` when no pane
|
|
1377
|
+
* is mounted, when it is closed, and whenever the left gutter was already wide enough.
|
|
1378
|
+
*
|
|
1379
|
+
* @public
|
|
1380
|
+
*/
|
|
1381
|
+
declare function useNavigationShift(): number;
|
|
1382
|
+
|
|
1383
|
+
/** Props for `DocxEditor.PageSetupDialog`. @public */
|
|
1384
|
+
interface DocxEditorPageSetupDialogProps {
|
|
1385
|
+
/** Whether the dialog is shown. The host owns this state. */
|
|
1386
|
+
open: boolean;
|
|
1387
|
+
/** Called on Cancel, Escape, overlay click, and after a successful Apply. */
|
|
1388
|
+
onClose: () => void;
|
|
1389
|
+
className?: string;
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Page Setup dialog: size preset, orientation, margins in inches. Reads the section
|
|
1393
|
+
* through `usePageSetup()` and applies the whole form as one undoable command.
|
|
1394
|
+
*
|
|
1395
|
+
* @public
|
|
1396
|
+
*/
|
|
1397
|
+
declare function DocxEditorPageSetupDialog({ open, onClose, className, }: DocxEditorPageSetupDialogProps): ReactElement | null;
|
|
1398
|
+
|
|
1399
|
+
/** Props for `DocxEditor.PageNumber`. @public */
|
|
1400
|
+
interface DocxEditorPageNumberProps {
|
|
1401
|
+
/** Appended after the default page-number classes. */
|
|
1402
|
+
className?: string;
|
|
1403
|
+
/** Inline presentation overrides for the indicator element. */
|
|
1404
|
+
style?: CSSProperties;
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Floating localized page readout for the active `DocxEditor.Viewport`.
|
|
1408
|
+
*
|
|
1409
|
+
* Render it as a sibling of the viewport inside a positioned wrapper. It appears while a
|
|
1410
|
+
* multi-page document scrolls and fades after 600 ms of inactivity.
|
|
1411
|
+
*
|
|
1412
|
+
* @public
|
|
1413
|
+
*/
|
|
1414
|
+
declare function DocxEditorPageNumber({ className, style }: DocxEditorPageNumberProps): react.JSX.Element | null;
|
|
1415
|
+
|
|
1416
|
+
/** Props for `DocxEditor.FontNotice`. @public */
|
|
1417
|
+
interface DocxEditorFontNoticeProps {
|
|
1418
|
+
/** Appended after the default notice classes. */
|
|
1419
|
+
className?: string;
|
|
1420
|
+
/** Inline presentation overrides for the notice element. */
|
|
1421
|
+
style?: CSSProperties;
|
|
1422
|
+
/** Translator override; defaults to the ambient locale context. */
|
|
1423
|
+
t?: TFunction;
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Word-style font compatibility notice.
|
|
1427
|
+
*
|
|
1428
|
+
* Shown when the open document declares font families this platform cannot resolve —
|
|
1429
|
+
* not installed, not embedded in the file, not supplied by the app's font
|
|
1430
|
+
* configuration — so the text is rendering in a substitute face. Dismissing hides the
|
|
1431
|
+
* notice for that set of families; a different document (or a font arriving) changes
|
|
1432
|
+
* the set and surfaces it again.
|
|
1433
|
+
*
|
|
1434
|
+
* @public
|
|
1435
|
+
*/
|
|
1436
|
+
declare function DocxEditorFontNotice({ className, style, t: tProp }: DocxEditorFontNoticeProps): react.JSX.Element | null;
|
|
1437
|
+
|
|
1438
|
+
/** Props for `DocxEditor.HeaderFooterChrome`. @public */
|
|
1439
|
+
interface DocxEditorHeaderFooterChromeProps {
|
|
1440
|
+
className?: string;
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Thin overlay while a header or footer scope is open: region label and contextual options.
|
|
1444
|
+
* Mount beside `DocxEditor.Content`.
|
|
1445
|
+
*
|
|
1446
|
+
* @public
|
|
1447
|
+
*/
|
|
1448
|
+
declare function DocxEditorHeaderFooterChrome({ className, }: DocxEditorHeaderFooterChromeProps): ReactElement | null;
|
|
1449
|
+
|
|
1450
|
+
/** Shared props for every part. @public */
|
|
1451
|
+
interface HyperLinkPartProps {
|
|
1452
|
+
className?: string;
|
|
1453
|
+
/** Merge this part's wiring onto the single child element instead of the default one. */
|
|
1454
|
+
asChild?: boolean;
|
|
1455
|
+
/** Render nothing — inside the default arrangement this removes the part. */
|
|
1456
|
+
hidden?: boolean;
|
|
1457
|
+
children?: ReactNode;
|
|
1458
|
+
}
|
|
1459
|
+
/** Props for the action parts, which also take an icon. @public */
|
|
1460
|
+
interface HyperLinkActionProps extends HyperLinkPartProps {
|
|
1461
|
+
/** Icon override; falls back to `children`, then to the part's default glyph. */
|
|
1462
|
+
icon?: ReactNode;
|
|
1463
|
+
}
|
|
1464
|
+
/** Props for `DocxEditor.HyperLink`. @public */
|
|
1465
|
+
interface HyperLinkProps extends HyperLinkPartProps {
|
|
1466
|
+
/**
|
|
1467
|
+
* Render the packaged arrangement. `false` mounts only the popover shell and whatever
|
|
1468
|
+
* parts you pass as children — the rung for "I want the wiring, not the layout".
|
|
1469
|
+
*/
|
|
1470
|
+
preset?: boolean;
|
|
1471
|
+
}
|
|
1472
|
+
/**
|
|
1473
|
+
* The popover panel.
|
|
1474
|
+
*
|
|
1475
|
+
* Positioned inside the VIEWPORT (the scroll container), so ordinary CSS keeps it attached to
|
|
1476
|
+
* the page while the user scrolls — no scroll listener, no per-frame reposition. The
|
|
1477
|
+
* coordinates the engine reports are viewport-relative, so they are converted against the
|
|
1478
|
+
* container's own rect once, at open.
|
|
1479
|
+
*/
|
|
1480
|
+
declare function HyperLinkRoot({ className, asChild, hidden, children, preset }: HyperLinkProps): react.JSX.Element | null;
|
|
1481
|
+
/** The target readout, and the action that follows it. @public */
|
|
1482
|
+
declare function HyperLinkUrl({ className, asChild, hidden, children }: HyperLinkPartProps): react.JSX.Element | null;
|
|
1483
|
+
declare namespace HyperLinkUrl {
|
|
1484
|
+
var docxHyperLinkPart: "Url";
|
|
1485
|
+
}
|
|
1486
|
+
/** Copy the sanitized target to the clipboard. @public */
|
|
1487
|
+
declare function HyperLinkCopy({ className, asChild, hidden, children, icon: glyph, }: HyperLinkActionProps): react.JSX.Element | null;
|
|
1488
|
+
declare namespace HyperLinkCopy {
|
|
1489
|
+
var docxHyperLinkPart: "Copy";
|
|
1490
|
+
}
|
|
1491
|
+
/** Switch the panel into edit mode. @public */
|
|
1492
|
+
declare function HyperLinkEdit({ className, asChild, hidden, children, icon: glyph, }: HyperLinkActionProps): react.JSX.Element | null;
|
|
1493
|
+
declare namespace HyperLinkEdit {
|
|
1494
|
+
var docxHyperLinkPart: "Edit";
|
|
1495
|
+
}
|
|
1496
|
+
/** Remove the link, keeping its text. @public */
|
|
1497
|
+
declare function HyperLinkUnlink({ className, asChild, hidden, children, icon: glyph, }: HyperLinkActionProps): react.JSX.Element | null;
|
|
1498
|
+
declare namespace HyperLinkUnlink {
|
|
1499
|
+
var docxHyperLinkPart: "Unlink";
|
|
1500
|
+
}
|
|
1501
|
+
/** Display-text and URL fields. @public */
|
|
1502
|
+
declare function HyperLinkFields({ className, hidden }: HyperLinkPartProps): react.JSX.Element | null;
|
|
1503
|
+
declare namespace HyperLinkFields {
|
|
1504
|
+
var docxHyperLinkPart: "Fields";
|
|
1505
|
+
}
|
|
1506
|
+
/** Commit the draft. @public */
|
|
1507
|
+
declare function HyperLinkApply({ className, asChild, hidden, children }: HyperLinkPartProps): react.JSX.Element | null;
|
|
1508
|
+
declare namespace HyperLinkApply {
|
|
1509
|
+
var docxHyperLinkPart: "Apply";
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* Why the last Apply did nothing.
|
|
1513
|
+
*
|
|
1514
|
+
* A refusal that closes nothing and says nothing is the worst of both: the panel sits open
|
|
1515
|
+
* and the user re-presses the same button. The engine already knows the reason (a scheme it
|
|
1516
|
+
* will not write, a selection spanning paragraphs, no text to link); this shows it.
|
|
1517
|
+
*/
|
|
1518
|
+
declare function HyperLinkError({ className, hidden }: HyperLinkPartProps): react.JSX.Element | null;
|
|
1519
|
+
declare namespace HyperLinkError {
|
|
1520
|
+
var docxHyperLinkPart: "Error";
|
|
1521
|
+
}
|
|
1522
|
+
/** Dismiss without applying. @public */
|
|
1523
|
+
declare function HyperLinkCancel({ className, asChild, hidden, children }: HyperLinkPartProps): react.JSX.Element | null;
|
|
1524
|
+
declare namespace HyperLinkCancel {
|
|
1525
|
+
var docxHyperLinkPart: "Cancel";
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* The link popover compound.
|
|
1529
|
+
*
|
|
1530
|
+
* @public
|
|
1531
|
+
*/
|
|
1532
|
+
interface DocxEditorHyperLinkNamespace {
|
|
1533
|
+
(props: HyperLinkProps): ReturnType<typeof HyperLinkRoot>;
|
|
1534
|
+
readonly Url: typeof HyperLinkUrl;
|
|
1535
|
+
readonly Copy: typeof HyperLinkCopy;
|
|
1536
|
+
readonly Edit: typeof HyperLinkEdit;
|
|
1537
|
+
readonly Unlink: typeof HyperLinkUnlink;
|
|
1538
|
+
readonly Fields: typeof HyperLinkFields;
|
|
1539
|
+
readonly Error: typeof HyperLinkError;
|
|
1540
|
+
readonly Apply: typeof HyperLinkApply;
|
|
1541
|
+
readonly Cancel: typeof HyperLinkCancel;
|
|
1542
|
+
}
|
|
1543
|
+
declare const DocxEditorHyperLink: DocxEditorHyperLinkNamespace;
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* Subscribe to the active note view scope with reference-stable results when unchanged.
|
|
1547
|
+
*
|
|
1548
|
+
* @public
|
|
1549
|
+
*/
|
|
1550
|
+
declare function useNoteScopeState(): Extract<ViewScope, {
|
|
1551
|
+
kind: 'note';
|
|
1552
|
+
}> | null;
|
|
1553
|
+
type NotePropertiesState = Exclude<ReturnType<Editor['getNotePropertiesState']>, null>;
|
|
1554
|
+
/**
|
|
1555
|
+
* Subscribe to `getNotePropertiesState()` with reference-stable results when unchanged.
|
|
1556
|
+
*
|
|
1557
|
+
* @public
|
|
1558
|
+
*/
|
|
1559
|
+
declare function useNotePropertiesState(): NotePropertiesState | null;
|
|
1560
|
+
|
|
1561
|
+
/** Props for `DocxEditor.NotesChrome`. @public */
|
|
1562
|
+
interface DocxEditorNotesChromeProps {
|
|
1563
|
+
className?: string;
|
|
1564
|
+
}
|
|
1565
|
+
declare function DocxEditorNotesChrome({ className, }: DocxEditorNotesChromeProps): ReactElement | null;
|
|
1566
|
+
|
|
1567
|
+
/** Props for a packaged context-menu row. @public */
|
|
1568
|
+
interface ContextMenuCommandProps {
|
|
1569
|
+
/** Icon override. Defaults to the row's own Material Symbol. */
|
|
1570
|
+
icon?: ReactNode;
|
|
1571
|
+
/** i18n key for the label, overriding the packaged one. */
|
|
1572
|
+
labelKey?: string;
|
|
1573
|
+
/** i18n key for the shortcut column, overriding the packaged one. */
|
|
1574
|
+
shortcutKey?: string;
|
|
1575
|
+
className?: string;
|
|
1576
|
+
/** Render nothing — inside the default set this removes the row. */
|
|
1577
|
+
hidden?: boolean;
|
|
1578
|
+
}
|
|
1579
|
+
/** Cut the selection to the clipboard. Disabled with the engine's reason when nothing is selected. @public */
|
|
1580
|
+
declare const ContextMenuCut: (({ icon, labelKey, shortcutKey, className, hidden }: ContextMenuCommandProps) => react.JSX.Element | null) & {
|
|
1581
|
+
docxRow: string;
|
|
1582
|
+
};
|
|
1583
|
+
/** Copy the selection. Stays available in a read-only document. @public */
|
|
1584
|
+
declare const ContextMenuCopy: (({ icon, labelKey, shortcutKey, className, hidden }: ContextMenuCommandProps) => react.JSX.Element | null) & {
|
|
1585
|
+
docxRow: string;
|
|
1586
|
+
};
|
|
1587
|
+
/** Delete the selection. @public */
|
|
1588
|
+
declare const ContextMenuDelete: (({ icon, labelKey, shortcutKey, className, hidden }: ContextMenuCommandProps) => react.JSX.Element | null) & {
|
|
1589
|
+
docxRow: string;
|
|
1590
|
+
};
|
|
1591
|
+
/** Select the whole body. @public */
|
|
1592
|
+
declare const ContextMenuSelectAll: (({ icon, labelKey, shortcutKey, className, hidden }: ContextMenuCommandProps) => react.JSX.Element | null) & {
|
|
1593
|
+
docxRow: string;
|
|
1594
|
+
};
|
|
1595
|
+
/**
|
|
1596
|
+
* Paste the clipboard's text at the selection.
|
|
1597
|
+
*
|
|
1598
|
+
* THE ROW READS THE CLIPBOARD, not the engine. `exec` is synchronous and clipboard read is
|
|
1599
|
+
* not — it prompts in Chrome and is refused outright by Firefox and Safari — so the read
|
|
1600
|
+
* happens here, inside the click that asked for it, where the permission gesture belongs,
|
|
1601
|
+
* and the text goes to the engine as an argument.
|
|
1602
|
+
*
|
|
1603
|
+
* Nothing can know whether the read will succeed BEFORE it is attempted, so the row starts
|
|
1604
|
+
* enabled (when the engine would accept a paste at all) and disables itself, with the
|
|
1605
|
+
* browser's own reason, once a read has actually been refused. Guessing the answer up front
|
|
1606
|
+
* would either grey out a working Paste on Chrome or advertise a dead one on Safari.
|
|
1607
|
+
*
|
|
1608
|
+
* @public
|
|
1609
|
+
*/
|
|
1610
|
+
declare function ContextMenuPaste({ icon, labelKey, shortcutKey, className, hidden, }: ContextMenuCommandProps): react.JSX.Element | null;
|
|
1611
|
+
declare namespace ContextMenuPaste {
|
|
1612
|
+
var docxRow: "edit.paste";
|
|
1613
|
+
}
|
|
1614
|
+
/** Props for packaged table context-menu rows. @public */
|
|
1615
|
+
interface ContextMenuTableRowProps extends ContextMenuCommandProps {
|
|
1616
|
+
/** When true, the row uses the destructive treatment. */
|
|
1617
|
+
destructive?: boolean;
|
|
1618
|
+
}
|
|
1619
|
+
/** Insert a row above the current table row. @public */
|
|
1620
|
+
declare const ContextMenuInsertRowAbove: (({ icon, labelKey, className, hidden, destructive }: ContextMenuTableRowProps) => react.JSX.Element | null) & {
|
|
1621
|
+
docxRow: string;
|
|
1622
|
+
};
|
|
1623
|
+
/** Insert a row below the current table row. @public */
|
|
1624
|
+
declare const ContextMenuInsertRowBelow: (({ icon, labelKey, className, hidden, destructive }: ContextMenuTableRowProps) => react.JSX.Element | null) & {
|
|
1625
|
+
docxRow: string;
|
|
1626
|
+
};
|
|
1627
|
+
/** Insert a column to the left of the current column. @public */
|
|
1628
|
+
declare const ContextMenuInsertColumnLeft: (({ icon, labelKey, className, hidden, destructive }: ContextMenuTableRowProps) => react.JSX.Element | null) & {
|
|
1629
|
+
docxRow: string;
|
|
1630
|
+
};
|
|
1631
|
+
/** Insert a column to the right of the current column. @public */
|
|
1632
|
+
declare const ContextMenuInsertColumnRight: (({ icon, labelKey, className, hidden, destructive }: ContextMenuTableRowProps) => react.JSX.Element | null) & {
|
|
1633
|
+
docxRow: string;
|
|
1634
|
+
};
|
|
1635
|
+
/** Delete the current table row. @public */
|
|
1636
|
+
declare const ContextMenuDeleteTableRow: (({ icon, labelKey, className, hidden, destructive }: ContextMenuTableRowProps) => react.JSX.Element | null) & {
|
|
1637
|
+
docxRow: string;
|
|
1638
|
+
};
|
|
1639
|
+
/** Delete the current table column. @public */
|
|
1640
|
+
declare const ContextMenuDeleteTableColumn: (({ icon, labelKey, className, hidden, destructive }: ContextMenuTableRowProps) => react.JSX.Element | null) & {
|
|
1641
|
+
docxRow: string;
|
|
1642
|
+
};
|
|
1643
|
+
/** Delete the entire table. @public */
|
|
1644
|
+
declare const ContextMenuDeleteTable: (({ icon, labelKey, className, hidden, destructive }: ContextMenuTableRowProps) => react.JSX.Element | null) & {
|
|
1645
|
+
docxRow: string;
|
|
1646
|
+
};
|
|
1647
|
+
/** Compact vertical-alignment picker for selected table cells. @public */
|
|
1648
|
+
declare function ContextMenuCellVerticalAlignment({ hidden }: ContextMenuCommandProps): react.JSX.Element | null;
|
|
1649
|
+
declare namespace ContextMenuCellVerticalAlignment {
|
|
1650
|
+
var docxRow: "table.cellVerticalAlignment";
|
|
1651
|
+
}
|
|
1652
|
+
/** Rebuild the pointed-at table of contents from the document's headings. @public */
|
|
1653
|
+
declare const ContextMenuRefreshToc: (({ icon, labelKey, className, hidden }: ContextMenuCommandProps) => react.JSX.Element | null) & {
|
|
1654
|
+
docxRow: string;
|
|
1655
|
+
};
|
|
1656
|
+
/** Re-resolve only the page numbers of the pointed-at table of contents. @public */
|
|
1657
|
+
declare const ContextMenuRefreshTocPageNumbers: (({ icon, labelKey, className, hidden }: ContextMenuCommandProps) => react.JSX.Element | null) & {
|
|
1658
|
+
docxRow: string;
|
|
1659
|
+
};
|
|
1660
|
+
/** Props for `DocxEditor.ContextMenu.Item`: a host-owned row. @public */
|
|
1661
|
+
interface ContextMenuItemProps {
|
|
1662
|
+
/**
|
|
1663
|
+
* Label, as a resolved STRING rather than an i18n key — the row belongs to the host's own
|
|
1664
|
+
* action, so the host's own catalogue resolves it. The packaged rows go the other way.
|
|
1665
|
+
*/
|
|
1666
|
+
label: string;
|
|
1667
|
+
icon?: ReactNode;
|
|
1668
|
+
/** Right-aligned shortcut text, already resolved. */
|
|
1669
|
+
shortcut?: string;
|
|
1670
|
+
disabled?: boolean;
|
|
1671
|
+
/** Tooltip when disabled. Say why — never invent a reason the engine did not give. */
|
|
1672
|
+
disabledReason?: string;
|
|
1673
|
+
/** Checked state, for a row that toggles. Leave undefined on a row that just acts. */
|
|
1674
|
+
active?: boolean;
|
|
1675
|
+
onSelect?: () => void;
|
|
1676
|
+
className?: string;
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* A host-owned context-menu row, styled and behaved like the packaged ones.
|
|
1680
|
+
*
|
|
1681
|
+
* The toolbar's `Action` for the right-click surface: no slot, no command, no engine wiring
|
|
1682
|
+
* — enabled state and the action are the host's, because the engine has no opinion about an
|
|
1683
|
+
* action it does not model. Selecting it closes the menu.
|
|
1684
|
+
*
|
|
1685
|
+
* @public
|
|
1686
|
+
*/
|
|
1687
|
+
declare function ContextMenuItem({ label, icon, shortcut, disabled, disabledReason, active, onSelect, className, }: ContextMenuItemProps): react.JSX.Element;
|
|
1688
|
+
|
|
1689
|
+
/** Props for `DocxEditor.ContextMenu`. @public */
|
|
1690
|
+
interface DocxEditorContextMenuProps {
|
|
1691
|
+
/** Appended after the base `docx-contextmenu` class. */
|
|
1692
|
+
className?: string;
|
|
1693
|
+
/** i18n resolver for row labels; without it the raw keys show (never English). */
|
|
1694
|
+
t?: ToolbarTranslate;
|
|
1695
|
+
/**
|
|
1696
|
+
* `false` renders children verbatim with no default set. Default `true`: a child naming a
|
|
1697
|
+
* packaged row overrides it in place, others append.
|
|
1698
|
+
*/
|
|
1699
|
+
preset?: boolean;
|
|
1700
|
+
/**
|
|
1701
|
+
* `true` suppresses the panel entirely and lets the browser's own menu through. For a
|
|
1702
|
+
* host that wants the native menu back on some documents without unmounting the part.
|
|
1703
|
+
*/
|
|
1704
|
+
disabled?: boolean;
|
|
1705
|
+
/** Notified whenever the panel opens or closes. */
|
|
1706
|
+
onOpenChange?: (open: boolean) => void;
|
|
1707
|
+
children?: ReactNode;
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* The packaged right-click menu over the painted document.
|
|
1711
|
+
*
|
|
1712
|
+
* Mounted by default inside `DocxEditor.Viewport`; `contextMenu={false}` on `DocxEditor`
|
|
1713
|
+
* removes it. Rendered as a child of the viewport so it finds its own surface, but
|
|
1714
|
+
* positioned in client space, so it is never clipped by the scroller.
|
|
1715
|
+
*
|
|
1716
|
+
* @public
|
|
1717
|
+
*/
|
|
1718
|
+
declare function DocxEditorContextMenu({ className, t, preset, disabled, onOpenChange, children, }: DocxEditorContextMenuProps): react.JSX.Element;
|
|
1719
|
+
/**
|
|
1720
|
+
* `DocxEditor.ContextMenu` with its rows attached as statics.
|
|
1721
|
+
*
|
|
1722
|
+
* @public
|
|
1723
|
+
*/
|
|
1724
|
+
interface DocxEditorContextMenuNamespace {
|
|
1725
|
+
(props: DocxEditorContextMenuProps): ReactElement;
|
|
1726
|
+
readonly Cut: typeof ContextMenuCut;
|
|
1727
|
+
readonly Copy: typeof ContextMenuCopy;
|
|
1728
|
+
readonly Paste: typeof ContextMenuPaste;
|
|
1729
|
+
readonly Delete: typeof ContextMenuDelete;
|
|
1730
|
+
readonly SelectAll: typeof ContextMenuSelectAll;
|
|
1731
|
+
readonly InsertRowAbove: typeof ContextMenuInsertRowAbove;
|
|
1732
|
+
readonly InsertRowBelow: typeof ContextMenuInsertRowBelow;
|
|
1733
|
+
readonly InsertColumnLeft: typeof ContextMenuInsertColumnLeft;
|
|
1734
|
+
readonly InsertColumnRight: typeof ContextMenuInsertColumnRight;
|
|
1735
|
+
readonly DeleteTableRow: typeof ContextMenuDeleteTableRow;
|
|
1736
|
+
readonly DeleteTableColumn: typeof ContextMenuDeleteTableColumn;
|
|
1737
|
+
readonly DeleteTable: typeof ContextMenuDeleteTable;
|
|
1738
|
+
readonly CellVerticalAlignment: typeof ContextMenuCellVerticalAlignment;
|
|
1739
|
+
readonly RefreshToc: typeof ContextMenuRefreshToc;
|
|
1740
|
+
readonly RefreshTocPageNumbers: typeof ContextMenuRefreshTocPageNumbers;
|
|
1741
|
+
/** A host-owned row: no slot, no command, the host's own label and action. */
|
|
1742
|
+
readonly Item: typeof ContextMenuItem;
|
|
1743
|
+
/** Any chrome slot as a live row (`<ContextMenu.Slot slot="text.bold" />`). */
|
|
1744
|
+
readonly Slot: typeof MenuItem;
|
|
1745
|
+
/** Bare row presentation, for a host building something the parts do not cover. */
|
|
1746
|
+
readonly Row: typeof MenuRow;
|
|
1747
|
+
/** A named section of rows: a visible heading plus a real ARIA group. */
|
|
1748
|
+
readonly Group: typeof MenuGroup;
|
|
1749
|
+
readonly Separator: typeof MenuSeparator;
|
|
1750
|
+
readonly Submenu: typeof MenuSubmenu;
|
|
1751
|
+
}
|
|
1752
|
+
declare const ContextMenu: DocxEditorContextMenuNamespace;
|
|
1753
|
+
|
|
1754
|
+
/** Where the panel opened, in client coordinates. */
|
|
1755
|
+
interface ContextMenuAnchor {
|
|
1756
|
+
readonly x: number;
|
|
1757
|
+
readonly y: number;
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* The element the opening right-click landed on, or null while the menu is closed.
|
|
1761
|
+
*
|
|
1762
|
+
* Public so capability packages can render contextual sections — a row that only exists
|
|
1763
|
+
* when the press landed on their own painted chrome — without a second listener.
|
|
1764
|
+
*
|
|
1765
|
+
* @public
|
|
1766
|
+
*/
|
|
1767
|
+
declare function useContextMenuTarget(): HTMLElement | null;
|
|
1768
|
+
|
|
1769
|
+
/** Shared props for every part. @public */
|
|
1770
|
+
interface ContentControlPartProps {
|
|
1771
|
+
className?: string;
|
|
1772
|
+
asChild?: boolean;
|
|
1773
|
+
hidden?: boolean;
|
|
1774
|
+
children?: ReactNode;
|
|
1775
|
+
}
|
|
1776
|
+
/** Props for action parts that also take an icon. @public */
|
|
1777
|
+
interface ContentControlActionProps extends ContentControlPartProps {
|
|
1778
|
+
icon?: ReactNode;
|
|
1779
|
+
}
|
|
1780
|
+
/** Props for `DocxEditor.ContentControl`. @public */
|
|
1781
|
+
interface ContentControlProps extends ContentControlPartProps {
|
|
1782
|
+
/**
|
|
1783
|
+
* Render the packaged arrangement. `false` mounts only the shell and whatever parts
|
|
1784
|
+
* you pass as children.
|
|
1785
|
+
*/
|
|
1786
|
+
preset?: boolean;
|
|
1787
|
+
}
|
|
1788
|
+
declare function ContentControlRoot({ className, asChild, hidden, children, preset, }: ContentControlProps): react.JSX.Element | null;
|
|
1789
|
+
declare function ContentControlHeader({ className, asChild, hidden, children }: ContentControlPartProps): react.JSX.Element | null;
|
|
1790
|
+
declare function ContentControlFields({ className, asChild, hidden, children }: ContentControlPartProps): react.JSX.Element | null;
|
|
1791
|
+
declare function ContentControlRemove({ className, asChild, hidden, icon: iconOverride, children, }: ContentControlActionProps): react.JSX.Element | null;
|
|
1792
|
+
/**
|
|
1793
|
+
* The content-control inspector compound. Parts live on the namespace statics.
|
|
1794
|
+
*
|
|
1795
|
+
* @public
|
|
1796
|
+
*/
|
|
1797
|
+
interface DocxEditorContentControlNamespace {
|
|
1798
|
+
(props: ContentControlProps): ReturnType<typeof ContentControlRoot>;
|
|
1799
|
+
readonly Header: typeof ContentControlHeader;
|
|
1800
|
+
readonly Fields: typeof ContentControlFields;
|
|
1801
|
+
readonly Remove: typeof ContentControlRemove;
|
|
1802
|
+
}
|
|
1803
|
+
declare const DocxEditorContentControl: DocxEditorContentControlNamespace;
|
|
1804
|
+
|
|
1805
|
+
type EditorMode = 'edit' | 'view';
|
|
1806
|
+
/**
|
|
1807
|
+
* Props for the React `DocxEditor`. The adapter is a thin renderer over the
|
|
1808
|
+
* `Editor` contract; it holds no editing-engine state of its own and never
|
|
1809
|
+
* imports ProseMirror or OOXML feature logic.
|
|
1810
|
+
*/
|
|
1811
|
+
interface DocxEditorProps {
|
|
1812
|
+
/**
|
|
1813
|
+
* Immutable byte-backed font sources sampled at mount. Remount to replace this
|
|
1814
|
+
* configuration atomically.
|
|
1815
|
+
*
|
|
1816
|
+
* Optional, but it decides layout FIDELITY. With it, the engine shapes text through
|
|
1817
|
+
* HarfBuzz and measures line and page breaks from real font metrics. Without it, layout
|
|
1818
|
+
* runs on a fixed monospace approximation: glyphs still paint in their true faces, so the
|
|
1819
|
+
* page looks right, but wrap points and pagination are estimated rather than
|
|
1820
|
+
* Word-accurate. Omit it to mount in one line; supply it when breaks must match Word.
|
|
1821
|
+
*/
|
|
1822
|
+
fonts?: FontConfiguration | FontConfigurationFragment | FontResolver;
|
|
1823
|
+
/**
|
|
1824
|
+
* Title-bar slots. The host owns what goes here — brand lockup, switchers, theme
|
|
1825
|
+
* toggle, Open/New/Save controls — and passes them in; the editor renders them
|
|
1826
|
+
* verbatim on either side of the document title.
|
|
1827
|
+
*/
|
|
1828
|
+
readonly renderTitleBarLeft?: () => ReactNode;
|
|
1829
|
+
readonly renderTitleBarRight?: () => ReactNode;
|
|
1830
|
+
/**
|
|
1831
|
+
* Chrome colour mode. `'system'` follows the OS and re-resolves when it changes.
|
|
1832
|
+
* Only the editor CHROME is themed — the document canvas stays Word-faithful.
|
|
1833
|
+
*/
|
|
1834
|
+
readonly colorMode?: 'light' | 'dark' | 'system';
|
|
1835
|
+
/**
|
|
1836
|
+
* Resolves i18n keys for the editor chrome.
|
|
1837
|
+
*
|
|
1838
|
+
* Defaults to the bundled English catalogue, so the chrome is legible with no setup.
|
|
1839
|
+
* Strings still come from `packages/i18n/en.json` rather than literals in components;
|
|
1840
|
+
* this only chooses who resolves the key. For another language, pass
|
|
1841
|
+
* `createT(locale)` from `@docx-editor.dev/i18n`.
|
|
1842
|
+
*/
|
|
1843
|
+
t?: (key: string) => string;
|
|
1844
|
+
/**
|
|
1845
|
+
* Renders the packaged chrome — title bar and toolbar — around the document.
|
|
1846
|
+
* Default `true`. Set `false` for the painted surface alone when the host supplies
|
|
1847
|
+
* its own chrome; the composition primitives (`Root` / `Viewport` / `Content`) are
|
|
1848
|
+
* the better starting point if you are replacing more than the frame.
|
|
1849
|
+
*/
|
|
1850
|
+
chrome?: boolean;
|
|
1851
|
+
/** Document title shown in the chrome's title bar. */
|
|
1852
|
+
title?: string;
|
|
1853
|
+
/** Called when the title is edited. Omitting it makes the title read-only. */
|
|
1854
|
+
onTitleChange?: (title: string) => void;
|
|
1855
|
+
/**
|
|
1856
|
+
* Save handler for the chrome's save control and the menu's File › Save row. Runs
|
|
1857
|
+
* `Editor.save()` at the host.
|
|
1858
|
+
*
|
|
1859
|
+
* Without it the title-bar button is absent and File › Save falls back to the packaged
|
|
1860
|
+
* behaviour: `Editor.save()` and a download named after `title`.
|
|
1861
|
+
*/
|
|
1862
|
+
onSave?: () => void;
|
|
1863
|
+
/**
|
|
1864
|
+
* Open handler for the menu's File › Open row.
|
|
1865
|
+
*
|
|
1866
|
+
* Without it the row falls back to the packaged behaviour: a file picker whose bytes go
|
|
1867
|
+
* to `Editor.load`. Supply this to drive the load from your own storage — the row is
|
|
1868
|
+
* still a user-initiated file READ either way, never a fetch the document can trigger.
|
|
1869
|
+
*/
|
|
1870
|
+
onOpen?: () => void;
|
|
1871
|
+
/**
|
|
1872
|
+
* The packaged menu bar — File · Format · Insert · Help — under the document title.
|
|
1873
|
+
*
|
|
1874
|
+
* `false` removes it. An OBJECT is `DocxEditorMenuProps`, passed straight through, so a
|
|
1875
|
+
* host can redirect one row without giving up the bar: `menu={{ reportIssue: false }}`
|
|
1876
|
+
* drops the report-an-issue row, `menu={{ onPageSetup: openMine }}` swaps the dialog,
|
|
1877
|
+
* and `menu={{ children: <DocxEditor.Menu.File>…</DocxEditor.Menu.File> }}` replaces a
|
|
1878
|
+
* whole menu in place. Before this took an object the only way to change any of that was
|
|
1879
|
+
* `menu={false}` plus rebuilding the entire title block.
|
|
1880
|
+
*
|
|
1881
|
+
* Every actionable row is a chrome slot, so it shares its label, icon, command and
|
|
1882
|
+
* enabled state with the toolbar control for the same capability.
|
|
1883
|
+
*/
|
|
1884
|
+
menu?: boolean | DocxEditorMenuProps;
|
|
1885
|
+
/**
|
|
1886
|
+
* Render the packaged hyperlink popover (`false` removes it).
|
|
1887
|
+
*
|
|
1888
|
+
* The engine's link GESTURES stay wired either way — a click on a link and Ctrl/Cmd+K
|
|
1889
|
+
* still reach `useHyperlinkPopup()` — so a host that turns this off to render its own
|
|
1890
|
+
* panel loses the packaged UI and nothing else.
|
|
1891
|
+
*/
|
|
1892
|
+
hyperlinkPopup?: boolean;
|
|
1893
|
+
/**
|
|
1894
|
+
* Render the packaged right-click menu (`false` removes it, restoring the browser's own).
|
|
1895
|
+
*
|
|
1896
|
+
* An object is passed through to `DocxEditor.ContextMenu` as props, so a host can compose
|
|
1897
|
+
* its own rows — `{ children: <DocxEditor.ContextMenu.Item … /> }` — without dropping to
|
|
1898
|
+
* the primitives. The engine's selection behavior is the same either way: a right-click
|
|
1899
|
+
* never moves the caret, so the menu always acts on the selection the user already had.
|
|
1900
|
+
*/
|
|
1901
|
+
contextMenu?: boolean | DocxEditorContextMenuProps;
|
|
1902
|
+
/**
|
|
1903
|
+
* Render the packaged navigation pane — headings and find — over the document's left
|
|
1904
|
+
* gutter (`false` removes it and its toggle).
|
|
1905
|
+
*
|
|
1906
|
+
* On by default because an open pane costs the document nothing: it floats over gutter
|
|
1907
|
+
* space that is already empty, and only moves the page when the window is genuinely too
|
|
1908
|
+
* narrow to hold both. Compose `DocxEditor.Navigation` yourself, or build on
|
|
1909
|
+
* `useNavigationPane` / `useDocumentOutline` / `useDocumentSearch`, for a different one.
|
|
1910
|
+
*/
|
|
1911
|
+
navigation?: boolean;
|
|
1912
|
+
/** A document to load: DOCX bytes or an existing handle. */
|
|
1913
|
+
document?: DocumentSource;
|
|
1914
|
+
/** 'edit' (default) or 'view' (read-only). Applied at mount only — not reactive; remount to change. */
|
|
1915
|
+
mode?: EditorMode;
|
|
1916
|
+
zoom?: number;
|
|
1917
|
+
locale?: string;
|
|
1918
|
+
author?: string;
|
|
1919
|
+
/**
|
|
1920
|
+
* Capability modules to register (`@docx-editor.dev/pro`'s review module,
|
|
1921
|
+
* custom nodes). Applied at mount only, like `mode`.
|
|
1922
|
+
*/
|
|
1923
|
+
modules?: readonly EditorModule[];
|
|
1924
|
+
/**
|
|
1925
|
+
* Extra chrome rendered INSIDE the viewport, after the painted pages — the
|
|
1926
|
+
* slot pro or host chrome mounts into without leaving the sugar (e.g.
|
|
1927
|
+
* `DocxEditorReview` from `@docx-editor.dev/pro/react`). For more control,
|
|
1928
|
+
* compose `DocxEditor.Root`/`Viewport`/`Content` directly.
|
|
1929
|
+
*/
|
|
1930
|
+
children?: ReactNode;
|
|
1931
|
+
className?: string;
|
|
1932
|
+
/** Fired after the underlying `Editor` is created. */
|
|
1933
|
+
onReady?: (editor: Editor) => void;
|
|
1934
|
+
/** Fired with the same typed font failure shown by the accessible alert UI. */
|
|
1935
|
+
onFontError?: (error: EditorFontError) => void;
|
|
1936
|
+
/** Fired when the document changes (revision + identity deltas, not bytes). */
|
|
1937
|
+
onChange?: (change: DocumentChange) => void;
|
|
1938
|
+
}
|
|
1939
|
+
/**
|
|
1940
|
+
* The imperative handle, identical on both adapters (enforced by
|
|
1941
|
+
* `bun run check:parity-contract`). Every member forwards to the `Editor` facade and is
|
|
1942
|
+
* safe to call before the editor has mounted — mutations no-op, reads return the honest
|
|
1943
|
+
* empty answer (`null`, a `notFound` refusal, a loading snapshot) — so a host can hold
|
|
1944
|
+
* the ref from first render without guarding it.
|
|
1945
|
+
*
|
|
1946
|
+
* The ref deliberately stays small: everything else (zoom, paging, formatting queries,
|
|
1947
|
+
* document state) is reachable through the full facade via `getEditor`, so the ref never
|
|
1948
|
+
* mirrors capabilities the `Editor` contract already names.
|
|
1949
|
+
*/
|
|
1950
|
+
interface DocxEditorRef {
|
|
1951
|
+
/** Load a document: DOCX bytes or an existing handle. No-op before mount. */
|
|
1952
|
+
load(document: DocumentSource): void;
|
|
1953
|
+
/** Serialize the current document; `null` when no editor is mounted. */
|
|
1954
|
+
save(): Promise<ArrayBuffer | null>;
|
|
1955
|
+
/** Identity and revision of the loaded document; `null` before mount. */
|
|
1956
|
+
getDocumentHandle(): DocumentHandle | null;
|
|
1957
|
+
/** The full `Editor` facade for advanced callers; `null` before mount. */
|
|
1958
|
+
getEditor(): Editor | null;
|
|
1959
|
+
focus(): void;
|
|
1960
|
+
/** Run a typed command through the facade; refused with `notFound` before mount. */
|
|
1961
|
+
exec(command: EditorCommand, options?: {
|
|
1962
|
+
scope?: EditorScope;
|
|
1963
|
+
}): ExecResult;
|
|
1964
|
+
/** The current read model; a loading, non-editable snapshot before mount. */
|
|
1965
|
+
snapshot(options?: {
|
|
1966
|
+
scope?: EditorScope;
|
|
1967
|
+
}): EditorSnapshot;
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
/**
|
|
1971
|
+
* The composed editor component with its composition primitives attached as statics,
|
|
1972
|
+
* so `<DocxEditor.Root>`, `<DocxEditor.Viewport>`, and `<DocxEditor.Content>` work
|
|
1973
|
+
* without extra imports.
|
|
1974
|
+
*
|
|
1975
|
+
* @public
|
|
1976
|
+
*/
|
|
1977
|
+
interface DocxEditorNamespace extends ForwardRefExoticComponent<DocxEditorProps & RefAttributes<DocxEditorRef>> {
|
|
1978
|
+
readonly Root: typeof DocxEditorRoot;
|
|
1979
|
+
readonly Viewport: typeof DocxEditorViewport;
|
|
1980
|
+
readonly Content: typeof DocxEditorContent;
|
|
1981
|
+
readonly Toolbar: typeof DocxEditorToolbar;
|
|
1982
|
+
/**
|
|
1983
|
+
* The menu bar — File · Format · Insert · Help — with its parts as statics (`.File`,
|
|
1984
|
+
* `.Format`, `.Insert`, `.Help`, `.Item`, `.Row`, `.Submenu`, `.TableGrid`, …). Mounted
|
|
1985
|
+
* by default under the title; `menu={false}` removes it.
|
|
1986
|
+
*/
|
|
1987
|
+
readonly Menu: typeof DocxEditorMenu;
|
|
1988
|
+
/** Conditional loading screen: renders while there is no document to paint. */
|
|
1989
|
+
readonly Loading: typeof DocxEditorLoading;
|
|
1990
|
+
/** Context-fed horizontal ruler with draggable margins (props-driven export stays). */
|
|
1991
|
+
readonly HorizontalRuler: typeof DocxEditorHorizontalRuler;
|
|
1992
|
+
/** Context-fed vertical ruler with draggable margins (props-driven export stays). */
|
|
1993
|
+
readonly VerticalRuler: typeof DocxEditorVerticalRuler;
|
|
1994
|
+
/** Context-fed heading outline over `Editor.getOutline()`. */
|
|
1995
|
+
readonly DocumentOutline: typeof DocxEditorDocumentOutline;
|
|
1996
|
+
/**
|
|
1997
|
+
* The navigation pane — Headings and Find — with its parts as statics (`.Header`,
|
|
1998
|
+
* `.Close`, `.Title`, `.Tabs`, `.Tab`, `.Headings`, `.Find`, `.Toggle`). Mounted by
|
|
1999
|
+
* default; `navigation={false}` removes it.
|
|
2000
|
+
*/
|
|
2001
|
+
readonly Navigation: typeof Navigation;
|
|
2002
|
+
/** Page Setup dialog — size, orientation, margins — applied as one undo step. */
|
|
2003
|
+
readonly PageSetupDialog: typeof DocxEditorPageSetupDialog;
|
|
2004
|
+
/** Floating localized page readout for the active viewport. */
|
|
2005
|
+
readonly PageNumber: typeof DocxEditorPageNumber;
|
|
2006
|
+
/** Word-style notice when document fonts render in substitute faces. */
|
|
2007
|
+
readonly FontNotice: typeof DocxEditorFontNotice;
|
|
2008
|
+
/** Header/footer scope chrome while editing page furniture. */
|
|
2009
|
+
readonly HeaderFooterChrome: typeof DocxEditorHeaderFooterChrome;
|
|
2010
|
+
readonly NotesChrome: typeof DocxEditorNotesChrome;
|
|
2011
|
+
/**
|
|
2012
|
+
* The link popover — target readout, copy, edit, unlink — and its parts. Mounted by
|
|
2013
|
+
* default inside the viewport; `hyperlinkPopup={false}` removes it.
|
|
2014
|
+
*/
|
|
2015
|
+
readonly HyperLink: typeof DocxEditorHyperLink;
|
|
2016
|
+
/**
|
|
2017
|
+
* The right-click menu over the painted document, with its rows as statics (`.Cut`,
|
|
2018
|
+
* `.Copy`, `.Paste`, `.Delete`, `.SelectAll`, `.Item`, `.Slot`, `.Submenu`, …). Mounted
|
|
2019
|
+
* by default inside the viewport; `contextMenu={false}` removes it and lets the
|
|
2020
|
+
* browser's own menu through.
|
|
2021
|
+
*/
|
|
2022
|
+
readonly ContextMenu: typeof ContextMenu;
|
|
2023
|
+
/**
|
|
2024
|
+
* The content-control inspector — alias, tag, type, lock, placeholder, bound — and
|
|
2025
|
+
* remove-keeping-content. Mounted by default inside the viewport; opens from the
|
|
2026
|
+
* `contentControl.inspector` chrome slot.
|
|
2027
|
+
*/
|
|
2028
|
+
readonly ContentControl: typeof DocxEditorContentControl;
|
|
2029
|
+
}
|
|
2030
|
+
declare const DocxEditor: DocxEditorNamespace;
|
|
2031
|
+
|
|
2032
|
+
/**
|
|
2033
|
+
* The editor instance from the nearest `DocxEditor.Root`, or `null` before the Root's
|
|
2034
|
+
* mount effect has created it (and outside any Root). Deliberately not a throwing
|
|
2035
|
+
* variant: pre-mount is a normal frame every consumer renders through, and the state
|
|
2036
|
+
* hooks built on this already answer it with a typed loading snapshot.
|
|
2037
|
+
*
|
|
2038
|
+
* @public
|
|
2039
|
+
*/
|
|
2040
|
+
declare function useDocxEditor(): DocxEditorInstance | null;
|
|
2041
|
+
/**
|
|
2042
|
+
* Whether a review rail is mounted under this Root, and how much room it wants.
|
|
2043
|
+
*
|
|
2044
|
+
* The GUTTER is the reason this exists. `DocxEditor.Viewport` reserves space beside the
|
|
2045
|
+
* page for the pane, and the ruler shifts by the same amount — but neither of them can see
|
|
2046
|
+
* whether a rail was actually composed in. Keyed on the pane's open state alone, every
|
|
2047
|
+
* consumer of the tier-2 `<DocxEditor>` sugar (which mounts no rail) had its page pushed
|
|
2048
|
+
* 158px off centre beside an empty column.
|
|
2049
|
+
*
|
|
2050
|
+
* A rail registers on mount and unregisters on unmount, so the reservation follows what is
|
|
2051
|
+
* really on screen. Count rather than boolean: StrictMode mounts twice, and a host may
|
|
2052
|
+
* legitimately compose two rails.
|
|
2053
|
+
*/
|
|
2054
|
+
interface ReviewRailRegistry {
|
|
2055
|
+
readonly mounted: number;
|
|
2056
|
+
readonly register: () => () => void;
|
|
2057
|
+
}
|
|
2058
|
+
declare const ReviewRailContext: react.Context<ReviewRailRegistry | null>;
|
|
2059
|
+
|
|
2060
|
+
interface SlotProps extends HTMLAttributes<HTMLElement> {
|
|
2061
|
+
children?: ReactNode;
|
|
2062
|
+
/** Fanned out alongside the child's own ref. */
|
|
2063
|
+
ref?: Ref<unknown>;
|
|
2064
|
+
}
|
|
2065
|
+
/** Renders its single child element with the slot's props merged in. */
|
|
2066
|
+
declare function Slot({ children, ...slotProps }: SlotProps): ReactElement<unknown, string | react.JSXElementConstructor<any>> | null;
|
|
2067
|
+
|
|
2068
|
+
interface LocaleProviderProps {
|
|
2069
|
+
i18n?: Translations;
|
|
2070
|
+
children: ReactNode;
|
|
2071
|
+
}
|
|
2072
|
+
declare function LocaleProvider({ i18n, children }: LocaleProviderProps): react.JSX.Element;
|
|
2073
|
+
declare function useTranslation(): {
|
|
2074
|
+
t: TFunction;
|
|
2075
|
+
};
|
|
2076
|
+
|
|
2077
|
+
/** Live furniture scope state from `Editor.getHeaderFooterState()`. */
|
|
2078
|
+
type HeaderFooterState = Exclude<ReturnType<Editor['getHeaderFooterState']>, null>;
|
|
2079
|
+
/**
|
|
2080
|
+
* Subscribe to `getHeaderFooterState()` with reference-stable results when unchanged.
|
|
2081
|
+
*
|
|
2082
|
+
* @public
|
|
2083
|
+
*/
|
|
2084
|
+
declare function useHeaderFooterState(): HeaderFooterState | null;
|
|
2085
|
+
|
|
2086
|
+
/** Where the popover sits, in viewport coordinates. */
|
|
2087
|
+
interface HyperlinkPopupAnchor {
|
|
2088
|
+
readonly left: number;
|
|
2089
|
+
readonly top: number;
|
|
2090
|
+
}
|
|
2091
|
+
/** What the popover is showing. @public */
|
|
2092
|
+
type HyperlinkPopupMode =
|
|
2093
|
+
/** Not shown. */
|
|
2094
|
+
'closed'
|
|
2095
|
+
/** An existing link: its target, plus copy / edit / unlink. */
|
|
2096
|
+
| 'reading'
|
|
2097
|
+
/** Text + URL fields, for a new link or a change to an existing one. */
|
|
2098
|
+
| 'editing';
|
|
2099
|
+
/** The popover's observable state. @public */
|
|
2100
|
+
interface HyperlinkPopupState {
|
|
2101
|
+
readonly mode: HyperlinkPopupMode;
|
|
2102
|
+
/** The link being read or edited, or null while inserting a new one. */
|
|
2103
|
+
readonly link: SurfaceHyperlink | null;
|
|
2104
|
+
/** Viewport position for the panel; null means "the host places it". */
|
|
2105
|
+
readonly anchor: HyperlinkPopupAnchor | null;
|
|
2106
|
+
/** Draft display text, in edit mode. */
|
|
2107
|
+
readonly text: string;
|
|
2108
|
+
/** Draft target, in edit mode. */
|
|
2109
|
+
readonly url: string;
|
|
2110
|
+
/** True after a copy, until the next state change — for a "Copied" confirmation. */
|
|
2111
|
+
readonly copied: boolean;
|
|
2112
|
+
/** True when the last Apply was refused, so the panel can say so instead of sitting there. */
|
|
2113
|
+
readonly error: boolean;
|
|
2114
|
+
/** Whether the document can be edited right now; read-only trims the actions. */
|
|
2115
|
+
readonly canEdit: boolean;
|
|
2116
|
+
}
|
|
2117
|
+
/** What `useHyperlinkPopup` answers. @public */
|
|
2118
|
+
interface UseHyperlinkPopupResult {
|
|
2119
|
+
readonly state: HyperlinkPopupState;
|
|
2120
|
+
/** Open in reading mode over a link, or in editing mode when there is none. */
|
|
2121
|
+
open: (link?: SurfaceHyperlink | null, anchor?: HyperlinkPopupAnchor | null) => void;
|
|
2122
|
+
/**
|
|
2123
|
+
* Open insert-or-edit for the SELECTION — what Ctrl/Cmd+K and the toolbar's link button
|
|
2124
|
+
* do. Anchors itself at the caret, seeds the display text from the selection, and opens
|
|
2125
|
+
* edit mode pre-filled when the caret is already inside a link.
|
|
2126
|
+
*/
|
|
2127
|
+
openAtCaret: () => void;
|
|
2128
|
+
close: () => void;
|
|
2129
|
+
/** Copy the sanitized target. Answers false when there is nothing safe to copy. */
|
|
2130
|
+
copy: () => Promise<boolean>;
|
|
2131
|
+
/** Switch to editing, seeded from the link at the caret. */
|
|
2132
|
+
beginEdit: () => void;
|
|
2133
|
+
setText: (text: string) => void;
|
|
2134
|
+
setUrl: (url: string) => void;
|
|
2135
|
+
/** Apply the draft. Answers false when the engine refused it (a bad scheme, no text). */
|
|
2136
|
+
commitEdit: () => boolean;
|
|
2137
|
+
/** Take the link off, keeping its text. */
|
|
2138
|
+
unlink: () => boolean;
|
|
2139
|
+
/**
|
|
2140
|
+
* Open the target in a new tab, through the engine's single `window.open` gate. Answers
|
|
2141
|
+
* false for an inert link — there is nothing to open, and this never invents a URL.
|
|
2142
|
+
*/
|
|
2143
|
+
openTarget: () => boolean;
|
|
2144
|
+
}
|
|
2145
|
+
/**
|
|
2146
|
+
* The hyperlink popover's behavior.
|
|
2147
|
+
*
|
|
2148
|
+
* Inside a `DocxEditor.HyperLink` (which the packaged editor mounts by default) this is the
|
|
2149
|
+
* SHARED state that compound is driving, so a custom toolbar button and the popover agree.
|
|
2150
|
+
* Outside one it is a standalone instance that registers with the engine itself — a host
|
|
2151
|
+
* building its own link UI from scratch needs nothing else.
|
|
2152
|
+
*
|
|
2153
|
+
* @public
|
|
2154
|
+
*/
|
|
2155
|
+
declare function useHyperlinkPopup(): UseHyperlinkPopupResult;
|
|
2156
|
+
/**
|
|
2157
|
+
* A popover instance. `active` gates ENGINE REGISTRATION only — an instance created inside
|
|
2158
|
+
* a provider still exists, it just does not compete for the surface's chrome handlers.
|
|
2159
|
+
*
|
|
2160
|
+
* @public
|
|
2161
|
+
*/
|
|
2162
|
+
declare function useHyperlinkPopupInstance(active?: boolean): UseHyperlinkPopupResult;
|
|
2163
|
+
|
|
2164
|
+
/** A complete configuration, or a fragment this hook composes with the defaults. @public */
|
|
2165
|
+
type DocxFontsInput = FontConfiguration | FontConfigurationFragment;
|
|
2166
|
+
/**
|
|
2167
|
+
* How a host supplies fonts: a value, a promise, or a function returning either.
|
|
2168
|
+
*
|
|
2169
|
+
* The function form is the useful one — `{ fonts: defaultFonts }` from
|
|
2170
|
+
* `@docx-editor.dev/fonts` — because it defers the work until the hook actually runs it.
|
|
2171
|
+
*
|
|
2172
|
+
* @public
|
|
2173
|
+
*/
|
|
2174
|
+
type DocxFontsSource = DocxFontsInput | Promise<DocxFontsInput> | (() => DocxFontsInput | Promise<DocxFontsInput>);
|
|
2175
|
+
/** What the document itself can be: a URL to fetch, or bytes already in hand. @public */
|
|
2176
|
+
type DocxSource = string | URL | Uint8Array | ArrayBuffer;
|
|
2177
|
+
/** Options for {@link useDocxSource}. @public */
|
|
2178
|
+
interface UseDocxSourceOptions {
|
|
2179
|
+
fonts?: DocxFontsSource;
|
|
2180
|
+
/** Passed to `fetch` for a URL source — credentials, headers, an AbortSignal's siblings. */
|
|
2181
|
+
fetchOptions?: RequestInit;
|
|
2182
|
+
}
|
|
2183
|
+
/** What {@link useDocxSource} reports. @public */
|
|
2184
|
+
interface UseDocxSourceResult {
|
|
2185
|
+
/** Bytes for `DocxEditor`'s `document` prop; undefined until they arrive. */
|
|
2186
|
+
readonly document: Uint8Array | undefined;
|
|
2187
|
+
/** Composed configuration for the `fonts` prop; undefined until fonts settle. */
|
|
2188
|
+
readonly fonts: FontConfiguration | undefined;
|
|
2189
|
+
/** Why the DOCUMENT could not be opened. Font failures never land here — see below. */
|
|
2190
|
+
readonly error: Error | null;
|
|
2191
|
+
/** True until the document either arrives or fails. */
|
|
2192
|
+
readonly isLoading: boolean;
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Load a document (and optionally fonts) for `DocxEditor`.
|
|
2196
|
+
*
|
|
2197
|
+
* ```tsx
|
|
2198
|
+
* const { document, fonts, error } = useDocxSource(url, { fonts: defaultFonts });
|
|
2199
|
+
* if (error) return <p>{error.message}</p>;
|
|
2200
|
+
* return <DocxEditor document={document} fonts={fonts} />;
|
|
2201
|
+
* ```
|
|
2202
|
+
*
|
|
2203
|
+
* FONTS NEVER FAIL THE DOCUMENT. A face that will not load degrades that family to
|
|
2204
|
+
* fixed-width measurement — the document still opens, it just paginates less like Word — so
|
|
2205
|
+
* a font failure leaves `error` null and is the loader's to report. A document failure is
|
|
2206
|
+
* different: there is nothing to show, so it lands on `error`.
|
|
2207
|
+
*
|
|
2208
|
+
* THE DOCUMENT WAITS FOR THE FONTS. They fetch concurrently, but `document` stays undefined
|
|
2209
|
+
* until fonts have settled — resolved OR failed — because layout MEASURES with them. Handing
|
|
2210
|
+
* the editor bytes first paginates the whole document on the fixed fallback and then
|
|
2211
|
+
* re-paginates when the real faces arrive, which the reader sees as the text jumping. One
|
|
2212
|
+
* slightly longer wait beats a visible reflow. Without a `fonts` option there is nothing to
|
|
2213
|
+
* wait for and the bytes go straight through.
|
|
2214
|
+
*
|
|
2215
|
+
* A URL is fetched with the browser's own `fetch`, exactly as the caller wrote it. Validate
|
|
2216
|
+
* it first if it came from user input: this hook adds no allowlist of its own, and inventing
|
|
2217
|
+
* one would only give callers a false sense of where the trust boundary is.
|
|
2218
|
+
*
|
|
2219
|
+
* @public
|
|
2220
|
+
*/
|
|
2221
|
+
declare function useDocxSource(source: DocxSource | null | undefined, options?: UseDocxSourceOptions): UseDocxSourceResult;
|
|
2222
|
+
|
|
2223
|
+
/**
|
|
2224
|
+
* Anything that can describe fonts: a resolved configuration, a bare fragment, a promise
|
|
2225
|
+
* for either (what a loader like `defaultFonts()` returns), or an on-demand
|
|
2226
|
+
* {@link FontResolver}.
|
|
2227
|
+
*
|
|
2228
|
+
* @public
|
|
2229
|
+
*/
|
|
2230
|
+
type FontsInput = FontConfiguration | FontConfigurationFragment | FontResolver | Promise<FontConfiguration | FontConfigurationFragment | undefined> | undefined;
|
|
2231
|
+
/**
|
|
2232
|
+
* Merge font origins into one stable value for `DocxEditor.Root`'s `fonts` prop.
|
|
2233
|
+
*
|
|
2234
|
+
* ```tsx
|
|
2235
|
+
* // On demand: only the families this document names are fetched.
|
|
2236
|
+
* const fonts = useFonts(googleFonts());
|
|
2237
|
+
*
|
|
2238
|
+
* // On demand, plus brand faces you always want.
|
|
2239
|
+
* const fonts = useFonts(googleFonts(), brandFragment);
|
|
2240
|
+
*
|
|
2241
|
+
* // Eager, from the bundled substitutes.
|
|
2242
|
+
* const fonts = useFonts(defaultFonts());
|
|
2243
|
+
*
|
|
2244
|
+
* return <DocxEditor.Root fonts={fonts}>{children}</DocxEditor.Root>;
|
|
2245
|
+
* ```
|
|
2246
|
+
*
|
|
2247
|
+
* Origins compose first-wins in argument order, exactly like `composeFontConfiguration`:
|
|
2248
|
+
* the first argument beats later ones, and any of them beats a substitution for a family
|
|
2249
|
+
* some origin supplies directly.
|
|
2250
|
+
*
|
|
2251
|
+
* The returned resolver never changes identity, so the editor is never rebuilt on account
|
|
2252
|
+
* of this prop — which also means the arguments are re-read per LOAD rather than per
|
|
2253
|
+
* render. Changing them mid-document does not re-resolve fonts; load a document, or
|
|
2254
|
+
* remount, for new fonts to take effect.
|
|
2255
|
+
*
|
|
2256
|
+
* @public
|
|
2257
|
+
*/
|
|
2258
|
+
declare function useFonts(source: FontsInput, ...fragments: readonly (FontConfigurationFragment | undefined)[]): FontResolver;
|
|
2259
|
+
|
|
2260
|
+
/**
|
|
2261
|
+
* OOXML content-control lock axis, mirrored from layout boundary records for the
|
|
2262
|
+
* React-only inspector surface — adapters must not import the layout package.
|
|
2263
|
+
*
|
|
2264
|
+
* @public
|
|
2265
|
+
*/
|
|
2266
|
+
type ContentControlLock = 'unlocked' | 'sdtLocked' | 'contentLocked' | 'sdtContentLocked';
|
|
2267
|
+
/** Chrome slots for the content-control group (design S14). @public */
|
|
2268
|
+
declare const CONTENT_CONTROL_SLOTS: {
|
|
2269
|
+
readonly showAll: "contentControl.showAll";
|
|
2270
|
+
readonly formFill: "contentControl.formFill";
|
|
2271
|
+
readonly inspector: "contentControl.inspector";
|
|
2272
|
+
readonly remove: "contentControl.remove";
|
|
2273
|
+
};
|
|
2274
|
+
/** @public */
|
|
2275
|
+
type ContentControlSlotId = (typeof CONTENT_CONTROL_SLOTS)[keyof typeof CONTENT_CONTROL_SLOTS];
|
|
2276
|
+
/**
|
|
2277
|
+
* Live inspector model for the control at the caret.
|
|
2278
|
+
*
|
|
2279
|
+
* `locked` is the content-edit axis. Removal lock is reported separately via
|
|
2280
|
+
* `removalLocked` from the boundary's effective lock / surface disabled reason.
|
|
2281
|
+
*
|
|
2282
|
+
* @public
|
|
2283
|
+
*/
|
|
2284
|
+
interface ContentControlInspectorState {
|
|
2285
|
+
readonly id: string;
|
|
2286
|
+
readonly tag: string | null;
|
|
2287
|
+
readonly alias: string | null;
|
|
2288
|
+
readonly controlType: ContentControlType;
|
|
2289
|
+
/** Content-edit locked (`contentLocked` / `sdtContentLocked` union). */
|
|
2290
|
+
readonly locked: boolean;
|
|
2291
|
+
/** Wrapper removal refused (`sdtLocked` / `sdtContentLocked` union). */
|
|
2292
|
+
readonly removalLocked: boolean;
|
|
2293
|
+
readonly placeholder: boolean;
|
|
2294
|
+
readonly bound: boolean;
|
|
2295
|
+
readonly effectiveLock: ContentControlLock | null;
|
|
2296
|
+
}
|
|
2297
|
+
/** What `useContentControl` answers. @public */
|
|
2298
|
+
interface UseContentControlResult {
|
|
2299
|
+
/** The control at the caret, or null when the caret is outside every control. */
|
|
2300
|
+
readonly control: ContentControlInspectorState | null;
|
|
2301
|
+
/** Every control in reading order. */
|
|
2302
|
+
readonly controls: readonly ContentControlSummary[];
|
|
2303
|
+
/** Whether show-all boundary chrome is on. */
|
|
2304
|
+
readonly showAll: boolean;
|
|
2305
|
+
/** Whether form-fill Tab navigation is on. */
|
|
2306
|
+
readonly formFill: boolean;
|
|
2307
|
+
/** Whether the inspector panel is open. */
|
|
2308
|
+
readonly inspectorOpen: boolean;
|
|
2309
|
+
/** Document is editable and a control at the caret allows value edits. */
|
|
2310
|
+
readonly canSetValue: boolean;
|
|
2311
|
+
/** Document is editable, a control is at the caret, and removal is not locked. */
|
|
2312
|
+
readonly canRemove: boolean;
|
|
2313
|
+
/** Engine reason when set-value would be refused, else null. */
|
|
2314
|
+
readonly setValueDisabledReason: string | null;
|
|
2315
|
+
/** Engine reason when remove would be refused, else null. */
|
|
2316
|
+
readonly removeDisabledReason: string | null;
|
|
2317
|
+
readonly setShowAll: (show: boolean) => void;
|
|
2318
|
+
readonly toggleShowAll: () => void;
|
|
2319
|
+
readonly setFormFill: (on: boolean) => void;
|
|
2320
|
+
readonly toggleFormFill: () => void;
|
|
2321
|
+
readonly openInspector: () => void;
|
|
2322
|
+
readonly closeInspector: () => void;
|
|
2323
|
+
readonly toggleInspector: () => void;
|
|
2324
|
+
/** Unwrap the control at the caret, keeping content. */
|
|
2325
|
+
readonly remove: () => ExecResult;
|
|
2326
|
+
/** Set the control's value (string mapped by type inside the engine). */
|
|
2327
|
+
readonly setValue: (value: string) => ExecResult;
|
|
2328
|
+
}
|
|
2329
|
+
/**
|
|
2330
|
+
* Headless content-control chrome. Mount under `DocxEditor.Root`.
|
|
2331
|
+
*
|
|
2332
|
+
* Both the context-provided instance and a local fallback run every render (same order),
|
|
2333
|
+
* matching `useHyperlinkPopup`.
|
|
2334
|
+
*
|
|
2335
|
+
* @public
|
|
2336
|
+
*/
|
|
2337
|
+
declare function useContentControl(): UseContentControlResult;
|
|
2338
|
+
/**
|
|
2339
|
+
* Create the content-control chrome state. Used by `DocxEditor.Root` to publish one
|
|
2340
|
+
* shared instance; also usable in tests without the provider.
|
|
2341
|
+
*
|
|
2342
|
+
* @public
|
|
2343
|
+
*/
|
|
2344
|
+
declare function useContentControlInstance(): UseContentControlResult;
|
|
2345
|
+
|
|
2346
|
+
/** Optional lifecycle hooks for test instrumentation. @internal */
|
|
2347
|
+
interface UseEditorStateOptions {
|
|
2348
|
+
readonly onSubscribe?: () => void;
|
|
2349
|
+
readonly onUnsubscribe?: () => void;
|
|
2350
|
+
}
|
|
2351
|
+
/**
|
|
2352
|
+
* Subscribe to a slice of the editor's read model. Re-renders the component ONLY when
|
|
2353
|
+
* `selector`'s result changes (by `isEqual`, default `Object.is`).
|
|
2354
|
+
*
|
|
2355
|
+
* Before the editor exists — outside a `DocxEditor.Root`, pre-mount, and on the
|
|
2356
|
+
* server — the selector receives a frozen loading snapshot (`isLoading: true`,
|
|
2357
|
+
* `page: {current: 0, total: 0}`), never `null`.
|
|
2358
|
+
*
|
|
2359
|
+
* @public
|
|
2360
|
+
*/
|
|
2361
|
+
declare function useEditorState<T>(selector: (snapshot: EditorSnapshot) => T, isEqual?: (a: T, b: T) => boolean, options?: UseEditorStateOptions): T;
|
|
2362
|
+
|
|
2363
|
+
/**
|
|
2364
|
+
* A caret position: a paragraph and a UTF-16 offset inside it — the shape the write APIs take
|
|
2365
|
+
* as their `at`.
|
|
2366
|
+
*
|
|
2367
|
+
* @public
|
|
2368
|
+
*/
|
|
2369
|
+
interface EditorCaret {
|
|
2370
|
+
readonly paragraphId: string;
|
|
2371
|
+
readonly offset: number;
|
|
2372
|
+
}
|
|
2373
|
+
/**
|
|
2374
|
+
* The caret's paragraph and offset, or null when nothing is placed.
|
|
2375
|
+
*
|
|
2376
|
+
* Compared by value, so a consumer re-renders only when the caret actually moves.
|
|
2377
|
+
*
|
|
2378
|
+
* ```tsx
|
|
2379
|
+
* const caret = useEditorCaret();
|
|
2380
|
+
* // …later, in a menu row that inserts at where the user was reading:
|
|
2381
|
+
* insertCustomNode(editor, citation, attrs, label, caret ? { at: caret } : {});
|
|
2382
|
+
* ```
|
|
2383
|
+
*
|
|
2384
|
+
* @public
|
|
2385
|
+
*/
|
|
2386
|
+
declare function useEditorCaret(): EditorCaret | null;
|
|
2387
|
+
|
|
2388
|
+
/**
|
|
2389
|
+
* The live state of one editor control, plus its action.
|
|
2390
|
+
*
|
|
2391
|
+
* @public
|
|
2392
|
+
*/
|
|
2393
|
+
interface EditorCommandState {
|
|
2394
|
+
/**
|
|
2395
|
+
* Run the command through the can-before-exec path.
|
|
2396
|
+
*
|
|
2397
|
+
* @returns `true` when the engine accepted and ran the command; `false` on refusal.
|
|
2398
|
+
*/
|
|
2399
|
+
readonly execute: () => boolean;
|
|
2400
|
+
/** Whether the command is currently applied at the selection (bold on bold text). */
|
|
2401
|
+
readonly isActive: boolean;
|
|
2402
|
+
/** Whether the engine will honour the command right now. */
|
|
2403
|
+
readonly isEnabled: boolean;
|
|
2404
|
+
/** The engine's reason when disabled — surface it as a tooltip, never invent one. */
|
|
2405
|
+
readonly disabledReason: string | null;
|
|
2406
|
+
}
|
|
2407
|
+
/**
|
|
2408
|
+
* Bind a chrome slot (`'text.bold'`, `'history.undo'`, …) or a raw `EditorCommand`
|
|
2409
|
+
* (`{ type: 'selectAll' }`) to the editor. The result object is identity-stable while its
|
|
2410
|
+
* fields are unchanged, so it can sit in dependency arrays and `memo` props without churn.
|
|
2411
|
+
*
|
|
2412
|
+
* @public
|
|
2413
|
+
*/
|
|
2414
|
+
declare function useEditorCommand(target: ChromeSlotId | EditorCommand): EditorCommandState;
|
|
2415
|
+
|
|
2416
|
+
/**
|
|
2417
|
+
* Live state for a value-typed toolbar control.
|
|
2418
|
+
*
|
|
2419
|
+
* @public
|
|
2420
|
+
*/
|
|
2421
|
+
interface EditorValueCommandState<T extends string | number> {
|
|
2422
|
+
readonly execute: (value: T) => void;
|
|
2423
|
+
readonly value: T | null;
|
|
2424
|
+
readonly options: readonly T[];
|
|
2425
|
+
readonly isEnabled: boolean;
|
|
2426
|
+
readonly disabledReason: string | null;
|
|
2427
|
+
}
|
|
2428
|
+
/**
|
|
2429
|
+
* Bind a value-typed chrome slot (`image.wrap`, `image.altText`) to the editor.
|
|
2430
|
+
*
|
|
2431
|
+
* @public
|
|
2432
|
+
*/
|
|
2433
|
+
declare function useEditorValueCommand(slotId: 'image.wrap'): EditorValueCommandState<ImageWrapTarget>;
|
|
2434
|
+
/**
|
|
2435
|
+
* @public
|
|
2436
|
+
*/
|
|
2437
|
+
declare function useEditorValueCommand(slotId: 'image.altText'): EditorValueCommandState<string>;
|
|
2438
|
+
|
|
2439
|
+
/**
|
|
2440
|
+
* Subscribe to an editor event (`'change'`, `'selectionChange'`, `'error'`, …) for the
|
|
2441
|
+
* lifetime of the component. No-op until the nearest `DocxEditor.Root` has created the
|
|
2442
|
+
* editor; resubscribes automatically when the instance is replaced.
|
|
2443
|
+
*
|
|
2444
|
+
* @public
|
|
2445
|
+
*/
|
|
2446
|
+
declare function useEditorEvent<E extends keyof EditorEvents>(event: E, handler: EditorEvents[E]): void;
|
|
2447
|
+
|
|
2448
|
+
/**
|
|
2449
|
+
* The fields `apply` accepts — twips throughout, like every read shape. Omitted fields
|
|
2450
|
+
* are left as authored. `scope` is Word's "Apply to": `'document'` (the default) writes
|
|
2451
|
+
* every section, `'section'` only the one the selection is in.
|
|
2452
|
+
*
|
|
2453
|
+
* @public
|
|
2454
|
+
*/
|
|
2455
|
+
interface PageSetupUpdate {
|
|
2456
|
+
readonly pageWidthTwips?: number;
|
|
2457
|
+
readonly pageHeightTwips?: number;
|
|
2458
|
+
readonly orientation?: 'portrait' | 'landscape';
|
|
2459
|
+
readonly marginTopTwips?: number;
|
|
2460
|
+
readonly marginRightTwips?: number;
|
|
2461
|
+
readonly marginBottomTwips?: number;
|
|
2462
|
+
readonly marginLeftTwips?: number;
|
|
2463
|
+
readonly scope?: 'document' | 'section';
|
|
2464
|
+
}
|
|
2465
|
+
/** What `usePageSetup` returns. @public */
|
|
2466
|
+
interface UsePageSetupReturn {
|
|
2467
|
+
/** The CARET section's page setup, or null while nothing is loaded. Reference-stable. */
|
|
2468
|
+
readonly pageSetup: PageSetup | null;
|
|
2469
|
+
/** Whether the engine can write page setup right now (mounted, editable). */
|
|
2470
|
+
readonly isEnabled: boolean;
|
|
2471
|
+
/** Write the given fields as one undoable step. Returns whether the engine accepted. */
|
|
2472
|
+
readonly apply: (update: PageSetupUpdate) => boolean;
|
|
2473
|
+
}
|
|
2474
|
+
/**
|
|
2475
|
+
* The section's page setup — size, orientation, margins — plus the command to change it.
|
|
2476
|
+
*
|
|
2477
|
+
* Reads `snapshot().pageSetup`, which is reference-stable across ticks that did not move
|
|
2478
|
+
* the section, so a subscriber re-renders only when the page actually changes shape. In
|
|
2479
|
+
* a multi-section document it reflects the CARET's section, as Word's ruler does.
|
|
2480
|
+
*
|
|
2481
|
+
* @public
|
|
2482
|
+
*/
|
|
2483
|
+
declare function usePageSetup(): UsePageSetupReturn;
|
|
2484
|
+
|
|
2485
|
+
/**
|
|
2486
|
+
* The fields `apply` accepts — twips throughout, like every other read shape here.
|
|
2487
|
+
*
|
|
2488
|
+
* Omitted fields are left as authored; `null` CLEARS one, so the paragraph falls back to
|
|
2489
|
+
* its style. That is a different thing from zero, which blocks the cascade — the same
|
|
2490
|
+
* distinction `setParagraphSpacing` draws.
|
|
2491
|
+
*
|
|
2492
|
+
* `firstLine` is ONE SIGNED offset from the left indent: negative IS the hanging indent.
|
|
2493
|
+
* OOXML spells it as two mutually exclusive attributes, and a caller should not have to
|
|
2494
|
+
* know which of them wins.
|
|
2495
|
+
*
|
|
2496
|
+
* @public
|
|
2497
|
+
*/
|
|
2498
|
+
interface IndentUpdate {
|
|
2499
|
+
readonly left?: number | null;
|
|
2500
|
+
readonly right?: number | null;
|
|
2501
|
+
readonly firstLine?: number | null;
|
|
2502
|
+
}
|
|
2503
|
+
/** What `useParagraphIndent` returns. @public */
|
|
2504
|
+
interface UseParagraphIndentReturn {
|
|
2505
|
+
/**
|
|
2506
|
+
* The EFFECTIVE indent at the selection — style and numbering cascade included — or
|
|
2507
|
+
* null with no document, and inside a table.
|
|
2508
|
+
*
|
|
2509
|
+
* The values are the FIRST touched paragraph's, with `mixed` reporting per field
|
|
2510
|
+
* whether the rest agree. Unlike the other formatting reads it does not go null on
|
|
2511
|
+
* disagreement: a ruler has to draw its handles somewhere, and Word draws them at the
|
|
2512
|
+
* first selected paragraph rather than hiding them.
|
|
2513
|
+
*
|
|
2514
|
+
* Reference-stable across ticks that did not move it, so a subscriber re-renders only
|
|
2515
|
+
* when the indent actually changes.
|
|
2516
|
+
*/
|
|
2517
|
+
readonly indent: IndentFormatting | null;
|
|
2518
|
+
/** Whether the engine can write indent right now (mounted, editable). */
|
|
2519
|
+
readonly isEnabled: boolean;
|
|
2520
|
+
/** Write the given fields as one undoable step. Returns whether the engine accepted. */
|
|
2521
|
+
readonly apply: (update: IndentUpdate) => boolean;
|
|
2522
|
+
}
|
|
2523
|
+
/**
|
|
2524
|
+
* The selection's paragraph indent — left, right, and the signed first line — plus the
|
|
2525
|
+
* command to change it.
|
|
2526
|
+
*
|
|
2527
|
+
* This is what `DocxEditor.HorizontalRuler` drives its four handles from. A host that
|
|
2528
|
+
* wants its own indent chrome takes the hook and renders whatever it likes; the ruler's
|
|
2529
|
+
* drag geometry is separately available as pure functions
|
|
2530
|
+
* (`dragIndent` / `handlePosition` from the engine).
|
|
2531
|
+
*
|
|
2532
|
+
* @public
|
|
2533
|
+
*/
|
|
2534
|
+
declare function useParagraphIndent(): UseParagraphIndentReturn;
|
|
2535
|
+
|
|
2536
|
+
interface PaginatedDocxEditorProps {
|
|
2537
|
+
/** The document to open. Replacing it remounts the surface. */
|
|
2538
|
+
readonly source: Uint8Array;
|
|
2539
|
+
/** Points to CSS pixels. */
|
|
2540
|
+
readonly scale?: number;
|
|
2541
|
+
/** Host-supplied font metrics; layout stays DOM-free without it. */
|
|
2542
|
+
readonly measurer?: TextMeasurer;
|
|
2543
|
+
/** Called on every committed revision and every selection change. */
|
|
2544
|
+
readonly onStateChange?: (state: PaginatedSurfaceState) => void;
|
|
2545
|
+
/** Called once if the document cannot be opened, with the engine's typed reason. */
|
|
2546
|
+
readonly onError?: (reason: string, detail?: string) => void;
|
|
2547
|
+
readonly className?: string;
|
|
2548
|
+
/**
|
|
2549
|
+
* The face runs naming no font are painted in.
|
|
2550
|
+
*
|
|
2551
|
+
* Applied to the DOCUMENT container only. Setting it on an ancestor leaks the document's
|
|
2552
|
+
* face into the surrounding chrome — a measured text face is chosen to match what the
|
|
2553
|
+
* shaper measured, and it renders the toolbar and the brand lockup heavier than the UI
|
|
2554
|
+
* font they were designed in.
|
|
2555
|
+
*/
|
|
2556
|
+
readonly documentFontFamily?: string;
|
|
2557
|
+
readonly ref?: Ref<PaginatedDocxEditorHandle>;
|
|
2558
|
+
}
|
|
2559
|
+
/**
|
|
2560
|
+
* What a host can drive from outside.
|
|
2561
|
+
*
|
|
2562
|
+
* Commands only. There is no accessor for the document or the layout, because a caller
|
|
2563
|
+
* holding either could act on a revision the model has already left behind.
|
|
2564
|
+
*/
|
|
2565
|
+
interface PaginatedDocxEditorHandle {
|
|
2566
|
+
focus(): void;
|
|
2567
|
+
type(text: string): void;
|
|
2568
|
+
undo(): void;
|
|
2569
|
+
redo(): void;
|
|
2570
|
+
selectAll(): void;
|
|
2571
|
+
navigate(command: NavigationCommand, extend?: boolean): void;
|
|
2572
|
+
toggleRunProperty(localName: string, attributes?: Record<string, string>): void;
|
|
2573
|
+
setRunProperty(localName: string, attributes?: Record<string, string>): void;
|
|
2574
|
+
setParagraphProperty(localName: string, attributes?: Record<string, string>): void;
|
|
2575
|
+
/** Formatting at the selection, for a toolbar to reflect. */
|
|
2576
|
+
formatting(): SurfaceFormatting | null;
|
|
2577
|
+
/** The section the document declares — what a ruler is made of. */
|
|
2578
|
+
sectionProperties(): SectionProperties | null;
|
|
2579
|
+
/** Serialize the current document. */
|
|
2580
|
+
save(): Uint8Array | null;
|
|
2581
|
+
}
|
|
2582
|
+
declare function PaginatedDocxEditor({ source, scale, measurer, onStateChange, onError, className, documentFontFamily, ref, }: PaginatedDocxEditorProps): react.JSX.Element;
|
|
2583
|
+
|
|
2584
|
+
interface PaginatedDocxEditorShellProps {
|
|
2585
|
+
readonly source: Uint8Array;
|
|
2586
|
+
/** Shown in the title bar. */
|
|
2587
|
+
readonly documentName?: string;
|
|
2588
|
+
readonly scale?: number;
|
|
2589
|
+
readonly measurer?: TextMeasurer;
|
|
2590
|
+
readonly onStateChange?: (state: PaginatedSurfaceState) => void;
|
|
2591
|
+
readonly onError?: (reason: string, detail?: string) => void;
|
|
2592
|
+
/** Called with the serialized document when File ▸ Save is used. */
|
|
2593
|
+
readonly onSave?: (bytes: Uint8Array) => void;
|
|
2594
|
+
/**
|
|
2595
|
+
* Title-bar slots, owned by the HOST.
|
|
2596
|
+
*
|
|
2597
|
+
* Brand lockup, adapter and example switchers on the left; document actions on the right.
|
|
2598
|
+
* They belong to whoever embeds the editor — a demo's switchers are not editor chrome, and
|
|
2599
|
+
* baking them in would ship them to every consumer.
|
|
2600
|
+
*/
|
|
2601
|
+
readonly renderTitleBarLeft?: () => ReactNode;
|
|
2602
|
+
readonly renderTitleBarRight?: () => ReactNode;
|
|
2603
|
+
/** Commands, forwarded from the editor the shell hosts. */
|
|
2604
|
+
readonly ref?: Ref<PaginatedDocxEditorHandle>;
|
|
2605
|
+
/** Applies the editor's own dark palette; the document canvas stays Word-faithful. */
|
|
2606
|
+
readonly colorMode?: 'light' | 'dark';
|
|
2607
|
+
/** Reported when the zoom control changes, so the host can re-scale the surface. */
|
|
2608
|
+
readonly onZoomChange?: (zoom: number) => void;
|
|
2609
|
+
/** The face the document is painted in; never applied to the chrome. */
|
|
2610
|
+
readonly documentFontFamily?: string;
|
|
2611
|
+
readonly className?: string;
|
|
2612
|
+
}
|
|
2613
|
+
declare function PaginatedDocxEditorShell({ source, scale, measurer, documentName, onStateChange, onError, onSave, renderTitleBarLeft, renderTitleBarRight, ref, colorMode, onZoomChange, documentFontFamily, className, }: PaginatedDocxEditorShellProps): react.JSX.Element;
|
|
2614
|
+
|
|
2615
|
+
/**
|
|
2616
|
+
* The horizontal ruler — page margins plus Word's four indent handles.
|
|
2617
|
+
*
|
|
2618
|
+
* Margins are the grey zones at either end; dragging the grey/white boundary moves them.
|
|
2619
|
+
*
|
|
2620
|
+
* The indent handles are Word's, not Google's three:
|
|
2621
|
+
*
|
|
2622
|
+
* ▽ first line at leftMargin + left + firstLine
|
|
2623
|
+
* △ hanging at leftMargin + left — drags `left`, PINS the first-line marker
|
|
2624
|
+
* ▭ left box at leftMargin + left — drags `left`, TAKES the first line with it
|
|
2625
|
+
* △ right at pageWidth - rightMargin - right
|
|
2626
|
+
*
|
|
2627
|
+
* The hanging triangle and the left box are coincident horizontally, as in Word, and are
|
|
2628
|
+
* separated vertically instead — the box sits below the strip. They differ only in what a
|
|
2629
|
+
* drag takes with them.
|
|
2630
|
+
*
|
|
2631
|
+
* All the arithmetic lives in the engine (`ruler-indent.ts`), including the snap grid and
|
|
2632
|
+
* the clamps, so this file only converts pixels to twips and paints.
|
|
2633
|
+
*/
|
|
2634
|
+
|
|
2635
|
+
/**
|
|
2636
|
+
* Section page setup as the engine reports it (`Editor.getPageSetup()`) —
|
|
2637
|
+
* page size, orientation, and margins, in twips. Derived from the contract.
|
|
2638
|
+
*/
|
|
2639
|
+
type RulerPageSetup = NonNullable<ReturnType<Editor['getPageSetup']>>;
|
|
2640
|
+
/**
|
|
2641
|
+
* A tab stop the ruler paints. `position` is twips from the left margin edge —
|
|
2642
|
+
* the same value the `removeTabMark` command takes as `positionTwips`.
|
|
2643
|
+
*/
|
|
2644
|
+
interface RulerTabStop {
|
|
2645
|
+
position: number;
|
|
2646
|
+
alignment: 'left' | 'center' | 'right' | 'decimal' | 'bar';
|
|
2647
|
+
}
|
|
2648
|
+
interface HorizontalRulerProps$1 {
|
|
2649
|
+
pageSetup?: RulerPageSetup | null;
|
|
2650
|
+
zoom?: number;
|
|
2651
|
+
/** Whether the MARGIN handles drag. */
|
|
2652
|
+
editable?: boolean;
|
|
2653
|
+
onLeftMarginChange?: (marginTwips: number) => void;
|
|
2654
|
+
onRightMarginChange?: (marginTwips: number) => void;
|
|
2655
|
+
/** Fires when a margin drag is released — the moment to commit what the drag previewed. */
|
|
2656
|
+
onMarginDragEnd?: () => void;
|
|
2657
|
+
/**
|
|
2658
|
+
* Paint the four indent handles.
|
|
2659
|
+
*
|
|
2660
|
+
* Off by default so a ruler with no paragraph context does not show handles pinned at
|
|
2661
|
+
* zero. When on they are painted whatever `indentEditable` says: Word shows the markers
|
|
2662
|
+
* on a read-only document and simply refuses the drag, and hiding them would remove the
|
|
2663
|
+
* only place a reader can see a paragraph's indents.
|
|
2664
|
+
*/
|
|
2665
|
+
showIndentHandles?: boolean;
|
|
2666
|
+
/** The paragraph's indent in twips; `firstLine` is SIGNED, negative for a hanging. */
|
|
2667
|
+
indent?: RulerIndent | null;
|
|
2668
|
+
/** Whether the INDENT handles drag — a different capability from `editable`. */
|
|
2669
|
+
indentEditable?: boolean;
|
|
2670
|
+
/** Fires continuously through an indent drag, for the host to preview. */
|
|
2671
|
+
onIndentChange?: (indent: RulerIndent) => void;
|
|
2672
|
+
/** Fires when an indent drag is released — the moment to commit one undoable step. */
|
|
2673
|
+
onIndentDragEnd?: () => void;
|
|
2674
|
+
unit?: 'inch' | 'cm';
|
|
2675
|
+
className?: string;
|
|
2676
|
+
style?: CSSProperties;
|
|
2677
|
+
tabMarks?: RulerTabStop[] | null;
|
|
2678
|
+
onTabMarkRemove?: (positionTwips: number) => void;
|
|
2679
|
+
}
|
|
2680
|
+
declare function HorizontalRuler({ pageSetup, zoom, editable, onLeftMarginChange, onRightMarginChange, onMarginDragEnd, showIndentHandles, indent, indentEditable, onIndentChange, onIndentDragEnd, unit, className, style, tabMarks, onTabMarkRemove, }: HorizontalRulerProps$1): react__default.ReactElement;
|
|
2681
|
+
|
|
2682
|
+
/**
|
|
2683
|
+
* One heading of the engine's outline (`Editor.getOutline()`): text, level,
|
|
2684
|
+
* and the block id `Editor.scrollToBlock` accepts. Derived from the contract.
|
|
2685
|
+
*/
|
|
2686
|
+
type OutlineHeading = ReturnType<Editor['getOutline']>[number];
|
|
2687
|
+
|
|
2688
|
+
/** One tracked change as the engine reports it (`Editor.getTrackedChanges()`). */
|
|
2689
|
+
type TrackedChangeSummary = ReturnType<Editor['getTrackedChanges']>[number];
|
|
2690
|
+
interface ScrollPageInfo {
|
|
2691
|
+
currentPage: number;
|
|
2692
|
+
totalPages: number;
|
|
2693
|
+
visible: boolean;
|
|
2694
|
+
}
|
|
2695
|
+
interface HorizontalRulerProps {
|
|
2696
|
+
pageSetup: RulerPageSetup | undefined;
|
|
2697
|
+
zoom: number;
|
|
2698
|
+
unit: 'inch' | 'cm';
|
|
2699
|
+
editable: boolean;
|
|
2700
|
+
onLeftMarginChange: (marginTwips: number) => void;
|
|
2701
|
+
onRightMarginChange: (marginTwips: number) => void;
|
|
2702
|
+
tabMarks: RulerTabStop[] | null;
|
|
2703
|
+
onTabMarkRemove: (positionTwips: number) => void;
|
|
2704
|
+
}
|
|
2705
|
+
interface VerticalRulerProps$1 {
|
|
2706
|
+
pageSetup: RulerPageSetup | undefined;
|
|
2707
|
+
zoom: number;
|
|
2708
|
+
unit: 'inch' | 'cm';
|
|
2709
|
+
editable: boolean;
|
|
2710
|
+
onTopMarginChange: (marginTwips: number) => void;
|
|
2711
|
+
onBottomMarginChange: (marginTwips: number) => void;
|
|
2712
|
+
}
|
|
2713
|
+
interface OutlineProps {
|
|
2714
|
+
headings: readonly OutlineHeading[];
|
|
2715
|
+
onHeadingClick: (blockId: string) => void;
|
|
2716
|
+
onClose: () => void;
|
|
2717
|
+
topOffset: number;
|
|
2718
|
+
scrollLeft: number;
|
|
2719
|
+
}
|
|
2720
|
+
/**
|
|
2721
|
+
* Outer chrome of the editor: i18n + error provider wrappers, the
|
|
2722
|
+
* scroll container with its background-click handler, horizontal and
|
|
2723
|
+
* vertical rulers, the floating page indicator, document outline panel
|
|
2724
|
+
* + toggle button, plus slots for the toolbar, paged-area body,
|
|
2725
|
+
* overlays, dialogs, and hidden file inputs.
|
|
2726
|
+
*
|
|
2727
|
+
* The expanded-sidebar-item highlight styles are computed here from
|
|
2728
|
+
* `expandedSidebarItem` + `trackedChanges` because they need to live
|
|
2729
|
+
* inside the editor-content `<div>` for proper scoping.
|
|
2730
|
+
*/
|
|
2731
|
+
declare function DocxEditorShell({ i18n, isDark, onEditorError, containerRef, scrollContainerRef, editorContentRef, className, containerStyle, mainContentStyle, editorContainerStyle, showRuler, readOnlyProp, showOutline, showOutlineButton, sidebarOpen, minLayoutWidth, toolbarHeight, editorScrollLeft, expandedSidebarItem, trackedChanges, onScrollContainerMouseDown, onEditorBgMouseDown, onEditorContextMenu, horizontalRulerProps, verticalRulerProps, outlineProps, onToggleOutline, scrollPageInfo, toolbar, pagedArea, overlays, dialogs, fileInputs, }: {
|
|
2732
|
+
i18n: React.ComponentProps<typeof LocaleProvider>['i18n'];
|
|
2733
|
+
isDark?: boolean;
|
|
2734
|
+
onEditorError: (error: Error) => void;
|
|
2735
|
+
containerRef: React.Ref<HTMLDivElement>;
|
|
2736
|
+
scrollContainerRef: React.Ref<HTMLDivElement>;
|
|
2737
|
+
editorContentRef: React.Ref<HTMLDivElement>;
|
|
2738
|
+
className: string | undefined;
|
|
2739
|
+
containerStyle: CSSProperties;
|
|
2740
|
+
mainContentStyle: CSSProperties;
|
|
2741
|
+
editorContainerStyle: CSSProperties;
|
|
2742
|
+
showRuler: boolean;
|
|
2743
|
+
readOnlyProp: boolean | undefined;
|
|
2744
|
+
showOutline: boolean;
|
|
2745
|
+
showOutlineButton: boolean;
|
|
2746
|
+
sidebarOpen: boolean;
|
|
2747
|
+
minLayoutWidth: number;
|
|
2748
|
+
toolbarHeight: number;
|
|
2749
|
+
editorScrollLeft: number;
|
|
2750
|
+
expandedSidebarItem: string | null;
|
|
2751
|
+
trackedChanges: readonly TrackedChangeSummary[];
|
|
2752
|
+
onScrollContainerMouseDown: (e: React.MouseEvent) => void;
|
|
2753
|
+
onEditorBgMouseDown: (e: React.MouseEvent) => void;
|
|
2754
|
+
onEditorContextMenu: (e: React.MouseEvent) => void;
|
|
2755
|
+
horizontalRulerProps: HorizontalRulerProps;
|
|
2756
|
+
verticalRulerProps: VerticalRulerProps$1;
|
|
2757
|
+
outlineProps: OutlineProps;
|
|
2758
|
+
onToggleOutline: () => void;
|
|
2759
|
+
scrollPageInfo: ScrollPageInfo;
|
|
2760
|
+
toolbar: ReactNode;
|
|
2761
|
+
pagedArea: ReactNode;
|
|
2762
|
+
overlays: ReactNode;
|
|
2763
|
+
dialogs: ReactNode;
|
|
2764
|
+
fileInputs: ReactNode;
|
|
2765
|
+
}): react.JSX.Element;
|
|
2766
|
+
|
|
2767
|
+
/**
|
|
2768
|
+
* Paragraph-style preview + option resolution — shared between the React and
|
|
2769
|
+
* Vue toolbars so the style-picker dropdown looks and behaves identically.
|
|
2770
|
+
*
|
|
2771
|
+
* Pure logic only: no i18n and no framework CSS types. The returned preview is
|
|
2772
|
+
* a plain `{ fontSize, lineHeight, fontWeight?, fontStyle?, color? }` object,
|
|
2773
|
+
* which is structurally assignable to both React's `CSSProperties` and Vue's
|
|
2774
|
+
* inline-style record, so neither adapter needs a cast. Name localization stays
|
|
2775
|
+
* in the adapters (they own the i18n `t()` boundary).
|
|
2776
|
+
* @packageDocumentation
|
|
2777
|
+
* @public
|
|
2778
|
+
*/
|
|
2779
|
+
|
|
2780
|
+
/**
|
|
2781
|
+
* One entry of `Editor.getDocumentStyles()` — the engine's document-style
|
|
2782
|
+
* summary the picker consumes. Derived from the contract, not re-declared.
|
|
2783
|
+
* @public
|
|
2784
|
+
*/
|
|
2785
|
+
type DocumentStyleSummary = ReturnType<Editor['getDocumentStyles']>[number];
|
|
2786
|
+
|
|
2787
|
+
/**
|
|
2788
|
+
* Alignment Dropdown Component (Google Docs style)
|
|
2789
|
+
*
|
|
2790
|
+
* A single dropdown button for paragraph alignment controls:
|
|
2791
|
+
* - Shows current alignment icon + chevron
|
|
2792
|
+
* - Opens a floating panel with Left, Center, Right, Justify options
|
|
2793
|
+
* - Active option is highlighted
|
|
2794
|
+
*/
|
|
2795
|
+
|
|
2796
|
+
/**
|
|
2797
|
+
* The paragraph alignments this control understands, in OOXML `w:jc`
|
|
2798
|
+
* vocabulary (`both` is Word's justify; `distribute` renders as justify).
|
|
2799
|
+
* Presentation-only: the dropdown emits the first four.
|
|
2800
|
+
*/
|
|
2801
|
+
type ParagraphAlignment = 'left' | 'center' | 'right' | 'both' | 'distribute';
|
|
2802
|
+
|
|
2803
|
+
/**
|
|
2804
|
+
* Shared FontOption shape + normaliser used by FontPicker components
|
|
2805
|
+
* in both adapters. Lifted from packages/react/src/components/ui/
|
|
2806
|
+
* normalizeFontFamilies.ts so the type definition has a single home.
|
|
2807
|
+
* @packageDocumentation
|
|
2808
|
+
* @public
|
|
2809
|
+
*/
|
|
2810
|
+
interface FontOption {
|
|
2811
|
+
name: string;
|
|
2812
|
+
fontFamily: string;
|
|
2813
|
+
category?: 'sans-serif' | 'serif' | 'monospace' | 'other';
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
/**
|
|
2817
|
+
* Pure list-state helpers used by both adapter toolbars to track
|
|
2818
|
+
* whether the selection is in a bullet/numbered list and at what
|
|
2819
|
+
* indent level. Lifted from packages/react/src/components/ui/
|
|
2820
|
+
* ListButtons.tsx so the React + Vue toolbars share identical
|
|
2821
|
+
* state-mutation logic.
|
|
2822
|
+
* @packageDocumentation
|
|
2823
|
+
* @public
|
|
2824
|
+
*/
|
|
2825
|
+
type ListType = 'bullet' | 'numbered' | 'none';
|
|
2826
|
+
interface ListState {
|
|
2827
|
+
type: ListType;
|
|
2828
|
+
level: number;
|
|
2829
|
+
isInList: boolean;
|
|
2830
|
+
numId?: number;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
/**
|
|
2834
|
+
* TableToolbar Component
|
|
2835
|
+
*
|
|
2836
|
+
* Provides controls for editing tables:
|
|
2837
|
+
* - Add row above/below
|
|
2838
|
+
* - Add column left/right
|
|
2839
|
+
* - Delete row/column
|
|
2840
|
+
* - Merge cells
|
|
2841
|
+
* - Split cell
|
|
2842
|
+
*
|
|
2843
|
+
* Shows when cursor is in a table.
|
|
2844
|
+
*/
|
|
2845
|
+
|
|
2846
|
+
/**
|
|
2847
|
+
* Table editing action types
|
|
2848
|
+
*/
|
|
2849
|
+
type TableAction = 'addRowAbove' | 'addRowBelow' | 'addColumnLeft' | 'addColumnRight' | 'deleteRow' | 'deleteColumn' | 'mergeCells' | 'splitCell' | 'deleteTable' | 'selectTable' | 'selectRow' | 'selectColumn' | 'borderAll' | 'borderOutside' | 'borderInside' | 'borderNone' | 'borderTop' | 'borderBottom' | 'borderLeft' | 'borderRight' | {
|
|
2850
|
+
type: 'cellFillColor';
|
|
2851
|
+
color: string | null;
|
|
2852
|
+
} | {
|
|
2853
|
+
type: 'borderColor';
|
|
2854
|
+
color: string;
|
|
2855
|
+
} | {
|
|
2856
|
+
type: 'borderWidth';
|
|
2857
|
+
size: number;
|
|
2858
|
+
} | {
|
|
2859
|
+
type: 'cellBorder';
|
|
2860
|
+
side: 'top' | 'bottom' | 'left' | 'right' | 'all';
|
|
2861
|
+
style: string;
|
|
2862
|
+
size: number;
|
|
2863
|
+
color: string;
|
|
2864
|
+
} | {
|
|
2865
|
+
type: 'cellVerticalAlign';
|
|
2866
|
+
align: 'top' | 'center' | 'bottom';
|
|
2867
|
+
} | {
|
|
2868
|
+
type: 'cellMargins';
|
|
2869
|
+
margins: {
|
|
2870
|
+
top?: number;
|
|
2871
|
+
bottom?: number;
|
|
2872
|
+
left?: number;
|
|
2873
|
+
right?: number;
|
|
2874
|
+
};
|
|
2875
|
+
} | {
|
|
2876
|
+
type: 'cellTextDirection';
|
|
2877
|
+
direction: string | null;
|
|
2878
|
+
} | {
|
|
2879
|
+
type: 'toggleNoWrap';
|
|
2880
|
+
} | {
|
|
2881
|
+
type: 'rowHeight';
|
|
2882
|
+
height: number | null;
|
|
2883
|
+
rule?: 'auto' | 'atLeast' | 'exact';
|
|
2884
|
+
} | {
|
|
2885
|
+
type: 'toggleHeaderRow';
|
|
2886
|
+
} | {
|
|
2887
|
+
type: 'distributeColumns';
|
|
2888
|
+
} | {
|
|
2889
|
+
type: 'autoFitContents';
|
|
2890
|
+
} | {
|
|
2891
|
+
type: 'tableProperties';
|
|
2892
|
+
props: {
|
|
2893
|
+
width?: number | null;
|
|
2894
|
+
widthType?: string | null;
|
|
2895
|
+
justification?: 'left' | 'center' | 'right' | null;
|
|
2896
|
+
};
|
|
2897
|
+
} | {
|
|
2898
|
+
type: 'openTableProperties';
|
|
2899
|
+
} | {
|
|
2900
|
+
type: 'applyTableStyle';
|
|
2901
|
+
styleId: string;
|
|
2902
|
+
};
|
|
2903
|
+
|
|
2904
|
+
/**
|
|
2905
|
+
* Toolbar Component
|
|
2906
|
+
*
|
|
2907
|
+
* The customizable formatting rail — undo/redo, zoom, styles, fonts,
|
|
2908
|
+
* bold/italic/underline, colors, alignment, lists, table/image context,
|
|
2909
|
+
* clear formatting. Used standalone (`<Toolbar ...props>`), inside
|
|
2910
|
+
* `<EditorToolbar>` (reads from context via `EditorToolbar.Toolbar`), or
|
|
2911
|
+
* embedded inline. Also the home of the `ToolbarButton` / `ToolbarGroup` /
|
|
2912
|
+
* `ToolbarSeparator` primitives and the shared `FormattingAction` /
|
|
2913
|
+
* `SelectionFormatting` / `ToolbarProps` types.
|
|
2914
|
+
*/
|
|
2915
|
+
|
|
2916
|
+
/**
|
|
2917
|
+
* Current formatting state of the selection
|
|
2918
|
+
*/
|
|
2919
|
+
interface SelectionFormatting {
|
|
2920
|
+
/** Whether selected text is bold */
|
|
2921
|
+
bold?: boolean;
|
|
2922
|
+
/** Whether selected text is italic */
|
|
2923
|
+
italic?: boolean;
|
|
2924
|
+
/** Whether selected text is underlined */
|
|
2925
|
+
underline?: boolean;
|
|
2926
|
+
/** Whether selected text has strikethrough */
|
|
2927
|
+
strike?: boolean;
|
|
2928
|
+
/** Whether selected text is superscript */
|
|
2929
|
+
superscript?: boolean;
|
|
2930
|
+
/** Whether selected text is subscript */
|
|
2931
|
+
subscript?: boolean;
|
|
2932
|
+
/** Font family of selected text */
|
|
2933
|
+
fontFamily?: string;
|
|
2934
|
+
/** Font size of selected text (in half-points) */
|
|
2935
|
+
fontSize?: number;
|
|
2936
|
+
/** Text color */
|
|
2937
|
+
color?: string;
|
|
2938
|
+
/** Highlight color */
|
|
2939
|
+
highlight?: string;
|
|
2940
|
+
/** Paragraph alignment */
|
|
2941
|
+
alignment?: ParagraphAlignment;
|
|
2942
|
+
/** List state of the current paragraph */
|
|
2943
|
+
listState?: ListState;
|
|
2944
|
+
/** Line spacing in twips (OOXML value, 240 = single spacing) */
|
|
2945
|
+
lineSpacing?: number;
|
|
2946
|
+
/** Paragraph style ID */
|
|
2947
|
+
styleId?: string;
|
|
2948
|
+
/** Paragraph left indentation in twips */
|
|
2949
|
+
indentLeft?: number;
|
|
2950
|
+
/** Whether the paragraph is RTL (bidi) */
|
|
2951
|
+
bidi?: boolean;
|
|
2952
|
+
}
|
|
2953
|
+
/**
|
|
2954
|
+
* Formatting action types
|
|
2955
|
+
*/
|
|
2956
|
+
type FormattingAction = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'superscript' | 'subscript' | 'clearFormatting' | 'bulletList' | 'numberedList' | 'indent' | 'outdent' | 'insertLink' | 'setRtl' | 'setLtr' | {
|
|
2957
|
+
type: 'fontFamily';
|
|
2958
|
+
value: string;
|
|
2959
|
+
} | {
|
|
2960
|
+
type: 'fontSize';
|
|
2961
|
+
value: number;
|
|
2962
|
+
} | {
|
|
2963
|
+
type: 'textColor';
|
|
2964
|
+
value: ColorValue | string;
|
|
2965
|
+
} | {
|
|
2966
|
+
type: 'highlightColor';
|
|
2967
|
+
value: string;
|
|
2968
|
+
} | {
|
|
2969
|
+
type: 'alignment';
|
|
2970
|
+
value: ParagraphAlignment;
|
|
2971
|
+
} | {
|
|
2972
|
+
type: 'lineSpacing';
|
|
2973
|
+
value: number;
|
|
2974
|
+
} | {
|
|
2975
|
+
type: 'applyStyle';
|
|
2976
|
+
value: string;
|
|
2977
|
+
};
|
|
2978
|
+
/**
|
|
2979
|
+
* Props for the Toolbar (formatting rail) component
|
|
2980
|
+
*/
|
|
2981
|
+
interface ToolbarProps {
|
|
2982
|
+
/** Current formatting of the selection */
|
|
2983
|
+
currentFormatting?: SelectionFormatting;
|
|
2984
|
+
/** Callback when a formatting action is triggered */
|
|
2985
|
+
onFormat?: (action: FormattingAction) => void;
|
|
2986
|
+
/** Callback for undo action */
|
|
2987
|
+
onUndo?: () => void;
|
|
2988
|
+
/** Callback for redo action */
|
|
2989
|
+
onRedo?: () => void;
|
|
2990
|
+
/** Whether undo is available */
|
|
2991
|
+
canUndo?: boolean;
|
|
2992
|
+
/** Whether redo is available */
|
|
2993
|
+
canRedo?: boolean;
|
|
2994
|
+
/** Whether the toolbar is disabled */
|
|
2995
|
+
disabled?: boolean;
|
|
2996
|
+
/** Additional CSS class name */
|
|
2997
|
+
className?: string;
|
|
2998
|
+
/** Additional inline styles */
|
|
2999
|
+
style?: CSSProperties;
|
|
3000
|
+
/** Whether to enable keyboard shortcuts (default: true) */
|
|
3001
|
+
enableShortcuts?: boolean;
|
|
3002
|
+
/** Ref to the editor container for keyboard events */
|
|
3003
|
+
editorRef?: react__default.RefObject<HTMLElement>;
|
|
3004
|
+
/** Custom toolbar items to render at the end */
|
|
3005
|
+
children?: ReactNode;
|
|
3006
|
+
/** When true, renders with display:contents so children flow in the parent flex container */
|
|
3007
|
+
inline?: boolean;
|
|
3008
|
+
/** Whether to show font family picker (default: true) */
|
|
3009
|
+
showFontPicker?: boolean;
|
|
3010
|
+
/**
|
|
3011
|
+
* Custom list of fonts in the toolbar dropdown. When omitted, the built-in
|
|
3012
|
+
* 12-font default is used. Strings render in the "Other" group; pass
|
|
3013
|
+
* `FontOption[]` for category grouping and CSS fallback chains.
|
|
3014
|
+
* An empty array renders an empty (but enabled) dropdown.
|
|
3015
|
+
*/
|
|
3016
|
+
fontFamilies?: ReadonlyArray<string | FontOption>;
|
|
3017
|
+
/**
|
|
3018
|
+
* Fonts the loaded document references that the browser can render (embedded
|
|
3019
|
+
* faces + system-resolved). Rendered in a "Document fonts" group, deduped
|
|
3020
|
+
* against `fontFamilies`. Managed by the editor, not a consumer prop.
|
|
3021
|
+
*/
|
|
3022
|
+
documentFonts?: readonly FontOption[];
|
|
3023
|
+
/** Whether to show font size picker (default: true) */
|
|
3024
|
+
showFontSizePicker?: boolean;
|
|
3025
|
+
/** Whether to show text color picker (default: true) */
|
|
3026
|
+
showTextColorPicker?: boolean;
|
|
3027
|
+
/** Whether to show highlight color picker (default: true) */
|
|
3028
|
+
showHighlightColorPicker?: boolean;
|
|
3029
|
+
/** Whether to show alignment buttons (default: true) */
|
|
3030
|
+
showAlignmentButtons?: boolean;
|
|
3031
|
+
/** Whether to show list buttons (default: true) */
|
|
3032
|
+
showListButtons?: boolean;
|
|
3033
|
+
/** Whether to show line spacing picker (default: true) */
|
|
3034
|
+
showLineSpacingPicker?: boolean;
|
|
3035
|
+
/** Whether to show style picker (default: true) */
|
|
3036
|
+
showStylePicker?: boolean;
|
|
3037
|
+
/** Document styles for the style picker (`Editor.getDocumentStyles()`). */
|
|
3038
|
+
documentStyles?: readonly DocumentStyleSummary[];
|
|
3039
|
+
/** Theme for the style picker / color picker theme matrix */
|
|
3040
|
+
theme?: Theme | null;
|
|
3041
|
+
/** Callback for print action. Set to enable the File > Print menu entry. */
|
|
3042
|
+
onPrint?: () => void;
|
|
3043
|
+
/** Callback to open/import a DOCX file (File → Open) */
|
|
3044
|
+
onOpen?: () => void;
|
|
3045
|
+
/** Callback to save/download the current DOCX (File → Save) */
|
|
3046
|
+
onSave?: () => void;
|
|
3047
|
+
/** Whether to show zoom control (default: true) */
|
|
3048
|
+
showZoomControl?: boolean;
|
|
3049
|
+
/** Current zoom level (1.0 = 100%) */
|
|
3050
|
+
zoom?: number;
|
|
3051
|
+
/** Callback when zoom changes */
|
|
3052
|
+
onZoomChange?: (zoom: number) => void;
|
|
3053
|
+
/** Callback to refocus the editor after toolbar interactions */
|
|
3054
|
+
onRefocusEditor?: () => void;
|
|
3055
|
+
/** Callback when a table should be inserted */
|
|
3056
|
+
onInsertTable?: (rows: number, columns: number) => void;
|
|
3057
|
+
/** Whether to show table insert button (default: true) */
|
|
3058
|
+
showTableInsert?: boolean;
|
|
3059
|
+
/** Whether to show the Help menu in the menu bar (default: true) */
|
|
3060
|
+
showHelpMenu?: boolean;
|
|
3061
|
+
/** Callback when user wants to insert an image */
|
|
3062
|
+
onInsertImage?: () => void;
|
|
3063
|
+
/** Callback when user wants to insert a page break */
|
|
3064
|
+
onInsertPageBreak?: () => void;
|
|
3065
|
+
/** Callback when user wants to insert a "next page" section break */
|
|
3066
|
+
onInsertSectionBreakNextPage?: () => void;
|
|
3067
|
+
/** Callback when user wants to insert a "continuous" section break */
|
|
3068
|
+
onInsertSectionBreakContinuous?: () => void;
|
|
3069
|
+
/** Callback when user wants to insert a table of contents */
|
|
3070
|
+
onInsertTOC?: () => void;
|
|
3071
|
+
/** Callback when user wants to insert a shape */
|
|
3072
|
+
onInsertShape?: (data: {
|
|
3073
|
+
shapeType: string;
|
|
3074
|
+
width: number;
|
|
3075
|
+
height: number;
|
|
3076
|
+
fillColor?: string;
|
|
3077
|
+
fillType?: string;
|
|
3078
|
+
outlineWidth?: number;
|
|
3079
|
+
outlineColor?: string;
|
|
3080
|
+
}) => void;
|
|
3081
|
+
/** Image context when an image is selected */
|
|
3082
|
+
imageContext?: {
|
|
3083
|
+
wrapType: string;
|
|
3084
|
+
displayMode: string;
|
|
3085
|
+
cssFloat: string | null;
|
|
3086
|
+
} | null;
|
|
3087
|
+
/** Callback when image wrap type changes */
|
|
3088
|
+
onImageWrapType?: (wrapType: string) => void;
|
|
3089
|
+
/** Callback for image transform (rotate/flip) */
|
|
3090
|
+
onImageTransform?: (action: 'rotateCW' | 'rotateCCW' | 'flipH' | 'flipV') => void;
|
|
3091
|
+
/** Callback to open image properties dialog (alt text + border) */
|
|
3092
|
+
onOpenImageProperties?: () => void;
|
|
3093
|
+
/** Callback to open page setup dialog */
|
|
3094
|
+
onPageSetup?: () => void;
|
|
3095
|
+
/** Callback to open the watermark dialog */
|
|
3096
|
+
onWatermark?: () => void;
|
|
3097
|
+
/** Table context when cursor is in a table */
|
|
3098
|
+
tableContext?: {
|
|
3099
|
+
isInTable: boolean;
|
|
3100
|
+
rowCount?: number;
|
|
3101
|
+
columnCount?: number;
|
|
3102
|
+
canSplitCell?: boolean;
|
|
3103
|
+
hasMultiCellSelection?: boolean;
|
|
3104
|
+
cellBorderColor?: ColorValue;
|
|
3105
|
+
cellBackgroundColor?: string;
|
|
3106
|
+
} | null;
|
|
3107
|
+
/** Callback when a table action is triggered */
|
|
3108
|
+
onTableAction?: (action: TableAction) => void;
|
|
3109
|
+
}
|
|
3110
|
+
/**
|
|
3111
|
+
* Props for individual toolbar buttons
|
|
3112
|
+
*/
|
|
3113
|
+
interface ToolbarButtonProps {
|
|
3114
|
+
/** Whether the button is in active/pressed state */
|
|
3115
|
+
active?: boolean;
|
|
3116
|
+
/** Whether the button is disabled */
|
|
3117
|
+
disabled?: boolean;
|
|
3118
|
+
/** Button title/tooltip */
|
|
3119
|
+
title?: string;
|
|
3120
|
+
/** Click handler */
|
|
3121
|
+
onClick?: () => void;
|
|
3122
|
+
/** Button content */
|
|
3123
|
+
children: ReactNode;
|
|
3124
|
+
/** Additional CSS class name */
|
|
3125
|
+
className?: string;
|
|
3126
|
+
/** ARIA label for accessibility */
|
|
3127
|
+
ariaLabel?: string;
|
|
3128
|
+
}
|
|
3129
|
+
/**
|
|
3130
|
+
* Props for toolbar button groups
|
|
3131
|
+
*/
|
|
3132
|
+
interface ToolbarGroupProps {
|
|
3133
|
+
/** Group label for accessibility */
|
|
3134
|
+
label?: string;
|
|
3135
|
+
/** Group content */
|
|
3136
|
+
children: ReactNode;
|
|
3137
|
+
/** Additional CSS class name */
|
|
3138
|
+
className?: string;
|
|
3139
|
+
}
|
|
3140
|
+
/**
|
|
3141
|
+
* Individual toolbar button with shadcn styling
|
|
3142
|
+
*/
|
|
3143
|
+
declare function ToolbarButton({ active, disabled, title, onClick, children, className, ariaLabel, }: ToolbarButtonProps): react__default.JSX.Element;
|
|
3144
|
+
/**
|
|
3145
|
+
* Toolbar button group with modern styling
|
|
3146
|
+
*/
|
|
3147
|
+
declare function ToolbarGroup({ label, children, className }: ToolbarGroupProps): react__default.JSX.Element;
|
|
3148
|
+
/**
|
|
3149
|
+
* Icon-based formatting toolbar — undo/redo, zoom, styles, fonts,
|
|
3150
|
+
* bold/italic/underline, colors, alignment, lists, table/image context, clear formatting.
|
|
3151
|
+
*/
|
|
3152
|
+
declare function Toolbar(explicitProps: ToolbarProps): react__default.JSX.Element;
|
|
3153
|
+
|
|
3154
|
+
/**
|
|
3155
|
+
* TitleBar and sub-components for the Google Docs-style 2-level toolbar.
|
|
3156
|
+
*
|
|
3157
|
+
* - TitleBar: two-row layout (row 1: logo + doc name + right actions, row 2: menu bar)
|
|
3158
|
+
* - Logo: renders custom logo content left-aligned
|
|
3159
|
+
* - DocumentName: editable document name input
|
|
3160
|
+
* - MenuBar: File/Format/Insert menus (auto-wired from EditorToolbarContext)
|
|
3161
|
+
* - TitleBarRight: right-aligned actions slot
|
|
3162
|
+
*/
|
|
3163
|
+
|
|
3164
|
+
interface LogoProps {
|
|
3165
|
+
children: ReactNode;
|
|
3166
|
+
}
|
|
3167
|
+
declare function Logo({ children }: LogoProps): react__default.JSX.Element;
|
|
3168
|
+
interface DocumentNameProps {
|
|
3169
|
+
value: string;
|
|
3170
|
+
onChange?: (value: string) => void;
|
|
3171
|
+
placeholder?: string;
|
|
3172
|
+
editable?: boolean;
|
|
3173
|
+
}
|
|
3174
|
+
declare function DocumentName({ value, onChange, placeholder, editable }: DocumentNameProps): react__default.JSX.Element;
|
|
3175
|
+
interface TitleBarRightProps {
|
|
3176
|
+
children: ReactNode;
|
|
3177
|
+
}
|
|
3178
|
+
declare function TitleBarRight({ children }: TitleBarRightProps): react__default.JSX.Element;
|
|
3179
|
+
declare function MenuBar(): react__default.JSX.Element;
|
|
3180
|
+
interface TitleBarProps {
|
|
3181
|
+
children: ReactNode;
|
|
3182
|
+
}
|
|
3183
|
+
/**
|
|
3184
|
+
* TitleBar layout (Google Docs style):
|
|
3185
|
+
*
|
|
3186
|
+
* ┌──────────┬────────────────────────────┬──────────────────┐
|
|
3187
|
+
* │ │ Document Name │ │
|
|
3188
|
+
* │ Logo │ │ Right Actions │
|
|
3189
|
+
* │ │ File Format Insert │ │
|
|
3190
|
+
* └──────────┴────────────────────────────┴──────────────────┘
|
|
3191
|
+
*
|
|
3192
|
+
* Logo and TitleBarRight span full height. DocumentName + MenuBar
|
|
3193
|
+
* stack vertically in the center column.
|
|
3194
|
+
*/
|
|
3195
|
+
declare function TitleBar({ children }: TitleBarProps): react__default.JSX.Element;
|
|
3196
|
+
|
|
3197
|
+
/**
|
|
3198
|
+
* Floating page indicator shown next to the scrollbar while the user
|
|
3199
|
+
* scrolls a multi-page document. Wrapped so the `{current} of {total}`
|
|
3200
|
+
* template runs through `t()`; `useTranslation()` only works inside
|
|
3201
|
+
* `<LocaleProvider>`, which `DocxEditor`'s own body is not.
|
|
3202
|
+
*/
|
|
3203
|
+
declare function PageIndicator({ currentPage, totalPages, visible, }: {
|
|
3204
|
+
currentPage: number;
|
|
3205
|
+
totalPages: number;
|
|
3206
|
+
visible: boolean;
|
|
3207
|
+
}): react.JSX.Element;
|
|
3208
|
+
|
|
3209
|
+
/**
|
|
3210
|
+
* VerticalRuler Component
|
|
3211
|
+
*
|
|
3212
|
+
* A vertical ruler that displays alongside the document with:
|
|
3213
|
+
* - Page height scale with tick marks
|
|
3214
|
+
* - Top and bottom margin indicators
|
|
3215
|
+
* - Optional dragging to adjust margins
|
|
3216
|
+
* - Support for zoom levels
|
|
3217
|
+
*
|
|
3218
|
+
* Similar to Google Docs' vertical ruler.
|
|
3219
|
+
*/
|
|
3220
|
+
|
|
3221
|
+
interface VerticalRulerProps {
|
|
3222
|
+
/** Section page setup (`Editor.getPageSetup()`), twips throughout */
|
|
3223
|
+
pageSetup?: RulerPageSetup | null;
|
|
3224
|
+
/** Zoom level (1.0 = 100%) */
|
|
3225
|
+
zoom?: number;
|
|
3226
|
+
/** Whether margins can be dragged to adjust */
|
|
3227
|
+
editable?: boolean;
|
|
3228
|
+
/** Callback when top margin changes (in twips) */
|
|
3229
|
+
onTopMarginChange?: (marginTwips: number) => void;
|
|
3230
|
+
/** Callback when bottom margin changes (in twips) */
|
|
3231
|
+
onBottomMarginChange?: (marginTwips: number) => void;
|
|
3232
|
+
/** Fires when a margin drag is released — the moment to commit what the drag previewed. */
|
|
3233
|
+
onMarginDragEnd?: () => void;
|
|
3234
|
+
/** Unit to display (inches or cm) */
|
|
3235
|
+
unit?: 'inch' | 'cm';
|
|
3236
|
+
/** Additional CSS class name */
|
|
3237
|
+
className?: string;
|
|
3238
|
+
/** Additional inline styles */
|
|
3239
|
+
style?: CSSProperties;
|
|
3240
|
+
}
|
|
3241
|
+
declare const RULER_WIDTH = 20;
|
|
3242
|
+
declare function VerticalRuler({ pageSetup, zoom, editable, onTopMarginChange, onBottomMarginChange, onMarginDragEnd, unit, className, style, }: VerticalRulerProps): react__default.ReactElement;
|
|
3243
|
+
|
|
3244
|
+
/**
|
|
3245
|
+
* Re-render the caller whenever the editor commits a change, moves the
|
|
3246
|
+
* selection, or republishes display. Returns a counter that changes on each
|
|
3247
|
+
* such event, so it can also be used as a dependency.
|
|
3248
|
+
*/
|
|
3249
|
+
declare function useEditorSnapshot(editor: Editor | null): number;
|
|
3250
|
+
|
|
3251
|
+
/**
|
|
3252
|
+
* @docx-editor.dev/react
|
|
3253
|
+
*
|
|
3254
|
+
* React adapter for the DOCX editor. A thin renderer over the `Editor`
|
|
3255
|
+
* contract from `@docx-editor.dev/core`: it supplies DOM and paints
|
|
3256
|
+
* the engine's positioned display list, and holds no editing-engine state.
|
|
3257
|
+
*
|
|
3258
|
+
* @packageDocumentation
|
|
3259
|
+
* @public
|
|
3260
|
+
*/
|
|
3261
|
+
declare const VERSION = "0.0.2";
|
|
3262
|
+
|
|
3263
|
+
export { CONTENT_CONTROL_SLOTS, type ContentControlActionProps, type ContentControlInspectorState, type ContentControlLock, type ContentControlPartProps, type ContentControlProps, type ContentControlSlotId, type ContextMenuAnchor, ContextMenuCellVerticalAlignment, type ContextMenuCommandProps, ContextMenuCopy, ContextMenuCut, ContextMenuDelete, ContextMenuDeleteTable, ContextMenuDeleteTableColumn, ContextMenuDeleteTableRow, ContextMenuInsertColumnLeft, ContextMenuInsertColumnRight, ContextMenuInsertRowAbove, ContextMenuInsertRowBelow, ContextMenuItem, type ContextMenuItemProps, ContextMenuPaste, ContextMenuSelectAll, type ContextMenuTableRowProps, DocumentName, DocxEditor, DocxEditorContent, DocxEditorContentControl, type DocxEditorContentControlNamespace, type DocxEditorContentProps, DocxEditorContextMenu, type DocxEditorContextMenuNamespace, type DocxEditorContextMenuProps, DocxEditorDocumentOutline, type DocxEditorDocumentOutlineProps, DocxEditorFontNotice, type DocxEditorFontNoticeProps, DocxEditorHeaderFooterChrome, type DocxEditorHeaderFooterChromeProps, DocxEditorHorizontalRuler, DocxEditorHyperLink, type DocxEditorHyperLinkNamespace, DocxEditorImagePropertiesDialog, type DocxEditorImagePropertiesDialogProps, DocxEditorLoading, type DocxEditorLoadingComponent, type DocxEditorLoadingProps, DocxEditorLoadingSpinner, type DocxEditorLoadingSpinnerProps, DocxEditorMenu, type DocxEditorMenuNamespace, type DocxEditorMenuProps, type DocxEditorNamespace, DocxEditorNavigation, type DocxEditorNavigationNamespace, type DocxEditorNavigationProps, DocxEditorNotesChrome, type DocxEditorNotesChromeProps, DocxEditorPageSetupDialog, type DocxEditorPageSetupDialogProps, type DocxEditorProps, type DocxEditorRef, DocxEditorRoot, type DocxEditorRootProps, type DocxEditorRulerProps, DocxEditorShell, DocxEditorToolbar, type DocxEditorToolbarNamespace, type DocxEditorToolbarProps, DocxEditorVerticalRuler, DocxEditorViewport, type DocxEditorViewportProps, type DocxFontsInput, type DocxFontsSource, type DocxSource, type EditorCaret, type EditorCommandState, type EditorMode, type EditorValueCommandState, type FontFamilyItemProps, type FontFamilyNamespace, type FontFamilyPartProps, type FontFamilyProps, type FontsInput, type HeaderFooterState, HorizontalRuler, type HorizontalRulerProps$1 as HorizontalRulerProps, type HyperLinkActionProps, type HyperLinkPartProps, type HyperLinkProps, type HyperlinkPopupAnchor, type HyperlinkPopupMode, type HyperlinkPopupState, ImageAltText, ImageInsertProvider, ImageInsertTrigger, ImagePropertiesTrigger, ImageWrap, type IndentUpdate, LocaleProvider, Logo, type MenuActionProps, MenuBar, type MenuGroupProps, type MenuId, type MenuItemProps, type MenuPartComponent, type MenuProps, type MenuReportIssueProps, type MenuRowProps, type MenuSeparatorProps, type MenuSubmenuProps, type MenuTableGridProps, NAVIGATION_PANE_GAP, NAVIGATION_PANE_INSET, NAVIGATION_PANE_WIDTH, NavigationClose, NavigationFind, NavigationHeader, NavigationHeadings, type NavigationPartProps, type NavigationShiftInput, NavigationTab, type NavigationTabProps, type NavigationTab$1 as NavigationTabValue, NavigationTabs, NavigationTitle, NavigationToggle, type NormalizedImagePayload, type NotePropertiesState, type OutlineHeading$1 as OutlineHeading, type OutlineHeadingItem, PageIndicator, type PageSetupUpdate, PaginatedDocxEditor, type PaginatedDocxEditorHandle as PaginatedDocxEditorExpose, type PaginatedDocxEditorHandle, type PaginatedDocxEditorProps, PaginatedDocxEditorShell, type PaginatedDocxEditorShellProps, type ParagraphStyleItemProps, type ParagraphStyleNamespace, type ParagraphStyleOption, type ParagraphStylePartProps, type ParagraphStyleProps, RULER_WIDTH, ReviewRailContext, type ReviewRailRegistry, SEARCH_DEBOUNCE_MS, SEARCH_MATCH_LIMIT, Slot, type SlotProps, type TableBorderColorNamespace, type TableBorderStyleNamespace, type TableBorderTargetNamespace, type TableBorderWidthNamespace, type TableCellFillNamespace, type TableChromeItemProps, type TableChromePartComponent, type TableChromePartProps, TitleBar, TitleBarRight, Toolbar, type ToolbarActionProps, type ToolbarAlignmentComponent, ToolbarButton, type ToolbarButtonProps$1 as ToolbarButtonProps, ToolbarGroup, type ToolbarPartComponent, type ToolbarPartProps, type ToolbarProps, type ToolbarSeparatorProps, type ToolbarSlotPartComponent, type ToolbarSlotPartProps, type ToolbarTranslate, type UseContentControlResult, type UseDocumentOutlineResult, type UseDocumentSearchResult, type UseDocxSourceOptions, type UseDocxSourceResult, type UseFontFamilyResult, type UseHyperlinkPopupResult, type UseNavigationPaneOptions, type UseNavigationPaneResult, type UsePageSetupReturn, type UseParagraphIndentReturn, type UseParagraphStyleResult, VERSION, VerticalRuler, type VerticalRulerProps, navigationPaneReservation, navigationShift, normalizeImageBytes, useContentControl, useContentControlInstance, useContextMenuTarget, useDocumentOutline, useDocumentSearch, useDocxEditor, useDocxSource, useEditorCaret, useEditorCommand, useEditorEvent, useEditorSnapshot, useEditorState, useEditorValueCommand, useFontFamily, useFonts, useHeaderFooterState, useHyperlinkPopup, useHyperlinkPopupInstance, useNavigationPane, useNavigationShift, useNotePropertiesState, useNoteScopeState, usePageSetup, useParagraphIndent, useParagraphStyle, useTableBorderTargetLabel, useTranslation };
|