> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# Card

Holds one self-contained thing — a metric, an integration, a saved view — in a block you can compare against its neighbours in a grid; reach for `Table` when the same fields repeat down a list, and for a `Heading` when you only mean to section a page. Passing any handler turns the whole card into the target: it becomes focusable and picks up hover and pressed overlays, while clicks on a link or button inside it stay with that control.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/Card) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/data-display-card--overview)

```tsx
import { type MouseEvent, useState } from 'react';
import { Badge } from '@wallarm-org/design-system/Badge';
import { Button } from '@wallarm-org/design-system/Button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@wallarm-org/design-system/Card';

export const Basic = () => {
  // `data-last-click` records which target handled the click. It renders nothing,
  // and it is what the click-isolation e2e asserts on — the story used to prove
  // the same thing by writing to the console.
  const [lastClick, setLastClick] = useState<'card' | 'button' | 'none'>('none');

  return (
    <Card
      data-testid='card'
      onClick={e => {
        onCardClick(e);
        setLastClick('card');
      }}
      data-last-click={lastClick}
    >
      <CardHeader>
        <CardTitle>Card title</CardTitle>
        <Badge size='medium' type='solid' color='slate'>
          Badge
        </Badge>
      </CardHeader>

      <CardContent>Card description</CardContent>

      <CardFooter>
        <Button
          variant='secondary'
          color='neutral'
          onClick={(e: MouseEvent<HTMLButtonElement>) => {
            onButtonClick(e);
            setLastClick('button');
          }}
        >
          Button
        </Button>
      </CardFooter>
    </Card>
  );
};
```

## Usage

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { Button } from '@wallarm-org/design-system/Button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@wallarm-org/design-system/Card';
```

## Examples

### Variants

`primary` sits on the page surface and `secondary` on a tinted fill, each shown
plain, with a handler, and disabled — where the card fades and stops answering
the pointer.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { Button } from '@wallarm-org/design-system/Button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@wallarm-org/design-system/Card';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const Variants = () => (
  <VStack gap={24} align='center'>
    <HStack gap={16} align='center'>
      <Card color='primary'>
        <CardHeader>
          <CardTitle>Primary card</CardTitle>
          <Badge size='medium' type='solid' color='slate'>
            Badge
          </Badge>
        </CardHeader>
        <CardContent>This is a primary card variant</CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>

      <Card color='secondary'>
        <CardHeader>
          <CardTitle>Secondary card</CardTitle>
          <Badge size='medium' type='solid' color='slate'>
            Badge
          </Badge>
        </CardHeader>
        <CardContent>This is a secondary card variant</CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>
    </HStack>

    <HStack gap={16} align='center'>
      <Card color='primary' onClick={onCardClick}>
        <CardHeader>
          <CardTitle>Primary card</CardTitle>
          <Badge size='medium' type='solid' color='slate'>
            Badge
          </Badge>
        </CardHeader>
        <CardContent>This is a primary card variant with onClick event</CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>

      <Card color='secondary' onClick={onCardClick}>
        <CardHeader>
          <CardTitle>Secondary card</CardTitle>
          <Badge size='medium' type='solid' color='slate'>
            Badge
          </Badge>
        </CardHeader>
        <CardContent>This is a secondary card variant with onClick event</CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>
    </HStack>

    <HStack gap={16} align='center'>
      <Card data-testid='disabled-card' color='primary' disabled onClick={onCardClick}>
        <CardHeader>
          <CardTitle>Primary card</CardTitle>
          <Badge size='medium' type='solid' color='slate'>
            Badge
          </Badge>
        </CardHeader>
        <CardContent>This is a disabled primary card variant</CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>

      <Card data-testid='disabled-card' color='secondary' disabled onClick={onCardClick}>
        <CardHeader>
          <CardTitle>Secondary card</CardTitle>
          <Badge size='medium' type='solid' color='slate'>
            Badge
          </Badge>
        </CardHeader>
        <CardContent>This is a disabled secondary card variant</CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>
    </HStack>
  </VStack>
);
```

