@blocknote/prosemirror-suggest-changes

中文文档
0.1.3发布于 2025/05/13MITTypeScriptES Module零依赖近 30 天下载 1.1万

Check out the demo!

原始使用文档
文档目录8 节
  1. Installation
  2. Usage
  3. How it works
  4. API
  5. Schema
  6. Commands
  7. Plugin
  8. dispatchTransaction Decorator

@handlewithcare/prosemirror-suggest-changes

Check out the demo!

Development of this library is sponsored by the kind folks at dskrpt.de!

Installation

Install @handlewithcare/prosemirror-suggest-changes and its peer dependencies:

npm:

npm install @handlewithcare/prosemirror-suggest-changes prosemirror-view prosemirror-transform prosemirror-state prosemirror-model

yarn:

yarn add @handlewithcare/prosemirror-suggest-changes prosemirror-view prosemirror-transform prosemirror-state prosemirror-model

Usage

First, add the suggestion marks to your schema:

import { addSuggestionMarks } from "@handlewithcare/prosemirror-suggest-changes";

export const schema = new Schema({
  nodes: {
    ...nodes,
    doc: {
      ...nodes.doc,
      // We need to allow these marks as block marks as well,
      // to support block-level suggestions, like inserting a
      // new list item
      marks: "insertion modification deletion",
    },
  },
  marks: addSuggestionMarks(marks),
});

Then, add the plugin to your editor state:

import { suggestChanges } from "@handlewithcare/prosemirror-suggest-changes";

const editorState = EditorState.create({
  schema,
  doc,
  plugins: [
    // ... your other plugins
    suggestChanges(),
  ],
});

Use the dispatchTransaction decorator to intercept and transform transactions, and add suggestion decorations:

import {
  withSuggestChanges,
  getSuggestionDecorations,
} from "@handlewithcare/prosemirror-suggest-changes";

const editorEl = document.getElementById("editor")!;

const view = new EditorView(editorEl, {
  state: editorState,
  decorations: getSuggestionDecorations,
  dispatchTransaction: withSuggestChanges(),
});

And finally, use the commands to control the suggest changes state, apply suggestions, and revert suggestions. Here’s a sample view plugin that renders a simple menu with some suggestion-related commands:

import {
  toggleSuggestChanges,
  applySuggestions,
  revertSuggestions,
  isSuggestChangesEnabled,
} from "@handlewithcare/prosemirror-suggest-changes";

const suggestChangesViewPlugin = new Plugin({
  view(view) {
    const toggleButton = document.createElement("button");
    toggleButton.appendChild(document.createTextNode("Enable suggestions"));
    toggleButton.addEventListener("click", () => {
      toggleSuggestChanges(view.state, view.dispatch);
      view.focus();
    });

    const applyAllButton = document.createElement("button");
    applyAllButton.appendChild(document.createTextNode("Apply all"));
    applyAllButton.addEventListener("click", () => {
      applySuggestions(view.state, view.dispatch);
      view.focus();
    });

    const revertAllButton = document.createElement("button");
    revertAllButton.appendChild(document.createTextNode("Revert all"));
    revertAllButton.addEventListener("click", () => {
      revertSuggestions(view.state, view.dispatch);
      view.focus();
    });

    const commandsContainer = document.createElement("div");
    commandsContainer.append(applyAllButton, revertAllButton);

    const container = document.createElement("div");
    container.classList.add("menu");
    container.append(toggleButton, commandsContainer);

    view.dom.parentElement?.prepend(container);

    return {
      update() {
        if (isSuggestChangesEnabled(view.state)) {
          toggleButton.replaceChildren(
            document.createTextNode("Disable suggestions"),
          );
        } else {
          toggleButton.replaceChildren(
            document.createTextNode("Enable suggestions"),
          );
        }
      },
      destroy() {
        container.remove();
      },
    };
  },
});

How it works

This library provides three mark types:

  • insertion represents newly inserted content, including new text content and new block nodes
  • deletion represents content that is marked as deleted, including text and block nodes
  • modification represents nodes whose marks or attrs have changed, but whose content has not changed

Additionally, this library provides:

  • A plugin, which keeps track of whether suggestions are enabled or not
  • A decoration set factory, which renders pilcrows (¶) to make it clear to users when block nodes have been deleted or inserted
  • A set of commands (applySuggestions, revertSuggestions, applySuggestion, etc), for working with suggestions
  • A "dispatchTransaction decorator", withSuggestChanges

withSuggestChanges is a function that optionally takes a dispatchTransaction function and returns a decorated dispatchTransaction function. This decorated function will, when suggestions are enabled, intercept transactions before they are applied to the state, and produce transformed transactions that suggest the intended changes, instead of directly applying them. For example, a transaction that attempts to delete the text between positions 2 and 5 in the document will be replaced with a transaction that adds the deletion mark to the text between positions 2 and 5.

