Board Card
A work item as a board card — a done tick or status circle, a two-line title, a context line, and assignee, due and priority chips.
- Status
- Since
0.23.16- Accessibility pattern
- named done tick, named avatar
Last updated
Install
Add Board Card from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.
pnpm dlx shadcn@latest add @vegastack/board-cardThe same command installs the registry items it composes: @vegastack/avatar, @vegastack/badge, @vegastack/checkbox, @vegastack/hover-card, @vegastack/person-hover-card, @vegastack/date-time.
Usage
import { BoardCard } from "@/components/ui/board-card";
<Board
columns={lanes}
getItemId={(task) => task.id}
getItemLabel={(task) => task.title}
renderCard={(task) => (
<BoardCard
surface={false}
title={task.title}
context={`${task.project} · ${task.customer}`}
done={task.done}
onDoneChange={(done) => api.setDone(task.id, done)}
due={task.dueAt}
dateOptions={{ timeZone }}
priority={task.priority}
assignee={{ name: task.owner.name, image: task.owner.avatarUrl }}
/>
)}
onMove={move}
/>;BoardCard is the content of one card on a Board lane: a round
completion tick (or your status circle, through status) in a fixed leading column, then — all
in one text column beside it — a title of up to two lines, one muted context line ("project ·
customer"), and a bottom row with the assignee's avatar first, then the due chip, then the
priority chip. DataList's board view renders one per
row (its boardCard prop maps a row to these fields).
On a Board, pass surface={false}: the board owns the card's border, hover tint, focus cue,
drag and ⋯ menu. Every card ⋯ — the board's, a standalone card's actions, a
MediaCard's — sits top-aligned with the title's first line. On its own, the card draws 12px padding, a subtle border and a hover tint.
Examples
Due dates
The due chip reads the system date helpers (formatDueLabel), so a card and a list row agree:
destructive when overdue ("Overdue 2d"), warning when due today, quiet otherwise. Pass
dateOptions={{ timeZone }} so the server and the browser agree on "today".
Priority
Urgent is destructive and High is warning; Medium and Low are quiet outline chips.
priorityLabel renames the chip.
Done
done fills the round tick and strikes the title; the due chip stops warning. onDoneChange
makes the tick a control — without it the tick is read-only.
Status circle
status puts your status control in the tick's place — the same Status menu your list rows use
(a StatusIcon trigger: click opens the menu with O/P/B/D/C, Alt-click marks it done). It sits
above the card's activator on a Board, so a click edits the status without opening the card.
<BoardCard
surface={false}
title={task.title}
done={task.status === "done"}
status={
<TaskStatusMenu
status={task.status}
onChange={(to) => setStatus(task, to)}
/>
}
/>Minimal and linked
Every slot but the title is optional. Standalone, href (with your router's linkRender) makes
the title a link stretched over the card; on a Board, use the board's getItemHref instead.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
title* | React.ReactNode | — | The card's title — wraps to two lines, then truncates. |
actions | React.ReactNode | — | The ⋯ slot at the top end — a RowActionsMenu. It shows on hover and on focus, and always on
a touch screen. On a Board, leave it empty: the board's own card menu takes this place. |
assignee | BoardCardAssignee | — | Who the card is assigned to — an avatar leading the bottom row. |
context | React.ReactNode | — | One muted line under the title — where the card belongs ("Website redesign · Acme"). |
dateOptions | DateTimeOptions | — | now and timeZone for the due chip — pass the app's time zone so the server and browser
agree on "today". |
done | boolean | — | Whether the card is done. Setting it (or onDoneChange) shows the round completion tick at
the top start; a done card's title is struck through. |
doneLabel | string | "Mark done" | The tick's accessible name. |
due | DateInput | — | The due date. Renders a chip from the system date helpers: destructive when overdue, warning when due today. |
href | string | — | Make the card a link: the title is the link, stretched over the card. Standalone cards only —
on a Board, use the board's getItemHref. |
linkRender | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | <a /> | The element the link renders — a router link such as <Link href="" />. The card's href
wins over the template's. |
onDoneChange | ((done: boolean) => void) | — | Called with the new value when the tick is pressed. Without it the tick is read-only. |
priority | BoardCardPriority | — | The priority chip. Urgent and High are coloured; Medium and Low are quiet. |
priorityLabel | string | the priority in sentence case ("Urgent") | The priority chip's text. |
status | React.ReactNode | — | A status control in place of the tick — the host's Status menu (a StatusIcon trigger that
opens the status menu on click and marks done on Alt-click), the same control its list rows
use. It takes the leading column; done still strikes the title. |
surface | boolean | true | Draw the card's own border, padding and hover tint. Off on a Board, which owns the surface. |
Data attributes and CSS variables on BoardCard
| Attribute | Values |
|---|---|
data-done | "" |
data-priority | mirrors a prop or state value |
data-slot | "board-card-actions" | "board-card-assignee" | "board-card-content" | "board-card-context" | "board-card-done" | "board-card-due" | "board-card-footer" | "board-card-lead" | "board-card-priority" | "board-card-title" |
Accessibility
- The done tick is a real checkbox named "Mark done" (
doneLabel). On aBoardit sits above the card's activator, so it is clickable without opening or dragging the card. - A
statuscontrol brings its own name (for example "Status: Open — change status of …"). - The avatar is named by the assignee (its initials are hidden from screen readers).
- There is no focus ring: the system's focus cue is the background tint (FOC-13).
- The ⋯ slot shows on hover and on keyboard focus, and always on a touch screen.
| Key | Action |
|---|---|
| Tab | Move to the tick, the link, the ⋯ |
| Space | On the tick, toggle done |
| Enter | On the link, open the record |
| Contract | States tested |
|---|---|
| Behaviour | done, overdue, due-today, priority, assignee, source, link, no-surface |
| Accessibility | labeled, browser-accessibility-test |
| Visual | default, hover, done |