
Security News
PEP 810 Proposes Explicit Lazy Imports for Python 3.15
An opt-in lazy import keyword aims to speed up Python startups, especially CLIs, without the ecosystem-wide risks that sank PEP 690.
@blocknote/prosemirror-suggest-changes
Advanced tools
Check out [the demo](https://handlewithcarecollective.github.io/prosemirror-suggest-changes)!
Check out the demo!
Development of this library is sponsored by the kind folks at dskrpt.de!
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
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();
},
};
},
});
This library provides three mark types:
insertion
represents newly inserted content, including new text content and
new block nodesdeletion
represents content that is marked as deleted, including text and
block nodesmodification
represents nodes whose marks or attrs have changed, but whose
content has not changedAdditionally, this library provides:
applySuggestions
, revertSuggestions
, applySuggestion
,
etc), for working with suggestionsdispatchTransaction
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 }));
},
),
});
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>;
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;
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
DecoratorwithSuggestChanges
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"];
FAQs
Check out [the demo](https://handlewithcarecollective.github.io/prosemirror-suggest-changes)!
The npm package @blocknote/prosemirror-suggest-changes receives a total of 2,735 weekly downloads. As such, @blocknote/prosemirror-suggest-changes popularity was classified as popular.
We found that @blocknote/prosemirror-suggest-changes demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
An opt-in lazy import keyword aims to speed up Python startups, especially CLIs, without the ecosystem-wide risks that sank PEP 690.
Security News
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.