Files
shanxia2.0/docs/superpowers/specs/2026-10-29-tinymce-table-edge-resize-design.md
T
wuzilongandCursor 3aa0f0ff2e feat: 合同富文本改为表头调列宽、首列调行高,避免拖拽把邻列挤窄。
产品表按像素列宽重排,水印改到页面右下角,打开编辑时不再铺满整表绿线。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-29 11:57:39 +08:00

3.3 KiB

富文本表格:第一行调列宽、第一列调行高

日期:2026-10-29
范围:web-admin 的 TinyMceEditor(合同打印弹窗、合同详情、报价打印弹窗共用)
状态:已确认

1. 背景与目标

合同打印富文本里的产品表需要能手调列宽和行高。上一版在整张表的每条竖线、横线上放绿色拖拽条,悬停就铺满表格,并且拖动时按当时被挤窄的视觉宽度写回像素,规格列会被压成一字一行。

该整表拖拽已经关闭(table_resize_bars: false,不再调用整表 setupExcelLikeTableResize)。

本次只恢复一种更小的拖拽:

  • 第一行:拖表头格子的右边界,调整这一列的宽度
  • 第一列:拖该行最左边格子的下边界,调整这一行的高度

打开编辑器时不改已有列宽。只有用户真正拖动,才把新的宽或高写入 HTML。保存仍走现有的「保存模板」。

2. 采用方案

句柄只画在第一行的右边界、第一列的下边界,是贴着格子边缘的短段,不贯穿整张表。

拖宽某一列时,整张表变宽,其余列的宽度保持不变。拖高某一行时,只改这一行,列宽不动。

不采用:

  • 整表每条边线都放拖拽条
  • 锁死表格总宽、从右边一列借宽度

3. 列宽

产品表第一行是 12 个独立表头,每个 colspan 为 1。拖「规格」表头的右边界,只增加规格列的像素宽度,表宽增加同样的像素,单价及后面的列不变。

规则:

  • 只给第一行里 colspan === 1 的单元格放右边界句柄
  • 第一行若有合并单元格,该格不放列宽句柄,避免把多列宽度写成一列
  • 列宽下限 28px
  • 写入 table-layout: fixed、表格 width(像素)、对应 <col> 与该表头单元格的 width(像素)
  • 不把宽度写到明细行的每个 td 上
  • 拖拽写入的表格 max-width 使用本次像素总宽,避免编辑器样式里的 max-width: 100% 把刚拖宽的表再压回去
  • 最后一列同样可以拖,表宽跟着增加

4. 行高

每一行最左边、从第 1 列开始的那个单元格,在其下边界放句柄。合计行左边常是 colspan="2" 的「运费」「不含税金额合计」,拖它的下边界只增加这一行的高度,不改任何列宽。

规则:

  • 行高下限 20px
  • 拖行高时不重写列宽
  • 预览、只读编辑器不显示句柄,也不能拖

5. 交互

  • 鼠标靠近对应边界时才出现短句柄,离开后消失
  • 句柄用主题绿,便于辨认,但长度只覆盖该格的一条边
  • 松手后记入 TinyMCE 撤销栈
  • 原生表格调整条保持关闭,不恢复整表绿线

6. 不在本次范围

  • 打开合同时按内容重算产品表列宽(现有 normalizeContractProductTableWidths 保持不动)
  • 水印位置、合计大写是否换行
  • 工具栏里的合并、拆分、插删行列

7. 验证

  • 纯函数:给定各列宽度与拖拽位移,结果里只有目标列变化,表宽变化量等于该列变化量,邻列不变;列宽不低于 28px
  • 打开编辑器后、尚未拖拽时,产品表 col 宽度与打开前一致
  • 拖表头右边界后,仅该列与表宽变化
  • 拖合计行左侧合并格的下边界后,仅该行变高
  • 预览模式无句柄