);
}
// Main sortable list component
export function SortableList() {
const [items, setItems] = useState([
{ id: '1', text: 'Complete project documentation', completed: false, priority: 'high' },
{ id: '2', text: 'Review pull requests', completed: true, priority: 'medium' },
{ id: '3', text: 'Update dependencies', completed: false, priority: 'low' },
{ id: '4', text: 'Write unit tests', completed: false, priority: 'high' },
{ id: '5', text: 'Deploy to staging', completed: false, priority: 'medium' },
]);
// Configure sensors for keyboard and pointer
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
distance: 8, // 8px movement required to start drag
},
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
// Handle drag end
function handleDragEnd(event: DragEndEvent) {
const { active, over } = event;
if (over && active.id !== over.id) {
setItems((items) => {
const oldIndex = items.findIndex((item) => item.id === active.id);
const newIndex = items.findIndex((item) => item.id === over.id);
const newItems = arrayMove(items, oldIndex, newIndex);
// Announce change to screen readers
announceReorder(items[oldIndex], oldIndex + 1, newIndex + 1);
return newItems;
});
}
}
// Screen reader announcement
function announceReorder(item: TodoItem, fromPosition: number, toPosition: number) {
const announcement = `${item.text} moved from position ${fromPosition} to position ${toPosition}`;
const liveRegion = document.getElementById('drag-drop-announcements');
if (liveRegion) {
liveRegion.textContent = announcement;
}
}
return (
Todo List (Drag to Reorder)
{/* Screen reader instructions */}
To reorder items: Press Tab to navigate to an item's drag handle,
press Space or Enter to lift the item, use Arrow keys to move it,
and press Space or Enter again to drop it in the new position.
Press Escape to cancel the drag operation.
{/* Live region for announcements */}
{/* Sortable list */}