How best to represent transient ui such as for slash commands, hashtags, @ mentions?

I’d like to implement slash commands similar to those used in Confluence or Notion, but I’m not sure on the right approach. If I update the actual document model, then the transient components used for showing the popup selection options might be persisted or, in the case of collaborative editing, broadcast to others. The options then seem to be either (1) filter transient ui components out of the document model when persisting or broadcasting for collab editing, or (2) implement the ui components without modifying the document model. Both options have their issues, but option (1) would likely have a more convoluted implementation and be prone to more issues with persistence, collab editing, history tracking, etc.

My current plan is to go with (2). I could have a plugin where, on detection of a slash, at-sign, or hashtag, the plugin state is updated to reference the node containing the activating symbol. The render logic for the node would have to check this state and adjust appropriately.

Is this essentially what should be done? Are there better options?

edit: It seems like using a widget decoration might be the better way to do this…

I think decorations should fit well in this case—either use a node decoration to send a signal to a node view, or just use a mark decoration to style the text that’s currently being completed, and overlay a tooltip for the completion options.

2 Likes

I have a similar use-case and so far I’m pretty happy with prosemirror-autocomplete

3 Likes