Code Engine
A lightweight code editor backed by @duskmoon-dev/code-engine (CodeMirror 6 fork). Behaves like a native <input> element: the value attribute sets initial content, the value property reflects the current content, and the element fires input on every change and change on blur.
Installation
npm install @duskmoon-dev/el-code-engine
Usage
import { register } from '@duskmoon-dev/el-code-engine';
register();
<el-dm-code-engine
language="javascript"
theme="duskmoon"
value="console.log('hello');"
></el-dm-code-engine>
The editor fills its default minimum height of 200px, including empty and single-line documents.
Set min-height to reserve more space, or set height or max-height to constrain the editor and
scroll long documents inside it. Optional toolbars share that height with the editing area.
Features
- Syntax highlighting — Dynamic language loading for 30+ languages
- Themes — Built-in duskmoon, sunshine, moonlight, and one-dark themes
<input>-like API —valueproperty,inputandchangeevents- Topbar & Bottombar — Opt-in VS Code-style chrome with quick actions and status
- Line wrapping — Optional via
wrapattribute - Read-only mode — Via
readonlyattribute - Shadow DOM — Fully encapsulated styles
- ESM-only — Zero CommonJS overhead
Live Demo
JavaScript Editor
Read-Only CSS
Line Wrapping
Topbar & Bottombar
The code engine supports opt-in topbar and bottombar that add VS Code-style chrome around the editor. Enable them with show-topbar and show-bottombar attributes.
Default Bars
<el-dm-code-engine
language="javascript"
title="main.js"
show-topbar
show-bottombar
value="const x = 42;"
></el-dm-code-engine>
The topbar shows a language badge, title, and action buttons:
- Undo / Redo — Triggers CodeMirror’s built-in history
- Wrap toggle — Toggles line wrapping on/off
- Copy — Copies editor content to clipboard
- Fullscreen — Expands the editor to fill the viewport
The bottombar shows cursor position (Ln {line}, Col {col}), line count, encoding (UTF-8), and language name.
Custom Bars via Slots
Replace default bar content entirely using named slots:
<el-dm-code-engine language="rust" show-topbar show-bottombar>
<div slot="topbar">
<span>Custom Toolbar</span>
<button>Run</button>
<button>Format</button>
</div>
<div slot="bottombar">
<span>Custom Status Bar</span>
</div>
</el-dm-code-engine>
When a slot is populated, the entire default content for that bar is replaced. The bar container (with CSS part and base styling) remains.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
value |
string |
'' |
Initial editor content (attribute) / current content (property) |
language |
string |
— | Language for syntax highlighting (e.g. javascript, css, html, python) |
readonly |
boolean |
false |
Whether the editor is read-only |
theme |
'duskmoon' | 'sunshine' | 'moonlight' | 'one-dark' |
'duskmoon' |
Editor color theme |
wrap |
boolean |
false |
Enable line wrapping |
show-topbar |
boolean |
false |
Show the topbar |
show-bottombar |
boolean |
false |
Show the bottombar |
title |
string |
— | Title displayed in the topbar (e.g. filename) |
Supported Languages
Languages are loaded dynamically on demand. Some common options:
javascript, typescript, css, html, json, python, rust, go, java, cpp, sql, markdown, xml, yaml, toml, shell
Events
| Event | Detail | Description |
|---|---|---|
input |
{ value: string } |
Fired on every document change |
change |
{ value: string } |
Fired when the editor loses focus |
copy |
{ value: string } |
Fired when the copy button is clicked |
fullscreen |
{ active: boolean } |
Fired when fullscreen is toggled |
Event Handling
const editor = document.querySelector('el-dm-code-engine');
editor.addEventListener('input', (e) => {
console.log('Content changed:', e.detail.value);
});
editor.addEventListener('change', (e) => {
console.log('Editor blurred, final value:', e.detail.value);
});
Methods
| Method | Returns | Description |
|---|---|---|
getValue() |
string |
Returns current editor content |
setValue(value) |
void |
Sets editor content programmatically |
focus() |
void |
Focuses the editor |
Programmatic Usage
const editor = document.querySelector('el-dm-code-engine');
// Read content
const code = editor.value;
// Set content
editor.value = 'const x = 42;';
// Or use methods
editor.setValue('const y = 100;');
console.log(editor.getValue());
// Focus
editor.focus();
Slots
| Slot | Description |
|---|---|
topbar |
Custom topbar content (replaces default when populated) |
bottombar |
Custom bottombar content (replaces default when populated) |
CSS Parts
| Part | Description |
|---|---|
topbar |
The topbar container |
bottombar |
The bottombar container |
editor |
The CodeMirror mount container |
Notes
- ESM-only — This element does not ship a CommonJS build. Use a bundler that supports ES modules.
- Dynamic imports — Languages and themes are loaded on demand via
import(). The editor renders immediately and applies syntax highlighting once the language module loads. - Shadow DOM — CodeMirror styles are injected into the shadow root, so they don’t leak into or conflict with the host page.
- Value semantics — Like
<input>, thevalueattribute sets the initial content. Thevalueproperty always returns the current editor content. Content is preserved across DOM moves.