@ docen/ 编辑器
用于 docen 编辑器的组件层——将流利的 UI 主机与 @ docen/docx Tiptap 引擎变成统包网络组件, 如
<docen-document>, (中文(简体) ), 并拥有 LeaferJS 画布舞台,使页被粘贴.
特征
- 🧩 总钥匙
<docen-document>一个自定义元素用 @ docen/ docx 引擎捆绑 Fluent UI 主机(标题栏,丝带,文档区域,状态栏,平板,查找/替换) - 🎨 帆布渲染 页面在 LeaferJS 画布上渲染( 无可满足的文本, 无 DOM 文本); 无视图的 Tiptap 模型驱动编辑通过文本区桥
- 📄 办公室风格的平面 —— 有 Word 堆放规则(docGrid pitch, table band s分裂, 寡妇/孤儿) 的固定高通页; 在每个编辑上重新运行布局
- 🖌️ 流利的 UI 表面 ——环形(按钮,分拆/切换按钮,组合框,画廊,取色器),工作空间,任务/导航/格式面板,上下文菜单
- 🌐 i18n (英语) ——内建中文(zh-CN)和英文(en);再通过
registerTranslation编号 :localizationInfo。从状态栏(循环每个注册区域)或选项对话框中切换活性 - 🌓 浅/暗主题 - 流利的设计符号驱动铬
theme属性 - 🔄 DOCX 往返 - 开放/保存
.docx通过基本的 @ docen/ docx 引擎 - 🔌 加进 ——在不触碰主机内部的情况下,插入丝带标签,任务窗体和命令
安装
# Install with pnpm
$ pnpm add @docen/editor
# Install with npm
$ npm install @docen/editor
快速启动
<docen-document> 是一个自成一体的自定义元素——登记组件,
应用主题,并输入.
<docen-document id="doc" user="Demo Macro" filename="Welcome.docx"></docen-document>
<script type="module">
import { registerComponents, applyTheme } from "@docen/editor";
registerComponents(); // register all custom elements
applyTheme("light"); // "light" | "dark"
</script>
绝对打开并保存 DOCX :
const doc = document.querySelector<DocenDocument>("#doc")!;
await doc.openDOCX(file); // File | ArrayBuffer | Uint8Array
const output = await doc.saveDOCX(); // → Uint8Array
API 密码
网络组件 : <docen-document>
一个统包 WYSIWYG 文档编辑器. 标题栏(品牌、自动保存、保存/撤消/重写, 文件名菜单 丝带 文档区域, 状态栏(页/字数,语言指标,缩放),和相框全部被建入.
属性
配置属性由反应分割 :
- 反应 运行时的更改和组件的重置:
editable, (中文(简体) ),filename, (中文(简体) ),user, (中文(简体) ),avatar, (中文(简体) ),section-properties, (中文(简体) ),styles, (中文(简体) ),addins, (中文(简体) ),theme。 。 。 . - 一次 — 仅在连接时读取( 初始值); 运行时控制通过
方法:
content, (中文(简体) ),navigation-pane, (中文(简体) ),properties-pane, (中文(简体) ),zoom, (中文(简体) ),show-marks。 。 。 .
铬(标题栏、丝带、状态栏、相片)总是显示——扩展 通过加入而不是取出属性.
| 属性 | 默认 | 说明 |
|---|---|---|
user | —— 说 | 显示页眉中显示的名称 |
avatar | —— 说 | Avatar 图像 URL (发件) ~ 首字母外形 |
filename | "文档" | 在页眉中显示文档名称并保存对话框默认值 |
content | —— 说 | 初始文档为 Tiptap JSON (一次连接) |
editable | true | false 使表面只读( 反应) |
section-properties | —— 说 | JSON 部分页面设置( 大小、 边距、 方向); 被动 |
styles | —— 说 | JSON 命名样式; 反应 |
addins | —— 说 | JSON 外部加载数组( ribbon/ task- pane 数据); 参见加载 |
theme | light | "light" | "dark"; 驱动流利主题 |
navigation-pane | —— 说 | true 打开连接上的导航( 左) 窗格( 一次) |
properties-pane | —— 说 | true 打开连接上的属性( 右) 窗格( 一次) |
zoom | 100 | 初始缩放百分比(一次);运行时间通过 setZoom |
show-marks | false | true 显示分页标记( 一次); 运行时间 setShowMarks |
lang | —— 说 | BCP-47 UI 语言"zh-CN" 编号 : "en" /.); 偶发、反应性 |
未接线的丝带命令( skeleton 按钮) 渲染可视化但已灰化
(单位:千美元)disabled)——丝带保持了完整的Office外形而不用死点击.
方法
class DocenDocument extends HTMLElement {
// Open — single entry point auto-detects docx/md from the extension.
open(file: File): Promise<void>;
// Format-specific loaders (use when the format is known up front, e.g. a
// server-fetched docx buffer with no filename).
openDOCX(input: File | ArrayBuffer | Uint8Array): Promise<void>;
openMarkdown(input: File | string): Promise<void>;
saveDOCX(): Promise<Uint8Array>;
saveMarkdown(): string;
// Runtime model — flat Tiptap JSON (doc > block+). Pages are a rendering
// projection (@docen/layout paginates per edit), never stored in the model.
// For Tiptap's own getText / setContent / chain, use getEditor().
getJSON(): JSONContent;
setJSON(json: JSONContent): void;
// The underlying @docen/docx Tiptap Editor — the full Tiptap API surface.
getEditor(): Editor | undefined;
repaginate(): void;
// Task-pane visibility (Office.addin.showAsTaskpane / hide equivalent).
// `id` is "navigation" | "properties"; flips fire docen:taskpane-visibility-change.
showTaskpane(id: TaskPaneId): void;
hideTaskpane(id: TaskPaneId): void;
getTaskpaneState(id: TaskPaneId): boolean;
// Zoom (Office.Document.zoom.set equivalent; clamped 10–500).
setZoom(pct: number): void;
getZoom(): number;
// Editing/formatting marks (page + section-break markers).
setShowMarks(on: boolean): void;
getShowMarks(): boolean;
// Add-in registry — register/unregister ribbon + command contributions.
addAddin(addin: DocenAddin): void;
removeAddin(id: string): void;
// Office.context.displayLanguage equivalent — read-only current UI locale.
readonly displayLanguage: string;
}
活动
所有事件都泡出并编曲出自"影子DOM"——收听主持人
键. docen:save 编号 : :save-as 编号 : :open 编号 : :print 可取消 :
preventDefault() 以接管动作(否则内置行为运行).
docen:save-as 携带 { format } (单位:千美元)"docx" | "markdown")——哪些
用户选择的可保存变量 。 ()docen:open 是格式不可识别的:主机
从所选文件的扩展名自动检测 docx/ md, 因此它不带
细节。 )
| 活动 | 何时 | 细节 |
|---|---|---|
docen:ready | 编辑器已挂载并准备就绪 | —— 说 |
docen:change | 文件内容已更改( 自定义驱动程序) | { dirty } |
docen:save | 保存按钮.. preventDefault() 负责接管 | —— 说 |
docen:save-as | 保存 作为菜单—— preventDefault() 负责接管 | { format } |
docen:open | 打开菜单—— preventDefault() 负责接管 | —— 说 |
docen:new | 新建菜单——仅主机(无内置动作) | —— 说 |
docen:print | 打印菜单 - preventDefault() 负责接管 | —— 说 |
docen:taskpane-visibility-change | 打开/ 关闭任务窗格( 方法或窗格 QQ) | { id, visibilityMode } |
docen:zoom-change | 缩放已更改( 按钮/ 滑块 ) / setZoom(中文(简体) ) | { zoom } |
docen:marks-change | 格式化标记已切换 | { showMarks } |
docen:lang-change | 位置已更改( 状态- 栏周期/ 选项确定) | { lang } |
槽数
属性(右)相格正体由槽驱动. 默认后退是
内置 <docen-format-pane> (空状态); 设置自定义元素
上方的窗格,例如显示图像、表格或段落属性,取决于
当前选择.
| 槽 | 默认 | 说明 |
|---|---|---|
properties | <docen-format-pane> | 右被子躯. 设置一个组件以拥有属性 UI . |
<docen-document>
<image-properties slot="properties"></image-properties>
</docen-document>
选择意识转换是消费者的责任——办公室
模型将任务表内容+导航留给了添加. 跟踪选择
(如: docen:change)并互换分档部分(v-if / 有条件
(中文(简体) ). 内置 <docen-format-pane groups='[{title,fields:[…]}]'> 是一个
声明 radio 编号 : number 编号 : color 渲染器,你可以重复使用,作为分档
当声明字段足够时内容.
配置
构件外出工作. 协作行动(保存、打开、打印)手 关闭通过可取消的事件到主机; UI通过加载扩展.
<!-- Read-only document -->
<docen-document editable="false"></docen-document>
const doc = document.querySelector<DocenDocument>("#doc")!;
// Take over save (skip the built-in picker → route to your storage)
doc.addEventListener("docen:save", (event) => {
event.preventDefault();
saveToStorage(doc.getJSON());
});
// Autosave on change
doc.addEventListener("docen:change", () => scheduleAutosave());
加进
在不触摸主机内部的情况下插入丝带标签和命令——声明
(JSON属性,只数据——函数不能跨越属性边界)或
强制( 完全添加对象通过 addAddin) (中文(简体) ). 任务组的贡献是:
留作后续(导航/格式面板今天内置),因此
只有丝带标签流经 addins 属性现在.
<!-- Declarative: a "Citations" ribbon tab -->
<docen-document
addins='[{"id":"citations","ribbon":[{"tab":"citations","label":"Citations","groups":[{"id":"tools","label":"Tools","controls":[{"type":"button","id":"cite","label":"Cite","event":"bold"}]}]}]}]'
></docen-document>
// Imperative: full add-in (commands / pane-render allowed here)
doc.addAddin({
id: "citations",
name: "Citations",
ribbon: [
{
tab: "citations",
label: "Citations",
groups: [
{
id: "tools",
label: "Tools",
controls: [/* … */],
},
],
},
],
});
丝带控制 event 引擎本地 Tiptap 命令的名称路由
(单位:千美元)editor.chain().focus().<event>(value).run()),所以一个内置的名字像 bold
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}直接工作 通过提供 Tiptap 扩展名来覆盖命令,该扩展名
addCommands 重新定义同名名称.
国际化
东道船(英语:en,默认)和中文(zh-CN) (中文(简体) ). 每个标签
运行于单个 t(key) 找找, 地方决定 每一次
从 <docen-document lang> (提前至内部工作空间)
属性和丝带、页眉、状态栏和选项对话框重新定位
生活,没有依赖 <html lang>。状态栏语言药丸周期
每个注册的地块; 选项对话框生成一个 <select> 成员名单
列表中选择一个选项.
通过注册其翻译表来添加一个地块——选项滴出和 状态栏循环在无再接线的情况下取出:
import { registerTranslation } from "@docen/editor";
registerTranslation({
languageTag: "fr",
$name: "Français",
translations: { "ribbon.tab.home": "Accueil" /* … */ },
});
重新注册标签 合并 (后来在关键冲突上获胜),所以一个加法可以
扩展内置的地块,并带有自己的密钥,而不会对地基进行打乱. 这个
Office.js 显示形状也被支持——通过 localizationInfo 一个
添加和主机登录 addAddin数字 :
doc.addAddin({
id: "about",
localizationInfo: {
defaultLanguageTag: "en",
additionalLanguages: [{ languageTag: "zh-CN", translations: { "about.tab": "关于" } }],
},
// …ribbon, commands…
});
availableLanguages() 列出每个已注册标签( 用于自定义拾取器)
只读 displayLanguage 获取镜像 Office.context.displayLanguage。 。 。 .
UI 靴子
import { registerComponents, applyTheme } from "@docen/editor";
registerComponents(); // registers <docen-document>
applyTheme("light"); // "light" | "dark"