CodeField component
CodeField is a text field for code and settings: custom CSS, a JSON config, an embed snippet. It has highlighting, line numbers, Tab and Shift+Tab to indent, Enter that keeps the indent, and, for JSON, a live note of where the text stops being valid. It is a real textarea underneath, so typing, undo and mobile keyboards behave as usual, and it has no dependencies. It is not a full code editor: there is no completion, folding or multiple cursors.
Playground
Change a prop on the right and the preview updates. Switch to Code to copy what you see.
Highlighting and size
Set language to css, json, javascript, typescript, html, markdown, yaml, python, sql, bash and more. The field grows with its text between minRows and maxRows (4 and 20) and then scrolls. tabSize is the number of spaces per indent.
<CodeField label="Custom CSS" language="css" value={css} onChange={setCss} />
<CodeField label="Embed code" language="html" value={snippet} isReadOnly tabSize={4} showLineNumbers={false} />JSON in a form
With language json the field shows Not valid JSON (line 3, column 7) while typing. Add the json validation rule so a Form refuses to submit invalid JSON.
<Form onSubmit={save}>
<CodeField
label="Config"
name="config"
language="json"
minRows={6}
validation={{ rules: { required: true, json: true } }}
/>
</Form>Props
The full public API for CodeField. Every prop is stable and intentionally typed.
Data
| Prop | Type | Default | Description |
|---|---|---|---|
| value / defaultValue | string | "" | The text. value makes it controlled. |
| onChange | (value: string) => void | — | Every change. |
| name | string | — | In a Form: the key the text is stored under. Outside one: the textarea's name. |
| validation | FieldValidation | — | Rules when inside a Form. { json: true } checks the text is valid JSON. |
value / defaultValue
string
default: ""
The text. value makes it controlled.
onChange
(value: string) => void
default: —
Every change.
name
string
default: —
In a Form: the key the text is stored under. Outside one: the textarea's name.
validation
FieldValidation
default: —
Rules when inside a Form. { json: true } checks the text is valid JSON.
Appearance
| Prop | Type | Default | Description |
|---|---|---|---|
| language | string | plaintext | Highlighting: css, json, javascript, typescript, html, markdown, yaml, python, sql, bash and the other languages the TextEditor code block knows. |
| showLineNumbers | boolean | true | The line-number gutter. |
| minRows / maxRows | number | 4 / 20 | The field grows with its text between these heights, in lines, then scrolls. |
| size | "sm" | "md" | md | Font size and padding. |
| classNames | Partial<Record<slot, string>> | — | Class per part: base, label, control, gutter, input, description, error. |
language
string
default: plaintext
Highlighting: css, json, javascript, typescript, html, markdown, yaml, python, sql, bash and the other languages the TextEditor code block knows.
showLineNumbers
boolean
default: true
The line-number gutter.
minRows / maxRows
number
default: 4 / 20
The field grows with its text between these heights, in lines, then scrolls.
size
"sm" | "md"
default: md
Font size and padding.
classNames
Partial<Record<slot, string>>
default: —
Class per part: base, label, control, gutter, input, description, error.
Content
| Prop | Type | Default | Description |
|---|---|---|---|
| label / description | ReactNode | — | A visible label (it names the field) and help text. |
| error | ReactNode | boolean | form's error for name | An error message, or true for the invalid look. |
| labels | Partial<CodeFieldLabels> | English | tabHint and invalidJson(line, column). Also set app-wide with LocaleProvider. |
label / description
ReactNode
default: —
A visible label (it names the field) and help text.
error
ReactNode | boolean
default: form's error for name
An error message, or true for the invalid look.
labels
Partial<CodeFieldLabels>
default: English
tabHint and invalidJson(line, column). Also set app-wide with LocaleProvider.
Behavior & states
| Prop | Type | Default | Description |
|---|---|---|---|
| tabSize | number | 2 | Spaces per indent. |
| checkJson | boolean | true | With language="json", shows where the text stops being valid while typing. |
| isReadOnly | boolean | false | Read-only keeps the text selectable but not editable. |
| isDisabled | boolean | false | Dims the field and ignores input. |
tabSize
number
default: 2
Spaces per indent.
checkJson
boolean
default: true
With language="json", shows where the text stops being valid while typing.
isReadOnly
boolean
default: false
Read-only keeps the text selectable but not editable.
isDisabled
boolean
default: false
Dims the field and ignores input.
Accessibility
- A real textarea named by its label. The coloured copy and the line numbers are hidden from screen readers, so the text is read once.
- Tab indents instead of leaving the field. A hidden hint linked with aria-describedby says to press Escape, then Tab, to move to the next field. Shift+Tab outdents.
- Indenting and auto-indent go through the browser's own typing, so Ctrl or Cmd+Z undoes them.
- Token colours keep 4.5:1 contrast in light and dark themes; keywords are also bold and comments italic, so colour is not the only cue.
Best practices
- Tell people about the Escape, then Tab, way out if the field is not the last one in a long form.
- Use the json rule for settings that are stored as JSON, so a typo is caught before it is saved.
- For long files or editing with completion, use a dedicated code editor instead.