feat: add drag-and-drop for cards and columns with keyboard support

This commit is contained in:
Your Name
2026-02-15 18:55:35 +02:00
parent 624be051c1
commit 86de747bc4
4 changed files with 426 additions and 67 deletions

View File

@@ -1,4 +1,6 @@
import { format, isPast, isToday } from "date-fns";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import type { Card, Label } from "@/types/board";
import { LabelDots } from "@/components/board/LabelDots";
import { ChecklistBar } from "@/components/board/ChecklistBar";
@@ -6,9 +8,28 @@ import { ChecklistBar } from "@/components/board/ChecklistBar";
interface CardThumbnailProps {
card: Card;
boardLabels: Label[];
columnId: string;
}
export function CardThumbnail({ card, boardLabels }: CardThumbnailProps) {
export function CardThumbnail({ card, boardLabels, columnId }: CardThumbnailProps) {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable({
id: card.id,
data: { type: "card", columnId },
});
const style = {
transform: CSS.Transform.toString(transform),
transition,
opacity: isDragging ? 0.3 : undefined,
};
const hasDueDate = card.dueDate != null;
const dueDate = hasDueDate ? new Date(card.dueDate!) : null;
const overdue = dueDate != null && isPast(dueDate) && !isToday(dueDate);
@@ -20,8 +41,12 @@ export function CardThumbnail({ card, boardLabels }: CardThumbnailProps) {
return (
<button
ref={setNodeRef}
style={style}
onClick={handleClick}
className="w-full rounded-lg bg-pylon-surface p-3 shadow-sm text-left transition-all duration-200 hover:-translate-y-px hover:shadow-md"
{...attributes}
{...listeners}
>
{/* Label dots */}
{card.labels.length > 0 && (