Beautify the Mark

I added header and tail decorations (widget type) to the specific Mark in the custom plug-in,

But because of the special effects of decoration, it doesn’t take up the content,It makes my cursor look weird


The effect I want to achieve is to add a decoration to the top of the Mark. Removing one of the decorations will clear the current Mark. The decoration can be clicked (click effect), and the decoration can be treated as a Node like Node

  const { from, to, name } = this.getState(state)
  const decorationList = [];
  const doms = [];

  const left = document.createElement("span");
  left.innerHTML = "[";
  left.className = `${name}-left`;

  const right = document.createElement("span");
  right.innerHTML = "<span>]</span><span class='button'>Button</span>";
  right.className = `${name}-right`;

  doms.push(left, right);
  decorationList.push(Decoration.widget(from, left, { side: -1 }));
  decorationList.push(Decoration.widget(to, right, {}));
  setTimeout(() => doms.forEach((dom) => (dom.contentEditable = "true")));
  return DecorationSet.create(state.doc, decorationList);

I wish these marks could take up 1 field (edit and delete like text) or something better

Oh my God, why is no one commenting

Your question is pretty confusing. If you could make a minimal reproduction of the problem, on something like code sandbox, we’d better understand the issue.

This is incredibly suspicious and might be part of whatever problem you are facing, perhaps singularly:

setTimeout(() => doms.forEach((dom) => (dom.contentEditable = “true”)));

It will be called whenever the selection changes, and it mutates the DOM.

Where did you get the idea to do this? And why do you want to do this on a deferred schedule?

Does the same problem happen when you remove it?

As for other suggestions, I’d try extracting out that logic for building decorations and only re-running when state.doc changes. (See here for a minimal example of storing decorations in state: ProseMirror lint example)

ok, this is my codesandbox: objective-sun-ur1kwe - CodeSandbox 1

Allow me to restate my question:

  1. In my case the cursor jump is not ideal (because decorators do not take up inline space)
  2. I can’t edit to remove the decorator

What I need to achieve 2

Make the decorator editable, similar to the nodes in Prosemirror, but hopefully keeping the decorator properties

Maybe my description is a little off, but what I want to achieve is like the picture above. What’s a good way to do it

I’m sorry to give you the wrong impression that this is just my wishful thinking,

I wanted to make the decorator editable and deletable, But nothing happened

I tried doing this a few different ways, and I think the best way to do it is to have two atom nodes (leftBracket, and rightBracket) and manage adding and removing those manually when a mark gets added to a slice of the paragraph or removed, or one of the brackets gets removed.

I didn’t implement it fully, but I left comments here: keen-danilo-7nmr98 - CodeSandbox

Thank you very much, but I don’t know much about the implementation details. For example, appendTransaction I don’t know how to use it. I wrote a bunch of code myself, I don’t know if it’s my thinking or something.:face_with_spiral_eyes:

I couldn’t implement it on my own, I didn’t go back and forth with appendTransaction, I didn’t know how to tell if it was new, I didn’t have any ideas, I read a lot of articles and didn’t find out how to use it.

I hope someone can give me a case

Decoration is only a rendering effect, it does not exist in the model. If you want to achieve this effect, you need to wrap the text with 2 nodes.(likes @moonrise-tk said)