Drag and drop in React: lista ordinabile e kanban board
Guida al drag and drop in React
Drag and drop in React: lista ordinabile e kanban (dnd-kit) | We.Inc
Crea una lista ordinabile e una kanban board in React con dnd-kit, oppure con gli eventi drag HTML nativi. Board dal vivo nella pagina, spostamenti da tastiera inclusi, codice da copiare.
Per la maggior parte delle app React, dnd-kit è la scelta solida più semplice: un toolkit con licenza MIT che include sensori per puntatore, touch e tastiera. Installa @dnd-kit/react, avvolgi l'area in DragDropProvider, assegna a ogni card useSortable con un id, un index e un group, poi aggiorna lo stato in onDragEnd. Anche gli eventi drag HTML nativi funzionano, ma richiedono più codice scritto a mano.
Due modi per aggiungere il drag and drop
dnd-kit (@dnd-kit/react)
Drag and drop HTML nativo
Installazione
npm install @dnd-kit/react
Niente, è integrato nei browser
Tastiera
Sensore per tastiera incluso
I controlli da tastiera li costruisci tu
Touch
Sensori touch e puntatore inclusi
Varia a seconda del browser; prova sui telefoni
Liste ordinabili
useSortable da @dnd-kit/react/sortable
Calcoli sugli indici fatti da te negli handler di drop
Ideale per
Kanban board, liste ordinabili, griglie
Rilascio di file o drop semplici e isolati
Qui sotto trovi una board funzionante su cui puoi trascinare le card subito, con pulsanti freccia per chi non usa il mouse. Più in basso c'è il codice dnd-kit per la stessa lista ordinabile e la board a più colonne, più la versione con i semplici eventi del browser per confronto.
Trascina una card all'interno della sua colonna per riordinarla, o in un'altra colonna per spostarla.
Niente mouse? Raggiungi una card con Tab e usa i suoi pulsanti di spostamento per cambiare posizione o colonna.
Copia prima la lista ordinabile con dnd-kit, poi la versione kanban che aggiunge un group per colonna.
Tieni i dati della board come semplice stato indicizzato per colonna, e lascia che onDragEnd produca la copia successiva.
Dai a ogni elemento trascinabile un id stabile preso dai tuoi dati. Usare gli indici dell'array come id si rompe non appena gli elementi si spostano.
Esci subito quando event.canceled è true, così premere Escape durante il trascinamento lascia la board intatta.
Salva il nuovo ordine sul backend dopo il drop, e torna indietro se la richiesta fallisce.
Lascia uno spazio o un contorno visibile dove atterrerà la card; le persone devono vedere la destinazione prima di rilasciare.
Anche le colonne vuote hanno bisogno di una zona di drop con una certa altezza, altrimenti non ci si potrà mai rilasciare nulla.
Domande frequenti
react-beautiful-dnd è ancora una buona scelta?
Atlassian ha archiviato il repository di react-beautiful-dnd e consiglia il suo successore, Pragmatic drag and drop. Per i nuovi progetti React, dnd-kit e Pragmatic drag and drop sono le opzioni mantenute attivamente da confrontare.
Qual è la differenza tra @dnd-kit/core e @dnd-kit/react?
@dnd-kit/core con @dnd-kit/sortable è la coppia di pacchetti React di lunga data. @dnd-kit/react è il nuovo adattatore costruito su un core indipendente dal framework, che alimenta anche gli adattatori per Vue, Svelte e Solid. Il nuovo codice può partire da @dnd-kit/react, come fa la documentazione attuale.
Perché il mio evento drop non scatta mai con l'API HTML?
Una destinazione di drop deve chiamare event.preventDefault() nel suo handler dragover. Senza quella chiamata il browser considera l'elemento una destinazione non valida e l'evento drop non viene mai inviato.
Come rendo accessibile il drag and drop?
Rendi ogni card focalizzabile, offri un modo da tastiera per prenderla, spostarla e rilasciarla, e annuncia il risultato in una live region. dnd-kit include di serie un sensore per tastiera e il supporto all'accessibilità; con l'API nativa devi aggiungere tutto tu.
Prima lo stato, poi il trascinamento
Una board è un oggetto di array: un array di id delle card per ogni colonna. Il trascinamento decide solo quale card si è spostata, da dove è partita e dove è atterrata. Ogni libreria ti fornisce questi quattro dati, e il tuo codice li trasforma in un nuovo oggetto.
Scrivi quella funzione di spostamento come helper puro e testala senza browser. dnd-kit ne include perfino una, move da @dnd-kit/helpers, che prende i tuoi elementi e l'evento di trascinamento e restituisce la copia aggiornata.
Perché l'API nativa è più difficile di quanto sembri
Il browser emette sette eventi (dragstart, drag, dragenter, dragleave, dragover, drop e dragend) e devi annullare dragover su ogni destinazione valida. I dati viaggiano attraverso event.dataTransfer come stringhe, e puoi leggerli solo dentro l'handler di drop.
Non esiste un percorso da tastiera né un modo integrato per animare le altre card che si spostano. Va bene per rilasciare un file su un'area di caricamento, ma una board ordinabile diventa presto una piccola libreria a sé.
Lista ordinabile con dnd-kit
Installa con npm install @dnd-kit/react. Ogni elemento conosce il proprio index; dopo un drop, source.initialIndex e source.index ti dicono dove si è spostato.
SortableList.jsx
Riordina un array di nomi di attività. Copiare e poi usare splice lascia intatto lo stato precedente.
Kanban board con dnd-kit
Aggiungi un group a useSortable così le card possono passare da una colonna all'altra. source.initialGroup e source.group sono il nome della colonna vecchia e di quella nuova.
KanbanBoard.jsx
Tre colonne contenute in un unico oggetto. Uno spostamento dentro una colonna la riordina; uno spostamento tra colonne rimuove la card da un array e la inserisce nell'altro.
La stessa idea con gli eventi drag HTML nativi
Nessun pacchetto necessario. Nota il preventDefault in onDragOver: senza di esso il drop non scatta mai.
NativeColumns.jsx
Sposta una card in fondo alla colonna su cui viene rilasciata. Riordinare dentro una colonna richiederebbe logica aggiuntiva sugli indici.
Riferimento agli eventi drag HTML
I sette eventi di trascinamento e dove vengono emessi
Evento
Emesso su
Quando
L'elemento trascinato
Il trascinamento inizia; imposta qui dataTransfer
L'elemento trascinato
Ripetutamente durante il trascinamento
Una possibile destinazione
L'elemento trascinato ci entra
Una possibile destinazione
Ripetutamente mentre ci si trova sopra; chiama preventDefault per consentire il drop
Una possibile destinazione
L'elemento trascinato ne esce
La destinazione
L'elemento viene rilasciato su una destinazione valida; leggi qui dataTransfer
L'elemento trascinato
Il trascinamento termina, con un drop o annullato
Da fare
In corso
Fatto
Logo
Tabella prezzi
Modulo di contatto
Sezione hero
Dominio
{card} spostata in {column}, posizione {n}
Provala: una kanban board funzionante
Trascina le card tra Da fare, In corso e Fatto, oppure usa i pulsanti di spostamento su ogni card.