# CodeEditor 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. ```ehtml Example ``` ## 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` | `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` | `{}` | 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](rich-text): A rich text editor with a formatting toolbar, markdown shortcuts, links, task lists, a slash menu, find and replace and image upload.