Card
Preview: Outline
Surface for grouped content: header, body and footer slots; outline, elevated or filled.
Import
import { Card, CardHeader, CardBody, CardFooter } from '@marbleui/ui'Props
<Card>
| Prop | Type | Default | Description |
|---|---|---|---|
| interactive | boolean | — | |
| variant | 'outline' | 'elevated' | 'filled' | 'outline' |
Also accepts HTML element props (278).
<CardHeader>
| Prop | Type | Default | Description |
|---|---|---|---|
| title *required | ReactNode | — | |
| action | ReactNode | — | |
| className | string | — | |
| description | ReactNode | — | |
| level | 1 | 2 | 3 | 4 | 5 | 6 | 3 | Heading level for the title (default 3). |
<CardBody>
No props of its own.
Also accepts HTML element props (278).
Usage notes
Surface that groups related content into header, body and footer. For a single metric use Stat; for key–value pairs inside a card use DataList.
<Card variant="elevated">
<CardHeader title="Pro plan" description="For growing teams." />
<CardBody>$24 / seat / month</CardBody>
<CardFooter><Button size="sm">Upgrade</Button></CardFooter>
</Card>
variantisoutline(default),elevatedorfilled.interactiveonly adds hover styling. It does not make the card focusable or clickable; for a clickable card add your owntabIndex, role and handler, or wrap a real link.CardHeaderrenderstitleas anh3by default; setlevelto fit the page outline.actiontakes a node placed at the right.
Example source · show· hide
import { Badge } from '../badge'
import { Button } from '../button'
import { ProgressBar } from '../progress-bar'
import { Card, CardBody, CardFooter, CardHeader } from './card'
const Plan = ({ variant }: { variant: 'outline' | 'elevated' | 'filled' }) => (
<Card variant={variant} className="w-80">
<CardHeader title="Pro plan" description="For growing teams." action={<Badge tone="accent">Current</Badge>} />
<CardBody className="flex flex-col gap-3">
<div className="text-3xl font-semibold tracking-tight text-fg">
$24<span className="text-sm font-normal text-fg-muted"> / seat / month</span>
</div>
<ProgressBar label="Seats used" value={7} maxValue={10} size="sm" valueLabel="7 of 10" />
</CardBody>
<CardFooter className="justify-end">
<Button variant="ghost" size="sm">Compare plans</Button>
<Button size="sm">Upgrade</Button>
</CardFooter>
</Card>
)
export const styles = {
Outline: () => <Plan variant="outline" />,
Elevated: () => <Plan variant="elevated" />,
Filled: () => <Plan variant="filled" />,
Interactive: () => (
<div className="grid w-[34rem] grid-cols-2 gap-4">
{['Website redesign', 'Mobile app'].map((t, i) => (
<Card key={t} interactive tabIndex={0}>
<CardHeader title={t} description={i ? '12 open issues' : '4 open issues'} />
<CardBody>Updated {i ? '2 hours' : '5 minutes'} ago</CardBody>
</Card>
))}
</div>
),
}Source: packages/ui/src/card/card.tsx
Catalog
- Category
- data-display
- Priority
- Foundation
- Primitive
- custom