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

- **Category:** Inputs (`inputs`)
- **Slug:** `inputs/json-input`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { JsonInput } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/inputs/json-input

> A mono Textarea that validates JSON on blur, surfaces the parse error in danger tone, and can pretty-print the value.

## When to use it

Use **JsonInput** where a user authors raw JSON — a webhook payload, a config blob, a metadata field — and needs immediate feedback that it parses. To only **display** JSON, use **JsonViewer** or a **CodeBlock**. This control validates syntax, not shape: pair it with a schema check on submit for structural validation.

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `autoResize` | `boolean` | no | — | Grow to fit content instead of scrolling. |
| `className` | `string` | no | — | — |
| `defaultValue` | `string` | no | — | Initial text when uncontrolled. |
| `formatOnBlur` | `boolean` | no | `false` | Pretty-print the value on blur when it parses. Default `false`. |
| `indent` | `number` | no | `2` | Indentation width for formatting. Default `2`. |
| `onValidationChange` | `((error: string \| null) => void)` | no | — | Called when validity changes: the parse-error message, or `null` when valid/empty. |
| `onValueChange` | `((value: string) => void)` | no | — | Fires with the raw text on every keystroke. |
| `size` | `enum` | no | `md` | Control padding scale. Default `md`. |
| `style` | `CSSProperties` | no | — | — |
| `value` | `string` | no | — | Controlled text value. Pair with `onValueChange`. |
| `withFormatButton` | `boolean` | no | `false` | Render a "Format" button that pretty-prints on demand. Default `false`. |

## Examples

### Basics

Type JSON and blur the field: valid input clears, invalid input shows the parser's message and marks the field invalid. Controllable via `value` / `onValueChange`.

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

export default function Demo() {
  return (
    <div style={{ maxWidth: 460 }}>
      <JsonInput
        aria-label="Webhook payload"
        defaultValue={'{ "event": "deploy.succeeded", "attempts": 3 '}
        rows={5}
      />
    </div>
  );
}
```

### Format button

Set `withFormatButton` to add a Format action that pretty-prints valid JSON on demand; `formatOnBlur` does the same automatically when the field loses focus.

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

export default function Demo() {
  return (
    <div style={{ maxWidth: 460 }}>
      <JsonInput
        aria-label="Configuration"
        withFormatButton
        formatOnBlur
        defaultValue={'{"replicas":3,"region":"eu-central-1","flags":["ha","autoscale"]}'}
        rows={6}
      />
    </div>
  );
}
```

## Do & don't

**Do**

- Give it an `aria-label` (or wrap it in a `Field`).
- Use `onValidationChange` to disable submit while the JSON is invalid.
- Offer `withFormatButton` for anything a human hand-edits.

**Don't**

- Don't treat a valid parse as a valid document — check the shape separately.
- Don't reformat on every keystroke; format on blur or on demand.
- Don't hide the error — it names exactly where parsing failed.

## Accessibility

**Notes**

- The parse error renders in a `role="alert"` region and is referenced by the field's `aria-describedby`.
- The field carries `aria-invalid` while the value fails to parse.
- Spellcheck and autocomplete are disabled — this is code, not prose.

## Related

`textarea`, `input`, `code-block`, `json-viewer`

---

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