Axii 体系下的高性能富文本编辑器,基于 ProseMirror(文档模型与编辑内核)+ Axii(响应式 UI 与自定义块渲染)。
- 高性能:文本走 ProseMirror 原生渲染最快路径;自定义块组件只执行一次,更新是 attr 级 atom 的精确 DOM 写入,无重渲染、无 vdom diff。
- 自定义块一等公民:
defineBlock({ node: NodeSpec, component: AxiiComponent })即可注册新块,支持内容洞(可编辑子内容)与纯交互 widget。 - 响应式镜像:
editor.signals(doc / selection / canUndo …)是 data0 atom,工具栏等周边 UI 直接绑定即可。
完整规划与架构设计见 docs/plan.md。
npm install
npm run dev # 打开 playground
npm test # 浏览器模式(Playwright chromium)运行测试
npm run typecheck # tsc --noEmit
npm run build # 构建库产物到 dist//** @jsx createElement */
import { atom, RenderContext } from 'axii'
import { Doc0Editor, Editor, defineBlock, contentHole, BlockViewProps } from 'doc0'
import 'doc0/style.css'
// 一个带内容洞的自定义块
const Callout = defineBlock({
name: 'callout',
node: {
group: 'block',
content: 'paragraph+',
attrs: { kind: { default: 'info' } },
},
component: function CalloutView({ attrs, updateAttrs }: BlockViewProps, { createElement }: RenderContext) {
return (
<div class={() => `callout callout-${attrs.kind()}`}>
<button onClick={() => updateAttrs({ kind: attrs.kind() === 'info' ? 'warn' : 'info' })}>
{attrs.kind}
</button>
{contentHole()}
</div>
)
},
})
function App({}, { createElement }: RenderContext) {
const editor = new Doc0Editor({ blocks: [Callout] }) // 随组件自动销毁
return (
<div>
<button onClick={() => editor.commands.undo()} disabled={() => !editor.signals.canUndo()}>Undo</button>
<Editor editor={editor} />
</div>
)
}