For AI agents: the complete documentation index is available at https://a3s-lab.github.io/UI/v0.4.0/en/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/UI/v0.4.0/en/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/UI/v0.4.0/en/components/code-editor.md.

Code Editor

Code Editor has two layers: A3S UI provides a framework-agnostic native editing contract, while the full workbench below shows how to integrate the real Monaco Editor for a multi-file experience close to VS Code.

Full Monaco workbench

Live preview
Release reviewIllustrative workspace

Starting Monaco language services…

mainLn 1, Col 1Spaces: 2UTF-8A3S ACL
Command Palette

This is an interactive Monaco implementation, not a static mockup. It includes four independent file models, a file tree and tabs, search and modified state, custom ACL highlighting and completion, TypeScript and JSON diagnostics, Problems/Output/Terminal panels, a minimap, synchronized light and dark themes, and a command palette.

  • Press Ctrl/Cmd + Shift + P or F1 to open the command palette.
  • Press Ctrl/Cmd + S to save the active model and Ctrl/Cmd + J to toggle the bottom panel.
  • Switching through the file tree or tabs preserves each Monaco model's content, cursor, and undo history.
  • Selecting the warning in Problems returns to its ACL line; search, formatting, minimap, and theme commands are functional.

The workspace content illustrates the interaction and language services; it is not a production-ready deployment configuration. The host application remains responsible for persistence, authorization, remote language services, and task execution.

Native fallback

When Monaco is unnecessary, use the A3S UI textarea controller for indentation shortcuts, line and column status, save state, and JSON validation.

Live preview
workflow.ts
TypeScriptCtrl/Cmd S
Saved

Usage

Load the runtime before the Code Editor controller, or use the combined JavaScript bundle. The complete A3S stylesheet includes the structural and visual layers.

<div
  class="code-editor"
  role="group"
  data-language="typescript"
  aria-label="Workflow code editor"
>
  <header>
    <div data-code-editor-file><strong>workflow.ts</strong></div>
    <div data-code-editor-actions>
      <span data-code-editor-language>TypeScript</span>
    </div>
  </header>
  <section>
    <textarea aria-label="Workflow TypeScript" spellcheck="false"></textarea>
  </section>
  <footer>
    <div data-code-editor-info>
      <span data-code-editor-state aria-live="polite">Saved</span
      ><span data-code-editor-lines></span
      ><span data-code-editor-characters></span>
    </div>
    <div data-code-editor-meta>
      <output data-code-editor-position aria-label="Cursor position"></output>
    </div>
  </footer>
</div>
<script type="module">
  import "@a3s-lab/ui/runtime";
  import "@a3s-lab/ui/code-editor";
</script>

Using the complete runtime bundle is equivalent:

import "@a3s-lab/ui/all";

Parameters

ParameterValuesDefaultPurpose
Root data-languageAny language identifiertextDescribes the document and enables JSON validation when set to json
Root data-validationjson—Enables a validator explicitly, independent of the language label
Root data-indent-sizePositive integer2Number of spaces inserted by Tab and removed by Shift+Tab
Root data-sizesm, lg—Compact or tall editing surface; the default is 15rem
Root data-line-numbersfalse—Hides the generated line-number gutter
Root data-wraptrue—Wraps long lines in the native editing fallback
--code-editor-min-heightCSS length15remMinimum and default editor height
--code-editor-font-sizeCSS length0.75remMonospace editor and gutter size
--code-editor-line-heightCSS length1.375remShared text and line-number rhythm
--code-editor-tab-sizePositive integer2Visual tab width

The optional data-label-* attributes localize generated status text. Available names are labelLine, labelLines, labelCharacter, labelCharacters, labelPosition, labelSaved, labelDirty, labelReadonly, labelDisabled, labelValid, labelInvalidPrefix, and labelEmpty. The labelPosition template is also used in JSON error messages.

The header, [data-code-editor-file], [data-code-editor-actions], [data-code-editor-language], footer, and status output elements are optional. Keep the textarea's accessible name even when the chrome is omitted.

JavaScript API

When the native textarea fallback is present, the controller adds these methods to the root after initialization:

MethodPurpose
editor.getValue()Returns the current textarea value
editor.setValue(value, { clean })Sets the value and refreshes status; clean: true makes it the saved baseline
editor.markClean()Marks the current value as saved
editor.refresh()Re-reads a value changed by application code and refreshes status

The root emits a3s:code-input for user and programmatic changes, a3s:code-save for Ctrl/Cmd+S, and a3s:code-clean after markClean(). Event details include value, lines, characters, position, dirty, and validationState.

States and variants

JSON validation

Set data-validation="json" (or data-language="json") and include a message target. Empty input is treated as incomplete, valid input is announced as valid, and malformed input sets aria-invalid="true" on the textarea.

Live preview
settings.json
JSON
Saved

Read-only

Use the native readonly attribute for a selectable, non-editable document. Use disabled when the value should not participate in interaction or submission.

Live preview
runtime.yaml
YAML

Monaco integration contract

The full example loads Monaco into an isolated mount target while preserving the A3S workbench header, sidebar, panel, and status-bar contracts. The design system owns layout and presentation; the host adapter owns workers, language registration, completion, diagnostics, model lifecycle, persistence, and synchronization of status outputs and data-* state.

<div
  class="code-editor"
  role="group"
  data-language="typescript"
  aria-label="Workflow code editor"
>
  <header>...</header>
  <section>
    <div data-code-editor-viewport id="workflow-editor-mount"></div>
  </section>
  <footer>...</footer>
</div>

Accessibility

The Monaco example gives the editor, workspace navigation, panels, and command dialog separate accessible names, and announces save and command results politely. Keyboard users can complete the workflow through file buttons, tabs, and standard editor shortcuts. Monaco manages its own accessible text input, cursor, and diagnostic information.

The native fallback editing surface is a textarea, so selection, copy, undo, redo, screen-reader text editing, and browser form submission remain available without a JavaScript editor engine. Give it an explicit label or connect a visible <label> with for. Give the root role="group" when it has an accessible name. Keep only the save state inside an aria-live="polite" region so cursor movement and counts are not announced on every keystroke; validation messages manage their own status or alert role. The line-number gutter is decorative and is marked aria-hidden.

The controller respects readonly, disabled, reduced motion, browser zoom, and RTL direction. Ctrl/Cmd+S is intercepted only while the editable textarea has focus; Tab and Shift+Tab indent the current line or selection, while other modifier combinations retain browser and assistive-technology shortcuts.