Accept or reject without scrolling
Open a tracked change from your own list without moving the page, then accept or reject it with useReview.
When your own list drives the scroll, open an item with useReview().setActive(key, { reveal: false }). The caret moves to the item, and the page stays where it is. Then resolve the item with accept(item) or reject(item). Review writes such as accept, reject, and comment never scroll the page.
import { useReview, type ReviewItemView } from '@docx-editor.dev/pro/react';
export function ChangeRow({ item }: { item: ReviewItemView }) {
const { setActive, accept, reject } = useReview();
return (
<li onClick={() => setActive(item.key, { reveal: false })}>
{item.text}
<button
disabled={item.readOnly}
onClick={(event) => {
event.stopPropagation();
accept(item);
}}
>
Accept
</button>
<button
disabled={item.readOnly}
onClick={(event) => {
event.stopPropagation();
reject(item);
}}
>
Reject
</button>
</li>
);
}accept and reject return false when the editor refuses the decision, for example in viewing mode. Read useReview().lastRefusal for the diagnostic code.
<script setup lang="ts">
import { useReview, type ReviewItemView } from '@docx-editor.dev/pro/vue';
defineProps<{ item: ReviewItemView }>();
const { setActive, accept, reject } = useReview();
</script>
<template>
<li @click="setActive(item.key, { reveal: false })">
{{ item.text }}
<button :disabled="item.readOnly" @click.stop="accept(item)">Accept</button>
<button :disabled="item.readOnly" @click.stop="reject(item)">Reject</button>
</li>
</template>accept and reject return false when the editor refuses the decision, for example in viewing mode. useReview() returns lastRefusal as a ref, so read lastRefusal.value?.code in script, or lastRefusal?.code in the template.
The buttons stop the click from reaching the row, so a decision does not also activate the item.
reveal takes false or one of four placements:
| Value | Where the item lands |
|---|---|
'centerIfNeeded' (default) | Stays still when the item is on screen; centered when it has to travel. |
'center' | Always centered. |
'nearest' | The smallest scroll that brings it into view. |
'start' | Near the top of the viewport. |
Add announce: true to open the packaged balloon or card for the item.
Decide in a headless pipeline
The editing API has no viewport. Load the revisions and call Revision.accept() or Revision.reject().
import { DocxEditor } from '@docx-editor.dev/editor-api';
const runtime = await DocxEditor.createServer(bytes, { author: 'Review bot' });
await runtime.run(async (context) => {
const revisions = context.document.body.revisions;
revisions.load('items/author');
await context.sync();
for (const revision of revisions.items) {
if (revision.author === 'Review bot') revision.accept();
}
await context.sync();
});
const saved = await runtime.save();
runtime.dispose();