Files
workspace/code/g3soft-libs/.changeset/rich-text-format.md
T
2026-10-11 22:14:13 +08:00

5.9 KiB
Raw Blame History

@g3soft/ui
@g3soft/ui
minor

RichText 工具条补齐对齐与颜色,表格操作栏收敛为结构操作;修复内容区空白处点不聚焦。

新增(聚焦反馈)

  • 编辑器获得焦点时,正文区四周亮起 2px 主色描边(工具条不参与,参考 TinyMCE 给 .tox-edit-area 做的激活反馈)。用 inset box-shadow + border-radius(与外框 1px 边框同心)实现:不参与布局所以聚焦不会挤动正文,且滚动容器的阴影不随内容滚动 —— 换成 ::after 覆盖层滚一下就跟着正文跑掉了。触发条件取根节点的 :focus-within,这样点工具条按钮(焦点临时落在按钮上)描边不会闪。

修复

  • 内容区(.g3-rich-text__content)里只有可编辑区那一小块能点:.tiptap 原本写的 min-height: inherit 继承的是 EditorContent 那层包裹 DOM 的 computed 值(恒为 0,与 minHeight / maxHeight 无关),于是空文档时 200px 的内容区里只有约 45px 能点,下方全是「点上去既不聚焦也不落光标」的死区。现改为两层都用 flex: 1 0 auto 撑满:内容短时整块都是可编辑区,内容长时按内容撑开、由内容区滚动(不裁切);另外落在编辑器 DOM 之外的 mousedown 会兜底聚焦并把光标放到正文末尾(宿主样式改坏撑高时也有效)。

新增(工具条)

  • 对齐:左 / 居中 / 右三个按钮(@tiptap/extension-text-align,作用于 paragraph / heading)。用 toggleTextAlign,再点当前档位即取消对齐,不需要额外的「取消」按钮。
  • 字体颜色 / 背景颜色:两个取色按钮(图标 + 当前色条)。面板给出预设色板一屏、无颜色 清除属性、系统取色器选任意色;取色后面板自动收起,两个面板不会同时打开。
  • 工具条与正文之间改为双层柔和投影(0 2px 2px -2px + 0 8px 8px -4px,观感对齐 TinyMCE),同时去掉原来的 1px border-bottom(线会把投影的起笔压死);投影颜色抽成 --g3-rich-text-toolbar-shadow-near/-far 两个局部变量便于调深浅。工具条 position: relative; z-index: 1 抬在正文之上,内容滚到工具条下沿时投影不会被正文盖住;toolbar="bottom" 时两层投影翻到上方。

调整(工具条)

  • 图标分量:图标 16px、描边保持 lucide 原生粗细,前景从 ghost 默认的 text-2(65% 黑)提到 text-1(88%)—— 实测「发虚」的主因是浅灰前景而不是线宽,只加深颜色、不加重描边(试过描边 2.5 与放大到 24px,都偏重)。工具条与表格操作栏一起改,保持同一分量。
  • 重排:撤销 / 重做移到最前(历史先于格式),正文格式下拉紧接其后;按钮 32px(等于 --g3-control-height)、组内间隙 4px、内边距 8px / 10px(左右 10px 让首列图标与正文的 12px 内边距对齐),高度 36 → 48px。
  • 字体 / 字号收进 ⋯ 更多:改为二级菜单(字体 / 字号),选中态跟随光标,工具条上不再有那两个会随内容改宽度的下拉。另收起删除线 / 上标 / 下标 / 引用(格式 组)与视频(插入 组);表格插入按钮仍留在工具条(要先选行列)。自然宽度从 928px 降到 744px:760px 以上的容器都是一行。
  • ⋯ 菜单带分组标题、快捷键提示与选中态,与工具条共用同一份 ToolButton 定义。

调整(G3Dropdown)

  • 菜单面板上限从写死的 256px 改为按视口算:--g3-dropdown-max-height 兜底 calc(100vh - 48px)。256px 只够放 8 个菜单项,10 项的操作菜单就会在面板内部出滚动条(富文本 ⋯ 菜单 295px 即如此)。现在菜单随内容长、长到屏幕放不下才滚,短菜单不再无谓地滚。
  • 新增 menuMaxHeight?: boolean | number | string 按实例调整:false 不限制、数字按 px、字符串原样(如 '320px' / 'min(480px, 70vh)')、不传/true 用默认;子菜单沿用同一个值。面板 Teleport 到 body,调用方没法用 CSS 局部覆盖那个变量,所以要按实例控制只能靠它。注意 withDefaults 里显式写了 default: undefined —— 类型含 boolean 时 Vue 会把缺省值转成 false(正好等于「不限制」),不写就改掉了默认行为。

修复(G3Dropdown 子菜单)

  • 鼠标点击子菜单项此前完全无效:useFloating 在 document 的 pointerdown 捕获阶段判定「点击外部」,而子菜单面板 Teleport 到 body、不在父面板 DOM 里 → 父浮层先关闭,子项的 click 永远收不到(键盘路径同理)。现给 Popover 增加 popupScope(同一条浮层链的标识),Dropdown 的根面板与各级子菜单带上同一个值,链内面板不再算外部点击。回归用例见 packages/ui/src/dropdown/DropdownSubmenu.test.ts(此前只覆盖 hover 高亮与根层键盘导航,所以漏了这条)。

调整(表格操作栏)

  • 移除单元格左 / 中 / 右对齐与「取消单元格对齐」——单元格内容是 paragraph,对齐统一走顶部工具条(文档已注明)。
  • 移除「切换表头行」(插入表格面板已有「包含表头行」开关);保留切换表头列 / 表头单元格。
  • 「合并或拆分单元格」拆成两个独立按钮:mergeCells / splitCell,各自按 can() 置灰。
  • 删除行 / 删除列的图标改为按 lucide 规范手绘的「表格 + × 角标」——原先复用的 table-rows-split / table-columns-split 是「拆分行列」的画法,看不出删除语义。

文档见 docs/content/ui/form/rich-text.md;e2e 见 packages/ui/e2e/rich-text-focus.spec.ts(内容区几何 / 聚焦)、packages/ui/e2e/rich-text-toolbar.spec.ts(对齐 / 颜色)与 packages/ui/e2e/rich-text-table.spec.ts(合并拆分 / 删除行列 / 单元格对齐)。