代码编辑器
代码编辑器包含两层能力:A3S UI 提供框架无关的原生编辑契约,下面的完整工作台则演示如何接入真正的 Monaco Editor,构建接近 VS Code 的多文件开发体验。
完整 Monaco 工作台
安装 Terminal
npm install @a3s-lab/ui@0.4.0示例 index.html入口 main.js
<div
class="code-editor"
role="group"
data-language="typescript"
aria-label="工作流代码编辑器"
>
<header>...</header>
<section>
<div data-code-editor-viewport id="workflow-editor-mount"></div>
</section>
<footer>...</footer>
</div>import "@a3s-lab/ui/a3s.css";
import "@a3s-lab/ui/all";
这是一个可交互的真实 Monaco 示例,而不是静态效果图。它包含四个独立文件模型、文件树与标签页、搜索和修改状态、ACL 自定义语法高亮与补全、TypeScript 和 JSON 诊断、问题/输出/终端面板、Minimap、明暗主题同步,以及命令面板。
按 Ctrl/Cmd + Shift + P 或 F1 打开命令面板。
按 Ctrl/Cmd + S 保存当前模型,按 Ctrl/Cmd + J 显示或隐藏底部面板。
在文件树和标签页之间切换时,Monaco 会保留每个文件的内容、光标与撤销历史。
点击问题面板中的警告会回到对应 ACL 行;搜索、格式化、Minimap 与主题命令均可实际操作。
工作区内容用于演示交互和语言服务,并不代表一套可直接部署的生产配置。宿主应用仍应负责文件持久化、权限、远程语言服务与运行任务。
原生回退
无需 Monaco 时,使用 A3S UI 自带的 textarea 控制器即可获得缩进快捷键、行列状态、保存状态和 JSON 校验。
workflow.ts
TypeScript Ctrl/Cmd S
<div
id="code-editor-demo"
class="code-editor"
role="group"
data-language="typescript"
data-indent-size="2"
data-label-line="行"
data-label-lines="行"
data-label-character="字符"
data-label-characters="字符"
data-label-position="第 {line} 行,第 {column} 列"
data-label-saved="已保存"
data-label-dirty="有未保存修改"
data-label-readonly="只读"
aria-label="工作流代码编辑器"
>
<header>
<div data-code-editor-file>
<span data-code-editor-dirty-indicator aria-hidden="true"></span>
<strong>workflow.ts</strong>
</div>
<div data-code-editor-actions>
<span data-code-editor-language>TypeScript</span>
<kbd>Ctrl/Cmd S</kbd>
</div>
</header>
<section>
<textarea
aria-label="工作流 TypeScript 代码"
autoComplete="off"
autoCapitalize="off"
spellCheck={false}
defaultValue={
"export async function run(input: unknown) {\n return input;\n}"
}
/>
</section>
<footer>
<div data-code-editor-info>
<span data-code-editor-state aria-live="polite">
已保存
</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="光标位置"></output>
</div>
</footer>
</div>
用法
先加载运行时,再加载代码编辑器控制器;也可以直接使用组合 JavaScript 包。完整的 A3S 样式包已经包含结构层与视觉层。
< div
class = "code-editor"
role = "group"
data-language = "typescript"
aria-label = "工作流代码编辑器"
>
< 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 = "工作流 TypeScript 代码" spellcheck = "false" ></ textarea >
</ section >
< footer >
< div data-code-editor-info >
< span data-code-editor-state aria-live = "polite" >已保存</ 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 = "光标位置" ></ output >
</ div >
</ footer >
</ div >
< script type = "module" >
import "@a3s-lab/ui/runtime" ;
import "@a3s-lab/ui/code-editor" ;
</ script >
使用完整运行时包时,写法等价于:
import "@a3s-lab/ui/all" ;
参数
生成的状态文案可以通过 data-label-* 属性本地化。可用名称包括 labelLine、labelLines、labelCharacter、labelCharacters、labelPosition、labelSaved、labelDirty、labelReadonly、labelDisabled、labelValid、labelInvalidPrefix 与 labelEmpty。JSON 错误位置也使用 labelPosition 模板。
header、[data-code-editor-file]、[data-code-editor-actions]、[data-code-editor-language]、footer 与状态输出均为可选项。即使省略外层装饰,也要为 textarea 保留可访问名称。
JavaScript API
使用原生 textarea 回退模式时,控制器初始化后会在根节点添加以下方法:
根节点会在用户或程序修改时发出 a3s:code-input,在按下 Ctrl/Cmd+S 时发出 a3s:code-save,在 markClean() 后发出 a3s:code-clean。事件详情包含 value、lines、characters、position、dirty 与 validationState。
状态与变体
JSON 校验
设置 data-validation="json"(或 data-language="json")并提供消息目标。空值视为待完成,有效值会播报校验通过,格式错误会在 textarea 上设置 aria-invalid="true"。
<div
id="code-editor-json"
class="code-editor"
role="group"
data-language="json"
data-validation="json"
data-label-valid="JSON 有效"
data-label-invalid-prefix="JSON 错误,位置"
data-label-line="行"
data-label-lines="行"
data-label-character="字符"
data-label-characters="字符"
data-label-position="第 {line} 行,第 {column} 列"
data-label-saved="已保存"
data-label-dirty="有未保存修改"
aria-label="JSON 编辑器"
>
<header>
<div data-code-editor-file>
<span data-code-editor-dirty-indicator aria-hidden="true"></span>
<strong>settings.json</strong>
</div>
<div data-code-editor-actions>
<span data-code-editor-language>JSON</span>
</div>
</header>
<section>
<textarea
aria-label="JSON 设置"
autoComplete="off"
autoCapitalize="off"
spellCheck={false}
defaultValue={'{\n "enabled": true\n}'}
/>
</section>
<footer>
<div data-code-editor-info>
<span data-code-editor-state aria-live="polite">
已保存
</span>
<span data-code-editor-lines></span>
<span data-code-editor-characters></span>
</div>
<div data-code-editor-meta>
<output data-code-editor-message></output>
<output data-code-editor-position aria-label="光标位置"></output>
</div>
</footer>
</div>
只读
使用原生 readonly 属性保留选择和复制能力,同时禁止修改;当值不应参与交互或提交时,使用 disabled。
<div
id="code-editor-readonly"
class="code-editor"
role="group"
data-language="yaml"
data-size="sm"
data-label-line="行"
data-label-lines="行"
data-label-character="字符"
data-label-characters="字符"
data-label-position="第 {line} 行,第 {column} 列"
data-label-readonly="只读"
aria-label="只读 YAML 编辑器"
>
<header>
<div data-code-editor-file>
<span data-code-editor-dirty-indicator aria-hidden="true"></span>
<strong>runtime.yaml</strong>
</div>
<div data-code-editor-actions>
<span data-code-editor-language>YAML</span>
</div>
</header>
<section>
<textarea
aria-label="只读 YAML"
readOnly
spellCheck={false}
defaultValue={"runtime: a3s\nmemory: local"}
/>
</section>
<footer>
<div data-code-editor-info>
<span data-code-editor-state aria-live="polite"></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="光标位置"></output>
</div>
</footer>
</div>
Monaco 集成契约
完整示例通过独立挂载目标加载 Monaco,并保留 A3S 工作台的头部、侧栏、面板和状态栏契约。设计系统负责布局与视觉层;宿主适配器负责 worker、语言注册、补全、诊断、模型生命周期、持久化,以及状态输出和 data-* 状态的同步。
< div
class = "code-editor"
role = "group"
data-language = "typescript"
aria-label = "工作流代码编辑器"
>
< header >...</ header >
< section >
< div data-code-editor-viewport id = "workflow-editor-mount" ></ div >
</ section >
< footer >...</ footer >
</ div >
可访问性
Monaco 示例为编辑器、工作区导航、面板和命令对话框提供独立的可访问名称,并把保存与命令结果放入礼貌播报区域;键盘用户可使用文件按钮、标签页和标准编辑快捷键完成整个流程。Monaco 自身管理可访问文本输入、光标与诊断信息。
原生回退的编辑表面是 textarea,因此无需 JavaScript 编辑器引擎即可使用选择、复制、撤销、重做、屏幕阅读器文本编辑与浏览器表单提交。为它提供明确的 aria-label,或通过 for 关联可见 <label>;根节点有可访问名称时应设置 role="group"。只把保存状态放入 aria-live="polite" 区域,避免每次按键都播报光标位置和统计信息;校验消息会自行管理 status 或 alert 角色。行号槽是装饰内容,控制器会将其标记为 aria-hidden。
控制器遵循 readonly、disabled、减少动态效果、浏览器缩放与 RTL 方向。只有当可编辑 textarea 获得焦点时才会拦截 Ctrl/Cmd+S;Tab 与 Shift+Tab 缩进当前行或选区,其他修饰键组合仍交给浏览器和辅助技术处理。