How to handle events inside decorations?


#1

How do you handle events, such as button clicks, inside decorations?

For example, if I have a widget that is a button and when it is clicked I want to change its icon and hide some of its parent containers content.

I was able to get the behavior working via the nodeViews (listening the the click action in the container rather than the button itself). But this seems pretty hacky. Another alternative might be listening to custom events in the parent container. But before I do that, is there an equivalent of view.dispatch for decorations or some other recommended way to have the view react to events?


#2

This can be handled via inline dispatch references. There’s a good example of doing this in the website Comments decoration code (check out the renderComment method at the bottom of the file):


#3

Thanks for linking the example. Looks useful!

I also recently saw that the plugin spec has a view option. I’ll look into both and see which one fits my use case.

Thanks again


#4

hi @marijn

I see here that you passed the dispatch function to the commentUI plugin.

I tried doing the same, but ended up getting an applying a mismatch transaction error, since some decorations were created in the init hook and others in the apply hook and I’m guessing the state transaction can’t differ.

I believe you got around this by separating the commentPlugin and commentUI functionality.

I was wondering if another possibility was, rather than a dispatch function only to the UI plugin, passing the editor instance itself with its view and state.

Passing it like this:

export default (editorVm) => new Plugin({ ...})

And using it somewhere else like this:

 editorVm.view.dispatch(
    editorVm.state.tr.setMeta('meta key', {})
 )

Not sure if you foresee any problems not using the arguments not directly using the plugins respective hooks.


#5

That works. You’re sharing more information with the plugin than strictly necessary, and it can be a bit awkward to set things up so that the plugin, which has to be created before the state, gets access to the view, but you can do that.