Create an atomic widget

Hello. I am trying to create a widget decoration (a checkbox) to replace text such as “- [x]”. I am usingViewPlugin.fromClass to create the plugin, and inside I use Decoration.replace({ widget: new CheckboxWidget(checked) }) to create decorations.

The issue is that when I use arrow keys to move the cursor around the checkbox I am expecting it to be acting like an atomic object (cursor will move to left or right in one key press), but actually the cursor will just stay in one place because looks like it jumps into the hidden text “- [ ]”.

I searched this forum and found the suggestion of using transactionFilter.of but I am not sure how to do it properly. I tried to create another Extension by writing something like EditorState.transactionFilter.of((tr) => {..., I guess I need to see if the position of transaction’s selection has a checkbox decoration and do something with it – seems to be really complicated, and I am not sure if there is an API for “getDecorationAtPosition()” at all.

Is there a plan to add atomic widget support? If not, I wonder if you could help me point to some sample codes for using transactionFilter to resolve this issue?

Thanks a lot!

Hi. The original idea was, indeed, for extensions to handle this with a transaction filter (and that’s probably still a reasonable approach in some cases), but indeed, if you’re using a view plugin to draw your decorations, there’s a pipeline mismatch (the view only updates when the new state has been computed, so a transaction filter, which is part of the process that creates a new state, cannot query view plugins). This patch adds a new feature, PluginField.atomicRanges, which you can use to signal that the ranges in given decoration set should be skipped over by cursor motion. Could you take a look and let me know if that works for you?

1 Like

Thank you Marijin. This is really an elegant solution and appreciate the built-in support.

I tried adding provide: PluginField.atomicRanges.from((v) => v.decorations) into my viewPlugin and it works as expected:

Screen Shot 2021-05-27 at 1.26.28 PM
(the checkbox is a marker for "- [x] " but the cursor can jump between it now)