Vertically align sidebar blocks to content

Has anyone had any experience implementing something like the common comments-in-right-sidebar pattern, where the sidebar has blocks that track the vertical position of some text they relate to (e.g. as in Google docs)?

My first thought is to use decorations or node-views, and CSS floats to get them out of the text into the sidebar.

But I’m wondering if this will hit problems because, from a DOM point of view, these elements are inside the contenteditable element. e.g. will selecting text in the document cause these to get selected. What will happen on copy/paste/cut/delete when the selection spans one of these floated comment blocks? Maybe there are other problems I haven’t thought of related to the fact that all this non-document content is “in” the document.

On the other hand the sidebar element could be outside the document contenteditable, but then the challenge is to keep the sidebar blocks and the associated document text aligned vertically. Maybe a library like popperjs can help with this.

First step would be to try some experiments, but I thought I’d ask first. I’m sure others must have been down this road.

Thanks!

Tom

I am also curious about this one. I used the second option. 2 divs, contentEditable plus comments area wrapped in a scrollable one. Calculated all comment annotations top positions to draw boxes on the right . Then on conditions when they do overlap, are active or the content changes i rerender them. It can be certainly improved from a re-render standpoint but works well.

This is definitely awkward to do. As you mentioned, selection can get in the way when putting them inside the content. But also, any wrapping scrollable element will clip such elements.

But keeping the element aligned can also get very awkward when putting it outside the content. In some cases you may be able to use the tooltip plugin with the getCoords callback to reuse the logic that’s already there. But if you need a ton of these, you’d have to see whether that code is fast enough, since it has been written with only a handful of simultaneously active tooltips in mind.

I am rendering aligned “gutter” comments (that is what I call them) entirely distinct from the prosemirror DOM output. It is certainly feasible and I think the implementation I’ve arrived at is highly stable, useful and performant - hierarchical comment threads spawning from a text range or block, that align or form a top to bottom stack if needed, all after the user is done editing via debounce - it could have also been a throttle. Additionally as a UX ‘polish’, the selected text range forces alignment if there isnt enough space.

The short list of concerns you enumerated are part of the reason I chose to do it this way. Note the architecture for these comments is a separate list dissociated from the prosemirror document so this may be more natural with regards to drawing the UI, although I think it equally possibly with mark approach. Just slightly different bookeeping / pre-calculation steps.

On the other hand the sidebar element could be outside the document contenteditable, but then the challenge is to keep the sidebar blocks and the associated document text aligned vertically. Maybe a library like popperjs can help with this.

I can see popperjs being useful here, but I just wrote the bare minimum code to do the alignment myself - I also didn’t particular want a library dependency for this part of the code.

I happen to also have experience with popperjs and it might be over doing it. Would be curious how quick you can get something working with that library though.

Immediate alignment / floating is actually not required and may be distracting (I found) so you may have to actually work against the library or figure if you could defer position updates (iirc not how default popperjs / now floating-ui works)

Thanks for the responses.

@marijn by the tooltip plugin do do you mean: ProseMirror tooltip example ?

I notice it doesn’t update the position when the text reflows due to browser resizing, although I guess that wouldn’t be hard to add using onresize.

@bZichett would you be prepared to share some code? Even just a couple of relevant snippets would be useful to see.

re: immediate vs. delayed alignment (I was curious what Google Docs does so checked and it is also delayed), I wonder if floating-ui + some CSS transitions would be enough.

No, I somehow thought this was on the CodeMirror forum. Ignore that part. There’s no tooltip feature in the ProseMirror core library.