Prosemirror-virtual-cursor

Hello there. After reading the new cursor/caret design from Bike (link), I try to implement it with ProseMirror. There is my result: GitHub - ocavue/prosemirror-virtual-cursor

When the cursor if right between two different marks, it will show a little tail to indicate the mark of following input. Pressing arrow key can change the direction of the tail.

Under the hood, I hide the native cursor and use Decoration.widget to insert a <span> element to the cursor position. This approach have some issues since the <span> element break the word. Particularly, I found these two issues quite difficult:

Another approach would be calculate the coordinate of the cursor and put an element at that coordinate. By doing that, the DOM structure inside the paragraph doesn’t change, so these issues above should be fixed. However, this approach would be more difficult, since I need to ensure that the virtual cursor is at the correct coordinate. For example (1) the cursor position will change after the browser window is resized; (2) the cursor height is different in different elements.

I would appreciate to hear some advices from the community.

10 Likes

Yes, I agree that overlaying the fake cursor over the editor is probably going to cause less issues, but you’ll need to be careful about updating it when necessary. I think coordsAtPos should give you useful height info for the cursor in most cases.

1 Like

I refactored prosemirror-virtual-cursor and overlay the cursor over the editor. It looks great so far. Thanks for your helping.

4 Likes

Nice! That Bike editor had some great ideas.

1 Like

I love this! Nice work!

1 Like

Just want to say thank you for building this and open sourcing this – I had just spent some time thinking through how to implement this feature from Bike before deciding to check if someone else already did it!

It’s great not only since the plugin is reusable, but it’s also a great resource for others to learn from for doing more complex editor modifications in prose mirror.

1 Like