I’m using NodeView
and would like it to apply a style (e.g. shaded blue overlay) to indicate when its node is inside a selection (e.g. an enclosing TextSelection
/ AllSelection
/ CellSelection
/ etc).
I’ve considered and ruled out:
- Applying an inline decoration over the range of the selection (not supported —
NodeView
is only notified of node decorations) - Using a
NodeView
API that is called when document selection changes (doesn’t exist) - Using a CSS property / pseudo selector based on DOM selection (couldn’t find anything appropriate)
It seems like I need to write a plugin that applies a node decoration to each node (that I want styled) and then use the update
hook to apply the styling. Doing this inefficiently seems simple — after each transaction traverse the document between the current selection Node#nodesBetween
. To do this efficiently I think I’d need to track positions of node insertions/deletions/shifts in the plugin, and then find positions falling within the selection bounds during selection changes.
Am I missing anything here, or is this the best way to solve the problem? This feels like something that would be good to incorporate directly into ProseMirror, as it seems like it would be a fairly common task when dealing with NodeView.
Update: I ended up implementing an alternative approach, which is to create an observable of the editor selection in a plugin (fed by the plugin view update hook), and pass it down to the node view. The node view then subscribes to selection changes, and uses getPos()
to check if it’s in bounds, and updates itself based on that. Thanks @rifat for the suggestion from Atlassian’s editor https://bitbucket.org/atlassian/atlaskit-mk-2/src/116c9ac88c140c03c7b83a6c9eced7b0b214813d/packages/editor/editor-core/src/nodeviews/ui/wrapper-click-area.tsx#lines-55