@docx-editor.dev/pro/react
@docx-editor.dev/pro/react — React chrome for the review rail and custom nodes.
Compound components over the pro modules: arrange the parts you want rather than accepting one fixed layout. Requires the matching module to be registered on the editor — without it there is nothing to derive cards or chips from.
Functions (10)
activatedCustomNodeOffunctionSource ↗
The activation every host hook receives: identity, POST-fromDocx attrs, and — when the review module derived a card for the node — its literal text and canonical node id.
One enrichment step for every surface (click, hover, edit, context-menu card), so a hook written against the review rail's attrs shape sees the SAME shape from the chip. Without a review module the definition's fromDocx runs over the raw decode with text: ''; its veto (null) drops the activation, exactly as recognition would have.
declare function activatedCustomNodeOf(resolved: ResolvedCustomNodeActivation, editor: Editor | null | undefined): ActivatedCustomNode | null;CustomNodeChromefunctionSource ↗
Paints custom-node chips and dispatches pointer activation on them.
Renders nothing itself — it installs the chip styles and the activation listeners, so mount it once anywhere inside the editor provider. Chip colours come from each definition's chrome, which is host-authored and never file data.
declare function CustomNodeChrome(props: CustomNodeChromeProps): null;```tsx
<DocxEditor.Root>
<CustomNodeChrome onNodeClick={(node) => setPopover(node)} />
<DocxEditor.Viewport><DocxEditor.Content /></DocxEditor.Viewport>
</DocxEditor.Root>
```CustomNodeContextMenufunctionSource ↗
Renders the pointed-at node's card data plus its "Edit label" row, or nothing when the right-click landed elsewhere. Carries docxRowPlacement: 'start', so the context menu mounts it above the packaged rows.
declare function CustomNodeContextMenu(props: CustomNodeContextMenuProps): react.JSX.Element | null;resolveCustomNodeActivationfunctionSource ↗
The recognized custom node a pointer target sits on, or null.
Walks up from target to the painted control boundary, reads its data-tag, and matches the decoded identity against nodes. Returns null for anything that is not a recognized chip — ordinary text, an unclaimed SDT, a tag no definition owns.
Every input is DOM the engine painted from FILE DATA. The tag is attacker-controlled and goes through the codec's guards; it never reaches markup.
declare function resolveCustomNodeActivation(target: EventTarget | null, nodes: readonly AnyCustomNodeDefinition[]): ResolvedCustomNodeActivation | null;reviewModulefunctionSource ↗
Build the review module. Construction never validates the key and never touches the network.
declare function reviewModule(options?: ReviewModuleOptions): EditorModule;useCustomNodeDefinitionsfunctionSource ↗
The definitions a chrome surface should act on: the nodes prop when given, else the definitions registered on the editor (customNodesModule). Registering once and letting every surface default to it is the intended shape; the prop exists for a host that wants one surface scoped narrower.
declare function useCustomNodeDefinitions(nodes: readonly AnyCustomNodeDefinition[] | undefined): readonly AnyCustomNodeDefinition[];useReviewfunctionSource ↗
Read the review queue and act on it.
Subscribes to the editor's own change stream, so the list re-derives when the document does and not on every render.
declare function useReview(query?: ReviewItemQuery): UseReviewReturn;useReviewItemfunctionSource ↗
The review item the surrounding card (or balloon) renders, or null outside one.
The hook a host's own card content is built from: children passed into the rail's cards — extra actions, a custom body — read the CURRENT item here rather than receiving props, exactly the way the packaged parts do.
declare function useReviewItem(): ReviewItemView | null;useReviewOffunctionSource ↗
The same hook against an explicit editor, for hosts that hold their own.
declare function useReviewOf(editor: Editor | null, query?: ReviewItemQuery): UseReviewReturn;useStackedReviewPositionsfunctionSource ↗
Non-overlapping Y positions for cards you have measured.
Separate from useReview because only the CALLER knows how tall its cards are — a host rendering its own markup can be told where each anchor is, but not how much room its card needs. Pass the measured heights back and get positions that do not collide; skip it entirely and cards sit on their raw anchors, which is correct for a rail that does not stack.
Takes anything with a key and an anchor, not only cards: a compose box competes for the same column and has to be stacked WITH them or it lands on top of the card whose text was just re-selected. Entries must arrive in document order — the run is a single sweep.
UNITS. Anchors are in layout POINTS, because that is what the engine publishes; measured heights are in CSS PIXELS, because that is what the DOM reports. Pass scale so the two can be added. Without it a 330px card advanced the run by 330 POINTS — 440px — and two comments on adjacent lines of one paragraph sat a third of a page apart.
declare function useStackedReviewPositions(items: readonly {
readonly key: string;
readonly anchorY: number | null;
}[], heights: ReadonlyMap<string, number>, options?: {
readonly gap?: number;
readonly scale?: number;
readonly defaultHeight?: number;
}): ReadonlyMap<string, number>;Interfaces (12)
CustomNodeChromePropsinterfaceSource ↗
Props for [CustomNodeChrome](CustomNodeChrome): which definitions to paint, and where activation goes.
The two hooks are the component-level twins of a definition's own onClick/onHover. Host UI state belongs here rather than on the definition, which every surface shares and which has no React context to close over.
interface CustomNodeChromeProps| Member | Type | Summary |
|---|---|---|
| nodes? | readonly CustomNodeDefinition[] | Definitions to style and dispatch on. Defaults to the ones registered on the editor. |
| onNodeClick? | (node: ActivatedCustomNode) => void | Component-level activation hook — where host UI state (popovers) belongs. |
| onNodeHover? | (node: ActivatedCustomNode) => void |
CustomNodeContextMenuPropsinterfaceSource ↗
Props for [CustomNodeContextMenu](CustomNodeContextMenu): which definitions get menu sections, and which rows those sections offer.
The Edit row renders when either the definition's own onEdit or this component's onEditNode is present; the Remove row is on by default but only where the node's canonical id can be resolved.
interface CustomNodeContextMenuProps| Member | Type | Summary |
|---|---|---|
| nodes? | readonly CustomNodeDefinition[] | Definitions to offer sections for. Defaults to the ones registered on the editor. |
| onEditNode? | (node: ActivatedCustomNode, definition: CustomNodeDefinition) => void | Component-level edit hook — where host UI state (an edit dialog) belongs, the twin of `CustomNodeChrome`'s `onNodeClick`. Runs after the definition's own `onEdit`. The row renders when EITHER hook is present. |
| onRemoveRefused? | (node: ActivatedCustomNode, reason: string) => void | Called when Remove was refused, with the engine's own reason. |
| remove? | boolean | The "Remove label" row, on by default: it deletes the node — wrapper and label, one undo step — via `removeCustomNode`. Rendered only when the node's id is resolvable (a registered review module resolves it). `false` removes the row. |
DocxEditorReviewNamespaceinterfaceSource ↗
The review rail compound.
interface DocxEditorReviewNamespace| Member | Type | Summary |
|---|---|---|
| (member-0) | | |
| Accept | typeof ReviewAccept | |
| AddComment | typeof ReviewAddComment | The "comment on this" button beside a selected range. |
| Author | typeof ReviewAuthor | |
| Avatar | typeof ReviewAvatar | |
| Balloon | typeof ReviewBalloon | The decision balloon opened by clicking a format or structural change in the page. |
| Card | typeof ReviewCard | |
| Delete | typeof ReviewDelete | Discard the card: delete a comment thread, or reject a tracked change. |
| Draft | typeof ReviewDraft | The compose box a new comment is written in. |
| Empty | typeof ReviewEmpty | |
| List | typeof ReviewList | |
| Markers | typeof ReviewMarkers | The collapsed rail: one marker per item, shown when the pane is closed. |
| Reject | typeof ReviewReject | |
| Replies | typeof ReviewReplies | |
| Reply | typeof ReviewReply | |
| Summary | typeof ReviewSummary | |
| Time | typeof ReviewTime |
ProLicenseOptionsinterfaceSource ↗
Accepted by every pro entry point.
interface ProLicenseOptions| Member | Type | Summary |
|---|---|---|
| licenseKey? | string | Your license key from docx-editor.dev. Optional in v1: unlicensed use in development and evaluation is permitted, production use requires a license (see LICENSE.md) — the package trusts you either way. |
ResolvedCustomNodeActivationinterfaceSource ↗
What [resolveCustomNodeActivation](resolveCustomNodeActivation) found under a pointer target.
The RAW decode, before the definition's fromDocx has had its say — use activatedCustomNodeOf for the enriched form every host hook receives.
interface ResolvedCustomNodeActivation| Member | Type | Summary |
|---|---|---|
| controlId | string | null | The control's canonical node id, from the chrome layer — for review-item lookups. |
| definition | AnyCustomNodeDefinition | |
| node | ActivatedCustomNode | RAW decode: attrs straight from the tag, `fromDocx` not yet applied. |
ReviewActionPropsinterfaceSource ↗
Props for the action parts, which also take an icon.
interface ReviewActionProps extends ReviewPartProps| Member | Type | Summary |
|---|---|---|
| icon? | ReactNode | Icon override; falls back to `children`, then to the part's default glyph. |
ReviewActivationOptionsinterface
How activating a review item places it in the viewport.
interface ReviewActivationOptions| Member | Type | Summary |
|---|---|---|
| reveal? | 'start' | 'center' | 'centerIfNeeded' | 'nearest' | false | Where the item lands, or `false` to select it without scrolling at all. |
ReviewMarkersPropsinterfaceSource ↗
Props for the collapsed rail's gutter markers.
scale, offset and window are the rail's own geometry and are supplied for you — an override inherits them, so a host passes only what it wants to change.
interface ReviewMarkersProps| Member | Type | Summary |
|---|---|---|
| className? | string | |
| icon? | ReactNode | ((item: ReviewItemView) => ReactNode) | Replace the glyph. A FUNCTION of the item, unlike the action parts' plain node, because one `Markers` draws every marker in the gutter — a single node would put one shape on all of them, which is the thing this part was fixed to stop doing. Return null or undefined for an item to keep its packaged glyph. |
| offset? | number | |
| scale? | number | |
| window? | {
top: number;
bottom: number;
} | null | Visible band of the scroller; markers outside it are not mounted. |
ReviewModuleOptionsinterfaceSource ↗
How [reviewModule](reviewModule) is configured. Carries only the licence key today, so reviewModule() with no argument is the ordinary call.
interface ReviewModuleOptions extends ProLicenseOptionsReviewPartPropsinterfaceSource ↗
Shared props for every part.
interface ReviewPartProps| Member | Type | Summary |
|---|---|---|
| asChild? | boolean | Merge this part's wiring onto the single child element instead of the default one. |
| children? | ReactNode | |
| className? | string |
ReviewPropsinterfaceSource ↗
Props for DocxEditor.Review.
interface ReviewProps extends Omit<ReviewPartProps, 'children'>| Member | Type | Summary |
|---|---|---|
| card? | {
className?: string;
} | Class for each card. The rail's own `className` styles the column; this the boxes in it. |
| children? | ReactNode | ((item: ReviewItemView) => ReactNode) | The cards, or a render prop that replaces the packaged card entirely while keeping the rail's subscription, anchoring, stacking and virtualization. Nodes are treated as part overrides for the packaged card instead. |
| filter? | (item: ReviewItemView) => boolean | Show only some of the queue — comments in one rail, revisions in another. |
| formatting? | boolean | Show the "changed text formatting" cards. Default `false`, same reasoning as [structural](structural): a restyled document mints one per run, and the decision is reachable by clicking the grey-marked text instead. The rail keeps the decisions a reviewer reads in order — content changes and comments. |
| furniture? | ReactNode | Host content at the top of the rail, above the cards — filters, legends, summaries. |
| gap? | number | Gap (px) between stacked cards. The only source of vertical spacing in the rail. |
| preset? | boolean | Render the packaged arrangement. `false` mounts the rail and its context only, so a host can lay the cards out itself while keeping the subscription and the anchoring. |
| stack? | boolean | Stack cards so they never overlap, pushing later ones down. `false` leaves every card on its raw anchor, which is right for a rail that draws connectors instead. |
| structural? | boolean | Show the "changed the document structure" cards. Default `false`: a heavily revised document carries one per structural site and together they crowd out the cards a reviewer can act on. The revisions stay marked in the document, where clicking one opens its balloon — this hides only their rail cards. |
| t? | ToolbarTranslate | Label resolver, as `DocxEditor.Toolbar`, `.Menu` and `.ContextMenu` take one. Unresolved keys fall back to the bundled catalogue rather than to the key. |
UseReviewReturninterfaceSource ↗
What [useReview](useReview) returns: the review rail's data and the four things a card can do.
interface UseReviewReturn| Member | Type | Summary |
|---|---|---|
| accept | (item: ReviewItemView) => boolean | Accept a revision. Reports whether it landed. |
| activeKey | string | null | The item the caret is in, or null. |
| comment | (text: string, author?: string) => boolean | Comment on the current selection. Reports whether it landed, like [reply](reply). |
| items | readonly ReviewItemView[] | Every pending decision in the document, in reading order. |
| paneOpen | boolean | Whether the pane shows cards. Engine state: the toolbar's comments button toggles it. |
| ready | boolean | False until the engine has a document, so a surface can render nothing rather than empty. |
| reject | (item: ReviewItemView) => boolean | Reject a revision. Reports whether it landed, on the same terms as [accept](accept). |
| remove | (item: ReviewItemView) => boolean | Discard the item: delete a comment thread, or reject a tracked change. |
| reply | (item: ReviewItemView, text: string, author?: string) => boolean | Reply to a comment, or to a revision — which OOXML records as a comment on its range. |
| selectionAnchorY | number | null | Where a comment on the current selection would sit, or null when nothing is selected. |
| setActive | (key: string | null, options?: ReviewActivationOptions) => boolean | Card to document: selects the item's range and scrolls to it. |
| setPaneOpen | (open: boolean) => void | Open or close the pane — the same toggle the toolbar button runs. |
Type aliases (1)
ReviewItemViewtypeSource ↗
One card's data plus where it belongs on screen.
The engine's own placement, unchanged. It is already presentation-ready — author, initials, date, text, thread — because deriving those from the canonical tree is engine work, and an adapter deriving them would be document derivation in a host and would have to be written once per framework.
type ReviewItemView = ReviewItemPlacement;Variables (1)
DocxEditorReviewconstSource ↗
The review rail: comments and tracked changes as a compound component.
DocxEditorReview is itself the root; every part hangs off it, so a host arranges the pieces it wants rather than accepting one fixed layout. Requires the review module to be registered via createDocxEditor({ modules: [reviewModule()] }) — without it there is nothing to derive cards from.
DocxEditorReview: DocxEditorReviewNamespace```tsx
<DocxEditorReview>
<DocxEditorReview.List>
<DocxEditorReview.Card>
<DocxEditorReview.Author />
<DocxEditorReview.Summary />
<DocxEditorReview.Accept />
<DocxEditorReview.Reject />
</DocxEditorReview.Card>
</DocxEditorReview.List>
</DocxEditorReview>
```Namespaces (1)
CustomNodeContextMenunamespaceSource ↗
declare namespace CustomNodeContextMenu| Member | Type | Summary |
|---|---|---|
| docxRowPlacement | "start" |