diff --git a/src/components/DraggableList/SortableItem.tsx b/src/components/DraggableList/SortableItem.tsx
index 7ed0e0b85a0f7..b4c412bbdcbd1 100644
--- a/src/components/DraggableList/SortableItem.tsx
+++ b/src/components/DraggableList/SortableItem.tsx
@@ -4,7 +4,7 @@ import React from 'react';
import type {SortableItemProps} from './types';
function SortableItem({id, children, disabled = false}: SortableItemProps) {
- const {attributes, listeners, setNodeRef, transform, transition} = useSortable({id, disabled});
+ const {attributes, listeners, setNodeRef, transform, transition, isDragging} = useSortable({id, disabled});
const style = {
touchAction: 'none',
@@ -12,10 +12,21 @@ function SortableItem({id, children, disabled = false}: SortableItemProps) {
transition,
};
+ // Prevent Enter key from reaching MenuItem when dragging to avoid navigation conflicts
+ const handleKeyDown = (e: React.KeyboardEvent) => {
+ if (!isDragging || e.key !== 'Enter') {
+ return;
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ };
+
return (
({
}: DraggableListProps
& {ref?: React.ForwardedRef}) {
const styles = useThemeStyles();
+ // Unique ID per mount to ensure DndContext state resets when component remounts
+ const instanceId = useId();
+
+ // Track if a drag is currently active to avoid dispatching global Escape when not needed
+ const isDraggingRef = useRef(false);
+
+ // Cancel any active keyboard drag when the component unmounts to prevent ghost drag state
+ useEffect(() => {
+ return () => {
+ if (typeof document === 'undefined' || !isDraggingRef.current) {
+ return;
+ }
+ document.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape', code: 'Escape', bubbles: true, cancelable: true}));
+ };
+ }, []);
+
const items = data.map((item, index) => {
return keyExtractor(item, index);
});
+ const onDragStart = () => {
+ isDraggingRef.current = true;
+ };
+
/**
* Function to be called when the user finishes dragging an item
* It will reorder the list and call the callback function
* to notify the parent component about the change
*/
const onDragEnd = (event: DragEndEvent) => {
+ isDraggingRef.current = false;
const {active, over} = event;
if (over !== null && active.id !== over.id) {
@@ -49,6 +70,10 @@ function DraggableList({
}
};
+ const onDragCancel = () => {
+ isDraggingRef.current = false;
+ };
+
const sortableItems = data.map((item, index) => {
const key = keyExtractor(item, index);
// Check if item has a disabled property for dragging
@@ -77,6 +102,11 @@ function DraggableList({
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
+ keyboardCodes: {
+ start: ['Space'],
+ cancel: ['Escape'],
+ end: ['Space'],
+ },
}),
);
@@ -90,7 +120,10 @@ function DraggableList({
>