Default
Default
header, content, and footer are opaque ReactNode slots — Card doesn't dictate their internal typography or layout. In real usage, pad the content yourself (see Basic usage below) — plain strings are used here only because this live example can't render nested JSX props.
<Card
header="Plumbing job"
content="Leaking tap in the kitchen"
footer="Posted 2 days ago"
/>Dividers
topDivider renders a horizontal Divider between header and content; bottomDivider renders one between content and footer. Both default to false.
With dividers
topDivider and bottomDivider separate the three regions.
<Card
header="Plumbing job"
content="Leaking tap in the kitchen"
footer="Posted 2 days ago"
topDivider
bottomDivider
/>Border
Two token-driven border colours are available. The default is strong.
Border colours
default (--color-border-default) and strong (--color-border-strong, the default).
<div className="flex flex-col gap-6">
<Card border="default" content='border="default"' />
<Card border="strong" content='border="strong"' />
</div>Radius
Three token-driven corner radii are available. The default is lg (12px).
Radius ramp
sm (4px), md (8px), and lg (12px, default).
<div className="flex flex-col gap-6">
<Card radius="sm" content='radius="sm"' />
<Card radius="md" content='radius="md"' />
<Card radius="lg" content='radius="lg"' />
</div>Surface tone
tone and emphasis pass straight through to the underlying Surface, so any tone-aware component placed in a slot (e.g. Text) automatically picks up the right ink colour.
Neutral vs. inverse
tone passes through to the underlying Surface.
<div className="flex gap-4">
<Card tone="neutral" content='tone="neutral"' />
<Card tone="inverse" content='tone="inverse"' />
</div>Card on an inverse Surface
Matching Card's tone to its containing Surface keeps the chrome consistent with the canvas it sits on.
<Surface tone="inverse" className="rounded-lg p-6">
<Card tone="inverse" content="Card tone matches its Surface canvas" />
</Surface>When to use
Use Card to group a header, content, and/or footer region inside a single bordered, rounded container — e.g. a job summary, a review, or a product tile. Card composes Surface (background/tone) and Divider (section separators) rather than reimplementing either.
Slots
header, content, and footer are all optional, opaque ReactNode slots. Card renders whichever are provided and stays out of the way of their internal typography or layout — style the contents yourself with Text, Heading, or any other component.
Dividers
Add topDivider/bottomDivider when the header or footer needs a visible separation from the main content, e.g. a card with a title bar and a metadata footer. Leave them off for a single, undivided block of content.
Border and radius
| Prop | Typical use |
|---|---|
border | strong (default) for most cards; default for a subtler outline |
radius | lg (default) for most cards; sm/md when nesting inside another card or a tighter layout |
When not to use
- A full-bleed section with no border/radius: use
Surfacedirectly. - A specific, pre-composed card pattern (contact card, review card, product marketing card, etc.): those are dedicated components layered on top of
Card— use them instead of rebuilding their layout from scratch.
Props
Standard platform props also pass through to the underlying Surface (HTMLAttributes<HTMLDivElement> on web, ViewProps on native) — e.g. id/aria-* on web, nativeID/testID on native. className/style stay blocked. Note that the DOM’s own content?: string (RDFa) attribute is omitted from the web passthrough so it doesn’t collide with the content slot below.
| Prop | Type | Default | Description |
|---|---|---|---|
| border | 'default' | 'strong' | 'strong' | Token-driven border colour. Maps to --color-border-{default,strong} (web) / colorBorder{Default,Strong} (native). |
| radius | 'sm' | 'md' | 'lg' | 'lg' | Token-driven corner radius. Maps to --border-radius-{sm,md,lg} (web) / borderRadius{Sm,Md,Lg} (native). |
| tone | 'neutral' | 'inverse' | 'brand-primary' | 'brand-secondary' | 'neutral' | Passthrough to the underlying Surface. |
| emphasis | 'default' | 'strong' | 'default' | Passthrough to the underlying Surface. |
| header | ReactNode | - | Top slot. Omitted entirely when absent. |
| content | ReactNode | - | Middle slot. Omitted entirely when absent. |
| footer | ReactNode | - | Bottom slot. Omitted entirely when absent. |
| topDivider | boolean | false | Renders a horizontal Divider between header and content. |
| bottomDivider | boolean | false | Renders a horizontal Divider between content and footer. |
| data-testid | string | - | Web only. Forwarded to the underlying Surface. |
Import
Web
import { Card } from '@checkatrade/components-web';Native
import { Card } from '@checkatrade/components-native';Basic usage
<Card
header={<div className="px-6 py-4">Plumbing job</div>}
content={<div className="px-6 py-4">Leaking tap in the kitchen</div>}
footer={<div className="px-6 py-4">Posted 2 days ago</div>}
topDivider
bottomDivider
/>Card doesn’t add padding to its slots — pad the content yourself (as shown above), the way you would for any container with opaque children. Text doesn’t accept a className prop (its visual API is locked down), so wrap it in a padded div/span rather than trying to pad Text directly.
Platform status
| Platform / Area | Status |
|---|---|
| Design (Figma) | Beta |
| Web (React) | Beta |
| Native (React Native) | Beta |
| iOS (Swift) | Planned |
| Android (Kotlin) | Planned |
| Accessibility audit | Planned |
Accessibility
Card has no accessibility behaviour of its own — accessibility is driven entirely by whatever is passed into header/content/footer, plus the standard platform attributes (aria-*/data-testid on web, nativeID/testID on native) that pass through to the underlying Surface.
Known gaps
- No
mediaslot (image at the top of the card) yet — deferred until a real use case appears.
No releases yet.