Hey everyone, it's Sadee! If you've ever wanted to build a cool task board where you can move things around—kind of like Trello or Jira—you are in the right place. Today, we are going to build one from scratch. You will be able to click on a task, drag it across your screen, and drop it into a totally new column.
The best part? We aren't going to download any heavy drag-and-drop tools. We are just using the native tools that are already built right into your web browser!
How We Set Up the Project
If you look at the project files, you'll see we set everything up to be fast and easy to work with:
- We are using Vite to run our local server, which is why we have a vite.config.ts file.
- We are writing our code in TypeScript, and you can see the rules for that in the tsconfig.json file.
- We are using pnpm to manage all our packages, which creates the pnpm-lock.yaml file.
- To keep our app looking clean, we put our buttons, inputs, and text areas inside a nice UI folder. We also have a theme-provider.tsx file to help manage our colors.
Making the Task Cards Move
To make a task draggable, we built a file called TaskCard.tsx. When you want to drag an item, you just add the word draggable to your HTML tag. Then, you tell the browser what is being dragged by using an event called onDragStart.
Here is a simple look at how we wrote the code for our task cards:
// src/components/TaskCard.tsx
export default function TaskCard({ task }) {
// This runs the moment you click and start dragging
const handleDragStart = (event) => {
// We save the task ID so the browser remembers what we are holding
event.dataTransfer.setData("taskId", task.id);
};
return (
<div
draggable
onDragStart={handleDragStart}
className="p-4 mb-3 bg-white rounded shadow cursor-grab"
>
<p>{task.title}</p>
</div>
);
}
Catching the Task in a New Column
Now that we are holding our task, we need a place to put it down. For this, we built a
DropBox.tsx component and placed it inside our main Column.tsx file.
To make a drop zone work, you have to use two events: onDragOver and onDrop. The most important trick here is that you must stop the browser's default behavior when hovering, or it won't let you drop your item!
Here is how we built our drop zone:
// src/components/DropBox.tsx
export default function DropBox({ onTaskDropped }) {
// This tells the browser: "Yes, you are allowed to drop things here!"
const handleDragOver = (event) => {
event.preventDefault();
};
// This runs when you let go of the mouse button
const handleDrop = (event) => {
// We grab the task ID we saved earlier
const droppedTaskId = event.dataTransfer.getData("taskId");
// We send that ID to our app so it can update the screen
onTaskDropped(droppedTaskId);
};
return (
<div
onDragOver={handleDragOver}
onDrop={handleDrop}
className="w-full min-h-[200px] p-4 bg-gray-100 rounded-lg"
>
{/* Task cards will show up here */}
</div>
);
}
Adding New Tasks
We also wanted a way to type out brand new things to do. So, we made a TaskCreateField.tsx component where you can type your next big idea and add it straight to the board.
If you want to follow along with the video and build this exact project with me, you can check it out on my YouTube channel, codewithsadee.
Are there any other cool features you'd want to add to this task board next?
Top comments (0)