How to create a Kanban with react-beautiful-dnd
Felipe Jung
2021-01-01T00:00:00.000Z
Introduction#
Dealing with drag and drop can be hard, specially if you don't have much experience with any libraries focused on that. There are a lot of very good libraries out there that makes it easier to work with drag and drop, like react-dnd and react-draggable, but our focus today is on building a kanban (basically a board with draggable columns and cards) with react-beautiful-dnd.
react-beautiful-dnd#
react-beatiful-dnd is a library focused on making it easy to have list with draggables and reordable elements. Feel free to check it on the links below:
Initiating project#
I will be using create-react-app and typescript for this tutorial.
Create initial project structure using CRA then open it in your favorite code editor, Vistual Studio Code in my case.
npx create-react-app react-beautiful-dnd-kanban --template typescript
code react-beautiful-dnd-kanban
After some cleaning up in the project initial structure (check the changes here), we need to add the react-beautiful-dnd library and its types.
yarn add react-beautiful-dnd
yarn add -D @types/react-beautiful-dnd
And that's it! Now we can create the kanban components.
Kanban Components#
We can divide the kanban in simple three components, the board, the column and the card. The board is just a droppable zone, because you can move and drop columns in it. The column is a droppable zone (because you can drop cards in it) and also and draggable (because you can drag it and change the columns order). The card is a draggable, you can drag around columns.
We will start by coding the board (we can say it's the same as the Kanban, because everything is inside it):
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
export const Kanban = () => {
return (
<DragDropContext onDragEnd={() => console.log('Drag has ended')}>
<Droppable droppableId="columns" direction="horizontal" type="COLUMN">
{(provided) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
<h3>Hello World</h3>
</div>
)}
</Droppable>
</DragDropContext>
);
};
Column:
import { Draggable, Droppable } from 'react-beautiful-dnd';
type ColumnProps = {
id: string,
index: number
};
export const Column = ({ id, index }: ColumnProps) => (
<Draggable draggableId={id} index={index}>
{(draggableProvided, snapshot) => (
<div
ref={draggableProvided.innerRef}
{...draggableProvided.draggableProps}
>
<Droppable droppableId={id} type="COLUMN">
{(droppableProvided, snapshot) => (
<div
ref={droppableProvided.innerRef}
{...droppableProvided.droppableProps}
>
<h1>Column</h1>
</div>
)}
</Droppable>
</div>
)}
</Draggable>
);