mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): skip firing collision detection on dnd when droppable scrolled out
Requires some additional logic in the collision detection algorithm. Closes #4621
This commit is contained in:
parent
b4790002c7
commit
6d1057c560
@ -31,7 +31,7 @@ const IAIDroppable = (props: IAIDroppableProps) => {
|
||||
insetInlineStart={0}
|
||||
w="full"
|
||||
h="full"
|
||||
pointerEvents="none"
|
||||
pointerEvents={active ? 'auto' : 'none'}
|
||||
>
|
||||
<AnimatePresence>
|
||||
{isValidDrop(data, active) && (
|
||||
|
@ -2,7 +2,6 @@ import {
|
||||
DragOverlay,
|
||||
MouseSensor,
|
||||
TouchSensor,
|
||||
pointerWithin,
|
||||
useSensor,
|
||||
useSensors,
|
||||
} from '@dnd-kit/core';
|
||||
@ -14,6 +13,7 @@ import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { PropsWithChildren, memo, useCallback, useState } from 'react';
|
||||
import { useScaledModifer } from '../hooks/useScaledCenteredModifer';
|
||||
import { DragEndEvent, DragStartEvent, TypesafeDraggableData } from '../types';
|
||||
import { customPointerWithin } from '../util/customPointerWithin';
|
||||
import { DndContextTypesafe } from './DndContextTypesafe';
|
||||
import DragPreview from './DragPreview';
|
||||
|
||||
@ -77,7 +77,7 @@ const AppDndContext = (props: PropsWithChildren) => {
|
||||
onDragStart={handleDragStart}
|
||||
onDragEnd={handleDragEnd}
|
||||
sensors={sensors}
|
||||
collisionDetection={pointerWithin}
|
||||
collisionDetection={customPointerWithin}
|
||||
autoScroll={false}
|
||||
>
|
||||
{props.children}
|
||||
|
@ -0,0 +1,38 @@
|
||||
import { CollisionDetection, pointerWithin } from '@dnd-kit/core';
|
||||
|
||||
/**
|
||||
* Filters out droppable elements that are overflowed, then applies the pointerWithin collision detection.
|
||||
*
|
||||
* Fixes collision detection firing on droppables that are not visible, having been scrolled out of view.
|
||||
*
|
||||
* See https://github.com/clauderic/dnd-kit/issues/1198
|
||||
*/
|
||||
export const customPointerWithin: CollisionDetection = (arg) => {
|
||||
if (!arg.pointerCoordinates) {
|
||||
// sanity check
|
||||
return [];
|
||||
}
|
||||
|
||||
// Get all elements at the pointer coordinates. This excludes elements which are overflowed,
|
||||
// so it won't include the droppable elements that are scrolled out of view.
|
||||
const targetElements = document.elementsFromPoint(
|
||||
arg.pointerCoordinates.x,
|
||||
arg.pointerCoordinates.y
|
||||
);
|
||||
|
||||
const filteredDroppableContainers = arg.droppableContainers.filter(
|
||||
(container) => {
|
||||
if (!container.node.current) {
|
||||
return false;
|
||||
}
|
||||
// Only include droppable elements that are in the list of elements at the pointer coordinates.
|
||||
return targetElements.includes(container.node.current);
|
||||
}
|
||||
);
|
||||
|
||||
// Run the provided collision detection with the filtered droppable elements.
|
||||
return pointerWithin({
|
||||
...arg,
|
||||
droppableContainers: filteredDroppableContainers,
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue
Block a user