Skip to content
UI

Card

A bordered surface that groups the content and actions of one subject.

@zenoxai/ui/components/card Markdown

Microsoft 365 connector

Collects sign-in and audit logs every 5 minutes.
Last sync
4 minutes ago
Events today
182,340
<Card className="w-full max-w-sm">
  <CardHeader>
    <CardTitle>Microsoft 365 connector</CardTitle>
    <CardDescription>
      Collects sign-in and audit logs every 5 minutes.
    </CardDescription>
  </CardHeader>
  <CardContent>
    <dl className="grid grid-cols-2 gap-y-2">
      <dt className="text-text-secondary">Last sync</dt>
      <dd className="text-right">4 minutes ago</dd>
      <dt className="text-text-secondary">Events today</dt>
      <dd className="text-right tabular-nums">182,340</dd>
    </dl>
  </CardContent>
</Card>

Usage

import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@zenoxai/ui/components/card"

export function ConnectorCard() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Microsoft 365 connector</CardTitle>
        <CardDescription>
          Collects sign-in and audit logs every 5 minutes.
        </CardDescription>
      </CardHeader>
      <CardContent>Last sync 4 minutes ago</CardContent>
    </Card>
  )
}

Use a card for one subject: a connector, a settings group, a chart, a detail panel. The card sets the padding, and its parts read it, so CardHeader, CardContent and CardFooter line up without extra classes.

The header draws a divider under itself. To run the content straight on from the title, remove it with className="border-b-0 pb-0" on CardHeader.

Use something else when:

  • The card would show one figure with a label. Use StatTile.
  • The content is a row in a list of similar records. Use Item.
  • A section inside a card or a settings page needs a heading. Use SectionHeading.

With an action

CardAction puts a control at the top right of the header, aligned with the title. Use it for the one action that applies to the whole card.

Notification rules

Who is paged for each severity.
  • Critical: on-call analyst, by phone
  • High: SOC channel, by email
<Card className="w-full max-w-sm">
  <CardHeader>
    <CardTitle>Notification rules</CardTitle>
    <CardDescription>Who is paged for each severity.</CardDescription>
    <CardAction>
      <Button variant="outline" size="sm">
        <PlusIcon data-icon="inline-start" />
        Add rule
      </Button>
    </CardAction>
  </CardHeader>
  <CardContent>
    <ul className="grid gap-2">
      <li>Critical: on-call analyst, by phone</li>
      <li>High: SOC channel, by email</li>
    </ul>
  </CardContent>
</Card>

CardFooter has a top border and a muted background, and the card drops its bottom padding so the footer sits flush with the edge. Put the form actions there, aligned to the end.

Retention

Raw events older than this are deleted every night.

Events are kept for 90 days. Alerts and reports are kept for the life of the tenant.

<Card className="w-full max-w-sm">
  <CardHeader>
    <CardTitle>Retention</CardTitle>
    <CardDescription>
      Raw events older than this are deleted every night.
    </CardDescription>
  </CardHeader>
  <CardContent>
    <p>
      Events are kept for <span className="font-medium">90 days</span>.
      Alerts and reports are kept for the life of the tenant.
    </p>
  </CardContent>
  <CardFooter className="justify-end gap-2">
    <Button variant="ghost">Cancel</Button>
    <Button>Save changes</Button>
  </CardFooter>
</Card>

Small

size="sm" reduces the padding from 16px to 12px and moves the title to the compact step (14px, semibold; see Typography). Use it for side panels and grids of small cards.

Asset owner

Marina RochaInfrastructure team
<Card size="sm" className="w-full max-w-xs">
  <CardHeader>
    <CardTitle>Asset owner</CardTitle>
    <CardAction>
      <Button variant="ghost" size="xs">
        Reassign
      </Button>
    </CardAction>
  </CardHeader>
  <CardContent className="grid gap-1">
    <span className="font-medium">Marina Rocha</span>
    <span className="text-text-secondary">Infrastructure team</span>
  </CardContent>
</Card>

Accessibility

  • CardTitle renders an <h2>, so cards show up in heading navigation. Inside a section that already has an <h2>, render a lower level: <CardTitle render={<h3 />}>.
  • CardDescription is plain text. When it explains a control inside the card, link the two with aria-describedby.

API reference

Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.

Card

Card is a bordered surface that groups the content about one subject: a chart, a summary, a settings section. Compose CardHeader (CardTitle, CardDescription, CardAction), CardContent and CardFooter. For a single KPI figure use the StatTile pattern; for a row in a list, Item.

PropTypeDefault
size"default" | "sm"

`sm` tightens the padding and gaps from 16px to 12px and steps the title down to text-sm, for dense grids.

default

CardHeader

CardHeader is the top band, set off from the body by a divider. A CardAction inside it takes a right-hand column beside the title and description.

No props of its own. Accepts the props of the element it renders.

CardFooter

CardFooter is the bottom band, on a muted fill above a divider, for actions or a summary line.

No props of its own. Accepts the props of the element it renders.

CardTitle

CardTitle renders an <h2> by default, so card sections appear in heading navigation; pass `render={<h3 />}` where the card sits under another h2. It sits at the container step (text-base, medium); in a `size="sm"` card, at the compact step (text-md, semibold), where a medium weight would not stand apart from 12.5px medium labels.

PropTypeDefault
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-

CardAction

CardAction is the slot at the right of CardHeader, for a button or a menu that acts on the whole card. It is vertically centered on the title and description together, as the action of a SectionHeading is (upstream aligns it to the top).

No props of its own. Accepts the props of the element it renders.

CardDescription

No props of its own. Accepts the props of the element it renders.

CardContent

No props of its own. Accepts the props of the element it renders.