Drag & Drop
On part de la base de code du TD front-end. Vous trouverez à l'intérieur du fichier main.jsx un code pour react-query qui donnait le contexte avec QueryClientProvider. On va faire la même chose mais pour le drag & drop afin que deux composants puissent comuniquer ensemble sans savoir qui sont les deux.
Installation
Installer la librairie dnd-kit :
npm i @dnd-kit/core
Puis on ajoute le contexte dans le App.jx, on met le contexte autour des tâches comme ça ce contexte là ne concernera que les tâches et les colonnes. Ça nous facilitera la vie :
// ...
import { DndContext } from '@dnd-kit/core'
function App() {
// ...
return (
// ...
<DndContext>
// .map des tâches
</DndContext>
// ...
)
}
Création de notre premier droppable
Pour créer un droppable, on va utiliser le hook useDroppable.
import { useDroppable } from '@dnd-kit/core'
export function Column({ status, tasks }) {
const { setNodeRef } = useDroppable({ id: status })
return <div ref={setNodeRef} className="flex flex-col gap-4">
<h2 className="text-lg font-bold">{status}</h2>
<div className="border rounded-lg grow p-4">
<ul className="flex flex-col gap-4">
{tasks.map((task) => {
return <Task key={task.id} task={task} />;
})}
</ul>
</div>
</div>
}
Création de notre premier draggable
Pour créer un draggable, on va utiliser le hook useDraggable.
import { useDraggable } from '@dnd-kit/core'
export function Task({ task }) {
const { attributes, listeners, setNodeRef, transform } = useDraggable({ id: task.id })
const style = transform ? {
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
} : undefined
return <li key={task.id} className="border rounded-lg p-4" ref={setNodeRef} style={style} {...listeners} {...attributes}>
<h3 className="font-bold">{task.title}</h3>
<p>{task.description}</p>
</li>
}
Pour tester que ça marche, on peut récupérer le isOver du droppable pour voir si un draggable est sur le droppable.
import { useDroppable } from '@dnd-kit/core'
export function Column({ status, tasks }) {
const { setNodeRef, isOver } = useDroppable({ id: status })
const style = {
backgroundColor: isOver ? 'red' : 'white',
}
return <div ref={setNodeRef} className="flex flex-col gap-4" style={style}>
// ...
</div>
}
Testons les événements drag & drop
Pour tester les événements, on va retourner dans le DndContext, et on va utiliser l'événement onDragEnd, qui est l'événement qui est lancé lorsque le draggable est droppé.
import { DndContext } from '@dnd-kit/core'
function App() {
const handleDragEnd = (event) => {
console.log(event)
console.log(`La ${event.active.id} a été drop sur ${event.over.id}`)
}
// ...
return (
// ...
<DndContext onDragEnd={handleDragEnd}>
Ici, lorsqu'on drop une tâche sur une colonne, on va logguer l'id de la tâche et l'id de la colonne.