@docx-editor.dev/pro 0.0.1-placeholder → 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.
@@ -0,0 +1,592 @@
1
+ import { C as CustomNodeDefinition, A as ActivatedCustomNode } from '../define-custom-node-CkkDPdB0.cjs';
2
+ export { P as ProLicenseOptions, b as ReviewModuleOptions, e as reviewModule } from '../define-custom-node-CkkDPdB0.cjs';
3
+ import * as react from 'react';
4
+ import { ReactNode } from 'react';
5
+ import { ToolbarTranslate } from '@docx-editor.dev/react';
6
+ import { ReviewItemPlacement, ReviewItemQuery, Editor } from '@docx-editor.dev/core/contracts/editor';
7
+ import '@docx-editor.dev/core/editor';
8
+ import '@docx-editor.dev/core/store';
9
+
10
+ /**
11
+ * One card's data plus where it belongs on screen.
12
+ *
13
+ * The engine's own placement, unchanged. It is already presentation-ready — author,
14
+ * initials, date, text, thread — because deriving those from the canonical tree is engine
15
+ * work, and an adapter deriving them would be document derivation in a host and would have
16
+ * to be written once per framework.
17
+ */
18
+ type ReviewItemView = ReviewItemPlacement;
19
+ /**
20
+ * What {@link useReview} returns: the review rail's data and the four things a card can do.
21
+ *
22
+ * @public
23
+ */
24
+ interface UseReviewReturn {
25
+ /** Every pending decision in the document, in reading order. */
26
+ readonly items: readonly ReviewItemView[];
27
+ /** The item the caret is in, or null. */
28
+ readonly activeKey: string | null;
29
+ /** Card to document: selects the item's range and scrolls to it. */
30
+ readonly setActive: (key: string | null) => void;
31
+ /** Accept a revision. A no-op on an item whose `readOnly` is true. */
32
+ readonly accept: (item: ReviewItemView) => void;
33
+ /** Reject a revision. A no-op on an item whose `readOnly` is true. */
34
+ readonly reject: (item: ReviewItemView) => void;
35
+ /**
36
+ * Discard the item: delete a comment thread, or reject a tracked change.
37
+ *
38
+ * One verb for both, so a card can carry one "remove this" control whatever it holds.
39
+ * Reports whether it landed — a comment the engine refused to delete must not vanish from
40
+ * the caller's own state while the document still holds it.
41
+ */
42
+ readonly remove: (item: ReviewItemView) => boolean;
43
+ /**
44
+ * Reply to a comment, or to a revision — which OOXML records as a comment on its range.
45
+ *
46
+ * The author is AMBIENT (`DocxEditorConfig.author`); pass one to override it for a single
47
+ * reply. `CT_Comment` makes `@w:author` required, so the engine refuses a reply with
48
+ * neither rather than writing an empty attribute — which is why this REPORTS whether the
49
+ * reply landed. A box that cleared itself on a refusal would throw the text away and show
50
+ * nothing, and the writer would not learn their reply never existed.
51
+ */
52
+ readonly reply: (item: ReviewItemView, text: string, author?: string) => boolean;
53
+ /**
54
+ * Where a comment on the current selection would sit, or null when nothing is selected.
55
+ *
56
+ * From the engine, not from the DOM — the same rule the card anchors follow.
57
+ */
58
+ readonly selectionAnchorY: number | null;
59
+ /** Comment on the current selection. Reports whether it landed, like {@link reply}. */
60
+ readonly comment: (text: string, author?: string) => boolean;
61
+ /** Whether the pane shows cards. Engine state: the toolbar's comments button toggles it. */
62
+ readonly paneOpen: boolean;
63
+ /** Open or close the pane — the same toggle the toolbar button runs. */
64
+ readonly setPaneOpen: (open: boolean) => void;
65
+ /** True while the engine has no document, so a surface can render nothing rather than empty. */
66
+ readonly ready: boolean;
67
+ }
68
+ /**
69
+ * Read the review queue and act on it.
70
+ *
71
+ * Subscribes to the editor's own change stream, so the list re-derives when the document does
72
+ * and not on every render.
73
+ */
74
+ declare function useReview(query?: ReviewItemQuery): UseReviewReturn;
75
+ /** The same hook against an explicit editor, for hosts that hold their own. */
76
+ declare function useReviewOf(editor: Editor | null, query?: ReviewItemQuery): UseReviewReturn;
77
+ /**
78
+ * Non-overlapping Y positions for cards you have measured.
79
+ *
80
+ * Separate from `useReview` because only the CALLER knows how tall its cards are — a host
81
+ * rendering its own markup can be told where each anchor is, but not how much room its card
82
+ * needs. Pass the measured heights back and get positions that do not collide; skip it
83
+ * entirely and cards sit on their raw anchors, which is correct for a rail that does not stack.
84
+ *
85
+ * Takes anything with a key and an anchor, not only cards: a compose box competes for the
86
+ * same column and has to be stacked WITH them or it lands on top of the card whose text was
87
+ * just re-selected. Entries must arrive in document order — the run is a single sweep.
88
+ *
89
+ * UNITS. Anchors are in layout POINTS, because that is what the engine publishes; measured
90
+ * heights are in CSS PIXELS, because that is what the DOM reports. Pass `scale` so the two
91
+ * can be added. Without it a 330px card advanced the run by 330 POINTS — 440px — and two
92
+ * comments on adjacent lines of one paragraph sat a third of a page apart.
93
+ */
94
+ declare function useStackedReviewPositions(items: readonly {
95
+ readonly key: string;
96
+ readonly anchorY: number | null;
97
+ }[], heights: ReadonlyMap<string, number>, options?: {
98
+ readonly gap?: number;
99
+ readonly scale?: number;
100
+ readonly defaultHeight?: number;
101
+ }): ReadonlyMap<string, number>;
102
+
103
+ /**
104
+ * The review item the surrounding card (or balloon) renders, or null outside one.
105
+ *
106
+ * The hook a host's own card content is built from: children passed into the rail's cards
107
+ * — extra actions, a custom body — read the CURRENT item here rather than receiving props,
108
+ * exactly the way the packaged parts do.
109
+ *
110
+ * @public
111
+ */
112
+ declare function useReviewItem(): ReviewItemView | null;
113
+ /** Shared props for every part. @public */
114
+ interface ReviewPartProps {
115
+ className?: string;
116
+ /** Merge this part's wiring onto the single child element instead of the default one. */
117
+ asChild?: boolean;
118
+ /** Render nothing — inside the packaged arrangement this removes the part. */
119
+ hidden?: boolean;
120
+ children?: ReactNode;
121
+ }
122
+ /** Props for the action parts, which also take an icon. @public */
123
+ interface ReviewActionProps extends ReviewPartProps {
124
+ /** Icon override; falls back to `children`, then to the part's default glyph. */
125
+ icon?: ReactNode;
126
+ }
127
+ /** Props for `DocxEditor.Review`. @public */
128
+ interface ReviewProps extends Omit<ReviewPartProps, 'children'> {
129
+ /**
130
+ * Label resolver, as `DocxEditor.Toolbar`, `.Menu` and `.ContextMenu` take one. Unresolved
131
+ * keys fall back to the bundled catalogue rather than to the key.
132
+ */
133
+ t?: ToolbarTranslate;
134
+ /** Class for each card. The rail's own `className` styles the column; this the boxes in it. */
135
+ card?: {
136
+ className?: string;
137
+ };
138
+ /**
139
+ * The cards, or a render prop that replaces the packaged card entirely while keeping the
140
+ * rail's subscription, anchoring, stacking and virtualization. Nodes are treated as part
141
+ * overrides for the packaged card instead.
142
+ *
143
+ * ```tsx
144
+ * <DocxEditor.Review>{(item) => <MyCard item={item} />}</DocxEditor.Review>
145
+ * ```
146
+ */
147
+ children?: ReactNode | ((item: ReviewItemView) => ReactNode);
148
+ /**
149
+ * Host content at the top of the rail, above the cards — filters, legends, summaries.
150
+ *
151
+ * Rendered only while the pane is OPEN. A closed rail gives up its width for a 32px strip
152
+ * of markers, and content laid out for the 300px column has nowhere to go in it; unmounting
153
+ * is the rail's own business, not something a host should have to subscribe to `paneOpen`
154
+ * to discover. Furniture that should outlive the toggle belongs outside the rail.
155
+ */
156
+ furniture?: ReactNode;
157
+ /**
158
+ * Render the packaged arrangement. `false` mounts the rail and its context only, so a host
159
+ * can lay the cards out itself while keeping the subscription and the anchoring.
160
+ */
161
+ preset?: boolean;
162
+ /**
163
+ * Stack cards so they never overlap, pushing later ones down. `false` leaves every card on
164
+ * its raw anchor, which is right for a rail that draws connectors instead.
165
+ */
166
+ stack?: boolean;
167
+ /** Gap (px) between stacked cards. The only source of vertical spacing in the rail. */
168
+ gap?: number;
169
+ /** Show only some of the queue — comments in one rail, revisions in another. */
170
+ filter?: (item: ReviewItemView) => boolean;
171
+ /**
172
+ * Show the "changed the document structure" cards. Default `false`: a heavily revised
173
+ * document carries one per structural site and together they crowd out the cards a
174
+ * reviewer can act on. The revisions stay marked in the document, where clicking one
175
+ * opens its balloon — this hides only their rail cards.
176
+ */
177
+ structural?: boolean;
178
+ /**
179
+ * Show the "changed text formatting" cards. Default `false`, same reasoning as
180
+ * {@link structural}: a restyled document mints one per run, and the decision is
181
+ * reachable by clicking the grey-marked text instead. The rail keeps the decisions a
182
+ * reviewer reads in order — content changes and comments.
183
+ */
184
+ formatting?: boolean;
185
+ }
186
+ /**
187
+ * The review rail.
188
+ *
189
+ * Positions absolutely inside the nearest positioned ancestor — put it in
190
+ * `DocxEditor.Viewport` beside `DocxEditor.Content`, which is what makes the cards scroll
191
+ * with the pages without a scroll listener.
192
+ *
193
+ * @public
194
+ */
195
+ declare function ReviewRoot({ className, furniture, asChild, hidden, children, t: hostT, card, preset, stack, gap, filter, structural, formatting, }: ReviewProps): react.JSX.Element | null;
196
+ interface ReviewListProps {
197
+ stack?: boolean;
198
+ positions?: ReadonlyMap<string, number>;
199
+ /** Cards the stacking pass collapsed to a header — pushed too far from their text. */
200
+ collapsed?: ReadonlySet<string>;
201
+ scale?: number;
202
+ offset?: number;
203
+ /** Visible band of the scroller; cards outside it are not mounted. Null renders all. */
204
+ window?: {
205
+ top: number;
206
+ bottom: number;
207
+ } | null;
208
+ /**
209
+ * A render prop takes over the card entirely, keeping the rail's subscription, anchoring
210
+ * and stacking. Nodes are treated as part overrides for the packaged card.
211
+ */
212
+ children?: ReactNode | ((item: ReviewItemView) => ReactNode);
213
+ className?: string;
214
+ hidden?: boolean;
215
+ }
216
+ /**
217
+ * The cards, each positioned at its anchor.
218
+ *
219
+ * REPLIES are not cards. A threaded reply belongs inside the comment it answers, and giving
220
+ * it a card of its own would put two entries in the rail for one conversation.
221
+ *
222
+ * @public
223
+ */
224
+ declare function ReviewList({ stack, positions, collapsed, scale, offset, window: visible, children, className, hidden, }: ReviewListProps): react.JSX.Element | null;
225
+ declare namespace ReviewList {
226
+ var docxReviewPart: "List";
227
+ }
228
+ /**
229
+ * The collapsed rail: one marker per item, at its anchor.
230
+ *
231
+ * @public
232
+ */
233
+ declare function ReviewMarkers({ scale, offset, window: visible, className, hidden, }: {
234
+ scale?: number;
235
+ offset?: number;
236
+ /** Visible band of the scroller; markers outside it are not mounted. */
237
+ window?: {
238
+ top: number;
239
+ bottom: number;
240
+ } | null;
241
+ className?: string;
242
+ hidden?: boolean;
243
+ }): react.JSX.Element | null;
244
+ declare namespace ReviewMarkers {
245
+ var docxReviewPart: "Markers";
246
+ }
247
+ /**
248
+ * The "comment on this" button, beside the selected text.
249
+ *
250
+ * Appears only for a RANGE. A comment on a caret has nothing to point at, and Word writes
251
+ * none, so the affordance is absent rather than present-and-refusing.
252
+ *
253
+ * @public
254
+ */
255
+ declare function ReviewAddComment({ top, drafting, className, hidden, children, }: ReviewPartProps & {
256
+ top: number | null;
257
+ drafting?: boolean;
258
+ }): react.JSX.Element | null;
259
+ declare namespace ReviewAddComment {
260
+ var docxReviewPart: "AddComment";
261
+ }
262
+ /**
263
+ * The compose box for a new comment.
264
+ *
265
+ * Nothing is written until it is submitted: an empty `w:comment` is a real comment in the
266
+ * file, and committing on open would leave one behind every time somebody changed their mind.
267
+ *
268
+ * @public
269
+ */
270
+ declare function ReviewDraft({ top, className, hidden }: ReviewPartProps & {
271
+ top: number;
272
+ }): react.JSX.Element | null;
273
+ declare namespace ReviewDraft {
274
+ var docxReviewPart: "Draft";
275
+ }
276
+ /**
277
+ * The decision balloon: CLICKING a format or structural change in the PAGE opens its card
278
+ * beside the text — author, what changed, when, and accept/reject where the engine can
279
+ * resolve it — and the card stays until a press lands somewhere that is neither a tracked
280
+ * change nor the balloon itself. Click-opened on purpose: a hover-opened card vanished
281
+ * under the pointer travelling toward its own buttons.
282
+ *
283
+ * ONLY the kinds whose rail cards are hidden by default. Content changes and comments are
284
+ * the rail's — a balloon over "added" text repeats a card already beside the page — while
285
+ * a format or structural change has nothing but its grey/washed marking, so the click on
286
+ * that marking is where its decision lives.
287
+ *
288
+ * Matches the pressed element against the UNFILTERED queue, attribution first and POSITION
289
+ * last: the `(id, author, date)` triple, then `(id, author)`, then the id, then the span's
290
+ * own paragraph range against the items' ranges — real files drift on attribution, and the
291
+ * range is the one thing the painter and the review model cannot disagree about. An
292
+ * element matching nothing still shows what its DOM carries, just without actions.
293
+ *
294
+ * @public
295
+ */
296
+ declare function ReviewBalloon({ className, hidden }: ReviewPartProps): react.JSX.Element | null;
297
+ declare namespace ReviewBalloon {
298
+ var docxReviewPart: "Balloon";
299
+ }
300
+ /** Shown when nothing is pending. @public */
301
+ declare function ReviewEmpty({ className, hidden, children }: ReviewPartProps): react.JSX.Element | null;
302
+ declare namespace ReviewEmpty {
303
+ var docxReviewPart: "Empty";
304
+ }
305
+ /**
306
+ * One card.
307
+ *
308
+ * Clicking it makes the item active, which SELECTS ITS RANGE in the document — the card and
309
+ * the text it is about are two views of one thing, and a card that highlighted nothing left
310
+ * the reader hunting for which words a comment meant.
311
+ *
312
+ * @public
313
+ */
314
+ declare function ReviewCard({ className, asChild, hidden, children }: ReviewPartProps): react.JSX.Element | null;
315
+ declare namespace ReviewCard {
316
+ var docxReviewPart: "Card";
317
+ }
318
+ /** The author's initials, in their colour. @public */
319
+ declare function ReviewAvatar({ className, asChild, hidden, children }: ReviewPartProps): react.JSX.Element | null;
320
+ declare namespace ReviewAvatar {
321
+ var docxReviewPart: "Avatar";
322
+ }
323
+ /** The author's name. @public */
324
+ declare function ReviewAuthor({ className, asChild, hidden, children }: ReviewPartProps): react.JSX.Element | null;
325
+ declare namespace ReviewAuthor {
326
+ var docxReviewPart: "Author";
327
+ }
328
+ /**
329
+ * When the change was made.
330
+ *
331
+ * `@w:date` is optional in `CT_TrackChange` and Word omits it when the author turned off
332
+ * "store randomized IDs"/date stamping, so a missing date renders nothing rather than an
333
+ * "Invalid Date".
334
+ *
335
+ * @public
336
+ */
337
+ declare function ReviewTime({ className, asChild, hidden, children }: ReviewPartProps): react.JSX.Element | null;
338
+ declare namespace ReviewTime {
339
+ var docxReviewPart: "Time";
340
+ }
341
+ /**
342
+ * What the card is about: the comment's text, or what the revision did.
343
+ *
344
+ * A revision that carries no characters — a formatting change, a paragraph mark, a row
345
+ * insertion — still gets a sentence. Word shows one, and a card reading only "Ada Lovelace"
346
+ * tells the reviewer nothing they can decide on.
347
+ *
348
+ * @public
349
+ */
350
+ declare function ReviewSummary({ className, asChild, hidden, children }: ReviewPartProps): react.JSX.Element | null;
351
+ declare namespace ReviewSummary {
352
+ var docxReviewPart: "Summary";
353
+ }
354
+ /** Accept the revision behind this card. @public */
355
+ declare function ReviewAccept({ className, asChild, hidden, children, icon: glyph }: ReviewActionProps): react.JSX.Element | null;
356
+ declare namespace ReviewAccept {
357
+ var docxReviewPart: "Accept";
358
+ }
359
+ /** Reject the revision behind this card. @public */
360
+ declare function ReviewReject({ className, asChild, hidden, children, icon: glyph }: ReviewActionProps): react.JSX.Element | null;
361
+ declare namespace ReviewReject {
362
+ var docxReviewPart: "Reject";
363
+ }
364
+ /**
365
+ * Discard what the card holds: delete a comment thread, or reject a tracked change.
366
+ *
367
+ * The rail had accept and reject for a change and NOTHING for a comment, so a remark could be
368
+ * resolved but never removed — a reader who commented by mistake had to go back to the text and
369
+ * delete the words to be rid of it. One control on both kinds, because "remove this" is the same
370
+ * intent whichever the card holds; the engine's `deleteReviewItem` decides what it means.
371
+ *
372
+ * Absent, not disabled, on a card with nothing to discard — a custom node's, or a revision kind
373
+ * the engine cannot resolve.
374
+ *
375
+ * Revealed on HOVER of the one thing it deletes, and on keyboard focus — the stylesheet owns
376
+ * that, not this component. A rail of twenty cards each carrying a standing invitation to
377
+ * delete somebody's remark reads as an invitation to click one by mistake; scoping it to the
378
+ * node under the pointer also means a reply and the comment it answers never offer two
379
+ * identical buttons at once, which is the state that makes a reader delete the wrong one.
380
+ *
381
+ * CSS rather than an `isActive` gate because a reply is never itself the active item, and
382
+ * because requiring the reader to open a card before they can be rid of it is a step with
383
+ * nothing behind it. `visibility`, not `opacity`: hidden must also mean unclickable, and the
384
+ * space stays reserved so the row does not jump as the pointer crosses it.
385
+ *
386
+ * @public
387
+ */
388
+ declare function ReviewDelete({ className, asChild, hidden, children, icon: glyph }: ReviewActionProps): react.JSX.Element | null;
389
+ declare namespace ReviewDelete {
390
+ var docxReviewPart: "Delete";
391
+ }
392
+ /** The thread under a comment, in document order. @public */
393
+ declare function ReviewReplies({ className, hidden }: ReviewPartProps): react.JSX.Element | null;
394
+ declare namespace ReviewReplies {
395
+ var docxReviewPart: "Replies";
396
+ }
397
+ /**
398
+ * The reply box.
399
+ *
400
+ * Open only on the ACTIVE card: a rail with a text field on every card is mostly text fields,
401
+ * and the caret landing in a tracked change is what says which conversation the reader is in.
402
+ *
403
+ * Replying to a revision writes a comment over that revision's range — `w:ins` and `w:del`
404
+ * have no body and no thread in OOXML, so there is nowhere else for the text to live.
405
+ *
406
+ * @public
407
+ */
408
+ declare function ReviewReply({ className, hidden, children }: ReviewPartProps): react.JSX.Element | null;
409
+ declare namespace ReviewReply {
410
+ var docxReviewPart: "Reply";
411
+ }
412
+ /**
413
+ * The review rail compound.
414
+ *
415
+ * @public
416
+ */
417
+ interface DocxEditorReviewNamespace {
418
+ (props: ReviewProps): ReturnType<typeof ReviewRoot>;
419
+ readonly List: typeof ReviewList;
420
+ readonly Empty: typeof ReviewEmpty;
421
+ readonly Card: typeof ReviewCard;
422
+ readonly Avatar: typeof ReviewAvatar;
423
+ readonly Author: typeof ReviewAuthor;
424
+ readonly Time: typeof ReviewTime;
425
+ readonly Summary: typeof ReviewSummary;
426
+ readonly Accept: typeof ReviewAccept;
427
+ readonly Reject: typeof ReviewReject;
428
+ /** Discard the card: delete a comment thread, or reject a tracked change. */
429
+ readonly Delete: typeof ReviewDelete;
430
+ readonly Replies: typeof ReviewReplies;
431
+ readonly Reply: typeof ReviewReply;
432
+ /** The collapsed rail: one marker per item, shown when the pane is closed. */
433
+ readonly Markers: typeof ReviewMarkers;
434
+ /** The "comment on this" button beside a selected range. */
435
+ readonly AddComment: typeof ReviewAddComment;
436
+ /** The compose box a new comment is written in. */
437
+ readonly Draft: typeof ReviewDraft;
438
+ /** The decision balloon opened by clicking a format or structural change in the page. */
439
+ readonly Balloon: typeof ReviewBalloon;
440
+ }
441
+ /**
442
+ * The review rail: comments and tracked changes as a compound component.
443
+ *
444
+ * `DocxEditorReview` is itself the root; every part hangs off it, so a host arranges the pieces
445
+ * it wants rather than accepting one fixed layout. Requires the review module to be registered
446
+ * via `createDocxEditor({ modules: [reviewModule()] })` — without it there is nothing to derive
447
+ * cards from.
448
+ *
449
+ * @example
450
+ * ```tsx
451
+ * <DocxEditorReview>
452
+ * <DocxEditorReview.List>
453
+ * <DocxEditorReview.Card>
454
+ * <DocxEditorReview.Author />
455
+ * <DocxEditorReview.Summary />
456
+ * <DocxEditorReview.Accept />
457
+ * <DocxEditorReview.Reject />
458
+ * </DocxEditorReview.Card>
459
+ * </DocxEditorReview.List>
460
+ * </DocxEditorReview>
461
+ * ```
462
+ *
463
+ * @public
464
+ */
465
+ declare const DocxEditorReview: DocxEditorReviewNamespace;
466
+
467
+ /**
468
+ * Props for {@link CustomNodeChrome}: which definitions to paint, and where activation goes.
469
+ *
470
+ * The two hooks are the COMPONENT-level twins of a definition's own `onClick`/`onHover`. Host UI
471
+ * state — a popover, a dialog — belongs here rather than on the definition, which is shared by
472
+ * every surface and has no React context to close over.
473
+ *
474
+ * @public
475
+ */
476
+ interface CustomNodeChromeProps {
477
+ /** Definitions to style and dispatch on. Defaults to the ones registered on the editor. */
478
+ readonly nodes?: readonly CustomNodeDefinition[];
479
+ /** Component-level activation hook — where host UI state (popovers) belongs. */
480
+ readonly onNodeClick?: (node: ActivatedCustomNode) => void;
481
+ readonly onNodeHover?: (node: ActivatedCustomNode) => void;
482
+ }
483
+ /**
484
+ * Paints custom-node chips and dispatches pointer activation on them.
485
+ *
486
+ * Renders nothing itself — it installs the per-definition chip styles and the click/hover
487
+ * listeners, so mount it once anywhere inside the editor provider. Chip colours come from each
488
+ * definition's `chrome`, which is HOST-authored and never file data.
489
+ *
490
+ * @example
491
+ * ```tsx
492
+ * <DocxEditor.Root>
493
+ * <CustomNodeChrome onNodeClick={(node) => setPopover(node)} />
494
+ * <DocxEditor.Viewport><DocxEditor.Content /></DocxEditor.Viewport>
495
+ * </DocxEditor.Root>
496
+ * ```
497
+ *
498
+ * @public
499
+ */
500
+ declare function CustomNodeChrome(props: CustomNodeChromeProps): null;
501
+
502
+ /**
503
+ * Props for {@link CustomNodeContextMenu}: which definitions get menu sections, and which rows
504
+ * those sections offer.
505
+ *
506
+ * The Edit row renders when either the definition's own `onEdit` or this component's
507
+ * `onEditNode` is present; the Remove row is on by default but only where the node's canonical id
508
+ * can be resolved.
509
+ *
510
+ * @public
511
+ */
512
+ interface CustomNodeContextMenuProps {
513
+ /** Definitions to offer sections for. Defaults to the ones registered on the editor. */
514
+ readonly nodes?: readonly CustomNodeDefinition[];
515
+ /**
516
+ * Component-level edit hook — where host UI state (an edit dialog) belongs, the twin of
517
+ * `CustomNodeChrome`'s `onNodeClick`. Runs after the definition's own `onEdit`. The row
518
+ * renders when EITHER hook is present.
519
+ */
520
+ readonly onEditNode?: (node: ActivatedCustomNode, definition: CustomNodeDefinition) => void;
521
+ /**
522
+ * The "Remove {label}" row, on by default: it deletes the node — wrapper and label, one
523
+ * undo step — via `removeCustomNode`. Rendered only when the node's id is resolvable
524
+ * (a registered review module resolves it). `false` removes the row.
525
+ */
526
+ readonly remove?: boolean;
527
+ }
528
+ /**
529
+ * Renders the pointed-at node's card data plus its "Edit {label}" row, or nothing when the
530
+ * right-click landed elsewhere. Carries `docxRowPlacement: 'start'`, so the context menu
531
+ * mounts it above the packaged rows.
532
+ *
533
+ * @public
534
+ */
535
+ declare function CustomNodeContextMenu(props: CustomNodeContextMenuProps): react.JSX.Element | null;
536
+ declare namespace CustomNodeContextMenu {
537
+ var docxRowPlacement: "start";
538
+ }
539
+
540
+ /**
541
+ * The definitions a chrome surface should act on: the `nodes` prop when given, else the
542
+ * definitions registered on the editor (`customNodesModule`). Registering once and letting
543
+ * every surface default to it is the intended shape; the prop exists for a host that wants
544
+ * one surface scoped narrower.
545
+ */
546
+ declare function useCustomNodeDefinitions(nodes: readonly CustomNodeDefinition[] | undefined): readonly CustomNodeDefinition[];
547
+ /**
548
+ * What {@link resolveCustomNodeActivation} found under a pointer target.
549
+ *
550
+ * The RAW decode, before the definition's `fromDocx` has had its say — use
551
+ * `activatedCustomNodeOf` for the enriched form every host hook receives.
552
+ *
553
+ * @public
554
+ */
555
+ interface ResolvedCustomNodeActivation {
556
+ /** RAW decode: attrs straight from the tag, `fromDocx` not yet applied. */
557
+ readonly node: ActivatedCustomNode;
558
+ readonly definition: CustomNodeDefinition;
559
+ /** The control's canonical node id, from the chrome layer — for review-item lookups. */
560
+ readonly controlId: string | null;
561
+ }
562
+ /**
563
+ * The recognized custom node a pointer target sits on, or null.
564
+ *
565
+ * Every input here is DOM the engine painted from file data — the tag is
566
+ * attacker-controlled and goes through the codec's guards, never into markup.
567
+ */
568
+ /**
569
+ * The activation every host hook receives: identity, POST-`fromDocx` attrs, and — when the
570
+ * review module derived a card for the node — its literal text and canonical node id.
571
+ *
572
+ * One enrichment step for every surface (click, hover, edit, context-menu card), so a hook
573
+ * written against the review rail's attrs shape sees the SAME shape from the chip. Without
574
+ * a review module the definition's `fromDocx` runs over the raw decode with `text: ''`;
575
+ * its veto (null) drops the activation, exactly as recognition would have.
576
+ */
577
+ declare function activatedCustomNodeOf(resolved: ResolvedCustomNodeActivation, editor: Editor | null | undefined): ActivatedCustomNode | null;
578
+ /**
579
+ * The recognized custom node a pointer target sits on, or null.
580
+ *
581
+ * Walks up from `target` to the painted control boundary, reads its `data-tag`, and matches the
582
+ * decoded identity against `nodes`. Returns null for anything that is not a recognized chip —
583
+ * ordinary text, an unclaimed SDT, a tag no definition owns.
584
+ *
585
+ * Every input is DOM the engine painted from FILE DATA. The tag is attacker-controlled and goes
586
+ * through the codec's guards; it never reaches markup.
587
+ *
588
+ * @public
589
+ */
590
+ declare function resolveCustomNodeActivation(target: EventTarget | null, nodes: readonly CustomNodeDefinition[]): ResolvedCustomNodeActivation | null;
591
+
592
+ export { CustomNodeChrome, type CustomNodeChromeProps, CustomNodeContextMenu, type CustomNodeContextMenuProps, DocxEditorReview, type DocxEditorReviewNamespace, type ResolvedCustomNodeActivation, type ReviewActionProps, type ReviewItemView, type ReviewPartProps, type ReviewProps, type UseReviewReturn, activatedCustomNodeOf, resolveCustomNodeActivation, useCustomNodeDefinitions, useReview, useReviewItem, useReviewOf, useStackedReviewPositions };