Horizontal grouping on a Kanban board.
<section class="swimlane" aria-labelledby="swimlane-heading" style="--accent: #D9C8F0;">
<h3 id="swimlane-heading" class="swimlane__heading">Assignee: Priya Nair</h3>
<div class="swimlane__scroll">
<div class="swimlane__strip">
<section class="swimlane__column" aria-labelledby="swimlane-col-todo">
<h4 id="swimlane-col-todo" class="swimlane__column-title">To do <span class="swimlane__count">2 items</span></h4>
<ul class="swimlane__cards">
<li class="swimlane__card" draggable="true">
<span class="swimlane__card-title">Draft onboarding flow</span>
<span class="swimlane__card-avatar">PN</span>
<button type="button" class="swimlane__move">Move to In progress</button>
</li>
<li class="swimlane__card" draggable="true">
<span class="swimlane__card-title">Audit empty states</span>
<span class="swimlane__card-avatar">PN</span>
<button type="button" class="swimlane__move">Move to In progress</button>
</li>
</ul>
</section>
<section class="swimlane__column" aria-labelledby="swimlane-col-progress">
<h4 id="swimlane-col-progress" class="swimlane__column-title">In progress <span class="swimlane__count">1 item</span></h4>
<ul class="swimlane__cards">
<li class="swimlane__card" draggable="true">
<span class="swimlane__card-title">Ship notification prefs</span>
<span class="swimlane__card-avatar">PN</span>
<button type="button" class="swimlane__move">Move to Done</button>
</li>
</ul>
</section>
</div>
</div>
</section>
<style>
.swimlane { font-family: system-ui, sans-serif; color: #241430; background: #FAF7F2; padding: 16px; border-radius: 10px; max-width: 660px; box-sizing: border-box; }
.swimlane__heading { margin: 0 0 12px; font-size: 15px; font-weight: 700; }
.swimlane__scroll { overflow-x: auto; padding-bottom: 4px; }
.swimlane__strip { display: flex; gap: 16px; min-width: max-content; }
.swimlane__strip--compact { gap: 8px; }
.swimlane__column { width: 220px; flex: 0 0 auto; background: #24143008; border-radius: 8px; padding: 10px; box-sizing: border-box; }
.swimlane__strip--compact .swimlane__column { width: 180px; padding: 6px; }
.swimlane__column-title { margin: 0 0 8px; font-size: 13px; font-weight: 600; display: flex; justify-content: space-between; align-items: center; }
.swimlane__count { font-weight: 500; font-size: 11px; color: #241430aa; }
.swimlane__cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.swimlane__card { background: #FAF7F2; border: 1px solid #24143020; border-radius: 6px; padding: 8px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12.5px; }
.swimlane__card-title { flex: 1 1 auto; }
.swimlane__card-avatar { width: 22px; height: 22px; border-radius: 50%; background: var(--accent); display: inline-flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; color: #241430; }
.swimlane__move { flex: 0 0 100%; font-size: 11px; border: 1px solid #24143040; background: transparent; border-radius: 6px; padding: 4px 6px; cursor: pointer; color: #241430; }
.swimlane__move:hover, .swimlane__move:focus-visible { background: #24143012; outline: 2px solid var(--accent); outline-offset: 1px; }
</style><section class="swimlane-tw font-sans text-[#241430] bg-[#FAF7F2] p-4 rounded-[10px] max-w-[660px] box-border" aria-labelledby="swimlane-tw-heading" style="--accent: #D9C8F0;">
<h3 id="swimlane-tw-heading" class="m-0 mb-3 text-[15px] font-bold">Assignee: Priya Nair</h3>
<div class="overflow-x-auto pb-1">
<div class="swimlane-tw__strip flex gap-4" style="min-width: max-content;">
<section class="swimlane-tw__column w-[220px] flex-none bg-[#24143008] rounded-lg p-2.5 box-border" aria-labelledby="swimlane-tw-col-todo">
<h4 id="swimlane-tw-col-todo" class="m-0 mb-2 text-[13px] font-semibold flex justify-between items-center">To do <span class="font-medium text-[11px] text-[#241430aa]">2 items</span></h4>
<ul class="list-none m-0 p-0 flex flex-col gap-2">
<li class="flex flex-wrap items-center gap-1.5 bg-[#FAF7F2] border border-[#24143020] rounded-md p-2 text-[12.5px]" draggable="true">
<span class="flex-1">Draft onboarding flow</span>
<span class="w-[22px] h-[22px] rounded-full inline-flex items-center justify-center text-[10px] font-bold" style="background: var(--accent);">PN</span>
<button type="button" class="swimlane-tw__move flex-none w-full text-[11px] border border-[#24143040] bg-transparent rounded-md px-1.5 py-1 cursor-pointer text-[#241430]">Move to In progress</button>
</li>
<li class="flex flex-wrap items-center gap-1.5 bg-[#FAF7F2] border border-[#24143020] rounded-md p-2 text-[12.5px]" draggable="true">
<span class="flex-1">Audit empty states</span>
<span class="w-[22px] h-[22px] rounded-full inline-flex items-center justify-center text-[10px] font-bold" style="background: var(--accent);">PN</span>
<button type="button" class="swimlane-tw__move flex-none w-full text-[11px] border border-[#24143040] bg-transparent rounded-md px-1.5 py-1 cursor-pointer text-[#241430]">Move to In progress</button>
</li>
</ul>
</section>
<section class="swimlane-tw__column w-[220px] flex-none bg-[#24143008] rounded-lg p-2.5 box-border" aria-labelledby="swimlane-tw-col-progress">
<h4 id="swimlane-tw-col-progress" class="m-0 mb-2 text-[13px] font-semibold flex justify-between items-center">In progress <span class="font-medium text-[11px] text-[#241430aa]">1 item</span></h4>
<ul class="list-none m-0 p-0 flex flex-col gap-2">
<li class="flex flex-wrap items-center gap-1.5 bg-[#FAF7F2] border border-[#24143020] rounded-md p-2 text-[12.5px]" draggable="true">
<span class="flex-1">Ship notification prefs</span>
<span class="w-[22px] h-[22px] rounded-full inline-flex items-center justify-center text-[10px] font-bold" style="background: var(--accent);">PN</span>
<button type="button" class="swimlane-tw__move flex-none w-full text-[11px] border border-[#24143040] bg-transparent rounded-md px-1.5 py-1 cursor-pointer text-[#241430]">Move to Done</button>
</li>
</ul>
</section>
</div>
</div>
</section>
<style>
.swimlane-tw__strip--compact { gap: 8px; }
.swimlane-tw__strip--compact .swimlane-tw__column { width: 180px; padding: 6px; }
.swimlane-tw__move:hover, .swimlane-tw__move:focus-visible { background: #24143012; outline: 2px solid var(--accent); outline-offset: 1px; }
</style>export function Swimlane({
groupBy = "Assignee",
laneName = "Priya Nair",
accent = "#D9C8F0",
showCount = true,
compact = false,
}) {
const columnStyle = { width: compact ? 180 : 220, flex: "0 0 auto", background: "#24143008", borderRadius: 8, padding: compact ? 6 : 10, boxSizing: "border-box" };
const cardStyle = { background: "#FAF7F2", border: "1px solid #24143020", borderRadius: 6, padding: 8, display: "flex", flexWrap: "wrap", alignItems: "center", gap: 6, fontSize: 12.5 };
const avatarStyle = { width: 22, height: 22, borderRadius: "50%", background: accent, display: "inline-flex", alignItems: "center", justifyContent: "center", fontSize: 10, fontWeight: 700, color: "#241430" };
const moveBtnStyle = { flex: "0 0 100%", fontSize: 11, border: "1px solid #24143040", background: "transparent", borderRadius: 6, padding: "4px 6px", cursor: "pointer", color: "#241430" };
return (
<section aria-labelledby="swimlane-heading" style={{ fontFamily: "system-ui, sans-serif", color: "#241430",
background: "#FAF7F2", padding: 16, borderRadius: 10, maxWidth: 660, boxSizing: "border-box" }}>
<h3 id="swimlane-heading" style={{ margin: "0 0 12px", fontSize: 15, fontWeight: 700 }}>{groupBy}: {laneName}</h3>
<div style={{ overflowX: "auto", paddingBottom: 4 }}>
<div style={{ display: "flex", gap: compact ? 8 : 16, minWidth: "max-content" }}>
<section aria-labelledby="swimlane-col-todo" style={columnStyle}>
<h4 id="swimlane-col-todo" style={{ margin: "0 0 8px", fontSize: 13, fontWeight: 600, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
To do {showCount && <span style={{ fontWeight: 500, fontSize: 11, color: "#241430aa" }}>2 items</span>}
</h4>
<ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 8 }}>
<li style={cardStyle} draggable="true">
<span style={{ flex: "1 1 auto" }}>Draft onboarding flow</span>
<span style={avatarStyle}>PN</span>
<button type="button" style={moveBtnStyle}>Move to In progress</button>
</li>
<li style={cardStyle} draggable="true">
<span style={{ flex: "1 1 auto" }}>Audit empty states</span>
<span style={avatarStyle}>PN</span>
<button type="button" style={moveBtnStyle}>Move to In progress</button>
</li>
</ul>
</section>
<section aria-labelledby="swimlane-col-progress" style={columnStyle}>
<h4 id="swimlane-col-progress" style={{ margin: "0 0 8px", fontSize: 13, fontWeight: 600, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
In progress {showCount && <span style={{ fontWeight: 500, fontSize: 11, color: "#241430aa" }}>1 item</span>}
</h4>
<ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 8 }}>
<li style={cardStyle} draggable="true">
<span style={{ flex: "1 1 auto" }}>Ship notification prefs</span>
<span style={avatarStyle}>PN</span>
<button type="button" style={moveBtnStyle}>Move to Done</button>
</li>
</ul>
</section>
</div>
</div>
</section>
);
}