Fix module drag: TypeError on droppableContainers.filter() crashing collision detection
droppableContainers in @dnd-kit/core collision detection args is a custom NodeMap class, not a plain Array. It implements [Symbol.iterator] (so for...of works internally in closestCenter/pointerWithin) but does NOT have Array.prototype methods like .filter(). Calling args.droppableContainers.filter(...) threw: TypeError: args.droppableContainers.filter is not a function dnd-kit silently catches errors in the collision detection callback and treats them as no collision (over = null). Every module drag ended with over = null, hitting the early return in handleDragEnd, causing the module to snap back to its original slot every time. Fix: Array.from(args.droppableContainers) converts the NodeMap iterable to a plain array before filtering for dropType === 'slot' containers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -69,13 +69,17 @@ function ModuleDragOverlay({ label }: { label: string }) {
|
|||||||
* (which needs the sortable rack targets) still works.
|
* (which needs the sortable rack targets) still works.
|
||||||
*/
|
*/
|
||||||
const slotFirstCollision: CollisionDetection = (args) => {
|
const slotFirstCollision: CollisionDetection = (args) => {
|
||||||
// Restrict to slot droppables only
|
// droppableContainers is a custom NodeMap (not a plain Array) — it only
|
||||||
const slotContainers = args.droppableContainers.filter(
|
// implements [Symbol.iterator], so .filter() doesn't exist on it.
|
||||||
|
// Convert to Array first before filtering.
|
||||||
|
const allContainers = Array.from(args.droppableContainers);
|
||||||
|
|
||||||
|
const slotContainers = allContainers.filter(
|
||||||
(c) => c.data.current?.dropType === 'slot'
|
(c) => c.data.current?.dropType === 'slot'
|
||||||
);
|
);
|
||||||
|
|
||||||
if (slotContainers.length > 0) {
|
if (slotContainers.length > 0) {
|
||||||
const slotHits = pointerWithin({ ...args, droppableContainers: slotContainers });
|
const slotHits = pointerWithin({ ...args, droppableContainers: slotContainers as typeof args.droppableContainers });
|
||||||
if (slotHits.length > 0) return slotHits;
|
if (slotHits.length > 0) return slotHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user