clauderic / dnd-kit

The modern, lightweight, performant, accessible and extensible drag & drop toolkit for React.
http://dndkit.com
MIT License
11.88k stars 602 forks source link

Scroll while dragging broked if container with dragable elements has `scroll-behavior: smooth` #1380

Open bigkrp opened 2 months ago

bigkrp commented 2 months ago

Tested on Firefox and Chrome

Example, please pay attention on Feeds component

//index.js
import React from "react";
import ReactDOM from "react-dom";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);
// App.js
import React from "react";
import styled from "styled-components";
import {
  DndContext,
  DragOverlay,
  useDroppable,
  useDraggable,
} from "@dnd-kit/core";
import "./styles.css";

export default function App() {
  const [rows] = React.useState(4);
  const [cols] = React.useState(4);
  return (
    <DndContext onDragEnd={(event) => console.log(event)}>
      <Layout>
        <Feeds>
          {Array(20)
            .fill(null)
            .map((_, index) => (
              <Draggable key={index} id={index}>
                <FeedBox>Feed {index}</FeedBox>
              </Draggable>
            ))}
        </Feeds>
        <DragOverlay>
          <FeedBox>Item</FeedBox>
        </DragOverlay>
        <DisplayGrid rows={rows} cols={cols}>
          {Array(rows * cols)
            .fill(null)
            .map((_, index) => (
              <Droppable key={index} id={index}>
                Display {index}
              </Droppable>
            ))}
        </DisplayGrid>
      </Layout>
    </DndContext>
  );
}

const Layout = styled.div`
  display: grid;
  grid-template-columns: 200px auto;
  grid-gap: 10px;
  background: #eee;
`;

const Feeds = styled.div`
  display: grid;
  grid-auto-flow: row;
  grid-auto-rows: 100px;
  grid-gap: 1em;

  max-height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  // Change scroll behavior
  scroll-behavior: smooth;
`;

const FeedBox = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  background: teal;
  color: white;
  height: 100px;
`;

const DisplayGrid = styled.div`
  display: grid;
  grid-template-rows: repeat(${(p) => p.rows}, 1fr);
  grid-template-columns: repeat(${(p) => p.cols}, 1fr);
  grid-gap: 1em;
  padding: 1em;
  background: green;
`;

const DisplayGridItem = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  background: yellow;
`;

function Droppable(props) {
  const { isOver, setNodeRef } = useDroppable({
    id: `droppable-${props.id}`,
  });

  const style = {
    background: isOver ? "orange" : undefined,
  };

  return (
    <DisplayGridItem ref={setNodeRef} style={style}>
      {props.children}
    </DisplayGridItem>
  );
}

function Draggable(props) {
  const { attributes, listeners, setNodeRef } = useDraggable({
    id: `draggable-${props.id}`,
  });

  return (
    <div
      style={{ display: "grid" }}
      ref={setNodeRef}
      {...listeners}
      {...attributes}
    >
      {props.children}
    </div>
  );
}

https://codesandbox.io/p/sandbox/react-dnd-grid-forked-fqhjxk?file=%2Fsrc%2FApp.js%3A29%2C46

ZhichaoOuyang commented 2 weeks ago

the same problem with you, how to solve it?