# 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.