# Key value editor (goodtabs UI)

Rows of key and value inputs with remove buttons and an add button below.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/key-value-editor.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/key-value-editor`

## Usage

```tsx
import { KeyValueEditor } from "@/components/ui/key-value-editor"

<KeyValueEditor defaultValue={[{ key: "DATABASE_URL", value: "" }]} onValueChange={setEnv} />
<KeyValueEditor secret addLabel="Add secret" value={secrets} onValueChange={setSecrets} />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| value | `{ key: string; value: string }[]` |  | Controlled rows. |
| defaultValue | `{ key: string; value: string }[]` | `[]` | Starting rows for the uncontrolled form. |
| onValueChange | `(value: KeyValue[]) => void` |  | Fires with the full list on every edit, add and remove. |
| keyPlaceholder | `string` | `"KEY"` | Placeholder for the key column. |
| valuePlaceholder | `string` | `"Value"` | Placeholder for the value column. |
| addLabel | `string` | `"Add variable"` | Label on the add button. |
| secret | `boolean` | `false` | Render values as password fields with a reveal toggle per row. |
| disabled | `boolean` | `false` | Disables every input and button. |

## When to use

- Environment variables, request headers, labels and metadata pairs
- Settings where the number of pairs is open ended and each pair is short
- When people type keys by hand and need to add rows quickly from the keyboard

## When not to use

- Long values such as certificates or JSON, use a textarea per entry
- Fixed fields with known names, use a normal form
- More than a few dozen rows, use a table with inline editing

## Notes for agents

- It takes a function (onValueChange), so the page or demo that renders it must be a client component
- Uncontrolled by default; pass value plus onValueChange to control it, and keep the array stable between renders
- Rows keep a stable internal id per index, so removing a row never re-keys its neighbours
- No validation is built in; empty rows stay in the list so you can trim or flag them yourself

Docs: https://ui.goodtabs.co/components/key-value-editor