Kanzo UI
Forms

CodeEditor

A CodeMirror 6 host wired to the Kanzo tokens, with the language left to you.

Installation

CodeEditor is imported from a subpath, not the root barrel:

import { CodeEditor } from "@kanzo-tech/ui/editor";

CodeMirror is an optional peer dependency and it is large. Keeping the editor out of @kanzo-tech/ui means every consumer that does not embed a code editor — most of them — never pays for it. Install the peers yourself, plus whatever language you need:

pnpm add @codemirror/state @codemirror/view @codemirror/commands @codemirror/language @codemirror/search
pnpm add @codemirror/lang-json

Usage

<CodeEditor extensions={json()} lineNumbers onChange={setValue} value={value} />

The shell owns the chrome, the theme and the document lifecycle; extensions is the language brain, injected by you. That is the split: an LSP client, a StreamParser, autocompletion or linting are the consumer's business, and the shell reconfigures live when the extension changes rather than tearing the editor down.

value is reconciled without clobbering the cursor, so the editor is safe to drive from state you also write to from elsewhere.

Find and replace

basics includes CodeMirror's search, and the panel it opens is built from this library's own controls — InputGroup, Toggle, Button, ButtonGroup — rather than from CodeMirror's stock form. It opens at the top of the editor on Mod+F, closes on Esc, and Enter steps to the next match (Shift+Enter to the previous one). The three toggles in the field are case sensitivity, whole-word matching and regular expressions; the replace row is dropped on a read-only document.

The search itself is CodeMirror's, unchanged: setSearchQuery, findNext, replaceAll and the rest are the public commands from @codemirror/search, and the panel only draws the form over them. So a caller who binds those commands elsewhere — a toolbar of their own, say — drives the same state and sees the same field update.

Turn it off with basics={false} and bring your own search() configuration.

Sizing

CodeMirror's own .cm-scroller does the scrolling. Bound the height with minHeight / maxHeight, or give the host a resolved height and use chrome={false} — but never wrap it in a second overflow-auto container, which collapses the editor to its content height and leaves the surrounding pane half empty.

Theming

kanzoHighlightStyle and kanzoHighlighting are exported from the same subpath. They read the Kanzo tokens, so a theme change re-skins the syntax colours along with everything else. They are included when basics is on; import them directly if you set basics={false} and still want the token palette.

API Reference

PropTypeDefault
valuestring
onChange(value: string) => void
extensionsExtension
readOnlybooleanfalse
lineNumbersbooleanfalse
invalidbooleanfalse
placeholderstring
minHeightstring
maxHeightstring
basicsbooleantrue
chromebooleantrue
classNamestring
onView(view: EditorView | null) => void

basics bundles history, the default keymap, line wrapping and the Kanzo token theme. Turn it off when your extensions own all behaviour and theming. chrome wraps the editor in the styled focus-ring surface; turn it off for a bare host, which is when className applies. onView hands you the EditorView on mount and null on unmount, for side-wiring such as pushing LSP notifications.

CodeEditorProps is exported, so a wrapper can take the same props without restating them.

On this page