If you already have a custom dispatchTransaction implementation, you can pass it to withSuggestChanges. Otherwise, it will rely on the default implementation (view.setState(view.state.apply(tr))).

const view = new EditorView(editorEl, {
  state: editorState,
  plugins,
  decorations: getSuggestionDecorations,
  dispatchTransaction: withSuggestChanges(
    /** An example dispatchTransaction that integrates with an external redux store */
    function dispatchTransaction(this: EditorView, tr: Transaction) {
      store.dispatch(transactionDispatched({ tr }));
    },
  ),
});

API

Schema

insertion

Represents newly inserted content, including new text content and new block nodes

const insertion: MarkSpec;

deletion

Represents content that is marked as deleted, including text and block nodes

const deletion: MarkSpec;

modification

Represents nodes whose marks or attrs have changed, but whose content has not changed

const modification: MarkSpec;

addSuggestionMarks

Add the deletion, insertion, and modification marks to the provided MarkSpec map.

function addSuggestionMarks<Marks extends string>(
  marks: Record<Marks, MarkSpec>,
): Record<Marks | "deletion" | "insertion" | "modification", MarkSpec>;

Commands

selectSuggestion

Command that updates the selection to cover an existing change.

function selectSuggestion(suggestionId: number): Command;

revertSuggestion

Command that reverts a given tracked change in a document.

This means that all content within the insertion mark will be deleted. The deletion mark will be removed, and their contents left in the doc. Modifications tracked in modification marks will be reverted.

function revertSuggestion(suggestionId: number): Command;

revertSuggestions

Command that reverts all tracked changes in a document.

This means that all content within insertion marks will be deleted. Deletion marks will be removed, and their contents left in the doc. Modifications tracked in modification marks will be reverted.

const revertSuggestions: Command;

applySuggestion

Command that applies a given tracked change to a document.

This means that all content within the deletion mark will be deleted. The insertion mark and modification mark will be removed, and their contents left in the doc.

function applySuggestion(suggestionId: number): Command;

applySuggestions

Command that applies all tracked changes in a document.

This means that all content within deletion marks will be deleted. Insertion marks and modification marks will be removed, and their contents left in the doc.

const applySuggestions: Command;

enableSuggestChanges

Command that enables suggest changes

const enableSuggestChanges: Command;

disableSuggestChanges

Command that disables suggest changes

const disableSuggestChanges: Command;

toggleSuggestChanges

Command that toggles suggest changes on or off

const toggleSuggestChanges: Command;

Plugin

suggestChanges

A plugin that tracks whether suggest changes is enabled. It also provides decorations that are useful for clarifying suggestions, such as pilcrows to mark when paragraph breaks have been deleted or inserted.

function suggestChanges(): Plugin<{ enabled: boolean }>;

suggestChangesKey

A plugin key for the suggestChanges plugin

const suggestChangesKey: PluginKey<{ enabled: boolean }>;

isSuggestChangesEnabled

A helper function to check whether suggest changes is enabled.

function isSuggestChangesEnabled(state: EditorState): boolean;

dispatchTransaction Decorator

withSuggestChanges

A dispatchTransaction decorator. Wrap your existing dispatchTransaction function with withSuggestChanges, or pass no arguments to use the default implementation (view.setState(view.state.apply(tr))).

The result is a dispatchTransaction function that will intercept and modify incoming transactions when suggest changes is enabled. These modified transactions will suggest changes instead of directly applying them, e.g. by marking a range with the deletion mark rather than removing it from the document.

function withSuggestChanges(
  dispatchTransaction?: EditorView["dispatch"],
): EditorView["dispatch"];

版本与发布记录

@blocknote/prosemirror-suggest-changes 共发布 1 个版本,首次发布于 2025/05/13;过去 12 个月发布了 0 个版本。

版本发布日期距今
0.1.3latest2025/05/131.5 年前

关于 @blocknote/prosemirror-suggest-changes 的常见问题

@blocknote/prosemirror-suggest-changes 是什么?

Check out the demo!

如何安装 @blocknote/prosemirror-suggest-changes?

在项目目录运行 npm install @blocknote/prosemirror-suggest-changes,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:prosemirror-model(^1.0.0)、prosemirror-state(^1.0.0)、prosemirror-transform(^1.0.0)、prosemirror-view(^1.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@blocknote/prosemirror-suggest-changes 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@blocknote/prosemirror-suggest-changes 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@blocknote/prosemirror-suggest-changes 可以商用吗?

@blocknote/prosemirror-suggest-changes 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@blocknote/prosemirror-suggest-changes 的下载量有多少?

根据 npm 官方下载统计,@blocknote/prosemirror-suggest-changes 在 2026/10/09 – 2026/11/07 这 30 天内被下载 10,593 次,日均约 353 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@blocknote/prosemirror-suggest-changes 还在维护吗?

最新版本 0.1.3 发布于 2025/05/13(1.5 年前);至今共发布 1 个版本,其中过去 12 个月发布了 0 个;首次发布于 2025/05/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。