Manual UI Templates CodeEditor

CodeEditor

elements man ui/templates/code-editor

A code editor with highlighting, line numbers, folding, completion, search, multiple cursors and diagnostics.

CodeEditor installs separately; it is not part of @elements/ui. The import comes with that install, and the template is used as shown.

Example
<CodeEditor value={file.source} language="typescript" label="Source" /> <!-- a query box: submitted with the form, checked as you type --> <CodeEditor name="query" language="sql" rows={3} lint={checkSql} statusBar />

Parts

Part What it is
CodeEditor The frame: optional header, the editor, optional status line, hidden form control.
.code-editor-header filename (or the language) and the copy button; the header slot adds controls.
.code-editor-content Where the editor mounts (.cm-editor). The server renders the code here as text first.
.code-editor-status Line and column, selection length, line count, language and indent.

Attributes

Attribute Type Default Description
value string (two-way) "" The code. Bind it to state; every edit writes back, and writing it from outside replaces the document.
language "text" | "javascript" | "typescript" | "jsx" | "tsx" | "json" | "css" | "html" | "markdown" | "python" | "sql" | "ehtml" | "jsoc" "text" Highlighting, indentation, folding and completion. Changing it keeps the document and undo history.
placeholder string "" Shown while empty; aria-placeholder.
label string "" Accessible name of the text box (aria-label).
filename string "" Shows a header with the file name.
copyButton boolean false Shows a header with a copy button; the icon turns to a check for two seconds.
statusBar boolean false Shows line, column, selection, line count, language and indent below the code.
lineNumbers boolean true The line number gutter, with the active line's number highlighted.
foldGutter boolean true Fold markers for blocks the language can fold.
highlightActiveLine boolean true Tints the line with the caret.
lineWrapping boolean false Wraps long lines instead of scrolling sideways.
dir "" | "ltr" | "rtl" | "auto" "" Text direction. rtl lays out right to left; auto gives each line the direction of its own text (perLineTextDirection). Unset inherits.
bracketMatching boolean true Highlights the bracket matching the one at the caret.
closeBrackets boolean true Typing an opening bracket or quote inserts the closing one.
autocomplete boolean true Completion popup from the language (Ctrl+Space opens it).
search boolean true Mod+F opens the search and replace panel; matches of the selection are highlighted.
indentWithTab boolean true Tab and Shift+Tab indent. Escape then Tab still leaves the editor, and the text box describes how.
tabSize number 2 Columns per tab and the indent unit, in spaces.
rows number 8 Minimum height in lines.
maxRows number 0 Height where the editor stops growing and scrolls. 0 grows without limit.
size "sm" | "md" | "lg" "md" Type size and padding.
name string "" Submits value with a form under this name.
required boolean false With name: an empty editor blocks the form's submit and takes focus.
disabled boolean false Not editable or focusable, dimmed, not submitted.
readonly boolean false Not editable; still focusable, selectable, searchable and submitted.
invalid boolean false Danger border and aria-invalid="true".
autofocus boolean false Focuses the editor when it mounts.
diagnostics CodeDiagnostic[] [] Problems to show: { from, to, severity, message, source, actions, markClass }, offsets in characters. actions are buttons shown with the message ({ name, apply(view, from, to) }), such as a fix. Ignored when lint is set.
lint (code: string) => CodeDiagnostic[] | Promise<CodeDiagnostic[]> null Checks the code after each pause in typing and shows what it returns.
extensions Extension[] [] More editor extensions: a gutter, a panel, a tooltip, a completion source, translated phrases (EditorState.phrases), a keymap, a language not listed, collaboration.
class string "" Extra classes on the frame.
attrs Record<string, string | number | boolean | undefined> {} Attributes for the text box (.cm-content): id, aria-labelledby, aria-describedby, data-testid.
onValueChange (value: string) => void () => {} Called when an edit changes the code. Not called for writes to value from outside.
onCreate (view: EditorView) => void () => {} Called with the editor's EditorView once it has mounted.
onFocus (e: FocusEvent) => void () => {} The editor gained focus.
onBlur (e: FocusEvent) => void () => {} The editor lost focus.

