Code editor

An editor for HTML, CSS, JavaScript, TypeScript, JSON and Markdown: syntax colours from the design tokens, line numbers, undo, smart indents, auto-closed brackets and tags, comments with Ctrl/⌘+/, search and replace, and form support. The page is rendered on the server as highlighted code and turns into the editor after hydration.

Its own package — install it separately, tectra-ng does not include it: npm install @tectra-ng/code-editor.

Features8APIThemingAccessibility

Basic

Bind the text with [(value)]; codeChanged reports every edit too. The language is html by default and the height 600px.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Spring sale</title>
<style>
.banner { padding: 24px; color: #1d4ed8; }
</style>
</head>
<body>
<!-- Main banner -->
<section class="banner" data-id="42">
<h1>Spring sale</h1>
<p>Up to <strong>30%</strong> off until Sunday.</p>
<a href="/catalog">Open the catalog</a>
</section>
<script>
document.querySelector('.banner').addEventListener('click', () => console.log('open'));
</script>
</body>
</html>

546 characters

Languages

language takes html, css, javascript, typescript, json, markdown or plain (short names such as js, ts, md work too). Each language has its own colours, comment style and indent rules.

/* Card */
.card {
display: grid;
gap: 12px;
padding: 16px 20px;
border-radius: 12px;
color: #0f172a !important;
}
@media (max-width: 640px) {
.card:hover > a { margin: 0 auto; }
}

Form

The editor is a form control: formControl, ngModel and validators work, the frame turns red when the control is invalid and touched, and disabled follows the control.

{
"theme": "dark",
"pageSize": 25
}
A JSON object

Read only

readOnly keeps the cursor, selection, copy and search but blocks edits — for logs and generated code.

{
"id": "req_8f2a",
"method": "POST",
"path": "/v1/orders",
"status": 201,
"durationMs": 184,
"headers": {
"content-type": "application/json"
},
"body": {
"items": 3,
"total": 129.5,
"coupon": null,
"gift": false
}
}

Options

Turn off lineNumbers, wordWrap or indentGuides, set tabSize (taken from the text when not set) and a placeholder for an empty editor.

export default {
async fetch(request) {
if (request.method !== 'GET') {
return new Response('Method not allowed', { status: 405 });
}
return new Response('Hello from the edge. This line is long on purpose so that you can see how word wrap moves the rest of it to the next visual line.');
},
};

Diff mode

diffMode with originalValue shows the changes from the original to value inline and scrolls to the first change; the new side stays editable unless readOnly. For more options use Code diff.

+1 −3 lines

Design tokens

dt changes the tokens of one editor; syntax changes the colours of the tokens inside it.

export function clamp(value: number, min: number, max: number): number {
return Math.min(Math.max(value, min), max);
}