adobe / adobe/react-spectrum

Custom getKeysForDrag bug - Drag and drop selected items seperatly with GridList

Open
#8,162 4 comments 0 reactions 0 assignees View on GitHub
enhancement help wanted
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

### Provide a general summary of the issue here

The documentation says that `getKeysForDrag` returns the selected items.
I want to overwrite this function to drag and drop selected items separately.
Even though I overwrite it, drag and drop don't work as expected.

https://github.com/user-attachments/assets/4bf6bc62-f29e-4146-9482-a7b8a3c147f7

Overwriting `getKeysForDrag`, full example in "Steps to reproduce"
```TS
dragAndDropHooks.useDraggableCollectionState =
function useDraggableCollectionStateOverride(
props: DraggableCollectionStateOpts
) {
const draggableHook = useDraggableCollectionState({
...props,
...options,
} as DraggableCollectionStateOptions);
draggableHook.getKeysForDrag = function (key: string) {
return new Set([key]); //Just the clicked item be a key for drag
};
return draggableHook;
};
```

### 🤔 Expected Behavior?

Items of a GridList to be reordered (drag and drop) separately

### 😯 Current Behavior

All the selected keys are dragged

### 💁 Possible Solution

I'm not sure, I didn't realize looking at the source code where `onReorder` evaluates the `event.keys`

### 🔦 Context

_No response_

### 🖥️ Steps to Reproduce

## Repository
You can just clone and run this repository:
https://github.com/JonRC/react-aria-grid-list-bug

## Code
Here is the code used in the repository below if you want reproduce by your own

```TS
/* eslint-disable @typescript-eslint/no-empty-object-type */
import {
DraggableCollectionStateOptions,
useDraggableCollectionState,
useListData,
} from "react-stately";
import {
GridList,
GridListItem,
useDragAndDrop,
Checkbox as AriaCheckbox,
CheckboxProps,
DragAndDropOptions,
} from "react-aria-components";
import { useMemo } from "react";

interface DraggableCollectionStateOpts
extends Omit {}

function App() {
const list = useListData({
initialItems: [
{ id: 1, name: "Adobe Photoshop" },
{ id: 2, name: "Adobe XD" },
{ id: 3, name: "Adobe Dreamweaver" },
{ id: 4, name: "Adobe InDesign" },
{ id: 5, name: "Adobe Connect" },
],
});

const options = useMemo(
() => ({
getItems: (keys) =>
[...keys].map((key) => ({
"text/plain": list.getItem(key)?.name ?? "",
})),
onReorder(e) {
if (e.target.dropPosition === "before") {
list.moveBefore(e.target.key, e.keys);
} else if (e.target.dropPosition === "after") {
list.moveAfter(e.target.key, e.keys);
}
},
}),
[list]
);

const { dragAndDropHooks } = useDragAndDrop(options);

dragAndDropHooks.useDraggableCollectionState =
function useDraggableCollectionStateOverride(
props: DraggableCollectionStateOpts
) {
const draggableHook = useDraggableCollectionState({
...props,
...options,
} as DraggableCollectionStateOptions);
draggableHook.getKeysForDrag = function (key: string) {
return new Set([key]); //Just the clicked item be a key for drag
};
return draggableHook;
};

return (

{(item) => (

{() => (
<>

{item.name}

)}

)}

);
}

export function Checkbox(props: CheckboxProps) {
return (

{({ isSelected, isIndeterminate }) => (
<>

{isIndeterminate ? "[ ]" : isSelected ? "[x]" : "[ ]"}

{props.children}

)}

);
}

export default App;
```

### Version

"react-aria-components": "^1.8.0"

### What browsers are you seeing the problem on?

Chrome

### If other, please specify.

_No response_

### What operating system are you using?

Linux, Ubuntu

### 🧢 Your Company/Team

_No response_

### 🕷 Tracking Issue

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.