Patterns / Code editor
Embed a code editor themed from Candor's tokens
CodeEditor (Pro) is a small field for code or a query a person writes or corrects: numbered lines, Tab and Shift+Tab to indent, the same token colours as CodeListing and Payload, and your app's validation message tied to its line. It is a plain textarea underneath, so typing, undo, selection and screen readers behave as they do in any field. It is not a full code editor: it has no autocomplete, linting, folding, search or multiple cursors. InstructionsEditor is CodeEditor for an agent's standing instructions, with {{variables}} checked as you type. Where a person needs what CodeEditor leaves out, embed an editor library and make it look like the rest of the page.
For code the agent wrote, CodeListing (Pro) shows it to read, with line numbers that aren't copied with it, the language named, Copy, ranges of lines marked with your reason, and, given the previous version, its changes line by line. Payload shows a short snippet or query text an agent produced, as text in a sunken well with a copy control.
This pattern uses CodeMirror. Its EditorView.theme takes an object that maps CSS selectors to style properties, with & standing for the editor element, and { dark: true } as a second argument tells it to apply its dark defaults to anything the theme doesn't style. Colours for code come from HighlightStyle.define, which maps tags from @lezer/highlight such as tags.keyword and tags.comment to a colour or font style, switched on with syntaxHighlighting.
Take the values from Candor's custom properties rather than copying colours. The editor's surface is var(--cd-sunken) with var(--foreground) for text and var(--border) for its edge, and the focus ring is var(--ring), the same as Payload. For code colours, use the ones Payload and CodeListing use when highlighting is on, which CodeEditor draws too: --cd-accent-text for keywords and functions, --cd-success-text for strings, --muted-foreground for comments (italic), --cd-attention-text for numbers and variables, and --cd-warning-text for properties, tags and types. Because the values are references, a change to your theme, including dark mode, reaches the editor without a second theme. CodeMirror's styling guide doesn't mention custom properties, so check this in your build before relying on it.
Show the agent's own output in CodeListing, or in Payload for a short snippet, with language naming it and highlight or data-syntax="highlight" on the page turning the colours on. Open an editor only where a person changes the text. CodeListing, Payload and CodeEditor split code into tokens shown as text and never treat it as markup, and CodeEditor gives your app what was typed as a string; an editor library has its own rules, so keep what a person types as a string there too and send it to your server, which decides whether to run it.
The components
- Code editorProA small code field: numbered lines, Tab to indent and your validation message on its line; no autocomplete or linting (Pro).
- Code listingProCode the agent wrote, to read: line numbers, Copy, marked ranges and its changes against the version before (Pro).
- PayloadFreeThe agent's code or query as text, with its language, a copy control and optional syntax colours.
- Instructions editorProAn agent's instructions in a CodeEditor, with {{variables}} checked as you type and a character count (Pro).
- LockedFreeAn editor that can't be used says why, rather than just going read-only.
See it working
Install
Each component brings in what it depends on. The free ones install as they are; Pro and Premium ones need a licence key.
Good to know
- Left to the app: loading and bundling CodeMirror and its language packages, the language modes, autocomplete, linting, keyboard shortcuts, and running what is written. InstructionsEditor's unknown-variable check is part of that component and doesn't run inside CodeMirror; if you replace its text box, bring the check with you.
- Mark the editor with an accessible name and say where focus goes when it opens. Check it against your own contrast needs, since a theme built from tokens is only as readable as the tokens.
- Read against CodeMirror's styling example on 9 November 2026. It gave no package versions; read the reference for the ones you install.