fix: prevent duplication of work package chips during drag and drop#129
Open
ihordubas99 wants to merge 2 commits intodevfrom
Open
fix: prevent duplication of work package chips during drag and drop#129ihordubas99 wants to merge 2 commits intodevfrom
ihordubas99 wants to merge 2 commits intodevfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket
https://community.openproject.org/projects/communicator-stream/work_packages/74540
What are you trying to accomplish?
Fix a duplication bug that occurs when dragging and dropping Work Package chips (both Inline and Block) inside the BlockNote editor.
Previously, if a user selected text along with a chip and initiated the drag specifically by grabbing the chip (contentEditable={false}), ProseMirror would treat the drop as a new HTML insertion (copy) rather than a structural move, leaving the original content behind.
What approach did you choose and why?
The root cause of the duplication bug lies in how the browser handles native dragstart events on non-editable elements. When a user drags a chip, the browser takes over the drag operation, causing ProseMirror to lose the context of the internal text selection. Because of this, ProseMirror defaults to a copy operation upon drop, inserting the HTML without removing the original source.
To resolve this, I created a custom useDragSelection hook to encapsulate the internal ProseMirror logic. This hook intercepts the dragstart event, checks if there is an active selection range, and explicitly instructs ProseMirror to treat the action as a move operation by configuring the internal dragging state. This ensures that the original content is properly deleted after the drop.
I implemented this hook in both the inline and block work package components. For the inline chip specifically, I extracted the BlockNote-specific logic (useBlockNoteEditor + useDragSelection) into a thin InlineWorkPackageChipInEditor wrapper component. This keeps InlineWorkPackageChip free of any BlockNote context dependency, making it independently testable and renderable outside of the editor. The drag handler is passed down as an optional onDragStart prop.
Initially, I considered overriding the global handleDrop or transformPastedHTML properties directly on the ProseMirror view. I ultimately discarded this approach because it creates a leaky abstraction and risks breaking standard drag-and-drop behaviors across the entire editor. Handling the fix locally at the component level via a reusable hook is a much safer approach that keeps the UI components clean and limits the potential blast radius.
Merge checklist