### Various content

What the block tolerates: body copy that wraps, a `CodeSnippet`, a whole `Field`,
a `CardTitle` with an `icon`, and a header standing on its own with nothing under it.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { Button } from '@wallarm-org/design-system/Button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@wallarm-org/design-system/Card';
import { CodeSnippetActions, CodeSnippetCode, CodeSnippetContent, CodeSnippetCopyButton, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';
import { Field, FieldDescription, FieldLabel } from '@wallarm-org/design-system/Field';
import { CircleDashed } from '@wallarm-org/design-system/icons';
import { Input } from '@wallarm-org/design-system/Input';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const VariousContent = () => (
  <HStack gap={16}>
    <VStack gap={16} align='stretch'>
      <Card data-testid='card'>
        <CardHeader>
          <CardTitle>Card title</CardTitle>
          <Badge size='medium' type='solid' color='slate'>
            Badge
          </Badge>
        </CardHeader>
        <CardContent>
          Card description Very long! Even if it goes to the second line, it won't break anything.
          It works perfectly! Can you see? Amazing yeah?
        </CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Card title</CardTitle>
        </CardHeader>
        <CardContent>
          <CodeSnippetRoot code='npx wasd-new@latest add code-snippet' language='bash'>
            <CodeSnippetActions>
              <CodeSnippetCopyButton />
            </CodeSnippetActions>
            <CodeSnippetContent>
              <CodeSnippetCode />
            </CodeSnippetContent>
          </CodeSnippetRoot>
        </CardContent>
        <CardFooter>
          <Button variant='secondary' size='small' color='neutral'>
            Button
          </Button>
        </CardFooter>
      </Card>
    </VStack>

    <Card>
      <CardHeader>
        <CardTitle>Card title</CardTitle>
        <Badge size='medium' type='solid' color='slate'>
          Badge
        </Badge>
      </CardHeader>
      <CardContent>
        <Field>
          <FieldLabel>Label</FieldLabel>
          <Input placeholder='Placeholder' />
          <FieldDescription>Input description</FieldDescription>
        </Field>
      </CardContent>
      <CardFooter>
        <Button variant='secondary' size='small' color='neutral'>
          Button
        </Button>
      </CardFooter>
    </Card>

    <VStack gap={16}>
      <Card>
        <CardHeader>
          <CardTitle icon={<CircleDashed />}>Card title</CardTitle>
        </CardHeader>
        <CardContent>Card description.</CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle icon={<CircleDashed />}>Card title</CardTitle>
        </CardHeader>
      </Card>
    </VStack>
  </HStack>
);
```

## Props

| Prop           | Type                                                 | Default   | Description |
| -------------- | ---------------------------------------------------- | --------- | ----------- |
| asChild        | `boolean \| undefined`                               | `false`   |             |
| disabled       | `boolean \| undefined`                               | `false`   |             |
| onClick        | `MouseEventHandler<HTMLDivElement> \| undefined`     |           |             |
| color          | `{ primary: string; secondary: string; }`            | `primary` |             |
| title          | `string \| undefined`                                |           |             |
| defaultChecked | `boolean \| undefined`                               |           |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |           |             |
| autoFocus      | `boolean \| undefined`                               |           |             |
| id             | `string \| undefined`                                |           |             |
| tabIndex       | `number \| undefined`                                |           |             |
| rel            | `string \| undefined`                                |           |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |           |             |
| data-testid    | `string \| undefined`                                |           |             |

### CardContent

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| asChild        | `boolean \| undefined`                               | `false` |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CardFooter

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| asChild        | `boolean \| undefined`                               | `false` |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CardHeader

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| asChild        | `boolean \| undefined`                               | `false` |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CardTitle

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| icon           | `ReactNode`                                          |         |             |
| title          | `string \| undefined`                                |         |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

## Explorer

