Build a three-column Kanban board (To Do / In Progress / Done) as a single React component. Each column shows its title, a live count, and its cards. Cards are draggable with the native HTML5 drag-and-drop API, and dragging a card onto another column moves it there — the source loses it, the target gains it, and both counts update.
The starter App.tsx renders the three columns with their initial cards and counts, but nothing moves yet. Wire up the drag-and-drop:
todo / doing / done arrays) in useState instead of the fixed const.onDragStart, record which card and which column it came from.onDragOver, call e.preventDefault() — without it the column is not a valid drop target and onDrop never fires. Add an over class to highlight it.onDrop, remove the card from its source array and append it to the target array. Counts read from each array's length, so they update on their own.Set up CI from To Do onto In Progress: To Do drops to 2, In Progress rises to 2, and the card appears at the bottom of In Progress.over highlight); it clears when you leave or drop.onDragOver must preventDefault. It is the single most-missed step; skip it and drops silently do nothing.columns[id].length at render time; never keep a separate counter in sync.over and dragging states) is already in styles.css; focus on the state and the handlers.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.