Skip to content
Component installs need the registry setup
VegaStack Design

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
stable
Since
0.23.16
Accessibility pattern
named done tick, named avatar

Last updated

Send the revised lighting schedule to the contractorHarbour Tower · Acme Build
Priya ShahDue in 2dHigh

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-card

The 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.

Send the revised lighting schedule to the contractorHarbour Tower · Acme Build
Priya ShahDue in 2dHigh

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".

OverdueWebsite · Northwind
Overdue 2d
Due todayWebsite · Northwind
Due today
Due laterWebsite · Northwind
Due Oct 5

Priority

Urgent is destructive and High is warning; Medium and Low are quiet outline chips. priorityLabel renames the chip.

Fix the checkout outage
Urgent
Draft the Q4 plan
High
Tidy the style guide
Medium
Rename the old folders
Low

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.

Book the site visitHarbour Tower · Acme Build
Alex LeeOverdue 1d

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.

Just a title

API Reference

PropTypeDefaultDescription
title*React.ReactNode—The card's title — wraps to two lines, then truncates.
actionsReact.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.
assigneeBoardCardAssignee—Who the card is assigned to — an avatar leading the bottom row.
contextReact.ReactNode—One muted line under the title — where the card belongs ("Website redesign · Acme").
dateOptionsDateTimeOptions—now and timeZone for the due chip — pass the app's time zone so the server and browser agree on "today".
doneboolean—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.
doneLabelstring"Mark done"The tick's accessible name.
dueDateInput—The due date. Renders a chip from the system date helpers: destructive when overdue, warning when due today.
hrefstring—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.
linkRenderReact.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.
priorityBoardCardPriority—The priority chip. Urgent and High are coloured; Medium and Low are quiet.
priorityLabelstringthe priority in sentence case ("Urgent")The priority chip's text.
statusReact.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.
surfacebooleantrueDraw the card's own border, padding and hover tint. Off on a Board, which owns the surface.

Data attributes and CSS variables on BoardCard

AttributeValues
data-done""
data-prioritymirrors 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 a Board it sits above the card's activator, so it is clickable without opening or dragging the card.
  • A status control 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.
KeyAction
TabMove to the tick, the link, the ⋯
SpaceOn the tick, toggle done
EnterOn the link, open the record
ContractStates tested
Behaviourdone, overdue, due-today, priority, assignee, source, link, no-surface
Accessibilitylabeled, browser-accessibility-test
Visualdefault, hover, done

Do / Don't

Do
Pass surface={false} inside a Board and let the board's getItemActions fill its ⋯ menu.
Don't
Pass actions to a BoardCard on a Board — the card would show two ⋯ menus.

On this page