Skip to content

fix(abstract): recompute transforms for drag operation snapshots (closes #2055) - #2061

Open
timagixe wants to merge 7 commits into
clauderic:mainfrom
timagixe:issues/2055
Open

fix(abstract): recompute transforms for drag operation snapshots (closes #2055)#2061
timagixe wants to merge 7 commits into
clauderic:mainfrom
timagixe:issues/2055

Conversation

@timagixe

Copy link
Copy Markdown
Contributor

Summary

Closes #2055.

This fixes drag operation event snapshots so event.operation.transform is kept up to date even when visual feedback is disabled with Feedback.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 the Feedback plugin reading dragOperation.transform. When feedback was disabled, that side effect never happened.

Changes

  • Recompute transforms in DragOperation.snapshot() instead of relying on a stale cached value.
  • Snapshot proposed coordinates for dragmove events before the move is committed, while preserving preventDefault() behavior.
  • Preserve same-tick relative move accumulation for queued by moves.
  • Add abstract regression tests for transform snapshots, modifiers, prevented moves, and queued relative moves.
  • Add DOM coverage for Feedback.configure({feedback: 'none'}).
  • Add a patch changeset for @dnd-kit/abstract.

Testing

  • bun test packages/abstract/tests
  • bun test packages/dom/tests
  • bunx tsc --noEmit -p packages/abstract/tsconfig.json

Notes

No stories or docs were added because this is a bug fix to existing event snapshot behavior, not a new feature or API.

@changeset-bot

changeset-bot Bot commented May 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e8d50e8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 10 packages
Name Type
@dnd-kit/abstract Patch
@dnd-kit/collision Patch
@dnd-kit/dom Patch
@dnd-kit/geometry Patch
@dnd-kit/helpers Patch
@dnd-kit/react Patch
@dnd-kit/state Patch
@dnd-kit/vue Patch
@dnd-kit/solid Patch
@dnd-kit/svelte Patch

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

@pkg-pr-new

pkg-pr-new Bot commented May 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

@dnd-kit/abstract

npm i https://pkg.pr.new/@dnd-kit/abstract@2061

@dnd-kit/collision

npm i https://pkg.pr.new/@dnd-kit/collision@2061

@dnd-kit/dom

npm i https://pkg.pr.new/@dnd-kit/dom@2061

@dnd-kit/geometry

npm i https://pkg.pr.new/@dnd-kit/geometry@2061

@dnd-kit/helpers

npm i https://pkg.pr.new/@dnd-kit/helpers@2061

@dnd-kit/react

npm i https://pkg.pr.new/@dnd-kit/react@2061

@dnd-kit/solid

npm i https://pkg.pr.new/@dnd-kit/solid@2061

@dnd-kit/state

npm i https://pkg.pr.new/@dnd-kit/state@2061

@dnd-kit/svelte

npm i https://pkg.pr.new/@dnd-kit/svelte@2061

@dnd-kit/vue

npm i https://pkg.pr.new/@dnd-kit/vue@2061

commit: e8d50e8

@clauderic clauderic added bug Something isn't working abstract Abstract package labels May 28, 2026

@clauderic clauderic left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:178snapshot() now has a side effect: when the passed coordinates equal position.current, it writes back into this.#transform. This couples snapshot creation to internal cache maintenance, which is subtle. A reader of snapshot() would not expect mutation. Consider lifting the cache update into the transform getter (which already writes #transform) or into move() after the event isn't prevented. Not blocking — the behavior is correct, just non-obvious.
  • computeTransform() now ignores position.delta in favor of coordinates - position.initial. That's equivalent today but worth a one-line comment noting the change of basis, since position.delta was the previous source of truth and someone might wonder why it's no longer used.
  • The new modifier pipeline pass wraps each createSnapshot(...) in untracked(...). The pre-existing code wrapped the whole iteration in untracked via the surrounding snapshot() body — confirming the modifier apply() 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 — casting draggable through unknown to mutate element is a smell; the test would be cleaner constructing the Draggable with an element option (if available) or using a real HTMLDivElement via 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]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

abstract Abstract package bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

event.operation.transform never gets updated when feedback is "none"

2 participants