Column Layouts (Kanban Boards)
A very common use case for drag-and-drop is a Kanban board (e.g., Trello or Jira). You have multiple columns, and items can be sorted within a column or moved between different columns.
Alugard-Drop makes this incredibly easy.
How it looks in index.html
Replace the content of your index.html <body> with this example structure to see it in action.
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kanban Board Example</title>
</head>
<body>
<div id="app">
<h2>Project Board</h2>
<div class="board">
<!-- Column 1: To Do -->
<div class="column">
<h3>To Do</h3>
<div id="todo" class="task-list">
<div class="task">Research competitors</div>
<div class="task">Design database schema</div>
<div class="task">Create wireframes</div>
</div>
</div>
<!-- Column 2: In Progress -->
<div class="column">
<h3>In Progress</h3>
<div id="in-progress" class="task-list">
<div class="task">Setup Vite project</div>
<div class="task">Configure Tailwind CSS</div>
</div>
</div>
<!-- Column 3: Done -->
<div class="column">
<h3>Done</h3>
<div id="done" class="task-list">
<div class="task">Initial meeting</div>
<div class="task">Requirements gathering</div>
</div>
</div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>src/main.ts
To make the Kanban board work, grab the .task-list containers and pass them to Alugard.
typescript
import alugard from 'alugard-drop';
import 'alugard-drop/style.css';
// Select all task lists in our columns
const todo = document.getElementById('todo')!;
const inProgress = document.getElementById('in-progress')!;
const done = document.getElementById('done')!;
// Initialize Alugard
const drake = alugard([todo, inProgress, done], {
// Optional configuration
revertOnSpill: true, // If dropped outside a valid container, return to original location
});
drake.on('drop', (el, target, source) => {
// Example of using events to track state changes
if (target !== source) {
console.log(`Task moved from ${source.id} to ${target.id}`);
}
});src/style.css
Styles to make our Kanban board look like a real board. We'll use CSS Flexbox.
css
body {
font-family: system-ui, -apple-system, sans-serif;
background: #f8fafc;
color: #0f172a;
margin: 0;
padding: 20px;
}
/* Board Layout */
.board {
display: flex;
gap: 20px;
align-items: flex-start; /* Prevents columns from completely stretching */
overflow-x: auto;
padding-bottom: 20px;
}
/* Individual Column Wrapper */
.column {
background: #e2e8f0;
border-radius: 8px;
width: 300px;
min-width: 300px;
display: flex;
flex-direction: column;
}
.column h3 {
margin: 0;
padding: 15px;
font-size: 16px;
color: #334155;
}
/* The drop target zone */
.task-list {
padding: 0 10px 10px 10px;
min-height: 100px; /* Crucial: Ensure empty columns have a drop target area */
display: flex;
flex-direction: column;
gap: 10px;
}
/* The draggable tasks */
.task {
background: white;
padding: 15px;
border-radius: 6px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
cursor: grab;
user-select: none; /* Prevents text selection while dragging */
}
.task:active {
cursor: grabbing;
}
/* Styling the element while it is being dragged (Transit element) */
.ad-transit {
opacity: 0.2;
border: 2px dashed #94a3b8;
background: #f1f5f9;
}