clauderic / clauderic/dnd-kit

You can keyboard-drag an item outside its scrollable container element by holding down the arrow key

Open
#2,119 1 comment 0 reactions 0 assignees View on GitHub
a11y bug dom triage:done
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.