You can keyboard-drag an item outside its scrollable container element by holding down the arrow key
- Dominant language
- TypeScript
- Stars
- 17.6k
- Forks
- 924
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 2
Description
I'm been working on porting a sortable list from `@dnd-kit/core` to `@dnd-kit/react`.
Once thing I've noticed is that if you have a DragDropProvider inside a scrollable container element, if you hit Enter to keyboard-drag an item, then hold down the Up or Down arrow key, you can drag the item entirely outside of the container element, presumably because the auto-scroller doesn't respond fast enough to keep up with the arrow key events.
I've made a temporary workaround to throttle arrow key events to no more than one per 100ms, which seems to stop the issue from happening:
```typescript
// During keyboard "dragging", disallow repeated keydown events more frequent than 100ms
// dnd-kit 0.5 has a bug where holding down an arrow key can "drag" an element out of its container.
const timeStampRef = useRef(0);
useEventListener(
document,
"keydown",
(event: Event) => {
const e = event as KeyboardEvent;
if (dragMethod === DragMethod.KEYBOARD && e.key.startsWith("Arrow")) {
// tried 50ms, was too fast
if (e.timeStamp - timeStampRef.current < 100) {
e.stopImmediatePropagation(); // stopPropagtion() isn't enough; dnd-kit also listens on *document*
} else {
timeStampRef.current = e.timeStamp;
}
}
},
true,
);
// Don't apply throttling when user is tapping the key (just when they hold it down)
useEventListener(document, "keyup", () => {
timeStampRef.current = 0;
});
```
(`useEventListener()` is just a hook that calls `addEventListener()` on and `removeEventListener()` on cleanup. `dragMethod` comes from a custom monitor that you see the code for in #2118.)
Contributor guide
Research direction
Reproduce the issue with a DragDropProvider inside a scrollable container: start a keyboard drag with Enter, then hold the Up or Down arrow key. Compare the behavior with the reported 100ms arrow-key throttle workaround. Done means repeated arrow-key events no longer move the dragged item outside its scrollable container while normal key taps still work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100