diff --git a/packages/@react-aria/dnd/src/DragManager.ts b/packages/@react-aria/dnd/src/DragManager.ts index 2128797ffb4..ab306c65465 100644 --- a/packages/@react-aria/dnd/src/DragManager.ts +++ b/packages/@react-aria/dnd/src/DragManager.ts @@ -583,6 +583,9 @@ class DragSession { this.dragTarget.element.focus(); } + // Re-trigger focus event on active element, since it will not have received it during dragging (see cancelEvent). + document.activeElement?.dispatchEvent(new FocusEvent('focusin', {bubbles: true})); + announce(this.stringFormatter.format('dropCanceled')); } diff --git a/packages/react-aria-components/stories/Table.stories.tsx b/packages/react-aria-components/stories/Table.stories.tsx index f33e05c8ac2..e30c0b75c58 100644 --- a/packages/react-aria-components/stories/Table.stories.tsx +++ b/packages/react-aria-components/stories/Table.stories.tsx @@ -529,6 +529,83 @@ DndTableExample.args = { isLoading: false }; +function DndTableWithNoValidDropTargetsRender(): JSX.Element { + let list = useListData({ + initialItems: [ + {id: '1', type: 'file', name: 'Adobe Photoshop'}, + {id: '2', type: 'file', name: 'Adobe XD'}, + {id: '3', type: 'folder', name: 'Documents'}, + {id: '4', type: 'file', name: 'Adobe InDesign'}, + {id: '5', type: 'folder', name: 'Utilities'}, + {id: '6', type: 'file', name: 'Adobe AfterEffects'} + ] + }); + + let {dragAndDropHooks} = useDragAndDrop({ + getItems(keys) { + return [...keys].filter(k => !!list.getItem(k)).map((key) => { + let item = list.getItem(key); + return { + 'custom-app-type': JSON.stringify(item), + 'text/plain': item!.name + }; + }); + }, + onItemDrop() {}, + shouldAcceptItemDrop() { + return false; + } + }); + + return ( +