Slots

Slot Content
header Controls in the header, before the copy button. The header shows when filename or copyButton is set.

Keyboard

Keys Action
Tab / Shift + Tab Indent and outdent the line or selection (indentWithTab). Escape, then Tab, moves focus out.
Escape (in a Dialog or popover) The editor's first: closes completion or a panel, or arms Escape then Tab, and the overlay stays open. An Escape the editor does not use, such as a second one, closes the overlay.
Ctrl + M (Shift + Alt + M on a Mac) Toggles Tab focus mode: Tab moves focus instead of indenting.
Mod + F Opens search and replace; Enter and Shift + Enter step through matches, Escape closes.
Mod + G / Shift + Mod + G, F3 / Shift + F3 Next and previous match.
Mod + D Selects the next occurrence of the selection, adding a cursor.
Mod + click, Alt + drag Mod + click adds a cursor; Alt + drag selects a rectangle (a cursor per line).
Mod + Alt + Up / Down Adds a cursor on the line above or below. Escape returns to one cursor.
Mod + Shift + L Selects every match of the selection.
Alt + L (Ctrl + L on a Mac) Selects the line.
Mod + I Grows the selection to the enclosing syntax node; Mod + U undoes a selection change.
Mod + A Selects everything.
Home / End, Mod + Home / Mod + End Line start and end; document start and end. Shift extends the selection.
Ctrl + Space (also Alt + ` on a Mac) Opens completion. Arrow keys move, PageUp and PageDown move a page, Enter accepts, Escape closes.
Mod + / Toggles a line comment.
Shift + Alt + A (Ctrl + Shift + A on a Mac) Toggles a block comment.
Mod + Enter Inserts a blank line after the current one.
Mod + Alt + \ Reindents the selected lines.
Backspace In an empty bracket pair the editor closed, deletes both brackets.
Mod + [ / Mod + ] Outdent and indent.
Alt + Up / Alt + Down Moves the line up or down.
Shift + Alt + Up / Down Copies the line up or down.
Shift + Mod + K Deletes the line.
Ctrl + Shift + [ / ] (Cmd + Alt + [ / ] on a Mac) Folds and unfolds the block at the caret.
Ctrl + Alt + [ / ] Folds and unfolds every block in the document.
Mod + Z / Mod + Shift + Z Undo and redo (Mod + Y also redoes).
Mod + Shift + M Opens the diagnostics panel; F8 moves to the next diagnostic.
Mod + Shift + \ Jumps to the matching bracket.
Mod + Alt + G Go to line: type a line (or line:column, +n, -n, n%), Enter jumps, Escape closes.

Data attributes

Attribute Values On Description
data-focused present .code-editor While the editor has focus.
data-ready present .code-editor Once the editor has mounted.
data-language the language .code-editor
data-disabled present .code-editor
data-readonly present .code-editor
data-invalid present .code-editor
data-copied present .code-editor-copy For two seconds after a copy.

Accessibility

  • The text box is the editor's contenteditable (.cm-content) with role="textbox" and aria-multiline="true", named by label or aria-labelledby, with aria-placeholder, aria-readonly, aria-disabled, aria-invalid and aria-required as they apply.
  • With indentWithTab the text box is described by a hidden hint: Escape then Tab leaves the editor, so a keyboard user is never trapped (WCAG 2.1.2).
  • The search panel, completion list and diagnostics are the editor's own accessible widgets: labelled fields, a listbox with aria-activedescendant, and announced lint messages.
  • The copy button is an icon button named "Copy code", renamed "Copied" after a copy; the icon swap does not change its size.

See also

  • RichText (opens in a new tab): A rich text editor with a formatting toolbar, markdown shortcuts, links, task lists, a slash menu, find and replace and image upload.