# StatCard

> A single key metric with its change, period and an optional chart.

Category: Data display · Status: stable · Package: @bindshq/stance-react@0.1.1 · Docs: https://stanceui.com/components/stat-card

Use StatCard at the top of dashboards for the few numbers that matter. The change is shown as a coloured badge and also announced in words, such as "up 12% from last month", so it never depends on colour. Use invert for metrics where a decrease is good.

## Import

```tsx
import { StatCard } from '@bindshq/stance-react';
```

Styles are imported once per app: `@bindshq/stance-tokens/css` and `@bindshq/stance-react/styles.css`.

## Examples

### Basic

```tsx
import { Icon, StatCard } from '@bindshq/stance-react';

export function Basic() {
  return (
    <StatCard
      label="Active signatures"
      value="1,284"
      delta="12%"
      trend="up"
      comparison="from last month"
      icon={<Icon name="pen-nib" />}
      style={{ width: 280 }}
    />
  );
}
```

### Dashboard row

```tsx
import { StatCard } from '@bindshq/stance-react';

export function Dashboard() {
  return (
    <div
      style={{
        display: 'grid',
        gap: 16,
        gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
        width: '100%',
      }}
    >
      <StatCard label="Mailboxes" value="312" delta="4%" trend="up" comparison="this week" />
      <StatCard label="Templates" value="24" delta="0" comparison="this week" />
      <StatCard
        label="Contracts signed"
        value="58"
        delta="9%"
        trend="down"
        comparison="vs. October"
      />
    </div>
  );
}
```

### Down is good

invert flips the sentiment for metrics like failures or churn.

```tsx
import { Icon, StatCard } from '@bindshq/stance-react';

export function Inverted() {
  return (
    <StatCard
      label="Failed deployments"
      value="3"
      delta="40%"
      trend="down"
      invert
      comparison="from last week"
      icon={<Icon name="alert-triangle" />}
      style={{ width: 280 }}
    />
  );
}
```

### With a sparkline

```tsx
import { StatCard } from '@bindshq/stance-react';

export function WithChart() {
  const points = [12, 18, 15, 22, 26, 24, 31, 35];
  const max = Math.max(...points);
  const d = points
    .map(
      (p, i) => `${i === 0 ? 'M' : 'L'}${(i / (points.length - 1)) * 100},${40 - (p / max) * 36}`,
    )
    .join(' ');
  return (
    <StatCard
      label="New users"
      value="35"
      delta="18%"
      trend="up"
      comparison="this week"
      chart={
        <svg viewBox="0 0 100 40" preserveAspectRatio="none" aria-hidden="true">
          <path
            d={d}
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
            vectorEffect="non-scaling-stroke"
          />
        </svg>
      }
      footer={<a href="#users">View all users</a>}
      style={{ width: 300 }}
    />
  );
}
```

### Loading

```tsx
import { StatCard } from '@bindshq/stance-react';

export function Loading() {
  return <StatCard label="Contracts signed" value="58" loading style={{ width: 280 }} />;
}
```

## API reference

| Component | Prop | Type | Default | Description |
| --- | --- | --- | --- | --- |
| StatCard | `label` (required) | `ReactNode` | None | What is measured. |
| StatCard | `value` (required) | `ReactNode` | None | The headline figure, pre-formatted. |
| StatCard | `delta` | `ReactNode` | None | Change since the comparison period. |
| StatCard | `trend` | `'up' \| 'down' \| 'neutral'` | `'neutral'` | Direction of change. |
| StatCard | `invert` | `boolean` | `false` | Treat down as positive. |
| StatCard | `comparison` | `string` | None | Period text, included in the announcement. |
| StatCard | `icon` | `ReactNode` | None | Icon beside the label. |
| StatCard | `chart` | `ReactNode` | None | Chart slot, e.g. a decorative sparkline. |
| StatCard | `footer` | `ReactNode` | None | Footer content such as a details link. |
| StatCard | `loading` | `boolean` | `false` | Show a placeholder and aria-busy. |

## Accessibility

- The visible delta badge is hidden from screen readers and replaced with a sentence such as "up 12% from last month".
- Positive and negative sentiment are shown with colour and an arrow icon, never colour alone.
- Mark decorative charts aria-hidden. If the chart carries information not in the value, provide a text alternative.
- loading sets aria-busy on the card.

## Guidelines

**Do**

- Format values with units and locale separators before passing them.
- Limit a row to four cards.

**Don’t**

- Use StatCard for long text or lists.

## Related

- https://stanceui.com/components/card
- https://stanceui.com/components/chart-container
- https://stanceui.com/components/progress
