fix(abstract): recompute transforms for drag operation snapshots (closes #2055) - #2061
fix(abstract): recompute transforms for drag operation snapshots (closes #2055)#2061timagixe wants to merge 7 commits into
Conversation
🦋 Changeset detectedLatest commit: e8d50e8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 10 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@dnd-kit/abstract
@dnd-kit/collision
@dnd-kit/dom
@dnd-kit/geometry
@dnd-kit/helpers
@dnd-kit/react
@dnd-kit/solid
@dnd-kit/state
@dnd-kit/svelte
@dnd-kit/vue
commit: |
clauderic
left a comment
There was a problem hiding this comment.
Summary
Reworks DragOperation.snapshot() and DragActions.move() so the snapshot passed to dragmove/dragend listeners reflects the proposed coordinates and the transform derived from running them through the modifier pipeline, rather than the stale post-microtask values. Adds focused regression tests in packages/abstract/tests/drag-operation-snapshot.test.ts and packages/dom/tests/feedback-none-transform.test.ts, including a preventDefault() case verifying the rejected coordinates are not committed.
Feedback
Suggestions
packages/abstract/src/core/manager/operation.ts:178—snapshot()now has a side effect: when the passedcoordinatesequalposition.current, it writes back intothis.#transform. This couples snapshot creation to internal cache maintenance, which is subtle. A reader ofsnapshot()would not expect mutation. Consider lifting the cache update into thetransformgetter (which already writes#transform) or intomove()after the event isn't prevented. Not blocking — the behavior is correct, just non-obvious.computeTransform()now ignoresposition.deltain favor ofcoordinates - position.initial. That's equivalent today but worth a one-line comment noting the change of basis, sinceposition.deltawas the previous source of truth and someone might wonder why it's no longer used.- The new modifier pipeline pass wraps each
createSnapshot(...)inuntracked(...). The pre-existing code wrapped the whole iteration inuntrackedvia the surroundingsnapshot()body — confirming the modifierapply()cannot synchronously trigger a reactive read that needs to be tracked. Looks fine, but worth a sanity check. packages/dom/tests/feedback-none-transform.test.ts:24— castingdraggablethroughunknownto mutateelementis a smell; the test would be cleaner constructing theDraggablewith anelementoption (if available) or using a realHTMLDivElementvia JSDOM.
Changeset
- Status: present and correct (
'@dnd-kit/abstract': patch).
Overall
Solid fix to a real foot-gun — the assertions for the preventDefault and accumulating by cases are especially nice. The snapshot side-effect is worth a maintainer eye but I don't think it blocks the fix. Thanks @timagixe!
[claude-review]
Summary
Closes #2055.
This fixes drag operation event snapshots so
event.operation.transformis kept up to date even when visual feedback is disabled withFeedback.configure({feedback: 'none'}).The root cause was that
DragOperation.snapshot()returned the cached transform, while the cache was normally refreshed as a side effect of theFeedbackplugin readingdragOperation.transform. When feedback was disabled, that side effect never happened.Changes
DragOperation.snapshot()instead of relying on a stale cached value.dragmoveevents before the move is committed, while preservingpreventDefault()behavior.bymoves.Feedback.configure({feedback: 'none'}).@dnd-kit/abstract.Testing
bun test packages/abstract/testsbun test packages/dom/testsbunx tsc --noEmit -p packages/abstract/tsconfig.jsonNotes
No stories or docs were added because this is a bug fix to existing event snapshot behavior, not a new feature or API.