<!-- Protocore Design System — MoneyAmount -->
# MoneyAmount

- **Category:** Data Display (`data-display`)
- **Slug:** `data-display/money-amount`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { MoneyAmount } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/data-display/money-amount

> A deterministic currency renderer — mono tabular figures, minor-unit aware, compact and sign-colored.

## When to use it

**MoneyAmount** is the single renderer for any currency figure — balances, fees, invoice totals, ledger lines. Tabular mono figures keep columns aligned, and passing `minorUnits` avoids float rounding on wire values. Because the `locale` is explicit, it is safe in server components with no hydration drift.

Use **MetricDelta** for a *change* in a metric (`+4.2%`) rather than an absolute amount. For an arbitrary number that isn't money, format it yourself — MoneyAmount always renders a currency symbol. A non-finite or unrecognized value renders an honest literal (the raw input plus the code), never a fabricated figure.

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `amount` | `string \| number` | yes | — | The value to render. A `number`, or a numeric `string` off the wire. When `minorUnits` is set this is interpreted as integer minor units (e.g. cents); otherwise it is the major-unit amount as-is. |
| `className` | `string` | no | — | — |
| `compact` | `boolean` | no | `false` | Use compact notation (`1200000` → `1.2M`). |
| `currency` | `string` | yes | — | ISO 4217 currency code (e.g. `"EUR"`, `"USD"`, `"JPY"`). |
| `locale` | `string` | no | `en` | BCP-47 locale used for grouping / decimal separators. Fixed and explicit so SSR and hydration agree. |
| `minorUnits` | `number` | no | — | Number of fractional (minor-unit) digits `amount` is expressed in — e.g. `2` means `amount` is cents and is divided by 100 before formatting. Omit when `amount` is already a major-unit value. |
| `sign` | `enum` | no | `auto` | Sign policy: `"auto"` shows `−` on negatives only, `"always"` prefixes `+` on positives too, `"never"` hides the sign entirely. |
| `style` | `CSSProperties` | no | — | — |

## Examples

### Basics

Pass a major-unit `amount` and an ISO 4217 `currency`. Formatting goes through `Intl.NumberFormat` with a fixed `locale` (default `"en"`) so server and client renders match byte-for-byte.

```tsx
import { MoneyAmount } from "@protocore/pds";

export default function MoneyAmountBasics() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8, alignItems: "flex-start" }}>
      <MoneyAmount amount={1499.5} currency="EUR" />
      <MoneyAmount amount={42_000} currency="USD" />
      <MoneyAmount amount={980_000} currency="JPY" />
    </div>
  );
}
```

### Minor units & compact

When money arrives off the wire as integer minor units (cents), set `minorUnits={2}` and the value is divided by 100 before formatting. `compact` switches to short notation (`2400000` → `$2.4M`).

```tsx
import { MoneyAmount } from "@protocore/pds";

export default function MoneyAmountMinorUnits() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8, alignItems: "flex-start" }}>
      {/* amount arrives off the wire as integer cents */}
      <MoneyAmount amount="149950" minorUnits={2} currency="EUR" />
      <MoneyAmount amount={2_400_000} minorUnits={2} currency="USD" compact />
      <MoneyAmount amount="0" minorUnits={2} currency="EUR" />
    </div>
  );
}
```

## Usage

**Do**

- Pass integer minor units with `minorUnits` when that's what the API returns.
- Keep one explicit `locale` across a view so grouping/decimals are consistent.
- Use `sign="always"` for ledgers where credit/debit direction must read at a glance.
- Use `compact` for dashboards and headline figures, not for exact line items.

**Don't**

- Don't pre-divide cents yourself and also pass `minorUnits` — pick one.
- Don't use it for non-currency numbers; it always emits a currency symbol.
- Don't rely on color alone to convey sign — the glyph carries it too.
- Don't feed it already-formatted strings with symbols; pass the raw number or numeric string.

## Accessibility

**Notes**

- Renders a plain `<span>` of formatted text; the number is read as written, symbol included.
- Sign tone (danger on negatives, success on `always` positives) is reinforced by the leading sign glyph, so it never depends on color alone.
- Invalid input surfaces a `title` explaining the unrecognized value/currency and renders the literal rather than a fake amount.

## Related

`metric-delta`, `relative-time`, `data-table`, `code-ref`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
