a tool for shared writing and social publishing
1import { Decoration, DecorationSet } from "prosemirror-view";
2import { Plugin } from "prosemirror-state";
3
4export const highlightSelectionPlugin = new Plugin({
5 state: {
6 init(_, { doc }) {
7 return DecorationSet.empty;
8 },
9 apply(tr, oldDecorations, oldState, newState) {
10 // Skip selection-only changes to avoid DOM mutations that break
11 // native selection handle dragging. On blur, we force an update
12 // so the highlight is visible when focus moves to the toolbar.
13 if (!tr.docChanged && !tr.getMeta("updateSelectionHighlight")) {
14 return oldDecorations;
15 }
16
17 let decorations = [];
18
19 // Check if there's a selection
20 const { from, to } = newState.selection;
21 if (from !== to) {
22 decorations.push(
23 Decoration.inline(from, to, { class: "selection-highlight" }),
24 );
25 }
26
27 return DecorationSet.create(newState.doc, decorations);
28 },
29 },
30 props: {
31 handleDOMEvents: {
32 blur(view) {
33 view.dispatch(
34 view.state.tr.setMeta("updateSelectionHighlight", true),
35 );
36 return false;
37 },
38 },
39 decorations(state) {
40 return this.getState(state);
41 },
42 },
43});