clauderic / dnd-kit Goto Github PK
View Code? Open in Web Editor NEWThe modern, lightweight, performant, accessible and extensible drag & drop toolkit for React.
Home Page: http://dndkit.com
License: MIT License
The modern, lightweight, performant, accessible and extensible drag & drop toolkit for React.
Home Page: http://dndkit.com
License: MIT License
Hi dnd master,
I'm trying to do something like this example with even more complexity within each columns (multi-level list...) but for the sake of this issue, the example is enough.
Describe the bug (Required)
When there is a lot of items in the first column (say A, so items are A1, A2...) and a very few in the second column (say B, with only B1 item), then a lot in the third column C, if you pick an item from A that is very down in the container, like A15 and try to put it in the B column, the A column or the C column scrolls up until the collision detect B1.
The more items you have in A and C, the more the bug is visible.
I assume the top property of the dragged item is causing this issue or something like this, I haven't jumped into the code but I guess.
Expected behavior (Required)
When picking A246, dragging over B1, want to be able to drop above or below B1 without waiting the scroll goes up :)
Maybe a collision "with the cursor position" would be great ? (I'm not aware of what is possible or not)
Thanks for the reading,
Cya
This issue is visible in the "Many items" multiple container example. Just pick up a single card starts the whole board scrolling rapidly to the right. I guess it's because the card is near the right edge, but in my experimentation it's very hard to get control of that horizontal scrolling if the board is wider than the screen.
Chrome/macOS
Is it possible to tune the scrolling behavior as a client of dnd-kit?
Go inside the storybook - Multiple containers story
Hi, I'd like to achieve a nested sortable (where I can drag and drop between different levels) like in this sortablejs example: https://sortablejs.github.io/Sortable/#nested
I've tried to make it based on documentation, but it looks like I cannot even drag outside SortableContext. Am I doing something wrong or is it not possible yet? If so is it planned?
My try: https://codesandbox.io/s/react-nested-dnd-kit-0cimu?file=/src/App.js
(I haven't bothered setting up proper swap logic yet, so any change in order goes back to initialValues after drop)
The NPM package format provides support for declaring a package's license:
https://docs.npmjs.com/cli/v6/configuring-npm/package-json#license
The above does not appear to be used by at least the dnd-kit/core
package. Haven't check others.
Additionally, while the repository has a LICENSE file, it does not appear to be included in with the package build.
hey, awesome library! really smooth transitions
is it possible to get the overId and activeId on a custom modifier context ? I would like to apply custom restrictions based on the type of the element i'm dragging rather than its position.
thanks
Issue
Although both kinds of sensors work initially. After a certain number of moves, they stop working altogether. I've checked the event handler, and it never triggered. So I don't think it's an issue with the way I'm handling updates.
Any idea of what it could be? I've attached a video in order to demonstrate the issue.
I followed this portion of the documentation in order to get started: https://docs.dndkit.com/presets/sortable
Code
import { styled, Grid } from "@material-ui/core";
import {
DndContext,
closestCenter,
KeyboardSensor,
PointerSensor,
useSensor,
useSensors,
DragEndEvent,
TouchSensor,
} from "@dnd-kit/core";
import React, { useState } from "react";
import { SUQuestion } from "./QuestionCard";
import { questions } from "./square.data";
import {
arrayMove,
SortableContext,
sortableKeyboardCoordinates,
} from "@dnd-kit/sortable";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
export const SquareUP = () => {
const [currentQuestions, setQuestions] = useState(questions);
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
}),
useSensor(TouchSensor)
);
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
const oldId = over ? over.id : "";
if (active.id !== oldId) {
setQuestions((oldQuestions) => {
const oldIndex = oldQuestions.findIndex(
(question) => question.letter === active.id
);
const newIndex = oldQuestions.findIndex(
(question) => question.letter === oldId
);
return arrayMove(oldQuestions, oldIndex, newIndex);
});
}
};
const normalizedQuestions = currentQuestions.map(
(question) => question.letter
);
return (
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
<SortableContext items={normalizedQuestions}>
<AssignmentContainer>
<QuestionContainer>
{currentQuestions.map((question, index) => {
return (
<Grid item xs={3} key={index}>
<SortableItem id={question.letter}>
<SUQuestion {...question} />
</SortableItem>
</Grid>
);
})}
</QuestionContainer>
</AssignmentContainer>
</SortableContext>
</DndContext>
);
};
const AssignmentContainer = styled("div")(({ theme }) => ({
display: "flex",
justifyContent: "center",
border: "1px solid black",
maxWidth: theme.spacing(100),
borderRadius: theme.spacing(1),
}));
const QuestionContainer = styled((props) => <Grid container {...props} />)(
({ theme }) => ({
margin: theme.spacing(2),
width: "100%",
justifyContent: "center",
})
);
const SortableItem: React.FunctionComponent<{ id: string }> = ({
children,
id,
}) => {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
} = useSortable({ id });
const style = {
transform: CSS.Transform.toString(transform),
transition,
cursor: "pointer",
};
return (
<div ref={setNodeRef} style={style} {...attributes} {...listeners}>
{children}
</div>
);
};
Hi,
I am using dndcontext and draggable component (say background component) to show panning effect, The nodes that sit on this background component have their own dnd context. The nodes are draggable by the handle. But the panning is triggered when I drag the body of the node. Due to which I am unable to resize the node.
Here is the sandbox link. https://codesandbox.io/s/crazy-antonelli-ubzm1
If you could take a quick look and advise if I am doing anything wrong or is it a bug.
My sortable item has several props exposed such as title, category and image.
So instead of
[items, setItems] = useState(['1', '2', '3']);
My sortable item looks like:
[items, setItems] = useState([
{id: '1', title: 'x', category: 'y'},
{id: '2', title: 'z', category: 'w'}
...])
I am not sure how I can make this work.
Any help would be appreciated!
Hello there !
I'm trying to drag and drop element with Jest and React Testing Library. I'm using @dnd-kit/sortable.
I configure my sensors to listen to pointer events and keyboard events. When I testing on a browser both sensore works perfectly but within a Jest / React Testing Library these sensors does'nt work anymore.
For the keyboard way:
For the pointer way. I use the dragStart
, dragOver
and drop
function from React Testing Library.
My question Is : Is there a way to test drag and drop in Jest + React Testing Library environment ? Or should I use Cypress ?
Hi @clauderic, thanks for great DnD Library.
I'm trying to create sortable nested tree with it. I'm almost done, but since we have quite a lot of items in the tree and so far I couldn't found virtualization library that would support nested structures. So I'm trying to get as much perf as possible through other means (mainly useMemo hooks and React.memo). However I have noticed that attributes
object returned from useDraggable
is always a new object, even when the data don't change. It would be greate to memoize this in order to make use of memoization on the items.
Sorry if the description is a little short. I may have a look into this and create PR if necessary.
The draggable items that are scrolled are not calculating the intersectionRatio
correctly.
Please, see this code sandbox for an example: https://codesandbox.io/s/react-dnd-grid-0ylzl?file=/src/App.js
NOTE: Try dragging the last draggable item into one droppable area.
Hey
First thanks for the library, really appreciated!
Based on #41 I tried to create a sortable grid where the items have a different row/col span. I.e. one item is 2x1, another is 1x2 and a third is 1x1: https://codesandbox.io/s/dndkit-sortable-image-grid-forked-wmn92
I'm now facing two problems:
adjustScale
on the DragOverlay
from true to false but couldn't figure out any change in behaviour.Appreciate any pointers what I'm doing wrong/how to fix these problems.
Hello !
When the sorting strategy is not verticalListSortingStrategy, the active element is not visible and the others elements does not move while the active element hovers them.
But when releasing the mouse, elements are correctly sorted !
Here is a video that show the error : https://www.loom.com/share/897f0d5e80e04514a2ef4ca7ef049914
Here is a repro code : https://codesandbox.io/s/suspicious-neumann-7s5rm?file=/src/App.js:240-267
Did I miss something ?
I am trying to recreate the sortable grid with a large first tile example from Storybook and seeing an issue with dragging to and from the first item's position. It looks like the transform position of the dragged item is incorrect in relation to the user's cursor (see video below).
See the code here:
https://codesandbox.io/s/ecstatic-pine-zs8nj?file=/src/SortableItem.jsx
Thanks for making such an intuitive drag and drop library, really excited to see this project progress!
Inside the components folder for stories, Item.module.css
(and other css modules using scss) should be renamed to Item.module.scss
to accurately reflect their contents.
The docs state: "Use the useDroppable hook to set up DOM nodes as droppable areas that draggable elements can be dropped over."
I'm wandering if it's possible for droppable areas to detect if sortable elements are dropped over them?
Apologies in advance if I've missed something. It was straightforward to create a working example of a droppable area working with a draggable element. I've tried to have a droppable area inside and outside the SortableContext.
I am dragging from one Droppable container to another Droppable/Sortable container. If the source Droppable has many items in it and the the destination Droppable does not have as many items, the over container still registers the source container even though I am over of the destination. Curiously, the source container will scroll until it reaches some threshold and then it correctly detects the correct over container.
Use Case
Users need to be able to move squares around specific squares (in a certain order), so I thought that using SortableContext would be both be the simplest solution that would solve my problem. I'd also love to render a 'default state' of sorts when the users are moving the objects (ie a card with a number shows up)
Problem
When using drag overlay, instead of staying where the original SortableItem was, it moves around alongside the item being moved. Do you know how I could fix this?
Here's a video of the problem
Package Information
{
"@dnd-kit/core": "^1.0.0",
"@dnd-kit/sortable": "^1.0.0",
}
Component In Question:
export const ScavengerHunt: React.FC<IScavengerHunt> = ({ questions }) => {
const [activeId, setActiveId] = useState<null | string>(null);
const [currentQuestions, setQuestions] = useState(
questions as Array<ISHModule>
);
const sensors = useSensors(
useSensor(TouchSensor),
useSensor(MouseSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
const oldId = over ? over.id : "";
setActiveId(null);
if (active.id !== oldId) {
setQuestions((oldQuestions) => {
const oldIndex = oldQuestions.findIndex(
(question) => question.id === active.id
);
const newIndex = oldQuestions.findIndex(
(question) => question.id === oldId
);
return arrayMove(oldQuestions, oldIndex, newIndex);
});
}
};
const handleDragStart = (event: DragStartEvent) => {
const { active } = event;
setActiveId(active.id);
};
const normalizedQuestions = currentQuestions.map((question) => question.id);
const rows = lodash.chunk(currentQuestions, 3);
return (
<DndContext
sensors={sensors}
onDragEnd={handleDragEnd}
onDragStart={handleDragStart}
>
<SortableContext items={normalizedQuestions}>
<Grid container spacing={4}>
{rows.map((row, index) => {
const direction = (index + 1) % 2 === 0 ? "row-reverse" : "row";
return (
<Grid
container
item
direction={direction}
key={index}
spacing={4}
>
{row.map((question) => {
return (
<Grid item xs={4} key={question.id}>
<SortableItem id={question.id}>
<SHQuestion {...question} />
</SortableItem>
</Grid>
);
})}
</Grid>
);
})}
</Grid>
</SortableContext>
{createPortal(
<DragOverlay>{activeId && <p>{activeId}</p>}</DragOverlay>,
document.body
)}
</DndContext>
);
};
Hello, based on the documentation, I am trying to create sortable elements in multiple containers, however, when dragging the elements in the same container, no return in "transform".
I'm a beginner in react, and I'm confused if this could be a bug, or if I'm missing some information.
I reproduced what I'm trying to do here:
https://codesandbox.io/s/friendly-glitter-5jlpf
Thanks for the library and attention.
Hi,
I was in love with this library until i hit this issue. :( I hope you could help me get this resolved.
I have a node that is both draggable and droppable.
I render two nodes into the playground like so
{nodes.map(node => {
return ;
})}
The issues with this approach.
Codesandbox - https://codesandbox.io/s/laughing-roentgen-6jopj
PS: In console log you can see the messages.
When "MultipleContainers" has horizontal scrolling then item cant detect "Trash"
there is a function "useSortableSensors" which never been imported...
maybe you have an idea how can I solve it
Hello,
This library seems very useful. Are there any plans to support touch events in the future? I think that would really help the adoption if you were able to support both HTML5 and touch seamlessly.
Cool library, looking forward to playing around with it.
Thanks,
-Todd
The press delay is no being honoured for any of the Sortable examples in Storybook in Android Chrome.
However the Press Delay under Basic does work.
Hi, First of all, great job building this. It's an awesome library.
I am facing a problem with a use case where I have a nested structure. Can you please help resolve this?
I have a structure similar to the following:
<DndContext>
<div>
<Draggable />
<Draggable />
{/* multiple draggable items */}
</div>
<div>
<Droppable>
<DndContext>
<SortableContext>
<SortableItem />
<SortableItem />
{/* multiple sortable items */}
</SortableContext>
</DndContext>
</Droppable>
<Droppable>
<DndContext>
<SortableContext>
<SortableItem />
<SortableItem />
{/* multiple sortable items */}
</SortableContext>
</DndContext>
</Droppable>
{/* Multiple similar droppable items */}
</div>
</DndContext>
Now, I am able to move the draggable items to droppable zones. But the events are not being detected when trying to sort items in the individual droppable zones. I assume it is something related to event bubbling, but not sure. Any help in this regard will be appreciated. Thanks ๐
Codesandbox Link:
https://codesandbox.io/s/dnd-kit-gm09q?file=/src/App.js
EDIT:
In the same codesandbox, add an empty section and try to add Page 12
to it before anything else. It isn't getting added. I don't know if I am missing something here.
Example: I have a sortable list of items, but the user can also drag an item from the list into a completely different section of the app.
If I understand the docs correctly, Droppables will only recognize Draggables that are descendants of the same DnDContext. Since the sortable list is a deeply nested component that is far away from the area that I want the item to be dragged to, it means the DnDContext would have to be extremely high up in the component tree and managing the events of the DnDContext across the two distant components is more complicated than I would want. I would have to either propagate the events or use a notification type pattern or something like that.
Is there a way to link DnDContexts? So if I have my sortable list I could also register the items to be dropped into a distant DnDContext? Or am I totally structuring things incorrectly?
It's a Awesome library and i would like to know whether there is any idea on a Sortable Treeview using dnd kit ?
Hi,
Thanks for the lib. I have some understanding questions about the sensor's and don't want to pollute the issues list.
Would you mind enabling the discussions feature? it's out in beta now.
Thanks!
When I use the DragOverlay inside a container (scaled), and the item has an absolute position inside it, the item replicated inside the drag overlay has the fixed position but with the left and top are taken from the original item (inside the scaled container).
Here is a repro example https://codesandbox.io/s/dnd-kit-scale-o69qm
This image shows the element that appears on click (bigger and shifted).
I tried to use adjustScale (but the provided scale inside the transform is 6 or 7 instead of 0.5) and other things. The only way to solve the problem was to add a modifier, force the scale, and add a transformation compensation, but I think it's a workaround.
Using getBoundingClientRect() I'm able to retrieve the correct coordinates with respect to the window, which I think should be used in this case to solve the problem.
Ideally we should build a hosted version of the playground for every PR. Arguably, the Playground perhaps just needs to belong in Storybook to simplify things.
Here is a codesandbox with the issue. If you have a single Draggable element, then the default animation associated with DragOverlay works fine. If you have multiple Draggable elements then the animation associated with DragOverlay is broken. It looks like it never resets to the original opacity. Not sure why.
https://codesandbox.io/s/intelligent-lake-uyimh?file=/src/App.js
Looks like these lines don't run
dnd-kit/packages/core/src/components/DragOverlay/hooks/useDropAnimation.ts
Lines 104 to 106 in ae212fe
Anyway around this?
I mean you can get around this by setting the dropAnimation={null} in the DragOverlay (although that's not desired for my use-case).
Hi!
First of all, thanks for a great library!
I'm struggling with finding a good way to send onClick event to a draggable and sortable item - kind of works if I remove "onDragStart" prop and use only "onDragMove" to handle dragging but in that case the click needs to be quite precise. Looking for a way to handle clicking with a bit more buffer between click and dragMove.
Codesandbox here.
Hi there, we're using the library to create a dnd experience between a scrollable fixed position div and a sortable ( scrollable ) drop zone.
This mostly works well ( we're currently using PR #54 as our basis ) but causes our DragOverlay to appear in the wrong top position after scrolling the drop zone.
Below is an example based on the sandbox shown in #43
https://codesandbox.io/s/react-dnd-grid-forked-gls5l?file=/src/App.js
We made a change to check whether an element ancestor is fixed in getScrollableAncestors
, which causes only that ancestor to be returned ( Obviously, this is just a small demo and doesn't deal with more complex scenarios / performance etc.)
This makes the following return the expected value for our scenario
dnd-kit/packages/core/src/utilities/rect/getRect.ts
Lines 82 to 84 in d13d284
Currently if you have a small scroll container and a large drag source, it's nearly impossible to get fine controlled auto-scrolling working properly given the existing auto-scrolling logic.
The getScrollDirectionAndSpeed will need to be updated to take into account the relative size of the item being dragged compared to the scroll container's actual size
Currently doing a pinch zoom over draggable items in Android Chrome will cause items to drag unexpectedly.
If the target element is removed from the document, events will still be targeted at it, and hence won't necessarily bubble up to the window or document anymore. If there is any risk of an element being removed while it is being touched, the best practice is to attach the touch listeners directly to the target.
Commonly drag and drop libraries use the example of Trello boards, where you can drag and drop to reorder the items on a board in a list of boards, and then drag and drop to reorder the list of boards.
The cherry on top for an example like this would be using a virtualizer for nested draggable lists, which would showcase how powerful/flexible this library is. (Maybe 100 boards with 1000 items each or something).
edit: (documentation tag should be added)
Is it possible to achieve nesting of nodes. Similar to react-dnd.
EX:
How do we achieve this?
Also would it be possible to integrate it with react-flow (https://github.com/wbkd/react-flow) Droppable & draggable as types of nodes.
Any help in this regard would be appreciated. Thanks
A popular use-case for DnD is to drag Draggables from a static list to a Sortable Droppable as in a block-based page builder. Consider adding example to the Storybook to achieve this.
Hello !
I have an issue when moving an element through elements with variable. Indeed, the transform property applies a scale an X an Y axis on move elements.
Here is a repro project : https://codesandbox.io/s/test-dnd-kit-g4x2i
Is there a way to fix the translate properties an bypass the scale ones ?
Thank you in advance :)
Hello and thank you for the great library,
I noticed unwanted artefacts in my implementation of a dnd between multiple containers of sortable items, which was an adaptation of your <MultipleContainers />
component demoed in the story.
After a while debugging it, I realised the same visual glitch is present in the story itself.
In order to reproduce it, you can:
That's for the bug itself. Regarding the functionality's API (dragging items from a list to another): do you think users should implement the low level transferring from one list to another themselves, as visible in the current story, or do you think the library should include an easier solution?
Sometimes it fails to find types for some of the packages, seems like a flaky race condition type of error
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.