diff --git a/src/components/drag-drop/SortableList.tsx b/src/components/drag-drop/SortableList.tsx index f7887641..7ae9e7a3 100644 --- a/src/components/drag-drop/SortableList.tsx +++ b/src/components/drag-drop/SortableList.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react'; import { useDrag, useDrop } from 'react-dnd'; import { DragDropItem } from '../../utils/dragDropUtils'; @@ -35,6 +35,37 @@ const SortableRow = ({ onMoveToZone: (itemId: string, fromZoneId: string, toZoneId: string, toIndex?: number) => void; }) => { const ref = useRef(null); + const [isKeyboardDragging, setIsKeyboardDragging] = useState(false); + + const moveItem = (direction: 'up' | 'down') => { + const targetIndex = direction === 'up' ? index - 1 : index + 1; + if (targetIndex < 0) return; + onReorder(zoneId, index, targetIndex); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + switch (e.key) { + case ' ': + case 'Enter': + e.preventDefault(); + setIsKeyboardDragging((prev) => !prev); + break; + + case 'ArrowUp': + e.preventDefault(); + if (isKeyboardDragging) moveItem('up'); + break; + + case 'ArrowDown': + e.preventDefault(); + if (isKeyboardDragging) moveItem('down'); + break; + + case 'Escape': + setIsKeyboardDragging(false); + break; + } + }; const [{ isDragging }, drag] = useDrag( () => ({ @@ -56,33 +87,20 @@ const SortableRow = ({ () => ({ accept: DRAG_ITEM_TYPE, hover: (dragged: DragPayload, monitor) => { - if (!ref.current) { - return; - } - - if (dragged.fromZoneId !== zoneId) { - return; - } - - if (dragged.index === index) { - return; - } + if (!ref.current) return; + if (dragged.fromZoneId !== zoneId) return; + if (dragged.index === index) return; const hoverRect = ref.current.getBoundingClientRect(); const hoverMiddleY = (hoverRect.bottom - hoverRect.top) / 2; + const clientOffset = monitor.getClientOffset(); - if (!clientOffset) { - return; - } + if (!clientOffset) return; const hoverClientY = clientOffset.y - hoverRect.top; - if (dragged.index < index && hoverClientY < hoverMiddleY) { - return; - } - if (dragged.index > index && hoverClientY > hoverMiddleY) { - return; - } + if (dragged.index < index && hoverClientY < hoverMiddleY) return; + if (dragged.index > index && hoverClientY > hoverMiddleY) return; onReorder(zoneId, dragged.index, index); dragged.index = index; @@ -103,12 +121,29 @@ const SortableRow = ({ return (
-
{item.title}
-
#{item.order + 1}
+
+
+
{item.title}
+
#{item.order + 1}
+
+ + {/* Accessible drag handle */} + +
); }; @@ -129,7 +164,7 @@ export const SortableList = ({ } return ( -
+
{items.map((item, index) => (