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}
|
insetInlineStart={0}
|
||||||
w="full"
|
w="full"
|
||||||
h="full"
|
h="full"
|
||||||
pointerEvents="none"
|
pointerEvents={active ? 'auto' : 'none'}
|
||||||
>
|
>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{isValidDrop(data, active) && (
|
{isValidDrop(data, active) && (
|
||||||
|
@ -2,7 +2,6 @@ import {
|
|||||||
DragOverlay,
|
DragOverlay,
|
||||||
MouseSensor,
|
MouseSensor,
|
||||||
TouchSensor,
|
TouchSensor,
|
||||||
pointerWithin,
|
|
||||||
useSensor,
|
useSensor,
|
||||||
useSensors,
|
useSensors,
|
||||||
} from '@dnd-kit/core';
|
} from '@dnd-kit/core';
|
||||||
@ -14,6 +13,7 @@ import { AnimatePresence, motion } from 'framer-motion';
|
|||||||
import { PropsWithChildren, memo, useCallback, useState } from 'react';
|
import { PropsWithChildren, memo, useCallback, useState } from 'react';
|
||||||
import { useScaledModifer } from '../hooks/useScaledCenteredModifer';
|
import { useScaledModifer } from '../hooks/useScaledCenteredModifer';
|
||||||
import { DragEndEvent, DragStartEvent, TypesafeDraggableData } from '../types';
|
import { DragEndEvent, DragStartEvent, TypesafeDraggableData } from '../types';
|
||||||
|
import { customPointerWithin } from '../util/customPointerWithin';
|
||||||
import { DndContextTypesafe } from './DndContextTypesafe';
|
import { DndContextTypesafe } from './DndContextTypesafe';
|
||||||
import DragPreview from './DragPreview';
|
import DragPreview from './DragPreview';
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ const AppDndContext = (props: PropsWithChildren) => {
|
|||||||
onDragStart={handleDragStart}
|
onDragStart={handleDragStart}
|
||||||
onDragEnd={handleDragEnd}
|
onDragEnd={handleDragEnd}
|
||||||
sensors={sensors}
|
sensors={sensors}
|
||||||
collisionDetection={pointerWithin}
|
collisionDetection={customPointerWithin}
|
||||||
autoScroll={false}
|
autoScroll={false}
|
||||||
>
|
>
|
||||||
{props.children}
|
{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…
x
Reference in New Issue
Block a user