react-dnd / react-dnd

Drag and Drop for React
http://react-dnd.github.io/react-dnd
MIT License
20.98k stars 1.99k forks source link

Aggressive Drop Containers #3474

Open Hexiota opened 2 years ago

Hexiota commented 2 years ago

Is your feature request related to a problem? Please describe. Our app is set up in such a way that there are transparent divs in front of potential drop targets.

Describe the solution you'd like The ability to activate drop areas behind other elements, without using Portals. The elements in front of our drop targets are already using a portal to be in the front, we just need them to appear opaque to react-dnd. Perhaps a configuration option such as shallow on isOver?

I've opted the example from the docs: https://codesandbox.io/embed/stupefied-grass-ep406f

The desired effect would be that the drop containers could recognize the drag over, even if the red element is blocking the drop containers.

Describe alternatives you've considered We are currently using react-beautiful-dnd, which works in this scenario, but has other issues (specifically with layered drop targets)

kristian240 commented 10 months ago

Hi @Hexiota not sure if this is still relevant for you but I have the same issue. I solve that by utilizeing the isOver. This was the solution.

const FloatingContainer = ({ children, ...rest }) => {
    const [{ isOver }, drop] = useDrop(
        () => ({
            accept: ItemTypes.Panel,
            drop(item: DragItem, monitor) {
                const delta = monitor.getDifferenceFromInitialOffset() as XYCoord;
                const left = Math.round(item.left + delta.x);
                const top = Math.round(item.top + delta.y);

                moveBox(item.id, left, top);
            },
            collect: (monitor) => ({
                isOver: monitor.canDrop(),
            }),
        }),
        [moveBox]
    );

    return (
        <Box ref={ref} position="relative" overflowY="auto" {...rest}>
            <Box
                ref={drop}
                position="absolute"
                inset="0"
                zIndex={100}
                pointerEvents={isOver ? undefined : 'none'}
            />

            {children}
        </Box>
    );