I am working on a todo list application and I wanted to make the todos draggable. I am using dnd-kit to achieve the same.
I provided the DndContext and SortableContext in my parent container. ListContainer.jsx
<DndContext collisionDetection={closestCorners}>
<SortableContext
items={toDo}
strategy={verticalListSortingStrategy}
>
<div className="bg-red-900">
{toDo.map((item) => (
<ToDo
key={item._id}
id={item._id}
value={text}
isCompleted={item.completed}
text={item.text}
updateTodo={() => updateTodo(item._id, item.text)}
deleteTodo={() => deleteToDo(user.id, item._id, setToDo)}
updateState={() => updateState(item._id)}
inputRef={inputRef}
/>
))}
</div>
</SortableContext>
</DndContext>
And then I used the useSortable hook to destructure some properties necessary to make the todo items draggable.
Todo.jsx
return (
<div
ref={setNodeRef}
{...listeners}
{...attributes}
style={style}
className={`${
isDark
? "bg-black/20 text-white hover:bg-black/60"
: "bg-gray-50/80 hover:bg-gray-200"
} w-full md:w-[70%] mx-auto my-2 flex items-center font-[600] font-mono text-lg justify-between rounded-md shadow-md transition-colors`}
>
<div
className="flex flex-grow items-center h-full p-4 gap-3 cursor-pointer"
onClick={handleCheckboxChange}
>
<input
type="checkbox"
checked={isChecked}
className="cursor-pointer"
readOnly
/>
<div className={`${isChecked ? "line-through" : ""} select-none`}>
<p> {text} </p>
</div>
</div>
<div className="flex gap-4 px-4 select-none text-lg">
<button onClick={handleUpdateToDo}>
<BiEdit />
</button>
<button onClick={deleteToDoHandler}>
<RiDeleteBin6Line />
</button>
</div>
</div>
);
};
Having multiple listeners on my todo component was leading to listners conflicts.
I tried to use drag handlers instead but my todos still wont move.
return (
<div
ref={setNodeRef}
style={style}
className={`${
isDark
? "bg-black/20 text-white hover:bg-black/60"
: "bg-gray-50/80 hover:bg-gray-200"
} w-full md:w-[70%] mx-auto my-2 flex items-center font-[600] font-mono text-lg justify-between rounded-md shadow-md transition-colors`}
>
<div
className="flex flex-grow items-center h-full p-4 gap-3 cursor-pointer"
onClick={handleCheckboxChange}
>
<input
type="checkbox"
checked={isChecked}
className="cursor-pointer"
readOnly
/>
<div className={`${isChecked ? "line-through" : ""} select-none`}>
<p> {text} </p>
</div>
</div>
<div className="flex gap-4 px-4 select-none text-lg">
<button onClick={handleUpdateToDo}>
<BiEdit />
</button>
<button onClick={deleteToDoHandler}>
<RiDeleteBin6Line />
</button>
<button className="px-2 py-2" {...attributes} {...listeners}>
Drag me
</button>
</div>
</div>
);
What am I missing here?