Univer Docs 编辑器 UI 层完全指南:@univerjs/docs-ui 插件架构、配置与实战
Univer Docs 编辑器 UI 层完全指南univerjs/docs-ui 插件架构、配置与实战【免费下载链接】univerUniver is a full-stack framework for creating and editing spreadsheets / word processor / presentation on both web and server.项目地址: https://gitcode.com/GitHub_Trending/un/univeruniverjs/docs-ui是 Univer 全栈办公框架中文档Univer Docs编辑器的 UI 表现层负责选区渲染、剪贴板、菜单、快捷键与各类文档交互服务。本文以仓库中的 packages/docs-ui/README.md 为骨架结合其源码实现系统讲解该包的职责边界、安装接入、插件配置、底层模块划分与常见实战用法帮助开发者快速在自己的 Web 应用中集成一个具备完整编辑体验的 Univer Docs。包概述docs-ui 在 Univer 文档体系中的定位Univer 文档能力被拆分为「数据/命令内核」与「UI 表现层」两层univerjs/docs负责文档数据模型、骨架Skeleton与命令而univerjs/docs-ui则在其之上提供编辑器 UI 层包括选区渲染、剪贴板支持、菜单体系、输入法IME处理、页眉页脚面板、字数统计、富文本编辑器组件等文档交互服务。README 中给出的包能力矩阵如下包UMD 全局名CSS多语言Facade 入口univerjs/docs-uiUniverDocsUi有有有该表可以在源码中得到印证package.json 中包名为univerjs/docs-ui其exports暴露了主入口、./locale/*语言包与./facadeFacade API三个子路径src/index.ts 首行即import ./global.css说明 CSS 随包一并导出而 src/facade/index.ts 通过import ./f-document为 Facade 层注入文档 UI 能力。依赖关系上package.json 声明了univerjs/core、univerjs/docs、univerjs/design、univerjs/engine-render、univerjs/ui等运行依赖并将react与rxjs列为 peer 依赖要求 React^16.9.0 || ^17 || ^18 || ^19rxjs7.0.0。也就是说docs-ui 本身是 React 组件层与 Canvas 渲染层的桥接者。安装保持所有 univerjs 包版本一致pnpm add univerjs/docs-ui # 或 npm install univerjs/docs-uiREADME 特别强调请让所有univerjs/*包保持在同一版本。Univer 各包之间通过workspace:*相互锁定见 package.json混用不同版本可能导致依赖注入或命令注册的不一致。在 monorepo 中使用时直接依赖工作区版本即可。安装后包提供三种消费入口主入口univerjs/docs-ui插件、命令、服务、组件语言包univerjs/docs-ui/locale/lang如en-US、zh-CNFacade 扩展univerjs/docs-ui/facade需单独import以激活扩展。快速接入注册 UniverDocsUIPluginREADME 给出的最小接入代码如下import univerjs/docs-ui/lib/index.css; import EnUS from univerjs/docs-ui/locale/en-US; import { UniverDocsUIPlugin } from univerjs/docs-ui; univer.registerPlugin(UniverDocsUIPlugin); // Merge EnUS into your Univer locale map when this package contributes UI text.三点使用说明CSS 必须引入该包自带global.cssTailwind 构建负责菜单、浮动工具栏、富文本编辑器等 UI 组件的样式多语言按需合并docs-ui 为工具栏、菜单、设置面板等贡献了大量 UI 文案en-US.ts 中可见docs-ui.toolbar.font、bold、table.insert等键需要把对应的语言包合并进 Univer 的locales配置插件有前置依赖从源码看plugin.ts 声明了DependentOn(UniverDocsPlugin, UniverRenderEnginePlugin)即必须先注册文档内核插件与渲染引擎插件docs-ui 才能正常工作。仓库中的真实集成示例位于 examples/src/docs/main.ts其插件注册顺序为univer.registerPlugin(UniverRenderEnginePlugin); univer.registerPlugin(UniverFormulaEnginePlugin); univer.registerPlugin(UniverUIPlugin, { container: app, ribbonType: grid }); univer.registerPlugin(UniverDocsPlugin); univer.registerPlugin(UniverDocsUIPlugin, { container: univerdoc });随后通过univer.createUnit(UniverInstanceType.UNIVER_DOC, DEFAULT_DOCUMENT_DATA_SIMPLE)创建文档单元。该示例还依次挂载了查找替换、绘图、批注、超链接、快捷插入等关联 UI 插件说明 docs-ui 是可与其他文档功能插件叠加的基础层。插件配置IUniverDocsUIConfig 全参数解析README 未展开配置项但源码 src/config/config.ts 完整定义了插件配置结构export interface IUniverDocsUIConfig { menu?: MenuConfig; container?: HTMLElement | string; toc?: boolean; footer?: boolean; wordCount?: boolean; placeholder?: boolean; fitToWidth?: IDocFitToWidthOptions; override?: DependencyOverride; }默认值defaultPluginConfig配置项默认值说明tocfalse是否启用目录大纲侧边栏footertrue是否显示页脚如页眉页脚面板入口wordCounttrue是否显示字数统计placeholdertrue是否显示空文档占位提示fitToWidth见下文文档宽度适配设置container—挂载容器元素或选择器如示例中的univerdocmenu—覆盖/追加菜单配置会被合并进menu配置键override—依赖覆盖用于替换内置服务实现插件构造器在 plugin.ts 中会把menu与其他配置拆分menu通过setConfig(menu, menu, { merge: true })合并进全局菜单配置其余字段写入docs-ui.config配置键即源码中的DOCS_UI_PLUGIN_CONFIG_KEY。fitToWidth文档自适应宽度fitToWidth是文档阅读体验的关键配置其类型定义与默认值如下export type DocFitMode none | fit-width; export type DocFitTarget viewport | container; export type DocFitAlign center | start; export type DocFitPaddingX number | ${number}%; export interface IDocFitToWidthOptions { mode?: DocFitMode; target?: DocFitTarget; paddingX?: DocFitPaddingX; minScale?: number; maxScale?: number; align?: DocFitAlign; } export const DEFAULT_DOC_FIT_TO_WIDTH_OPTIONS { mode: none, // 默认不缩放 target: viewport,// 以视口为适配基准 paddingX: 20, // 左右留白 20px minScale: 1, // 最小缩放 1 maxScale: undefined, // 不设上限 align: center, // 居中 };其计算逻辑集中在 src/services/doc-view-scale.tsnormalizeDocFitToWidthOptions负责把用户配置与默认值合并resolveDocFitPaddingX支持数字像素与百分比字符串两种 padding 写法20与5%calcDocFitToWidthScale仅在mode fit-width时生效核心公式为availableWidth / baseWidth并用minScale/maxScale钳制结果resolveDocFitBaseWidth依次优先使用文档样式中的pageSize.width、Modern 文档的MODERN_DOCUMENT_WIDTH中档宽度、骨架页宽作为基准宽度resolveDocViewScale将用户缩放倍率与自适应倍率相乘得到最终视图缩放。开启自适应宽度示例如下univer.registerPlugin(UniverDocsUIPlugin, { container: univerdoc, fitToWidth: { mode: fit-width, target: viewport, paddingX: 5%, minScale: 0.8, maxScale: 1.5, align: center, }, });插件生命周期命令、快捷键与渲染模块的装配从 plugin.ts 的源码可以完整还原该插件启动时做了什么这也是理解 UI 层职责边界的最佳入口。命令注册_initCommand插件一次性注册了 90 个命令/操作按功能可归为以下几类行内格式SetInlineFormatBoldCommand、SetInlineFormatItalicCommand、SetInlineFormatUnderlineCommand、SetInlineFormatStrikethroughCommand、上下标、字号、字体、文字颜色、文本背景色等段落与列表AlignLeft/Center/Right/JustifyCommand、OrderListCommand、BulletListCommand、ChangeListNestingLevelCommand、CheckListCommand、ToggleCheckListCommand标题与样式H1~H5HeadingCommand、TitleHeadingCommand、SubtitleHeadingCommand、NormalTextHeadingCommand、SetParagraphNamedStyleCommand表格CreateDocTableCommand、行列插入/删除系列命令、DocTableTabCommand编辑操作DeleteLeft/RightCommand、BreakLineCommand、MoveDocBlockCommand、剪贴板系列DocCopyCommand、DocCutCommand、DocPasteCommand、InnerPasteCommand、ReplaceSnapshotCommand、CoverContentCommand视图与模式SetDocZoomRatioCommand、SwitchDocModeCommand、DocSelectAllCommand面板DocParagraphSettingPanelOperation、DocSectionSettingPanelOperation、InsertDocumentSectionBreakOperation等。命令注册集中在 plugin.ts。快捷键注册_initializeShortcut插件注册了覆盖「光标移动、选区扩展、删除、换行、标题、Tab/ShiftTab」的快捷键集合plugin.ts包括MoveCursorUp/Down/Left/RightShortcut、MoveSelection*Shortcut、DeleteLeft/RightShortcut、BreakLineShortcut、SoftBreakLineShortcut、H1~H5HeadingShortcut等。这些快捷键通过IShortcutService注入职责划分清晰光标/选区类在 src/shortcuts/cursor.shortcut.ts格式类在 src/shortcuts/format.shortcut.ts标题类在 src/shortcuts/heading.shortcut.ts。渲染模块注册两阶段渲染相关能力被拆成两个阶段注册_initRenderBasicsonReady 阶段注册DocSkeletonManagerService、DocSelectionRenderService、DocInterceptorService、DocViewScaleService、DocPageLayoutService、DocIMEInputManagerService、DocRenderController、DocZoomRenderController_initRenderModulesonRendered 阶段注册DocEventManagerService、DocFloatMenuService、DocParagraphMenuService、DocBackScrollRenderController、DocSelectionRenderController、DocHeaderFooterController、DocResizeRenderController、DocParagraphPlaceholderRenderController、DocContextMenuRenderController、DocChecklistRenderController、DocClipboardController、DocInputController、DocIMEInputController、DocEditorBridgeController。可以看到选区渲染DocSelectionRender*、剪贴板DocClipboard*、输入法DocIME*、菜单DocFloatMenuService、DocParagraphMenuService、上下文菜单DocContextMenuRenderController正是 README 所描述的「selection rendering, clipboard support, menus, and document interaction services」的代码级落地。此外_initAutoFocusplugin.ts会订阅当前文档单元变化当存在非编辑器类型的文档单元时自动聚焦保证打开文档即进入可编辑状态。编辑器 UI 的四大核心能力1. 选区渲染与光标控制选区渲染由DocSelectionRenderService与DocSelectionRenderController实现配套工具包括文本区间/矩形区间互转services/selection 目录下的convert-text-range.ts、convert-rect-range.ts、text-range.ts、rect-range.ts、词边界计算word-boundary.ts以及文档渲染背景doc-render-background.ts。选区渲染服务注册在基础阶段是其他交互输入、剪贴板、菜单的前提。2. 剪贴板HTML ⇄ UDM 双向转换剪贴板是 docs-ui 技术含量最高的模块之一位于 services/clipboardHTML → UDM粘贴方向html-to-udm/converter.ts把外部 HTML 转成 Univer 的 UDMUniver Document Model结构并通过可插拔的 paste 插件适配不同来源——plugin-word.tsWord、plugin-lark.ts飞书、plugin-univer.tsUniver 内部拷贝parse-node-style.ts负责解析内联样式UDM → HTML复制/导出方向udm-to-html/convertor.ts与doc-html-export.service.ts提供convertBodyToHtml与DocHtmlExportService支持注册自定义DocHtmlExportTransformer粘贴适配doc-paste-mutation-adapter.service.tsIDocClipboardPasteAdapterService把粘贴内容适配为文档变更支持自定义块、自定义区间的映射。入口服务DocClipboardServiceIDocClipboardService在插件初始化时被替换为实际实现plugin.ts。剪贴板测试用例见 services/clipboard/tests包含 HTML/UDM 转换与复制粘贴服务的单测。3. 菜单与浮动工具栏根菜单/浮动工具栏menu/menu.ts提供BoldMenuItemFactory、ItalicMenuItemFactory、FontFamilySelectorMenuItemFactory、FontSizeSelectorMenuItemFactory、TextColorSelectorMenuItemFactory、AlignMenuItemFactory等工厂函数并定义FLOAT_TOOLBAR_MENU_POSITION与FLOAT_TEXT_STYLE_MENU_ID段落菜单menu/paragraph-menu.ts与DocParagraphMenuService提供段落级操作如表格块、内容插入、对齐设置DocParagraphMenuService还暴露IDocBlockMenuTarget类型UI 装配DocUIControllercontrollers/ui.controller.ts在初始化时完成appendRootMenu(floatToolbarMenuSchema)、mergeMenu(menuSchema)并向IUIPartsService注册页脚组件DocFooter与侧边菜单DocSideMenu对应footer/toc配置项。菜单 Schema 在 menu/schema.ts 中集中定义并由DocsUIMenuSchema导出。4. 输入法IME与自动格式化IME 支持DocIMEInputManagerService、DocIMEInputController、DocIMEStateChangeInterceptorService共同处理中日韩等组合输入场景DocIMEStateChangeInterceptorService会替换默认的IDocStateChangeInterceptorServiceplugin.ts拦截组合输入过程中的文档状态变更IMEInputCommand与IIMEInputCommandParams提供编程式输入入口自动格式化DocAutoFormatService与DocAutoFormatController实现输入后的自动排版如列表续接配套AfterSpaceCommand、EnterCommand、TabCommand。页眉页脚、页设置、字数统计等内置面板docs-ui 内置了多个开箱即用的文档设置面板对应views/与services/中的实现页眉页脚DocHeaderFooterController 面板组件 views/header-footer/panel/DocHeaderFooterPanel.tsx配套命令CoreHeaderFooterCommand、OpenHeaderFooterPanelCommand与SidebarDocHeaderFooterPanelOperation段落设置DocParagraphSettingController与 views/paragraph-setting/Setting.tsx支持行距line-spacing.ts等节/页面设置DocSectionSettingController与 views/section-setting/Setting.tsx支持分节符、分栏符插入InsertDocumentSectionBreakOperation、InsertDocumentColumnBreakOperation字数统计views/doc-statistics/DocStatistics.tsx 配合use-doc-statistics.tsHook由wordCount配置项控制缩放滑块views/count-bar/ZoomSlider.tsx 提供文档缩放控制底层由SetDocZoomRatioCommand/SetDocZoomRatioOperation支撑表格创建views/table/create/TableCreate.tsx 提供行列数选择的表格插入面板。把编辑器嵌入任意页面RichTextEditor 与 Editor 服务docs-ui 不只是整页文档编辑器还提供可嵌入的轻量富文本输入组件RichTextEditorviews/RichTextEditor.tsx。其 Props 设计如下interface IRichTextEditorProps { className?: string; autoFocus?: boolean; onFocusChange?: (isFocus: boolean, newValue?: string) void; initialValue?: IDocumentData | string; onClickOutside?: () void; preserveHostFocus?: boolean; // 输入聚焦时保持宿主全局单元焦点 keyboardEventConfig?: IKeyboardEventConfig; moveCursor?: boolean; isSingle?: boolean; // 单行模式 placeholder?: string; editorId?: string; onHeightChange?: (height: number) void; onChange?: (data: IDocumentData, str: string) void; maxHeight?: number; defaultHeight?: number; icon?: ReactNode; editorRef?: RefObjectEditor | null | ((editor: Editor | null) void); noStyle?: boolean; }该组件内部通过useEditorHook 与IEditorServiceEditorService创建独立的内联编辑器自动处理占位符显隐空文档时显示placeholder高度自适应基于DocSkeletonManagerService的真实骨架高度在defaultHeight与maxHeight之间伸缩撤销/重做键盘配置createEditorUndoRedoKeyboardConfig点击外部失焦useEditorClickOutside、左右方向键useLeftAndRightArrow、焦点状态useIsFocusing。Editor类位于 services/editor/editor.tsEditorService在 services/editor/editor-manager.service.ts二者共同维护「内联编辑器」生命周期——这也是示例项目如examples/src/sheets中的公式/单元格输入复用文档内核实现输入能力的基础。Facade API一行代码设置选区docs-ui 通过 Facade 扩展为FDocument增加 UI 能力。在 src/facade/f-document.ts 中定义了FDocumentUIMixininterface IFDocumentUIMixin { setSelection(startOffset: number, endOffset: number): void; } export class FDocumentUIMixin extends FDocument implements IFDocumentUIMixin { override setSelection(startOffset: number, endOffset: number): void { const renderManagerService this._injector.get(IRenderManagerService); const docSelectionRenderService renderManagerService.getRenderUnitById(this.getId()) ?.with(DocSelectionRenderService); docSelectionRenderService?.removeAllRanges(); docSelectionRenderService?.addDocRanges( [{ startOffset, endOffset, rangeType: DOC_RANGE_TYPE.TEXT }], true ); } } FDocument.extend(FDocumentUIMixin);使用前提是引入univerjs/docs-ui/facade如示例 examples/src/docs/main.ts 中的import univerjs/docs-ui/facade。激活后即可const fDocument univerAPI.getActiveDocument(); fDocument.setSelection(10, 20); // 选中第 1020 个字符从实现可以看到setSelection实际上是先清空现有选区再通过DocSelectionRenderService.addDocRanges以TEXT类型范围绘制选区这直观体现了「Facade 是服务层的薄封装」这一设计。本地化19 种语言开箱即用docs-ui 在 src/locale 目录下提供 19 种语言包en-US、zh-CN、zh-TW、zh-HK、ja-JP、ko-KR、de-DE、fr-FR、es-ES、pt-BR、it-IT、ru-RU、pl-PL、id-ID、vi-VN、ar-SA、ca-ES、fa-IR、sk-SK。语言包通过包导出子路径univerjs/docs-ui/locale/lang单独引用按需合并进 Univer 的locales配置避免全量打入。文案键集中在docs-ui命名空间下工具栏、菜单、面板等类型由 locale/types.ts 约束保证多语言键的编译期一致。测试覆盖与后续深入路径docs-ui 的测试体系非常完整约 40 个 spec 文件分布在各模块的__tests__目录可作为理解模块行为的辅助资料命令测试commands/commands/tests覆盖剪贴板、换行、列表、标题、行内格式、表格创建、块移动、替换内容等核心命令渲染控制器测试controllers/render-controllers/tests覆盖选区渲染、剪贴板控制器、上下文菜单、输入控制器、缩放等服务测试services/tests覆盖自动格式化、事件管理、IME、菜单样式、页布局、缩放、打印拦截器等组件测试views/tests覆盖段落菜单、侧边菜单、字数统计、缩放滑块、富文本编辑器 Hook 等。感兴趣的读者可以从以下文件继续深入插件装配入口 src/plugin.ts、配置定义 src/config/config.ts、剪贴板转换 src/services/clipboard、选区渲染 src/services/selection/doc-selection-render.service.ts、以及内嵌富文本编辑器 src/views/RichTextEditor.tsx。小结univerjs/docs-ui是 Univer Docs 从「文档内核」走向「可用编辑器」的关键一层。通过UniverDocsUIPlugin的一次注册即可获得选区渲染、剪贴板、菜单、快捷键、IME、页眉页脚、字数统计等完整的文档编辑交互通过fitToWidth、toc、wordCount等配置项可以按需裁剪 UI 能力通过RichTextEditor组件与 Facade 的setSelectionAPI还能把文档编辑能力嵌入到表单、单元格输入等任意场景中。结合本仓库源码逐一对照配置与模块可以更高效地把这套编辑器能力集成进自己的产品。【免费下载链接】univerUniver is a full-stack framework for creating and editing spreadsheets / word processor / presentation on both web and server.项目地址: https://gitcode.com/GitHub_Trending/un/univer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →