Skip to content
ArcadiaDesign
3 files changed+14 −3

TSX

A card is a code window: one step off the page on --bg-card, framed by a 7% hairline with continuous corners, and it never casts a shadow: it is part of the page, not floating over it. Put rows in CardRows (ListRows inset 6px), prose in CardBody, a title and meta in CardHeader, and actions in CardFooter.

Examples

Interactive header

With interactive, the whole header is one button: a disclosure, or a way to open the plan. Don't nest other buttons in it; a static header with CardMeta can hold them instead.

Move every preference into one dialog with a sidebar of sections, and keep the shortcut list searchable.

A form

render turns the card into the <form> itself, so the footer's buttons submit and reset it natively.

Profile

Window

variant="window" makes the first header a title bar: the file in mono (its name in text-1, the folder in text-3), stats and actions at the end and always shown, and a hairline below.

receipt.tssrc/lib+2 −1
export function receiptFor({ subtotalMinor, feeMinor = 0, currency }: Receipt) {

A file and its diff read as one object.

Levels and variants

stream, the default, is for turn-level cards: radius 15 with continuous corners, 12 where the browser lacks them.

Task WorkingAudit focus order3 steps, 42s
12 passed, 0 failed, 71 expect() calls

nested (10, round) sits inside a card or a row. inset is a well: the page seen through the frame.

rootStyle takes where the card sits and these knobs; the header, body, rows and footer read them too, so --card-px moves every part's padding at once.

--card-bg
PaintDefault var(--bg-card)
The card's surface.
--card-border
PaintDefault var(--stroke-3)
The 1px frame.
--card-radius
Ref<Radius>Default var(--radius-frame-card)
Corner radius (the card frame, 15; a nested card takes its rows' corner).
--card-corner
Ref<"--corner"> | "round"Default var(--corner)
Corner shape: continuous where supported, round on a nested card.
--card-px
Ref<Space>Default var(--space-3)
Inline padding of the header, body and footer.
--card-bar-h
Ref<Control>Default var(--control-lg)
A window's title bar height.
--card-header-gap
Ref<Space>Default var(--space-1-5)
Gap between a header's items.

Rows inside CardRows subtract their 6px inset and the border from the card radius, keeping the same corner shape.

A card is a plain <div> with no role; its parts are text and the controls you put in them. The one exception is an interactive header, which renders a <button>: give it aria-expanded when it discloses the body, as above, and keep its text short, because the whole header is its name.

When a card is a section people navigate to, give it a heading or role="region" with aria-labelledby on its title. Diff counts are colour and text, so "+14 −3" still reads without the colour.

EnterSpace
Activates an interactive header
Tab
Moves through the controls inside

Card

level
"stream" | "nested"Default "stream"
stream: a turn-level card, 15, continuous corners. nested: inside a card or row, round, concentric with its rows.
variant
"default" | "inset" | "window"Default "default"
inset: a well, the page seen through the frame. window: its first CardHeader is a title bar (mono, a hairline below).
mono
booleanDefault false
Code inside: --type-code, untracked.
rootStyle
CardStyle
Typed StyleX override: where the card sits and its --card-* knobs.

Rest props go to <div> props and render.

icon
IconName
Leading glyph, at icon-3.
interactive
booleanDefault false
The whole header is one button with a hover fill (a disclosure); no other buttons inside it.
divided
booleanDefault false
Hairline under the header (a body follows).

Rest props go to <div> props and render.

divided
booleanDefault false

Rest props go to <div> props and render.

link
boolean
A link (render={<a />}): underlined under the pointer.
rootStyle
stylex.StyleXStyles<Omit<Layout, "maxWidth"> & { maxWidth?: Layout["maxWidth"] | `${number}%` }>
Layout; maxWidth may be a percentage.

Rest props go to <span> props and render.

shown
booleanDefault false
Always in sight.

Rest props go to <div> props and render.

No props of its own. Rest props go to <span> props and render.

No props of its own. Rest props go to <div> props and render.

No props of its own. Rest props go to <div> props and render.