fix(notebook): eliminate drag-and-drop browser freeze and restore bundle preservation #63

Merged
clanker merged 1 commit from fix/notebook-dnd-hang into main 2026-09-16 07:40:28 +00:00
Member

Root Cause

  1. Unmemoized state updates during high-frequency dragover: setDropTarget was creating a new object reference on every frame (60-120 FPS), causing full notebook re-renders and re-calculation of budget statistics.
  2. Layout thrashing / oscillation: scale-[1.01], transition-all, and unmounting budgetStats to mount Nest inside shifted row bounding boxes, causing dragover position checks to alternate between before and inside in an infinite loop.
  3. Broken bundle preservation: Dropping an item previously moved only the item itself, leaving descendants stranded.

Changes

  • Memoized setDropTarget using equality checks on prev to skip redundant state changes.
  • Added e.stopPropagation() and e.dataTransfer.dropEffect = 'move' to drag event handlers.
  • Replaced scale-[1.01] and transition-all with non-reflowing ring-2 and transition-colors.
  • Positioned Nest inside badge as an absolute overlay and kept budget badges visible to maintain stable row height.
  • Restored recursive getAllDescendants collection so dragging an item moves its full subtree together.
### Root Cause 1. **Unmemoized state updates during high-frequency dragover**: `setDropTarget` was creating a new object reference on every frame (60-120 FPS), causing full notebook re-renders and re-calculation of budget statistics. 2. **Layout thrashing / oscillation**: `scale-[1.01]`, `transition-all`, and unmounting `budgetStats` to mount `Nest inside` shifted row bounding boxes, causing dragover position checks to alternate between `before` and `inside` in an infinite loop. 3. **Broken bundle preservation**: Dropping an item previously moved only the item itself, leaving descendants stranded. ### Changes - Memoized `setDropTarget` using equality checks on `prev` to skip redundant state changes. - Added `e.stopPropagation()` and `e.dataTransfer.dropEffect = 'move'` to drag event handlers. - Replaced `scale-[1.01]` and `transition-all` with non-reflowing `ring-2` and `transition-colors`. - Positioned `Nest inside` badge as an absolute overlay and kept budget badges visible to maintain stable row height. - Restored recursive `getAllDescendants` collection so dragging an item moves its full subtree together.
- Memoize setDropTarget state updates during handleDragOver to eliminate 120 FPS re-render loops.
- Prevent layout shifts and reflow oscillation in NotebookItemRow by replacing scale transform and transition-all with stable ring styling and absolute positioning for drop inside feedback.
- Retain budget quota badges in DOM during dragover to preserve row height.
- Reintroduce recursive getAllDescendants bundle preservation during drop operations.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Home/Spheres4Dummies!63
No description provided.