diff --git a/packages/dom/src/sortable/sortable.ts b/packages/dom/src/sortable/sortable.ts index 0c582ca91..f5c7ed7cf 100644 --- a/packages/dom/src/sortable/sortable.ts +++ b/packages/dom/src/sortable/sortable.ts @@ -10,7 +10,7 @@ import { defaultCollisionDetection, type CollisionDetector, } from '@dnd-kit/collision'; -import type {Alignment} from '@dnd-kit/geometry'; +import type {Alignment, Shape} from '@dnd-kit/geometry'; import {Draggable, Droppable} from '@dnd-kit/dom'; import type { DraggableInput, @@ -100,6 +100,8 @@ const store = new WeakStore< TemporaryState >(); +const shapeStore = new WeakStore(); + export class Sortable { public draggable: Draggable; public droppable: Droppable; @@ -161,6 +163,17 @@ export class Sortable { initialGroup: this.group, })) ); + + const isSource = untracked( + () => this.id === this.manager?.dragOperation.source?.id + ); + + if (isSource && !shapeStore.get(this.manager, this.id)) { + const shape = untracked(() => this.droppable.shape); + if (shape) { + shapeStore.set(this.manager, this.id, shape); + } + } } }, () => { @@ -173,7 +186,7 @@ export class Sortable { this.#previousIndex = index; this.#previousGroup = group; - this.animate(); + this.animate(false); } }, () => { @@ -191,6 +204,15 @@ export class Sortable { manager?.registry.register(plugin); } }, + () => { + const manager = untracked(() => this.manager); + const id = untracked(() => this.id); + const status = manager?.dragOperation.status; + + if (status?.dragging && manager && shapeStore.get(manager, id)) { + queueMicrotask(() => this.animate(true)); + } + }, ...inputEffects(), ], type, @@ -210,15 +232,18 @@ export class Sortable { this.transition = transition; } - protected animate() { + protected animate(idChanged = false) { untracked(() => { const {manager, transition} = this; - const {shape} = this.droppable; if (!manager) return; const {idle} = manager.dragOperation.status; + const shape = idChanged + ? shapeStore.get(manager, this.id) + : (this.droppable.shape ?? shapeStore.get(manager, this.id)); + if (!shape || !transition || (idle && !transition.idle)) { return; } @@ -251,6 +276,8 @@ export class Sortable { return; } + shapeStore.set(manager, this.id, updatedShape); + const delta = { x: shape.boundingRectangle.left - updatedShape.boundingRectangle.left, y: shape.boundingRectangle.top - updatedShape.boundingRectangle.top,