KeyValueEditor
A small table of names and values, like environment variables or headers.
SourcePackage @kerf-js/veneer
Preview
tsx
import { state } from '@kerf-js/core'import { KeyValueEditor, Stack, Text} from '@kerf-js/veneer'export function Env() { const env = state(ENV) return ( <Stack gap="related"> <KeyValueEditor label="Environment variables" keyLabel="Name" value={env} /> <Text subtle> {env.value.filter((r) => r.key).length} variables reach the next deploy. </Text> </Stack> )}const ENV = [ { key: 'NODE_ENV', value: 'production' }, { key: 'API_URL', value: 'https://api.kerf.dev' }, { key: 'LOG_LEVEL', value: 'info' },]Installation
npm install @kerf-js/veneerUsage
tsx
import { KeyValueEditor } from '@kerf-js/veneer'Form or JSON
json adds a switch. Both views edit the same value.
tsx
import { KeyValueEditor } from '@kerf-js/veneer'export function Json() { return ( <KeyValueEditor label="Response headers" keyLabel="Header" json defaultValue={HEADERS} /> )}const HEADERS = [ { key: 'Cache-Control', value: 'max-age=30' }, { key: 'X-Frame-Options', value: 'DENY' },]A repeated key
A warning, not a block: the last one wins.
tsx
import { KeyValueEditor } from '@kerf-js/veneer'export function Duplicate() { return ( <KeyValueEditor label="Environment variables" keyLabel="Name" defaultValue={[ ...ENV, { key: 'LOG_LEVEL', value: 'debug' }, ]} /> )}const ENV = [ { key: 'NODE_ENV', value: 'production' }, { key: 'API_URL', value: 'https://api.kerf.dev' }, { key: 'LOG_LEVEL', value: 'info' },]States
A key value editor can start empty or filled, and can show a hint or an error.
tsx
import { Grid, KeyValueEditor, Stack, Text} from '@kerf-js/veneer'export function States() { return ( <Grid cols={2} gap="group" > <Cell name="Empty"> <KeyValueEditor label="Response headers" /> </Cell> <Cell name="Filled"> <KeyValueEditor label="Response headers" defaultValue={HEADERS} /> </Cell> <Cell name="Hint"> <KeyValueEditor label="Response headers" hint="Added to every response." defaultValue={HEADERS} /> </Cell> <Cell name="Invalid"> <KeyValueEditor label="Response headers" error={ "X-Frame-Options can't be changed " + 'on this plan.' } defaultValue={HEADERS} /> </Cell> </Grid> )}const Cell = ({ name, children,}: { name: string children?: unknown}) => ( <Stack gap="tight"> <Text role="caption" subtle > {name} </Text> {children} </Stack>)const HEADERS = [ { key: 'Cache-Control', value: 'max-age=30' }, { key: 'X-Frame-Options', value: 'DENY' },]When to use
Use it for
- Pairs people add and remove by hand
Reach for something else
- JsonEditor, when values nest
Accessibility
- Tab
- Moves from cell to cell
- Enter
- On Add row, adds one and moves to it
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | The visible name, and what screen readers announce. |
hint | unknown | — | A short line of help under the field. |
error | unknown | — | Replaces the hint and marks the field invalid. |
icon | IconRef | — | Leading icon: it sweeps with the border. |
prefix | unknown | — | Text or an element inside the field before the value, such as $. |
suffix | unknown | — | Text or an element inside the field after the value, such as kg. |
variant | "floating" | "classic" | — | floating (default, or the app's veneer({ fields })) · classic: the label above. |
appearance | "line" | — | line: only a bottom line under the value, no box or fill. The boxed field otherwise. |
size | "sm" | "md" | "lg" | 'md' | Control size. md by default. |
clearable | boolean | false | A clear button (shown once there is a value). |
counter | number | — | Maximum length, shown as a counter. |
id | string | — | The element id. One is made for you if you leave it out. |
disabled | boolean | false | Can't be focused or changed. |
readonly | boolean | false | Shows the value and lets it be selected and copied, but not changed. |
value | KeyValue[] | State<KeyValue[]> | — | The rows as { key, value }, or a State to bind. |
defaultValue | KeyValue[] | — | The starting value, when the component owns the state. |
keyLabel | string | 'Key' | The first column's heading. |
valueLabel | string | 'Value' | The second column's heading. |
json | boolean | false | Adds a switch to a JSON view of the same value. |
| Event | Type | Default | Description |
|---|---|---|---|
onInput | ((e: InputEvent & { currentTarget: HTMLInputElement & HTMLTextAreaElemen… | — | Called on each keystroke. |
onValueChange | ((v: KeyValue[], reason: ChangeReason) => void) | — | Hears the new rows and why they changed. |
RelatedJson editorTable