Cardcomponent

Card({ as: Element = "article", children, href, onClick, title = "Open", ...props }: CardProps): ReactElement
ParamType
propsCardProps
Props for Card — combines ClickableProps (for navigable cards) with colour, status, padding, space, typography, and width variants. required
    .asBlockElement
Element this <Card> renders as, e.g. "header" to output a "<header>" Defaults to "article"
Return
ReactElement

Cards are boxed areas for content to sit within.

  • Rendered as <article> since each card represents a self-contained piece of content (override with props.as).
  • When href or onClick is set the card becomes navigable: a stretched overlay <a> / <button> covers the entire card while the children render normally inside.
  • Real interactive elements inside the card (e.g. inline <a> links) stay clickable thanks to position: relative; z-index: 2 rules in the stylesheet.
  • Accepts a status colour and raw ColorProps — the card styles the box; lay out its contents however the use case needs.

A boxed surface that groups a self-contained piece of content. Rendered as an <article>, painted from the tint ladder (surface, border, text) and styled with rounded corners and padding by default.

Things to know:

  • Set href or onClick to make the whole card navigable — a stretched, visually-hidden overlay <a> / <button> covers the card while the children render normally inside. Real interactive elements inside the card (inline links, buttons) stay clickable and keyboard-focusable.
  • color= and status= move the tint anchor for the card's scope, so the surface, border, text, and hover shade all re-derive together — and nested components (<Tag>, <Preformatted>, <Button>) inherit the same tint.
  • A card styles only the box. Lay out its contents with the usual block components (<Subheading>, <Paragraph>, <Row>, …).
  • Composes the standard styling variants: color, status, padding, space, width, plus typography.

Usage

Static card

tsx
import { Card, Subheading, Paragraph } from "shelving/ui";

<Card>
  <Subheading>Storage</Subheading>
  <Paragraph>1.2 GB of 5 GB used.</Paragraph>
</Card>

Navigable card

tsx
import { Card, Subheading, Paragraph } from "shelving/ui";

// The entire card is a link; `title` labels the overlay for screen readers.
<Card href="/projects/shelving" title="Open Shelving">
  <Subheading>Shelving</Subheading>
  <Paragraph>TypeScript data toolkit.</Paragraph>
</Card>

Status and colour

tsx
import { Card, Subheading } from "shelving/ui";

<Card status="error"><Subheading>Couldn't load</Subheading></Card>
<Card color="purple" padding="large" space="none"><Subheading>Featured</Subheading></Card>

Styling

Card paints from the tint ladder; override these hooks at :root (or any ancestor scope) to retheme. Move --card-tint to recolour everything at once; reach for a per-property hook for a single surgical change.

VariableStylesDefault
--card-tintTint anchor for the card scope — recolours surface, border, text and hover togetherinherit (flows from color= / status= / parent)
--card-backgroundSurface fillvar(--tint-90)
--card-hover-backgroundSurface fill when a navigable card is hoveredvar(--tint-95)
--card-colorText colourvar(--tint-00)
--card-borderBorder shorthandvar(--card-stroke) solid var(--tint-80)
--card-strokeBorder / outline thicknessvar(--stroke-normal) (2px)
--card-radiusCorner radiusvar(--radius-normal) (16px)
--card-paddingInner paddingvar(--space-normal) (16px)
--card-spaceOuter block margin (top + bottom)var(--space-paragraph) (16px)
--card-shadowDrop shadownone
--card-transitionTransitionall var(--duration-fast) (150ms)
--card-focus-borderFocus outlinevar(--stroke-focus) solid var(--color-focus)

Global tokens it reads — move these to retheme broadly rather than overriding ladder steps directly: the tint ladder --tint-00 / --tint-80 / --tint-90 / --tint-95, plus --space-normal, --space-paragraph, --radius-normal, --stroke-normal, --stroke-focus, --color-focus, and --duration-fast.

css
/* Theme: borderless cards with a soft shadow and tighter corners. */
:root {
  --card-border: none;
  --card-shadow: var(--shadow-small);
  --card-radius: var(--radius-small);
}

/* Retint every card purple — surface, border, text and hover all follow. */
:root {
  --card-tint: var(--color-purple);
}

Examples

<Card><Subheading>Static</Subheading></Card>
<Card href="/foo" title="Open foo"><Subheading>Clickable</Subheading></Card>
<Card status="error"><Subheading>Not found</Subheading></Card>