Search code examples
reactjsmonaco-editor

Monaco editor deltaDecorations changes the style of the whole text instead of just the given range


I am using Monaco editor with React. I want to change the background color of a specific range in a line. I am following this tutorial which is from the official documentation.

Here's how the code looks like.

const editorDidMount = (editor, monaco) => {
    const r = new monaco.Range(1, 3, 1, 10);
    editor.deltaDecorations(
        [],
        [
            {
                range: r,
                options: {
                    inlineClassName: "myInlineDecoration",
                },
            },
        ]
    );
};

This is how I create the editor element. Nothing special.

<MonacoEditor
    width={800}
    height={400}
    language="java"
    value={value}
    onChange={onValueChange}
    editorDidMount={editorDidMount}
/>

and the css

.myInlineDecoration {
    background: lightgreen;
}

The problem is that this changes the background color of the whole text to lightgreen instead of just the given range.

It looks like this. But I just want a specific range, not everything. enter image description here

I tried different options from here but none of them made any difference.

Let me know if more information is needed.


Solution

  • As you mentioned in your comment, the problem seems to be that the value starts as blank, and then the selection auto-expands to the whole text when it changes.

    If you want to keep decorations when the text changes, you could store the monaco objects in a ref and use them in a useEffect hook that executes every time the value changes.

    ...
      const monacoObjects = useRef(null);
    
      const editorDidMount = (editor, monaco) => {
        monacoObjects.current = {
          editor,
          monaco,
        };
      };
    
      useEffect(() => {
        if (!monacoObjects.current) return;
        const { monaco, editor } = monacoObjects.current;
        const r = new monaco.Range(1, 3, 1, 10);
        editor.deltaDecorations(
          [],
          [
            {
              range: r,
              options: {
                inlineClassName: "myInlineDecoration",
              },
            },
          ]
        );
      }, [value]);
    
      return (
        <MonacoEditor
          width={800}
          height={400}
          language="java"
          value={value}
          onChange={onValueChange}
          editorDidMount={editorDidMount}
        />
      );
    ...