feat: accessibility pass — semantic HTML, ARIA, focus indicators, high contrast

This commit is contained in:
Your Name
2026-02-15 19:19:34 +02:00
parent e2ce484955
commit 943b24c371
4 changed files with 64 additions and 12 deletions

View File

@@ -60,11 +60,14 @@ export function KanbanColumn({ column, onCardClick }: KanbanColumnProps) {
width,
};
const cardCount = column.cardIds.length;
return (
<motion.div
<motion.section
ref={setSortableNodeRef}
style={style}
className="group/column flex shrink-0 flex-col rounded-lg bg-pylon-column"
aria-label={`${column.title} column, ${cardCount} card${cardCount !== 1 ? "s" : ""}`}
initial={prefersReducedMotion ? false : { opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ type: "spring", stiffness: 300, damping: 25 }}
@@ -81,21 +84,22 @@ export function KanbanColumn({ column, onCardClick }: KanbanColumnProps) {
strategy={verticalListSortingStrategy}
>
<ScrollArea className="flex-1 overflow-y-auto">
<div ref={setDroppableNodeRef} className="flex min-h-[40px] flex-col gap-2 p-2">
<ul ref={setDroppableNodeRef} className="flex min-h-[40px] list-none flex-col gap-2 p-2">
{column.cardIds.map((cardId) => {
const card = board?.cards[cardId];
if (!card) return null;
return (
<CardThumbnail
key={cardId}
card={card}
boardLabels={board?.labels ?? []}
columnId={column.id}
onCardClick={onCardClick}
/>
<li key={cardId}>
<CardThumbnail
card={card}
boardLabels={board?.labels ?? []}
columnId={column.id}
onCardClick={onCardClick}
/>
</li>
);
})}
</div>
</ul>
</ScrollArea>
</SortableContext>
@@ -118,6 +122,6 @@ export function KanbanColumn({ column, onCardClick }: KanbanColumnProps) {
</Button>
</div>
)}
</motion.div>
</motion.section>
);
}