PlanCard
Hero example
When to use
Reach for PlanCard when a tier_2 or tier_3 agent has decomposed a user request into ordered steps and the user is watching progress unfold ("File Delaware franchise tax: compute → generate AR → submit → archive"). The card is the canonical surface for agentic plan execution — each step represents a discrete operation, and completed advances as the agent finishes each one. Render the card inline in the composer reply; the wrapping agent thread shows live updates.
Don't reach for PlanCard when the items are independent (not ordered) — use a checklist inside FilingStatusCard for unordered compliance sub-items, or a generic list. Don't use it for finished plans either; an archived plan reads better as a Timeline of the events that happened.
Anatomy
Two structural regions:
- Header.
Listicon + title (defaults to "Plan") + right-aligned{completed}/{total}progress in mono. - Ordered list (
<ol>). One row per item. Each row has:- 16px circular indicator. Done items: filled
--status-greenwith white✓. Active item (i === completed): empty circle with a 5px filled inner dot in--fg. Pending items: empty circle with 1.4px--ink-18border. - Item label. Done items have
line-throughdecoration in--ink-28. Active and pending items render in--fgand--fg-mutedrespectively.
- 16px circular indicator. Done items: filled
The <ol> carries no visible numbering — the indicator + ordering of children supplies it. Screen readers announce position via the ordered-list semantics.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | — | — |
| itemsrequired | string[] | — | — |
| completed | number | 0 | — |
The completed prop is a 0-indexed cursor — completed: 0 means "no steps done yet, first step is active." completed: items.length means "all steps done, no active step."
States
The card surfaces three per-item states via the completed cursor:
| State | Trigger | Indicator |
|---|---|---|
| Done | i < completed | Filled green circle with ✓ |
| Active | i === completed | Empty circle with filled inner dot |
| Pending | i > completed | Empty circle with --ink-18 border |
The card-level "complete" state (every item done) is implicit when completed === items.length. Consumer is responsible for transitioning the card away (or rendering a follow-up surface) when this happens.
Density
In compact, item vertical padding drops from 7px to 4px. Indicator and font sizes stay constant.
Themes
Tokens consumed
Done-indicator fill reads --status-green. Active-indicator inner dot reads --fg. Pending border reads --ink-18. Done-label line-through reads --ink-28.
Accessibility
- Keyboard interactions. None — the card is non-interactive.
- ARIA roles and properties. The
<ol>carries its native list semantics. Indicators are decorative spans (aria-hidden). The visible✓character on done items is text, so screen readers announce it. - Focus order. N/A.
- Screen-reader expectations. Reading order: title, "
{completed}of{total}", then each item in order. The ordered-list semantics implicitly announce "1.", "2.", etc. - Reduced motion. No keyframes in steady state. If the consumer animates the
completedcursor advancing, the motion contract requires the transition to collapse to opacity under reduced motion. - Forced colors. Done fill maps to
ButtonText; active inner dot toHighlight; pending border toButtonBorder. - WIG rules.
<ol>over a<div>list (semantic-element rule). Color is not the sole differentiator — done items also carry line-through; active items carry the inner-dot pattern.
Do / Don't
items short and verb-led ("Compute fee", "Generate AR", "Submit"). Each item is a step name, not a sentence.items longer than ~8 entries. Beyond that, the card grows past the inline-reply budget — use a dedicated plan page.completed monotonically as the agent finishes each step.items between renders. The ordinal sequence is the contract.completed: items.length when the plan finishes, then transition the card away after a beat.Recipes
This card appears in:
- Docs corpus recipe — agent replies that propose multi-step compliance plans.
- Board recipe — pre-meeting agenda surfaced as a plan.
Code example
import { PlanCard } from "@matter/components";
export function PlanInline({ plan }: { plan: AgentPlan }) {
return (
<PlanCard
title={plan.title}
items={plan.steps.map((s) => s.label)}
completed={plan.steps.filter((s) => s.state === "complete").length}
/>
);
}Source
packages/components/src/InlineCard/PlanCardCapTableSnapshotCard
Live cap-table snapshot — SVG donut showing fully-diluted ownership, a holder list with role and FDS percentage, sync timestamp, and an open-cap-table footer. Use when a single glance at ownership is the user's question.
SignatureStack
Package of documents awaiting signature — package name, status pill, per-document rows with thumb / meta / signer count / page count / size, overlapping recipient avatars, send-for-signature footer. Use when staging or tracking a multi-document signing flow.