@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 (17)
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;collaborationModulefunctionSource ↗
Build the collaboration module. Construction never validates the key and never touches the network.
declare function collaborationModule(options: CollaborationModuleOptions): EditorModule;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;DocxEditorCollaborationRootfunctionSource ↗
A DocxEditor.Root wired to a collaboration room.
```tsx const collaboration = useHocuspocusCollaboration({ modules: MODULES, room });
<DocxEditorCollaborationRoot collaboration={collaboration} fallback={<p>Connecting…</p>}> <DocxEditor.Toolbar /> <DocxEditor.Viewport> <DocxEditor.Content /> <DocxEditorCollaboration.CaretLabels /> </DocxEditor.Viewport> </DocxEditorCollaborationRoot> ```
The presence parts take no session: they read it from the editor this mounts.
declare function DocxEditorCollaborationRoot(input: DocxEditorCollaborationRootProps): react.JSX.Element;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;useCollaborationParticipantsfunctionSource ↗
Reactive participant roster for the collaboration session.
Omit session and it reads the one the editor above holds. Returns the same array reference until the roster actually changes, so a memoized consumer does not re-render on unrelated awareness traffic. No session yields a stable empty array.
declare function useCollaborationParticipants(session?: CollaborationSession | null): readonly CollaborationParticipant[];useCollaborationSessionfunctionSource ↗
The live collaboration session of the editor above this component, or null.
The editor already holds the session a collaborationModule contributed, so presence chrome reads it from here instead of being handed it: every part and hook in this package takes session as an OPTIONAL prop and falls back to this. A host that has one Root and one room never passes it at all.
Pass it explicitly when a component sits outside the Root that owns the room, or when one page renders two.
declare function useCollaborationSession(): CollaborationSession | null;useCollaborationStatusfunctionSource ↗
Reactive status for the collaboration session, with live and diverged derived.
Omit session and it reads the one the editor above holds. Pass it explicitly for a session this Root does not own.
declare function useCollaborationStatus(session?: CollaborationSession | null): UseCollaborationStatusReturn;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[];useDocumentCollaborationfunctionSource ↗
Own a provider-agnostic collaboration session for a React host.
The consumer creates the ydoc, the awareness, and whatever provider replicates them (WebSocket, WebRTC, offline persistence); this hook owns only the document session over them, with the same StrictMode-safe lifecycle as useWebrtcCollaboration. It imports no network provider.
declare function useDocumentCollaboration(options?: UseDocumentCollaborationOptions): UseDocumentCollaborationReturn;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;useReviewAuthorfunctionSource ↗
The resolved presentation of one author — colour, ramp slot, and any declared style — or undefined when no argument is given, or when the author is in neither the document's roster nor the review queue.
COMMENT AUTHORS INCLUDED. The document's revision roster does not carry someone who only left comments, so this resolves their declaration directly; their card draws in the colour the host declared, exactly as a reviewer's does.
The link between a CUSTOM card and the author styling system: a List render callback or card child reads the item's author here and draws with the same colours the painted document and the packaged cards use. Live: a setRevisionStyles call re-renders the rail, and this answer with it. Works anywhere under DocxEditorReview.
tsx
function MyCard({ item }: { item: ReviewItemView }) {
const author = useReviewAuthor(item.author);
return <div style={{ borderColor: author?.color }}>…</div>;
}
<DocxEditorReview.List>{(item) => <MyCard item={item} />}</DocxEditorReview.List>;
declare function useReviewAuthor(author: string | undefined): ReviewAuthorInfo | undefined;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 (33)
CollaborationAvatarPropsinterfaceSource ↗
Props for [DocxEditorCollaboration](DocxEditorCollaboration).Avatar.
interface CollaborationAvatarProps| Member | Type | Summary |
|---|---|---|
| children? | ReactNode | Replaces the initials inside the disc; the accent background stays. |
| className? | string | |
| participant | CollaborationParticipant |
CollaborationAvatarRenderPropsinterfaceSource ↗
Render props for [DocxEditorCollaboration](DocxEditorCollaboration).Avatars' per-participant override.
interface CollaborationAvatarRenderProps| Member | Type | Summary |
|---|---|---|
| avatarUrl? | string | The image declared for this participant with `DocxEditor.AuthorStyle`, or `undefined`. |
| color | string | The resolved accent — published colour, or the review roster's colour for the name. |
| initials | string | The first letter of up to two name words, uppercased. |
| participant | CollaborationParticipant |
CollaborationAvatarsPropsinterfaceSource ↗
Props for [DocxEditorCollaboration](DocxEditorCollaboration).Avatars.
interface CollaborationAvatarsProps| Member | Type | Summary |
|---|---|---|
| children? | (props: CollaborationAvatarRenderProps) => ReactNode | Renders one participant's avatar in place of the packaged disc. |
| className? | string | |
| max? | number | Avatars shown before the rest collapse into one "+N" chip. Omit to show everyone. |
| session? | CollaborationSession | null | The session whose participants the stack shows. Omit it and the part uses the one the editor above holds; `null` renders nothing. |
CollaborationCaretLabelRenderPropsinterfaceSource ↗
What a custom remote-caret label renders with.
The renderer mounts inside the adapter's provider tree, so every hook works in it — useDocxEditor, useEditorState, the review hooks. It has the opened document, not only the collaborator.
interface CollaborationCaretLabelRenderProps| Member | Type | Summary |
|---|---|---|
| avatarUrl? | string | The image declared for this collaborator with `DocxEditor.AuthorStyle`, or `undefined`. |
| color | string | The resolved accent: the published colour when the engine can paint it, otherwise the review roster's colour for the name — the same resolution the painted label uses. |
| participant | CollaborationParticipant | null | The session roster entry for the selection's actor, or null while presence catches up. |
| selection | CollaborationRemoteSelection | The remote selection this label marks, resolved into this replica's addresses. |
CollaborationCaretLabelsPropsinterfaceSource ↗
Props for [DocxEditorCollaboration](DocxEditorCollaboration).CaretLabels.
The rendered content lands in the engine's label layer, which is furniture: the layer is aria-hidden and takes no pointer events. Assistive technology does not read a label, and nothing inside one is clickable or focusable. Keep interactive or announced presence UI in your own chrome, such as the avatar stack.
interface CollaborationCaretLabelsProps| Member | Type | Summary |
|---|---|---|
| children? | (props: CollaborationCaretLabelRenderProps) => ReactNode | Renders one label's content. Without it the label shows the collaborator's name, matching the engine default, so mounting the part bare changes nothing visible. |
| session? | CollaborationSession | null | The session whose collaborators label the carets. Omit it and the part uses the one the editor above holds; `null` renders nothing. |
CollaborationFailureinterface
One collaboration failure: a typed code plus optional free-form detail.
interface CollaborationFailure| Member | Type | Summary |
|---|---|---|
| code | CollaborationFailureCode | |
| detail? | string |
CollaborationIdentityinterface
Human or automation identity attached to authored collaboration transactions.
interface CollaborationIdentity| Member | Type | Summary |
|---|---|---|
| actorId | string | |
| color? | string | |
| name | string | |
| role? | 'human' | 'agent' |
CollaborationIdentityUpdateinterfaceSource ↗
Display-identity fields a live session can update.
actorId and role are attribution and stay immutable for the session lifetime, so this type cannot name them.
interface CollaborationIdentityUpdate| Member | Type | Summary |
|---|---|---|
| color? | string | |
| name? | string |
CollaborationModuleOptionsinterfaceSource ↗
How [collaborationModule](collaborationModule) is configured. The session is required; the licence key is optional and never validated.
interface CollaborationModuleOptions extends ProLicenseOptions| Member | Type | Summary |
|---|---|---|
| session | EditorCollaborationSession |
CollaborationParticipantinterface
One validated identity visible through ephemeral collaboration presence.
interface CollaborationParticipant extends CollaborationIdentity| Member | Type | Summary |
|---|---|---|
| isLocal | boolean |
CollaborationRemoteSelectioninterface
Stable remote selection resolved into this replica's canonical paragraph addresses.
Anchor and head may name different paragraphs. A collapsed caret is the same address twice.
interface CollaborationRemoteSelection| Member | Type | Summary |
|---|---|---|
| actorId | string | |
| anchor | CollaborationRemoteSelectionAddress | |
| color? | string | |
| head | CollaborationRemoteSelectionAddress | |
| kind? | CollaborationSelectionKind | |
| name | string |
CollaborationRemoteSelectionAddressinterface
One endpoint of a remote selection resolved into this replica's canonical addresses.
paragraphId is the stable w14:paraId. nodeId is replica-local and is used to paint.
interface CollaborationRemoteSelectionAddress| Member | Type | Summary |
|---|---|---|
| nodeId | string | |
| offset | number | |
| paragraphId | string |
CollaborationRootSourceinterfaceSource ↗
What this component needs from a room, which every collaboration hook already returns.
Structural on purpose: useHocuspocusCollaboration, useWebrtcCollaboration and useDocumentCollaboration all satisfy it, and so does a host that owns its own resources.
interface CollaborationRootSource| Member | Type | Summary |
|---|---|---|
| document | Uint8Array | null | |
| modules | readonly EditorModule[] | |
| session | CollaborationSession | null |
CollaborationSessioninterfaceSource ↗
Host-facing collaboration session.
A host reads identity, status, presence, and undo. The editor attaches [EditorCollaborationSession](EditorCollaborationSession) internally and never through this type.
interface CollaborationSession| Member | Type | Summary |
|---|---|---|
| canRedo | | |
| canUndo | | |
| documentId | string | |
| identity | CollaborationIdentity | |
| participants | | |
| redo | | |
| remoteSelections | | |
| sessionId | string | Unique identity for this attachment lifetime. |
| setIdentity | | Update the display name and color mid-session, when the replica supports it. |
| status | | |
| statusSnapshot | | Cached status, current reason, and last failure. |
| subscribeParticipants | | |
| subscribeRemoteSelections | | |
| subscribeStatus | | |
| undo | |
CollaborationStatusSnapshotinterface
Cached status read. Same reference until status, reason, or last failure change.
interface CollaborationStatusSnapshot| Member | Type | Summary |
|---|---|---|
| lastFailure | CollaborationFailure | undefined | |
| reason | CollaborationFailure | undefined | |
| status | CollaborationStatus |
CreateDocumentCollaborationOptionsinterfaceSource ↗
Options for one full-document collaboration replica.
The caller owns ydoc.
interface CreateDocumentCollaborationOptions| Member | Type | Summary |
|---|---|---|
| awareness | Awareness | |
| bootstrap | CollaborationBootstrap | |
| documentId | string | |
| identity | CollaborationIdentity | |
| offlineEditing? | boolean | Admit local edits while the transport is `disconnected`. |
| sessionId? | string | Unique attachment identity. Omit it to generate a new identity for this session. |
| ydoc | Y.Doc |
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. |
DocxEditorCollaborationNamespaceinterfaceSource ↗
The collaboration presence compound.
interface DocxEditorCollaborationNamespace| Member | Type | Summary |
|---|---|---|
| Avatar | typeof CollaborationAvatar | One participant's avatar, for hosts arranging their own presence chrome. |
| Avatars | typeof CollaborationAvatars | The packaged avatar stack, coloured to match the review module's author colours. |
| CaretLabels | typeof CollaborationCaretLabels | Host-rendered remote-caret labels, with full adapter context inside each label. |
DocxEditorCollaborationRootPropsinterfaceSource ↗
Props for [DocxEditorCollaborationRoot](DocxEditorCollaborationRoot).
Everything DocxEditor.Root takes except the three this component owns.
interface DocxEditorCollaborationRootProps extends Omit<DocxEditorRootProps, 'document' | 'modules'>| Member | Type | Summary |
|---|---|---|
| collaboration | CollaborationRootSource | The room, straight from a collaboration hook. |
| fallback? | ReactNode | What to render before the room has a document — while connecting, or after a failure. |
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 | |
| Reopen | typeof ReviewReopen | |
| Replies | typeof ReviewReplies | |
| Reply | typeof ReviewReply | |
| Resolve | typeof ReviewResolve | |
| 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 open 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) | Compound parts for the rail and its implicit List. A function remains supported as the legacy shorthand for a List render callback, but cannot be combined with root siblings; prefer an explicit `<Review.List>{item => ...}</Review.List>` in new code. |
| 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. Explicit compound parts still inherit root-owned geometry; no omitted part is added back. |
| 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. |
UseCollaborationStatusReturninterfaceSource ↗
Status returned by [useCollaborationStatus](useCollaborationStatus).
interface UseCollaborationStatusReturn| Member | Type | Summary |
|---|---|---|
| attached | boolean | An editor has attached its document port to this replica. |
| diverged | boolean | This replica no longer agrees with the room, and waiting will not fix it. |
| lastFailure | CollaborationFailure | undefined | |
| live | boolean | Edits made now reach the room. |
| reason | CollaborationFailure | undefined | |
| status | CollaborationStatus | 'inactive' |
UseDocumentCollaborationOptionsinterfaceSource ↗
Input for [useDocumentCollaboration](useDocumentCollaboration).
interface UseDocumentCollaborationOptions| Member | Type | Summary |
|---|---|---|
| modules? | readonly EditorModule[] | Host modules. The hook adds `collaborationModule` when a room is ready. A host collaboration contribution is a configuration error and throws. |
| room? | UseDocumentCollaborationConnectOptions | null | Connect this room on mount. Omit it and call [UseDocumentCollaborationReturn.connect](UseDocumentCollaborationReturn.connect) after the host has a `ydoc` and a room. |
UseDocumentCollaborationReturninterfaceSource ↗
Values [useDocumentCollaboration](useDocumentCollaboration) returns.
interface UseDocumentCollaborationReturn| Member | Type | Summary |
|---|---|---|
| connect | (options: UseDocumentCollaborationConnectOptions) => Promise<CollaborationFailure | null> | Connect a room. RESOLVES with the failure, or null on success — it does not reject. |
| document | Uint8Array | null | |
| error | CollaborationFailure | null | |
| leave | (nextDocument: Uint8Array) => void | Destroy the session and carry on editing locally. |
| modules | readonly EditorModule[] | |
| pending | boolean | |
| session | CollaborationSession | null |
UseReviewReturninterfaceSource ↗
What [useReview](useReview) returns: the review rail's data and the 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). |
| commentResolutionDisabledReason | string | null | Why Resolve and Reopen are unavailable, or null. |
| 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. |
| reopen | (item: ReviewItemView) => boolean | Reopen a resolved comment thread. Repeating this on an open thread is likewise idempotent. |
| 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. |
| resolve | (item: ReviewItemView) => boolean | Resolve a comment thread. Repeating this on a resolved thread succeeds without a write. |
| 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: puts the caret at the start of the item's range and scrolls to it. Nothing is selected; the open item draws its own highlight. |
| setPaneOpen | (open: boolean) => void | Open or close the pane — the same toggle the toolbar button runs. |
Type aliases (6)
CollaborationBootstraptypeSource ↗
Create or join bootstrap for one collaboration replica.
Text, document, and WebRTC factories share this union.
create-or-join removes the out-of-band decision about which peer creates a room. The replica probes for an initialized room and joins it when one appears. Otherwise it runs a short awareness election and only the winning candidate seeds from document. A room that two peers seeded concurrently reports the terminal failure code concurrent-seed on every replica. The document and WebRTC factories accept this kind; the experimental text factory refuses it.
type CollaborationBootstrap = {
readonly kind: 'create';
readonly document: Uint8Array;
} | {
readonly kind: 'join';
readonly timeoutMs?: number;
readonly signal?: AbortSignal;
} | {
readonly kind: 'create-or-join';
readonly document: Uint8Array;
readonly probeTimeoutMs?: number;
readonly electionWindowMs?: number;
readonly timeoutMs?: number;
readonly signal?: AbortSignal;
};CollaborationFailureCodetype
Why a replica refused work, left ready, or failed a schema check.
Free-form extras (a transport phrase, a blob key, a store refusal) travel in [CollaborationFailure.detail](CollaborationFailure.detail), not here. invalid-shared-metadata follows that rule: it names one malformed field of the room's shared metadata, and which field is the detail. Distinct from invalid-document-id, which rejects a document id this host passed in. concurrent-seed reports two merged seed transactions in one room; the room cannot be repaired client-side — create a new room from saved bytes.
Two of these name a transport condition a host has to tell apart, because the answers are opposite. transport-disconnected recovers on its own, so wait. authentication-failed never does: the credential the provider re-sent was rejected, so refresh it and rejoin. transport remains the catch-all for a provider that reported neither.
type CollaborationFailureCode = 'already-initialized' | 'authentication-failed' | 'baseline-digest-mismatch' | 'baseline-too-large' | 'blob-digest-mismatch' | 'blob-read' | 'blob-store-full' | 'blob-too-large' | 'collaboration-session-destroyed' | 'collaboration-session-not-attached' | 'collaboration-session-not-ready' | 'collaboration-text-limit' | 'concurrent-seed' | 'document-id-mismatch' | 'duplicate-paragraph-id' | 'experimental-collaboration-body-text-only' | 'experimental-collaboration-existing-paragraphs-only' | 'experimental-collaboration-text-only' | 'experimental-collaboration-untracked-text-only' | 'immutable-baseline-changed' | 'immutable-metadata-changed' | 'initialization-aborted' | 'initialization-timeout' | 'invalid-baseline' | 'invalid-blob-descriptor' | 'invalid-bound' | 'invalid-document-id' | 'invalid-identity' | 'invalid-identity-color' | 'invalid-logical-id' | 'invalid-relationships' | 'invalid-session-id' | 'invalid-shared-metadata' | 'invalid-string' | 'local-mirror-failed' | 'materialize-dropped-content' | 'missing-blob' | 'missing-local-blob' | 'missing-root' | 'no-main-document-part' | 'not-initialized' | 'paragraph-set-mismatch' | 'port-already-attached' | 'protocol-version-mismatch' | 'prototype-key' | 'remote-apply-failed' | 'schema-version-mismatch' | 'shared-schema-invalid' | 'text-too-long' | 'too-many-attributes' | 'too-many-children' | 'too-many-nodes' | 'too-many-parts' | 'too-many-relationships' | 'transport' | 'transport-disconnected' | 'tree-too-deep' | 'unknown-logical-id' | 'unknown-paragraph-id' | 'unsafe-part-name' | 'unsupported-root-key';CollaborationSelectionKindtype
How a published selection covers the document.
Absent or omitted means a character range. cells means the table rectangle whose corner cells contain the two endpoints. The payload still carries only those endpoints, so a large table selection does not grow with the number of selected cells.
type CollaborationSelectionKind = 'cells';CollaborationStatustype
Lifecycle state of one collaboration replica.
One axis, because the only question a host has to answer is whether to tell the reader to wait or to reload:
- initializing — joining. Edits are refused. Recovers on its own. - ready — replicating. The only state that accepts edits. - disconnected — the transport dropped. The replica is intact and recovers on its own, so wait rather than reload. Edits are refused until reconnect by default; a session created with offline editing enabled keeps accepting them, and the buffered updates merge on reconnect. - error — this replica no longer agrees with the room. It does not recover: only a reload rejoins. [CollaborationStatusSnapshot.reason](CollaborationStatusSnapshot.reason) says why. - destroyed — torn down. Terminal.
type CollaborationStatus = 'initializing' | 'ready' | 'disconnected' | 'error' | 'destroyed';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;UseDocumentCollaborationConnectOptionstypeSource ↗
Arguments for [UseDocumentCollaborationReturn.connect](UseDocumentCollaborationReturn.connect): the createDocumentCollaboration options. The consumer owns ydoc, awareness, and whatever provider replicates them.
type UseDocumentCollaborationConnectOptions = CreateDocumentCollaborationOptions;Variables (2)
DocxEditorCollaborationconstSource ↗
Presence chrome over a live collaboration session.
Compose the parts inside DocxEditor.Root with the collaboration module registered:
DocxEditorCollaboration: DocxEditorCollaborationNamespace```tsx
<DocxEditorCollaboration.Avatars session={session} max={4} />
<DocxEditorCollaboration.CaretLabels session={session}>
{({ selection, color }) => <MyLabel name={selection.name} color={color} />}
</DocxEditorCollaboration.CaretLabels>
```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" |