diff --git a/packages/@react-aria/dnd/stories/DraggableCollection.tsx b/packages/@react-aria/dnd/stories/DraggableCollection.tsx
index 75a06aee855..355874a9224 100644
--- a/packages/@react-aria/dnd/stories/DraggableCollection.tsx
+++ b/packages/@react-aria/dnd/stories/DraggableCollection.tsx
@@ -100,7 +100,8 @@ function DraggableCollection(props) {
preview,
onDragStart: props.onDragStart,
onDragMove: props.onDragMove,
- onDragEnd: props.onDragEnd
+ onDragEnd: props.onDragEnd,
+ ...props.draggableCollectionStateProps
});
useDraggableCollection({}, dragState, ref);
diff --git a/packages/@react-aria/dnd/stories/dnd.stories.tsx b/packages/@react-aria/dnd/stories/dnd.stories.tsx
index 47592d22f4d..9b051365f91 100644
--- a/packages/@react-aria/dnd/stories/dnd.stories.tsx
+++ b/packages/@react-aria/dnd/stories/dnd.stories.tsx
@@ -20,6 +20,7 @@ import Copy from '@spectrum-icons/workflow/Copy';
import Cut from '@spectrum-icons/workflow/Cut';
import {Dialog, DialogTrigger} from '@react-spectrum/dialog';
import dndStyles from './dnd.css';
+import {DraggableCollectionExample as DraggableGridExampleStandalone} from './DraggableCollection';
import {DraggableListBox} from './DraggableListBox';
import {DragPreview} from '../src/DragPreview';
import {DroppableGridExample} from './DroppableGrid';
@@ -575,3 +576,21 @@ export const DroppableEnabledDisabledControl: DnDStoryObj = {
}
}
};
+
+export const DraggedItemOnly: DnDStoryObj = {
+ render: () => (
+
+ {
+ action('getItems')(draggedKey);
+ return [{
+ 'text/plain': `Dragged item: ${draggedKey}`
+ }];
+ }
+ }} />
+
+
+ ),
+ name: 'Drag only dragged item'
+};
diff --git a/packages/@react-aria/dnd/test/useDraggableCollection.test.js b/packages/@react-aria/dnd/test/useDraggableCollection.test.js
index 378a076913c..92e1afe1120 100644
--- a/packages/@react-aria/dnd/test/useDraggableCollection.test.js
+++ b/packages/@react-aria/dnd/test/useDraggableCollection.test.js
@@ -313,6 +313,35 @@ describe('useDraggableCollection', () => {
expect(cells).toHaveLength(2);
expect(cells.map(c => c.textContent)).toEqual(['Foo', 'Baz']);
});
+
+ it('should pass the dragged key as second argument to getItems', async () => {
+ let getItems = jest.fn().mockImplementation((keys) => {
+ return [...keys].map(key => ({'text/plain': key}));
+ });
+
+ let tree = render(
+
+
+
+ );
+
+ let grid = tree.getByRole('grid');
+ let cells = within(grid).getAllByRole('gridcell');
+ expect(cells).toHaveLength(3);
+
+ // Select 'foo' and 'bar'
+ await user.click(cells[0]);
+ await user.click(cells[1]);
+
+ let dataTransfer = new DataTransfer();
+ // Start dragging 'bar'
+ fireEvent(cells[1], new DragEvent('dragstart', {dataTransfer, clientX: 0, clientY: 0}));
+
+ expect(getItems).toHaveBeenCalledTimes(1);
+ let [keysArg, draggedKeyArg] = getItems.mock.calls[0];
+ expect(keysArg).toEqual(new Set(['foo', 'bar']));
+ expect(draggedKeyArg).toBe('bar');
+ });
});
describe('keyboard', () => {
diff --git a/packages/@react-spectrum/dnd/src/useDragAndDrop.ts b/packages/@react-spectrum/dnd/src/useDragAndDrop.ts
index e69e3c73702..ce2babd0d1f 100644
--- a/packages/@react-spectrum/dnd/src/useDragAndDrop.ts
+++ b/packages/@react-spectrum/dnd/src/useDragAndDrop.ts
@@ -65,7 +65,12 @@ export interface DragAndDropOptions extends Omit []
*/
- getItems?: (keys: Set) => DragItem[],
+ getItems?: (
+ /** The set of keys that can be affected by the drag (e.g. the current selection). */
+ keys: Set,
+ /** The key of the item the user actually dragged. */
+ draggedKey: Key
+ ) => DragItem[],
/** Provide a custom drag preview. `draggedKey` represents the key of the item the user actually dragged. */
renderPreview?: (keys: Set, draggedKey: Key) => JSX.Element
}
diff --git a/packages/@react-stately/dnd/src/useDraggableCollectionState.ts b/packages/@react-stately/dnd/src/useDraggableCollectionState.ts
index 5114fbe22a6..5e23743e81b 100644
--- a/packages/@react-stately/dnd/src/useDraggableCollectionState.ts
+++ b/packages/@react-stately/dnd/src/useDraggableCollectionState.ts
@@ -118,7 +118,7 @@ export function useDraggableCollectionState(props: DraggableCollectionStateOptio
},
getKeysForDrag: getKeys,
getItems(key) {
- return getItems(getKeys(key));
+ return getItems(getKeys(key), key);
},
isDisabled,
preview,
diff --git a/packages/@react-types/shared/src/dnd.d.ts b/packages/@react-types/shared/src/dnd.d.ts
index 2fedddd5fa9..96d886973be 100644
--- a/packages/@react-types/shared/src/dnd.d.ts
+++ b/packages/@react-types/shared/src/dnd.d.ts
@@ -285,7 +285,12 @@ export interface DraggableCollectionProps {
/** Handler that is called when the drag operation is ended, either as a result of a drop or a cancellation. */
onDragEnd?: (e: DraggableCollectionEndEvent) => void,
/** A function that returns the items being dragged. */
- getItems: (keys: Set) => DragItem[],
+ getItems: (
+ /** The set of keys that can be affected by the drag (e.g. the current selection). */
+ keys: Set,
+ /** The key of the item the user actually dragged. */
+ draggedKey: Key
+ ) => DragItem[],
/** The ref of the element that will be rendered as the drag preview while dragging. */
preview?: RefObject,
/** Function that returns the drop operations that are allowed for the dragged items. If not provided, all drop operations are allowed. */
diff --git a/packages/react-aria-components/src/useDragAndDrop.tsx b/packages/react-aria-components/src/useDragAndDrop.tsx
index bf59fd687b7..fb1e98c91a2 100644
--- a/packages/react-aria-components/src/useDragAndDrop.tsx
+++ b/packages/react-aria-components/src/useDragAndDrop.tsx
@@ -76,7 +76,12 @@ export interface DragAndDropOptions extends Omit []
*/
- getItems?: (keys: Set) => DragItem[],
+ getItems?: (
+ /** The set of keys that can be affected by the drag (e.g. the current selection). */
+ keys: Set,
+ /** The key of the item the user actually dragged. */
+ draggedKey: Key
+ ) => DragItem[],
/**
* A function that renders a drag preview, which is shown under the user's cursor while dragging.
* By default, a copy of the dragged element is rendered.