Help: Marquee Selection & Selecting Multiple Nodes for Dragging


I’ve looked around quite a bit to try and find someone doing this already, but I haven’t had any luck.

Essentially, I’d like to be able to begin a selection in one node, and as I continue dragging outside of the boundaries of that node, I begin selecting the parent node or the next child.

This mimics the behavior of selections in a software called Notion.

How would everyone recommend going about this?

I started down a path of assigning all draggable “blocks” unique ids, so I could potentially manage block selection decoration via CSS by targeting individual ids in a style tag (rather than updating the dom), but I’m not sure if that’s a worthy approach.

I would prefer it if I didn’t have to modify the node positions in order to support this as I think that could make multiplayer more complex.

Please let me know if you have any suggestions at all for this problem! I am just getting started, so I have a lot of flexibility to take alternative approaches.

For reference, Notion uses the content editable approach, but each block is an isolated content editable instance. So, they end up managing all block selection and dragging separate from content editable functionaliy. Another interesting constraint in Notion, is that there aren’t any embedded blocks, all blocks live at the top level. In my app with Prosemirror, there is quite a bit of nesting and constraints for what can go where.

Screenshot of Notion’s DOM during a selection for reference

I always wanted to try this, but I never found the time. But I think it should be possible.

1 Like

The table cell selection implementation might provide some inspiration, since it sounds similar.

1 Like

Thanks for the reference to table cell impl. It looks like there could be a lot of overlap with what I’m aiming to achieve.

In my opinion that’s annoying behavior that users don’t really want. But if you really want it to work like that why not use a block style editor that works like that out of the box? Like

For non-continuous multi-node selections – like an array of NodeSelection – what’s the sensible approach when extending Selection (if there is one)? this.ranges makes sense to use, but are there meaningful values for this.$anchor and this.$head?

I tried looking at the table cell selection for inspiration but because its still a continuous row or column cell selection, extending the selection with “proper” anchor and head values there is easier.

You could use the extent of the ‘primary’ range, if such a concept is meaningful. Basically, you want to provide something for code that doesn’t know how to work with multi-range selections to act on.