hello-pangea / dnd

Beautiful and accessible drag and drop for lists with React.
https://dnd.hellopangea.com
Other
1.83k stars 81 forks source link

Buggy horizontal reorder #796

Open schwjustin opened 1 month ago

schwjustin commented 1 month ago

Expected behavior

Smoothly move items horizontally and smoothly place them.

Actual behavior

I'm able to drag an item from right to left smoothly, but when I let go to place it there is a visual glitch where the placed item disappears and then reappears about 10px to the left of where it should be and then moves into its correct new position.

Steps to reproduce

const Header = () => {
    const [tabs, setTabs] = useState<any[]>([{ id: '0' }, { id: '1' }]);

    const reorder = (list, startIndex, endIndex) => {
        const result = Array.from(list);
        const [removed] = result.splice(startIndex, 1);
        result.splice(endIndex, 0, removed);

        return result;
    };

    const onDragEnd = (result) => {
        console.log(result);

        if (!result.destination) {
            return;
        }

        const newTabs = reorder(tabs, result.source.index, result.destination.index);

        setTabs(newTabs);
    };

    console.log('Render');

    return (
        <div
            className="w-full bg-black shrink-0 px-4"
            style={{
                height: 40,
            }}
        >
            <DragDropContext onDragEnd={onDragEnd}>
                <Droppable droppableId="tabs" direction="horizontal">
                    {(provided, snapshot) => (
                        <div
                            className="flex overflow-hidden whitespace-nowrap"
                            {...provided.droppableProps}
                            ref={provided.innerRef}
                        >
                            {tabs.map((tab, index) => (
                                <Draggable key={tab.id} draggableId={tab.id} index={index}>
                                    {(provided, snapshot) => {
                                        return (
                                            <div
                                                ref={provided.innerRef}
                                                {...provided.draggableProps}
                                                {...provided.dragHandleProps}
                                                className={`flex items-center p-2 border rounded bg-gray-100 mr-1 transition-transform ${
                                                    snapshot.isDragging
                                                        ? 'bg-gray-200 cursor-move tab-item dragging'
                                                        : 'tab-item'
                                                }`}
                                            >
                                                <button className="mr-2 bg-transparent border-none text-lg cursor-pointer text-black">
                                                    x
                                                </button>
                                                <span className="text-black">{tab.id}</span>
                                            </div>
                                        );
                                    }}
                                </Draggable>
                            ))}
                            {provided.placeholder}
                        </div>
                    )}
                </Droppable>
            </DragDropContext>
        </div>
    );
};

const HeaderMemo = memo(Header);

HeaderMemo.displayName = 'HeaderMemo';

// I'm using this header in my code as <HeaderMemo /> and I've tried it with memo and without.

What version of React are you using?

react ^18.3.1

What version of @hello-pangea/dnd are you running?

@hello-pangea/dnd ^16.6.0

What browser are you using?

Google Chrome

Demo

https://github.com/hello-pangea/dnd/assets/18671480/82b9e059-12c5-43a8-93e8-8f3864b16954

bernaferrari commented 3 weeks ago

Same happens to me on vertical reorder too!