Que fait Glisser-Déposer ?
Règles
- Utilisez
@dnd-kit/core + @dnd-kit/sortable — bibliothèque DnD moderne, accessible et tactile
- Listes triables : enveloppez dans
<SortableContext>, chaque élément utilise le hook useSortable()
- Tableaux Kanban :
<DndContext> avec plusieurs conteneurs <SortableContext> — un par colonne
- Zones de dépôt de fichiers :
react-dropzone ou les événements natifs onDragOver/onDrop avec e.dataTransfer.files
- Prise en charge tactile : dnd-kit gère le tactile nativement — utilisez
TouchSensor et PointerSensor avec des contraintes d'activation
- Accessibilité : dnd-kit fournit le DnD clavier prêt à l'emploi —
KeyboardSensor avec sortableKeyboardCoordinates
- Réordonnancement optimiste : mettez à jour l'état immédiatement lors du dépôt, persistez en arrière-plan vers le serveur, restaurez en cas d'erreur
- Superposition de glissement : utilisez
<DragOverlay> pour un aperçu flottant de l'élément glissé — meilleur retour visuel
Modèles
import { DndContext, closestCenter, DragOverlay } from "@dnd-kit/core";
import { SortableContext, verticalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
function SortableItem({ id, children }: { id: string; children: React.ReactNode }) {
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id });
const style = { transform: CSS.Transform.toString(transform), transition };
return (
<div ref={setNodeRef} style={style} {...attributes} {...listeners}>
{children}
</div>
);
}
function SortableList({ items }: { items: Item[] }) {
const [activeId, setActiveId] = useState<string | null>(null);
return (
<DndContext
collisionDetection={closestCenter}
onDragStart={({ active }) => setActiveId(active.id)}
onDragEnd={handleDragEnd}
>
<SortableContext items={items.map((i) => i.id)} strategy={verticalListSortingStrategy}>
{items.map((item) => (
<SortableItem key={item.id} id={item.id}>{item.name}</SortableItem>
))}
</SortableContext>
<DragOverlay>{activeId ? <ItemPreview id={activeId} /> : null}</DragOverlay>
</DndContext>
);
}
À éviter
- Utiliser directement l'API de glissement HTML5 — mauvaise prise en charge tactile/mobile/accessibilité
- Oublier l'accessibilité clavier — incluez toujours
KeyboardSensor
- Modifier l'état pendant le glissement — mettez à jour uniquement sur
onDragEnd
- Omettre
<DragOverlay> — sans lui, l'élément d'origine disparaît pendant le glissement sans aucun retour visuel