import type { DragEndEvent, DragStartEvent } from "@dnd-kit/core" import { useState } from "react" export interface UseSortableListProps { items: T[] onReorder?: (oldIndex: number, newIndex: number) => void onItemsChange?: (items: T[]) => void } export interface UseSortableListReturn { items: T[] activeId: string | null handleDragStart: (event: DragStartEvent) => void handleDragEnd: (event: DragEndEvent) => void handleDragCancel: () => void setItems: (items: T[]) => void } export function useSortableList({ items: initialItems, onReorder, onItemsChange, }: UseSortableListProps): UseSortableListReturn { const [items, setItemsState] = useState(initialItems) const [activeId, setActiveId] = useState(null) const setItems = (newItems: T[]) => { setItemsState(newItems) onItemsChange?.(newItems) } const handleDragStart = (event: DragStartEvent) => { setActiveId(event.active.id as string) } const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event setActiveId(null) if (over && active.id !== over.id) { const oldIndex = items.findIndex(item => typeof item === "string" ? item === active.id : typeof item === "object" && item !== null ? "id" in item && item.id === active.id : false, ) const newIndex = items.findIndex(item => typeof item === "string" ? item === over.id : typeof item === "object" && item !== null ? "id" in item && item.id === over.id : false, ) if (oldIndex !== -1 && newIndex !== -1) { const updated = [...items] const [movedItem] = updated.splice(oldIndex, 1) updated.splice(newIndex, 0, movedItem) setItems(updated) onReorder?.(oldIndex, newIndex) } } } const handleDragCancel = () => { setActiveId(null) } return { items, activeId, handleDragStart, handleDragEnd, handleDragCancel, setItems, } }