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

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

> A collapsible JSON tree that auto-masks sensitive keys, with copy and expand/collapse-all.

## When to use it

**JsonViewer** is for inspecting whole structured payloads — API responses, webhook bodies, relayer configs, trace objects. The collapse/expand-all bar and per-node copy make deep objects navigable, and default masking means you can render config that contains secrets without leaking them.

For a single identifier rather than an object, use **CodeRef**. For a curated set of labelled facts (not raw JSON), use **DefinitionList**. When you only need to hide one secret string, **MaskedValue** is lighter than dropping it into a viewer.

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `className` | `string` | no | — | — |
| `defaultCollapsed` | `boolean` | no | `false` | Start nested containers collapsed. |
| `maskPatterns` | `RegExp \| RegExp[]` | no | — | One or more patterns tested against each key; matching values are masked. Overrides the built-in `/secret\|token\|key\|password\|authorization/i`. |
| `name` | `ReactNode` | no | — | Optional file-name label shown at the left of the bar, e.g. `"payload.json"`. |
| `style` | `CSSProperties` | no | — | — |
| `value` | `unknown` | yes | — | The value to render. Any JSON-serializable value (object, array, or primitive). |

## Examples

### Basics

Pass any JSON-serializable `value` and an optional file-name `name`. Keys read as ink, strings secondary, numbers pick up the lone accent, punctuation muted. Every container node can copy its own subtree.

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

const payload = {
  eid: 30101,
  chain: "ethereum",
  nonce: 21904772,
  guid: "0x9f2c7a1e4b8d3f6009c5ea71b2d4c8f0",
  fees: { native: "0.0042", lzToken: null },
  dvns: ["google-cloud", "polyhedra"],
  confirmed: true,
};

export default function JsonViewerBasics() {
  return <JsonViewer name="packet.json" value={payload} />;
}
```

### Auto-masking secrets

Values under sensitive keys are masked by default — the built-in pattern is `/secret|token|key|password|authorization/i`. Masked leaves render bullets with a `masked` tag and are excluded from the visible tree, so config blobs are safe to display.

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

const config = {
  endpoint: "https://api.protocore.io/v2",
  apiKey: "pk_live_51H8xQ2mVn7Lp0Rs",
  signingSecret: "whsec_2mVn7Lp0Rs9aF3kQ",
  authorization: "Bearer eyJhbGciOiJIUzI1NiJ9",
  retries: 3,
  timeoutMs: 8000,
};

export default function JsonViewerMasking() {
  // Keys matching /secret|token|key|password|authorization/i mask by default.
  return <JsonViewer name="relayer.config.json" value={config} />;
}
```

## Usage

**Do**

- Use it to inspect raw payloads and configs where structure matters.
- Rely on the default mask patterns when rendering anything that may carry secrets.
- Set `defaultCollapsed` for large objects so users drill in deliberately.
- Narrow or widen `maskPatterns` to match your key naming conventions.

**Don't**

- Don't use it as a formatted key/value display for curated data — that's DefinitionList.
- Don't disable masking on payloads that include credentials.
- Don't paste enormous documents inline without `defaultCollapsed`; it gets unwieldy.
- Don't assume masking sanitizes your data — it only hides matched keys in the view.

## Accessibility

**Keyboard**

| Keys | Action |
| --- | --- |
| `Tab` | Moves through the bar buttons and each node's toggle / copy controls. |
| `Enter / Space` | Toggles a node open/closed, or triggers a copy action. |

**Notes**

- Each container toggle exposes `aria-expanded` and a descriptive `aria-label` (`Expand <key>` / `Collapse <key>`).
- Copy actions announce via a visually-hidden `role="status"` live region when the clipboard write succeeds.
- Structural punctuation and the masked tag are decorative; keys and values carry the meaning read by assistive tech.

## Related

`code-ref`, `masked-value`, `definition-list`, `money-amount`

---

© 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/
