@agile-team/wl-skills-ui 1.9.12 → 1.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,35 @@ All notable changes to **@agile-team/wl-skills-ui** will be documented in this f
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.9.14] - 2026-08-10
8
+
9
+ ### Added
10
+
11
+ - 新增受管业务组件字体 Token 与 Edge/Chrome 双浏览器计算样式门禁,统一 Element Table、BaseTable、AG Grid 的中英文数字字体链,同时保持登录页、大屏、编辑器、图表、图标字体和显式豁免区边界。
12
+ - 复合结构清单按 common-core 真实 DOM 补全 `.com-inputNumber-content` 根类,并新增 jh-input-number 高度、对齐、controls、单描边视觉回归。
13
+
14
+ ### Fixed
15
+
16
+ - 修复普通 InputNumber 高权重规则误命中 `jh-input-number`,造成复合数字框高度链、`textAlign` 与 controls 语义被压平的问题;复合根统一 26px 与五态外轮廓,内部 wrapper 不重复描边。
17
+ - 修复 AG Grid 普通单元格强制 flex 居中覆盖 BaseTable `align/headerAlign`,以及透明右边框遮掉焦点单元格一侧描边的问题;普通列重新遵循 AG Grid 原生对齐,仅复选框列保持精准居中。
18
+ - AG Grid 紧凑表头字号由半像素改为整数 13px,降低 Windows Edge 小字号抗锯齿差异。
19
+
20
+ ## [1.9.13] - 2026-08-07
21
+
22
+ ### Added
23
+
24
+ - 新增 `runtime/split-grid-resize` 分屏表格尺寸守护:只观察 `jh-drag-row` 的直接 pane,支持动态路由晚挂载,连续 Resize 按动画帧合并,并向 grid host 派发局部 `wl-ui:split-grid-resize` 事件。
25
+ - 复合结构清单新增 Element Plus input-group 新旧 DOM 与 common-core drag-row/AG Grid 契约,并补充 Node 行为测试和真实浏览器回归。
26
+
27
+ ### Fixed
28
+
29
+ - 修复带 prefix/append 的输入框主体与右侧图标高度、圆角、边框不一致;组合根统一 26px、6px 和五态描边,左右图标统一 14px,纯图标附加段统一 32px,同时兼容旧版 input 直挂和新版 wrapper DOM。
30
+ - 修复上下分屏拖动后 AG Grid 宿主未沿 pane 收缩、上表只被外层 `overflow:hidden` 裁切且缺少内部纵向滚动的问题;只补齐已识别 AG Grid 的 flex 高度链,让 AG Grid 自身 ResizeObserver 完成内部布局。
31
+
32
+ ### Changed
33
+
34
+ - 分屏守护不增加外层滚动条、不广播全局 `window.resize`、不访问 Vue 私有实例或猜测 gridApi;普通分屏、普通表格、非分屏 AG Grid、登录页和显式豁免区域不接管,卸载时清理包内结构标记。
35
+
7
36
  ## [1.9.12] - 2026-08-06
8
37
 
9
38
  ### Added
package/README.md CHANGED
@@ -104,8 +104,9 @@ wl-skills-ui/
104
104
  │ │ ├── common.ts # 通用业务预设(enable/audit/verify + 起步包)
105
105
  │ │ └── index.ts
106
106
  │ ├── auto.ts # Skin/老项目包级保护自动入口
107
- │ ├── guards.ts # 主题锁 + 长文本溢出保护聚合
107
+ │ ├── guards.ts # 主题锁 + 长文本 + 分屏表格尺寸保护聚合
108
108
  │ ├── overflow-tooltip.ts # 普通表格真实溢出 Tooltip 兜底
109
+ │ ├── split-grid-resize.ts # jh-drag-row 内 AG Grid Resize/高度链守护
109
110
  │ └── index.ts # 公共 API 入口
110
111
  │
111
112
  ├── scanner/ # 自动化扫描 / 修复
@@ -212,7 +213,7 @@ yarn add @agile-team/wl-skills-ui
212
213
  |---|---|---|
213
214
  | `element-plus` | **`2.2.6-prod.3`** | 集团 jh- 定制版;EP 2.3.0 起引入 `.el-input__wrapper`,与 jh-ui 3.x 不兼容 |
214
215
  | `@jhlc/jh-ui` | **`3.1.0`** | SCSS 皮肤包,`.com-text` label 包裹 + `.has-colon` 冒号注入(wl-skills-ui 已统一屏蔽表单冒号) |
215
- | `@agile-team/wl-skills-ui` | `^1.9.12` | 已对齐上述组合的 DOM 假设、客户主题锁、圆角契约、复合输入、表格长文本兜底与定制页样式边界 |
216
+ | `@agile-team/wl-skills-ui` | `^1.9.14` | 已对齐上述组合的 DOM 假设、客户主题锁、圆角契约、复合数字框、跨浏览器字体、AG Grid 原生对齐与定制页边界 |
216
217
 
217
218
  三种识别方式,任选其一:
218
219
 
@@ -226,7 +227,27 @@ yarn add @agile-team/wl-skills-ui
226
227
 
227
228
  ## 版本亮点
228
229
 
229
- 当前 v1.9.12:
230
+ 当前 v1.9.14:
231
+
232
+ - **Edge/Chrome 字体收敛**:受管 Element、BaseTable 与 AG Grid 统一使用覆盖中英文数字的
233
+ `--wk-font-family-sans`,AG 表头/正文使用整数 13px;不改写 `body/*`,登录页、大屏、
234
+ 编辑器、图表、图标字体和显式豁免区不受影响。
235
+ - **jh-input-number 精准解耦**:普通 Element 数字框规则不再误命中
236
+ `.com-inputNumber-content`;复合根统一 26px 和唯一状态描边,同时保留组件自身
237
+ `textAlign`、controls、单位及后缀语义。
238
+ - **BaseTable/AG Grid 原生语义恢复**:焦点单元格四边框完整;取消普通单元格和表头的
239
+ 强制居中,`align/headerAlign` 重新以列配置和 AG Grid 原生样式为准,复选框列仍精准居中。
240
+ - **双浏览器门禁**:Windows Edge 维护像素基准,Edge + Google Chrome 同时验证字体、
241
+ 数字框高度、焦点边框及左右对齐计算样式。
242
+
243
+ 上一版 v1.9.13:
244
+
245
+ - **输入附加段不再割裂**:`el-input-group` 由组合根统一 26px 高度、6px 外圆角和 default/hover/focus/error/disabled 描边;左侧 prefix、右侧 append 图标统一 14px,纯图标附加段 32px,文字/单位/按钮仍按内容宽度。
246
+ - **新旧 DOM 同时覆盖**:兼容 jh-ui 配套旧版 input 直挂结构和新版 `.el-input__wrapper` 结构,内部输入不再重复描边;普通 input、普通按钮、登录页和显式豁免区保持原行为。
247
+ - **分屏表格真正重布局**:`runtime/auto` 只观察 `jh-drag-row` 内真实 AG Grid pane,补齐可收缩高度链并按帧派发局部重布局事件;AG Grid 自身 ResizeObserver 生成内部滚动条,不给外层加滚动条、不广播全局 resize、不访问 Vue 私有实例。
248
+ - **回归边界闭环**:结构清单新增 input-group 新旧 DOM 与 drag-row/AG Grid 契约;Node 行为测试覆盖动态挂载、批量 Resize、豁免区,真实浏览器验证附加段计算样式及 220px→120px 收缩后的内部滚动。
249
+
250
+ 上一版 v1.9.12:
230
251
 
231
252
  - **复合结构有清单**:`standards/component-structures.json` 登记边框所有者、内部无描边层、高度策略、状态与 Teleport 出口;首批覆盖 common-core 多标签、人员/部门/树选择、多选、混合数字框及 BaseToolbar 分裂按钮。
232
253
  - **未知结构先评审**:新增 R040,对疑似复合 Element wrapper 只报告、不自动修复,要求先核对真实 DOM 并登记契约,禁止继续放大普通 Element 选择器。
@@ -403,7 +424,7 @@ npx wl-ui init --mode native
403
424
  // 4. src/main.ts
404
425
  import { installCommonPreset } from "@agile-team/wl-skills-ui/runtime/common-preset";
405
426
  installCommonPreset();
406
- // installCommonPreset 已包含主题锁和普通表格长文本包级保护,无需重复引入 runtime/auto。
427
+ // 已包含主题锁、普通表格长文本和分屏 AG Grid 尺寸保护,无需重复引入 runtime/auto。
407
428
  ```
408
429
 
409
430
  ```vue
@@ -764,7 +785,8 @@ export const myRules = [
764
785
 
765
786
  ### 维护者防回归
766
787
 
767
- 复合控件必须先登记结构契约,再增加精准样式;包发版必须经过 Chromium 基准图对比:
788
+ 复合控件必须先登记结构契约,再增加精准样式;包发版必须经过 Edge 基准图与
789
+ Edge/Chrome 双浏览器计算样式验证:
768
790
 
769
791
  ```bash
770
792
  # Windows 默认使用已安装的 Edge Chromium;非 Windows 首次安装一次
@@ -1,5 +1,20 @@
1
1
  # 字体排版规范
2
2
 
3
+ ## 字体族
4
+
5
+ 受管业务组件统一使用:
6
+
7
+ ```css
8
+ var(--wk-font-family-sans)
9
+ /* "Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC",
10
+ "Hiragino Sans GB", Arial, sans-serif */
11
+ ```
12
+
13
+ Windows 优先选择可同时覆盖中文、英文和数字的微软雅黑 UI 字体,避免 Edge 的增强文本
14
+ 对比度把逐字符 fallback 的差异放大为同一行粗细、字面高度不一致。该 Token 只映射到
15
+ Element Plus、BaseTable 和 AG Grid 等受管组件根,不直接覆盖 `body` 或 `*`;登录页、大屏、
16
+ 代码编辑器、图表、图标字体及显式豁免区继续保留自己的字体设计。
17
+
3
18
  ## 字号
4
19
 
5
20
  | Token | 值 | 用途 |
@@ -27,3 +42,4 @@
27
42
  3. 表格表头 `14px / font-weight: 500`
28
43
  4. 弹窗标题 `16px / font-weight: 600`
29
44
  5. Tag/角标 `12px`
45
+ 6. 紧凑 AG Grid 表头/正文统一使用整数 `13px`,避免小字号半像素在浏览器间放大差异
@@ -1,5 +1,11 @@
1
1
  :root body {
2
2
  /* 客户主题契约:防止平台运行时 body 内联主题覆盖。 */
3
+ /*
4
+ * Windows 企业端优先使用同时覆盖中文、英文与数字的微软雅黑 UI 字体,
5
+ * 避免 Edge/Chrome 按字符切换 Helvetica/Segoe UI 与中文 fallback 后出现粗细跳变。
6
+ * 该 Token 只由受管组件根消费,不直接改写 body 字体,登录页/大屏仍可独立设计。
7
+ */
8
+ --wk-font-family-sans: "Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", Arial, sans-serif !important;
3
9
  --el-color-primary: #002a8f !important;
4
10
  --el-color-primary-rgb: 0, 42, 143 !important;
5
11
  --el-color-primary-light-1: #1a3f9a !important;
package/dist/tokens.css CHANGED
@@ -1,5 +1,11 @@
1
1
  :root body {
2
2
  /* 客户主题契约:防止平台运行时 body 内联主题覆盖。 */
3
+ /*
4
+ * Windows 企业端优先使用同时覆盖中文、英文与数字的微软雅黑 UI 字体,
5
+ * 避免 Edge/Chrome 按字符切换 Helvetica/Segoe UI 与中文 fallback 后出现粗细跳变。
6
+ * 该 Token 只由受管组件根消费,不直接改写 body 字体,登录页/大屏仍可独立设计。
7
+ */
8
+ --wk-font-family-sans: "Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", Arial, sans-serif !important;
3
9
  --el-color-primary: #002a8f !important;
4
10
  --el-color-primary-rgb: 0, 42, 143 !important;
5
11
  --el-color-primary-light-1: #1a3f9a !important;
@@ -11,7 +11,7 @@
11
11
  | `element-plus` | **`2.2.6-prod.3`** | 集团 jh- 定制版,搭配 `@jhlc/jh-ui` 使用,DOM 仍为 `.el-input > .el-input__inner` 直挂结构(**EP 2.3.0 起才引入 `.el-input__wrapper`**) |
12
12
  | `@jhlc/jh-ui` | **`3.1.0`** | SCSS 皮肤包,`.com-text` label 包裹、`.has-colon ::after` 冒号注入、`.el-form-item--default { margin-bottom: 24px }` 等强约束 |
13
13
  | `@jhlc/common-core` | `3.1.0` 或 `3.1.0-prod.x` | 基础 util/types,`@jhlc/jh-ui` 间接依赖 |
14
- | `@agile-team/wl-skills-ui` | `^1.9.12` | 已对齐 jh-ui 3.1.0 + EP 2.2.6-prod.3 的 DOM 假设、客户主题锁、6px 基础圆角、紧凑表单、复合结构契约、表格行状态、分裂按钮、包级长文本提示、定制页样式边界与 Vite 4 开发转换 |
14
+ | `@agile-team/wl-skills-ui` | `^1.9.14` | 已对齐 jh-ui 3.1.0 + EP 2.2.6-prod.3 的 DOM 假设、客户主题锁、6px 基础圆角、紧凑表单、复合数字框、跨浏览器字体、AG Grid 原生对齐与定制页边界 |
15
15
 
16
16
  ## 项目集群当前实测
17
17
 
@@ -35,7 +35,7 @@
35
35
 
36
36
  ## 适配建议
37
37
 
38
- - 集团内项目:**统一锚定 `element-plus@2.2.6-prod.3` + `@jhlc/jh-ui@3.1.0`**,与 wl-skills-ui v1.9.12 三方对齐。
38
+ - 集团内项目:**统一锚定 `element-plus@2.2.6-prod.3` + `@jhlc/jh-ui@3.1.0`**,与 wl-skills-ui v1.9.14 三方对齐。
39
39
  - Skin 项目除全局样式外,在 `main.ts` 引入一次 `@agile-team/wl-skills-ui/runtime/auto`;Native 项目的 `installCommonPreset()` 已包含相同包级保护,不要重复安装。
40
40
  - 升级 `element-plus` 到 2.3+ 前,必须同步升级 `@jhlc/jh-ui` 到对应支持版本,否则 `.com-text` / `.el-input__inner` DOM 与 EP `__wrapper` 体系不兼容。
41
41
  - 新项目接入:见 README 「快速接入」章节,默认会按本表声明 peerDependency 范围。
@@ -36,8 +36,19 @@ wrapper 时,应先按上述流程确认,不能直接扩大全局 Element 选
36
36
 
37
37
  - common-core 多标签输入与人员选择多选。
38
38
  - 部门选择、树选择和 Element 多选封装。
39
- - 同节点 wrapper + 子 wrapper 的混合数字输入。
39
+ - common-core `jh-input-number` 的
40
+ `.com-inputNumber-content.el-input-number.el-input__wrapper` 复合根:外层统一 26px
41
+ 高度与唯一状态边框,内部 wrapper 无重复描边,并保留 `textAlign`、`controls`、单位与
42
+ 后缀等组件原生语义。
40
43
  - BaseToolbar 分裂按钮及其动作菜单 Teleport 出口。
44
+ - Element Plus 新旧两种 input-group prepend/append DOM:组合根负责唯一外轮廓,
45
+ 输入主体与附加段统一 26px,纯图标附加段 32px、图标 14px。
46
+ - common-core `jh-drag-row + BaseTable/AG Grid` 高度链:只在真实分屏 AG Grid 中
47
+ 补齐可收缩结构并通知表格内部重布局。
41
48
 
42
49
  组件结构变化时,测试会先在 fixture/selector 契约处失败,从而把风险阻断在发版前,
43
50
  不会等十余个业务项目升级后再发现。
51
+
52
+ input-group 附加段保留文字、单位、按钮的内容驱动宽度,只有“直接子节点为唯一
53
+ `.el-icon`”时才使用 32px 紧凑宽度;普通 input、普通按钮和非 input-group 不命中。
54
+ 分屏重布局的运行机制与接入方式见 `docs/split-grid-resize.md`。
@@ -0,0 +1,68 @@
1
+ # 上下分屏 AG Grid 尺寸重布局
2
+
3
+ ## 问题与边界
4
+
5
+ `jh-drag-row` 的 `.drager_top/.drager_bottom` 使用 `overflow:hidden` 隔离上下区域。
6
+ 拖动分隔条后,如果 BaseTable/AG Grid 宿主没有沿 flex 高度链一起收缩,外层只会裁切
7
+ 旧尺寸表格,上表内部不会得到新的 viewport 高度,也就看不到应有的纵向滚动条。
8
+
9
+ 本方案只治理以下同时成立的结构:
10
+
11
+ - 根节点是 `.drager_row`;
12
+ - 直接 pane 是 `.drager_top` 或 `.drager_bottom`;
13
+ - pane 内真实存在 `.ag-grid-table` 或 `.ag-root-wrapper`;
14
+ - 不在 `.lp-root`、`.session-login`、`.wl-ui-skin-exempt`、
15
+ `[data-wl-ui-skin="off"]` 中。
16
+
17
+ 普通分屏内容、Element Table、非分屏 AG Grid 和定制区域均不接管。
18
+
19
+ ## 实现机制
20
+
21
+ 1. `runtime/auto` 安装 `ResizeObserver`,只观察已识别分屏的两个直接 pane。
22
+ 2. 动态路由晚挂载的新分屏通过仅监听 `childList` 的 `MutationObserver` 注册;不监听
23
+ 全站 style/class 变化,也不扫描每一帧。
24
+ 3. 发现 AG Grid 后,为 pane、必要祖先和 grid host 增加包内结构标记;SCSS 只对这些
25
+ 标记补 `min-height:0`。当 grid 的直接父级本来就是纵向 flex 时,grid 使用
26
+ `flex:1 1 0 + height:0` 占据剩余空间。
27
+ 4. grid host 真实尺寸改变后,AG Grid 自身的 `ResizeObserver` 完成布局计算并让内部
28
+ `.ag-body-viewport` 生成滚动条。
29
+ 5. 同一动画帧内的连续 Resize 会合并,并在 grid host 上派发局部
30
+ `wl-ui:split-grid-resize` 事件,供特殊平台封装按需调用公开 grid API。
31
+
32
+ 本实现不会给 `.drager_top/.drager_bottom` 增加 `overflow:auto`,不会访问 Vue 私有实例,
33
+ 不会遍历或猜测 `gridApi`,也不会广播全局 `window.resize`。卸载守护时,本包增加的结构
34
+ 标记会一并清理。
35
+
36
+ ## 接入
37
+
38
+ Skin 项目必须同时接入样式与一次运行时保护:
39
+
40
+ ```scss
41
+ @use "@agile-team/wl-skills-ui/styles/presets/skin" as *;
42
+ ```
43
+
44
+ ```ts
45
+ import "@agile-team/wl-skills-ui/runtime/auto";
46
+ ```
47
+
48
+ Native 项目调用 `installCommonPreset()` 即可,它已经包含相同守护,不要重复引入
49
+ `runtime/auto`。
50
+
51
+ 平台封装若确实还需要主动调用 `api.doLayout()`,可选监听局部事件:
52
+
53
+ ```ts
54
+ gridHost.addEventListener("wl-ui:split-grid-resize", () => {
55
+ gridApi.doLayout?.();
56
+ });
57
+ ```
58
+
59
+ 常规 AG Grid 无需业务代码监听;宿主尺寸变化已经会触发它自己的 ResizeObserver。
60
+
61
+ ## 验收
62
+
63
+ - 拖动前后 `.drager_top/.drager_bottom` 仍为 `overflow:hidden`。
64
+ - `.ag-grid-table` 的实际高度随 pane 收缩,并带
65
+ `data-wl-ui-split-grid-host`。
66
+ - `.ag-body-viewport` 的 `scrollHeight > clientHeight` 时出现内部纵向滚动条。
67
+ - 分屏外的 AG Grid、普通表格、登录页和显式豁免区无新增结构标记。
68
+ - `npm run test:visual` 中“上下分屏收缩后由 AG Grid 内部 viewport 滚动”通过。
@@ -13,8 +13,15 @@
13
13
  - textarea focus 品牌边框与轻焦点环。
14
14
  - 数字输入只有一个边框所有者。
15
15
  - common-core 复合多标签外壳自然增高、内层无双描边。
16
+ - input-group 输入主体、前后附加段、左右图标的统一高度/尺寸/圆角与 focus 描边。
17
+ - jh-drag-row 收缩后 AG Grid host 跟随变高,纵向滚动只发生在内部 viewport。
16
18
  - Element Table 长文本真实溢出、省略号与按需完整提示。
17
19
  - 表格选中行柔和状态色、BaseToolbar 分裂按钮与定制区域豁免。
20
+ - common-core `jh-input-number` 与普通表单控件同高,保留 `textAlign` 和 controls,且只有
21
+ 复合根绘制状态边框。
22
+ - AG Grid 焦点单元格四边描边完整,`align/headerAlign` 继续由 BaseTable/AG Grid 列配置决定。
23
+ - 受管 Element Table、BaseTable 与 AG Grid 使用同一中英文数字字体链;计算样式契约分别
24
+ 在 Windows Edge 和 Google Chrome 运行,像素截图仍只维护一套 Edge 基准。
18
25
 
19
26
  ## 使用
20
27
 
@@ -36,7 +43,8 @@ pnpm release:check
36
43
  ```
37
44
 
38
45
  截图基准按 Playwright 的浏览器/平台规则保存,不随 npm 包发布。Windows 默认使用企业
39
- 环境已有的 Edge Chromium,也可通过 `WL_UI_BROWSER_CHANNEL` 显式指定 Playwright 通道。
46
+ 环境已有的 Edge Chromium,也可通过 `WL_UI_BROWSER_CHANNEL` 显式指定截图通道;无截图的
47
+ 字体、尺寸、焦点与对齐契约会额外启动系统 Edge 和 Google Chrome 各验证一次。
40
48
  视觉像素受操作系统、浏览器版本和字体渲染影响,生成与比较必须使用相同环境;当前
41
49
  基准为 Windows Edge Chromium。
42
50
  升级 Playwright、Chromium 或字体后,应单独提交基准变化并人工审图,不能把更新截图当成
package/es/auto.js CHANGED
@@ -1,4 +1,4 @@
1
- import { installUiRuntimeGuards } from './chunk-Z2OTWMW6.js';
1
+ import { installUiRuntimeGuards } from './chunk-QLPJLXY6.js';
2
2
  import './chunk-Q3N5QNRZ.js';
3
3
 
4
4
  // runtime/auto.ts
@@ -232,10 +232,187 @@ function uninstallOverflowTooltipGuard() {
232
232
  installedOptions = DEFAULT_OPTIONS;
233
233
  }
234
234
 
235
+ // runtime/split-grid-resize.ts
236
+ var SPLIT_ROOT_SELECTOR = ".drager_row";
237
+ var SPLIT_PANE_SELECTOR = ".drager_top, .drager_bottom";
238
+ var GRID_SELECTOR = ".ag-grid-table, .ag-root-wrapper";
239
+ var EXEMPT_SELECTOR = ".lp-root, .session-login, .wl-ui-skin-exempt, [data-wl-ui-skin='off']";
240
+ var SPLIT_GRID_RESIZE_EVENT = "wl-ui:split-grid-resize";
241
+ var installed = false;
242
+ var resizeObserver = null;
243
+ var mutationObserver = null;
244
+ var observedPanes = /* @__PURE__ */ new WeakSet();
245
+ var pendingPanes = /* @__PURE__ */ new Set();
246
+ var addedMarkers = /* @__PURE__ */ new Map();
247
+ var frameId = null;
248
+ function addMarker(element, name) {
249
+ if (element.hasAttribute(name)) return;
250
+ element.setAttribute(name, "");
251
+ const names = addedMarkers.get(element) ?? /* @__PURE__ */ new Set();
252
+ names.add(name);
253
+ addedMarkers.set(element, names);
254
+ }
255
+ function removeOwnedMarker(element, name) {
256
+ const names = addedMarkers.get(element);
257
+ if (!names?.has(name)) return;
258
+ element.removeAttribute(name);
259
+ names.delete(name);
260
+ if (names.size === 0) addedMarkers.delete(element);
261
+ }
262
+ function isManagedSplitRoot(element) {
263
+ return element instanceof window.HTMLElement && element.matches(SPLIT_ROOT_SELECTOR) && !element.closest(EXEMPT_SELECTOR);
264
+ }
265
+ function getGridHosts(pane) {
266
+ const hosts = /* @__PURE__ */ new Set();
267
+ for (const element of Array.from(
268
+ pane.querySelectorAll(GRID_SELECTOR)
269
+ )) {
270
+ const agGridTable = element.closest(".ag-grid-table");
271
+ if (agGridTable && pane.contains(agGridTable)) {
272
+ hosts.add(agGridTable);
273
+ continue;
274
+ }
275
+ if (element.matches(".ag-root-wrapper")) {
276
+ hosts.add(element);
277
+ }
278
+ }
279
+ return [...hosts];
280
+ }
281
+ function markHeightChain(pane, gridHost) {
282
+ addMarker(pane, "data-wl-ui-split-pane");
283
+ addMarker(gridHost, "data-wl-ui-split-grid-host");
284
+ let parent = gridHost.parentElement;
285
+ while (parent && parent !== pane) {
286
+ addMarker(parent, "data-wl-ui-split-grid-chain");
287
+ parent = parent.parentElement;
288
+ }
289
+ const directParent = gridHost.parentElement;
290
+ if (!directParent) return;
291
+ const style = window.getComputedStyle(directParent);
292
+ if ((style.display === "flex" || style.display === "inline-flex") && style.flexDirection === "column") {
293
+ addMarker(directParent, "data-wl-ui-split-grid-flex-parent");
294
+ } else {
295
+ removeOwnedMarker(directParent, "data-wl-ui-split-grid-flex-parent");
296
+ }
297
+ }
298
+ function notifyPane(pane) {
299
+ const hosts = getGridHosts(pane);
300
+ if (hosts.length === 0) return;
301
+ for (const host of hosts) {
302
+ markHeightChain(pane, host);
303
+ const { height, width } = host.getBoundingClientRect();
304
+ host.dispatchEvent(
305
+ new window.CustomEvent(SPLIT_GRID_RESIZE_EVENT, {
306
+ bubbles: true,
307
+ detail: { height, pane, width }
308
+ })
309
+ );
310
+ }
311
+ }
312
+ function flushPendingPanes() {
313
+ frameId = null;
314
+ const panes = [...pendingPanes];
315
+ pendingPanes.clear();
316
+ for (const pane of panes) notifyPane(pane);
317
+ }
318
+ function schedulePane(pane) {
319
+ if (!pane.isConnected || !pane.querySelector(GRID_SELECTOR)) return;
320
+ pendingPanes.add(pane);
321
+ if (frameId !== null) return;
322
+ frameId = window.requestAnimationFrame(flushPendingPanes);
323
+ }
324
+ function registerSplitRoot(root) {
325
+ for (const pane of Array.from(
326
+ root.querySelectorAll(SPLIT_PANE_SELECTOR)
327
+ )) {
328
+ if (pane.parentElement !== root) continue;
329
+ if (!observedPanes.has(pane)) {
330
+ observedPanes.add(pane);
331
+ resizeObserver?.observe(pane);
332
+ }
333
+ schedulePane(pane);
334
+ }
335
+ }
336
+ function scanNode(node) {
337
+ if (!(node instanceof window.Element)) return;
338
+ if (isManagedSplitRoot(node)) registerSplitRoot(node);
339
+ for (const root of Array.from(
340
+ node.querySelectorAll(SPLIT_ROOT_SELECTOR)
341
+ )) {
342
+ if (isManagedSplitRoot(root)) registerSplitRoot(root);
343
+ }
344
+ const containingRoot = node.closest(SPLIT_ROOT_SELECTOR);
345
+ if (containingRoot && isManagedSplitRoot(containingRoot)) {
346
+ registerSplitRoot(containingRoot);
347
+ }
348
+ }
349
+ function scanDocument() {
350
+ for (const root of Array.from(
351
+ document.querySelectorAll(SPLIT_ROOT_SELECTOR)
352
+ )) {
353
+ if (isManagedSplitRoot(root)) registerSplitRoot(root);
354
+ }
355
+ }
356
+ function handleDragEnd(event) {
357
+ const { target } = event;
358
+ if (!(target instanceof window.Element)) return;
359
+ const root = target.closest(SPLIT_ROOT_SELECTOR);
360
+ if (!root || !isManagedSplitRoot(root)) return;
361
+ registerSplitRoot(root);
362
+ }
363
+ function installSplitGridResizeGuard() {
364
+ if (installed || typeof window === "undefined" || typeof document === "undefined") {
365
+ return;
366
+ }
367
+ installed = true;
368
+ if (typeof window.ResizeObserver !== "undefined") {
369
+ resizeObserver = new window.ResizeObserver((entries) => {
370
+ for (const entry of entries) {
371
+ if (entry.target instanceof window.HTMLElement) schedulePane(entry.target);
372
+ }
373
+ });
374
+ }
375
+ if (document.body && typeof window.MutationObserver !== "undefined") {
376
+ mutationObserver = new window.MutationObserver((records) => {
377
+ for (const record of records) {
378
+ for (const node of Array.from(record.addedNodes)) scanNode(node);
379
+ }
380
+ });
381
+ mutationObserver.observe(document.body, { childList: true, subtree: true });
382
+ }
383
+ document.addEventListener("mouseup", handleDragEnd, true);
384
+ document.addEventListener("touchend", handleDragEnd, true);
385
+ if (document.readyState === "loading") {
386
+ document.addEventListener("DOMContentLoaded", scanDocument, { once: true });
387
+ } else {
388
+ scanDocument();
389
+ }
390
+ }
391
+ function uninstallSplitGridResizeGuard() {
392
+ if (!installed) return;
393
+ installed = false;
394
+ resizeObserver?.disconnect();
395
+ mutationObserver?.disconnect();
396
+ resizeObserver = null;
397
+ mutationObserver = null;
398
+ observedPanes = /* @__PURE__ */ new WeakSet();
399
+ pendingPanes.clear();
400
+ for (const [element, names] of addedMarkers) {
401
+ for (const name of names) element.removeAttribute(name);
402
+ }
403
+ addedMarkers = /* @__PURE__ */ new Map();
404
+ if (frameId !== null) window.cancelAnimationFrame(frameId);
405
+ frameId = null;
406
+ document.removeEventListener("mouseup", handleDragEnd, true);
407
+ document.removeEventListener("touchend", handleDragEnd, true);
408
+ document.removeEventListener("DOMContentLoaded", scanDocument);
409
+ }
410
+
235
411
  // runtime/guards.ts
236
412
  function installUiRuntimeGuards() {
237
413
  installBrandThemeLock();
238
414
  installOverflowTooltipGuard();
415
+ installSplitGridResizeGuard();
239
416
  }
240
417
 
241
- export { installOverflowTooltipGuard, installUiRuntimeGuards, uninstallOverflowTooltipGuard };
418
+ export { SPLIT_GRID_RESIZE_EVENT, installOverflowTooltipGuard, installSplitGridResizeGuard, installUiRuntimeGuards, uninstallOverflowTooltipGuard, uninstallSplitGridResizeGuard };
@@ -1,4 +1,4 @@
1
- import { installUiRuntimeGuards } from './chunk-Z2OTWMW6.js';
1
+ import { installUiRuntimeGuards } from './chunk-QLPJLXY6.js';
2
2
  import { renderTagNode, renderClassifyTag, registerColumnAutoMaps, renderRatingLevel, renderBadge } from './chunk-4IOYRBW4.js';
3
3
  export { registerDictColorMap, registerDictColorMaps, renderDictClassifyTag, setDictResolver } from './chunk-4IOYRBW4.js';
4
4
  import './chunk-Q3N5QNRZ.js';
package/es/index.d.ts CHANGED
@@ -180,10 +180,20 @@ declare function installOverflowTooltipGuard(options?: OverflowTooltipGuardOptio
180
180
  /** 卸载兜底监听,主要供微前端销毁和回归测试使用。 */
181
181
  declare function uninstallOverflowTooltipGuard(): void;
182
182
 
183
+ declare const SPLIT_GRID_RESIZE_EVENT = "wl-ui:split-grid-resize";
184
+ interface SplitGridResizeDetail {
185
+ height: number;
186
+ pane: HTMLElement;
187
+ width: number;
188
+ }
189
+ declare function installSplitGridResizeGuard(): void;
190
+ declare function uninstallSplitGridResizeGuard(): void;
191
+
183
192
  /**
184
193
  * 安装不依赖业务页面写法的包级运行时保护。
185
- * 包含客户主题锁与普通表格长文本溢出提示兜底;重复调用安全。
194
+ * 包含客户主题锁、普通表格长文本溢出提示兜底与分屏 AG Grid 尺寸守护;
195
+ * 重复调用安全。
186
196
  */
187
197
  declare function installUiRuntimeGuards(): void;
188
198
 
189
- export { BRAND_THEME_TOKENS, ColumnLike, type OverflowTooltipGuardOptions, type PresetConfig, clearColumnAutoMap, createPreset, defineColumns, getColumnAutoMap, getInstalledPresets, installBrandThemeLock, installOverflowTooltipGuard, installPreset, installUiRuntimeGuards, registerColumnAutoMap, registerColumnAutoMaps, uninstallOverflowTooltipGuard };
199
+ export { BRAND_THEME_TOKENS, ColumnLike, type OverflowTooltipGuardOptions, type PresetConfig, SPLIT_GRID_RESIZE_EVENT, type SplitGridResizeDetail, clearColumnAutoMap, createPreset, defineColumns, getColumnAutoMap, getInstalledPresets, installBrandThemeLock, installOverflowTooltipGuard, installPreset, installSplitGridResizeGuard, installUiRuntimeGuards, registerColumnAutoMap, registerColumnAutoMaps, uninstallOverflowTooltipGuard, uninstallSplitGridResizeGuard };
package/es/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { installOverflowTooltipGuard, installUiRuntimeGuards, uninstallOverflowTooltipGuard } from './chunk-Z2OTWMW6.js';
1
+ export { SPLIT_GRID_RESIZE_EVENT, installOverflowTooltipGuard, installSplitGridResizeGuard, installUiRuntimeGuards, uninstallOverflowTooltipGuard, uninstallSplitGridResizeGuard } from './chunk-QLPJLXY6.js';
2
2
  import { registerColumnAutoMaps } from './chunk-4IOYRBW4.js';
3
3
  export { AUDIT_STATUS_MAP, ENABLE_STATUS_MAP, RATING_LEVEL_COLORS, VERIFY_STATUS_MAP, clearColumnAutoMap, defineColumns, getColumnAutoMap, registerColumnAutoMap, registerColumnAutoMaps, registerDictColorMap, registerDictColorMaps, renderAuditStatus, renderBadge, renderClassifyTag, renderCountBadge, renderDangerText, renderDictClassifyTag, renderEnableStatus, renderOps, renderRatingLevel, renderTagNode, renderTagSlot, renderVerifyStatus, setDictResolver } from './chunk-4IOYRBW4.js';
4
4
  export { BRAND_THEME_TOKENS, installBrandThemeLock } from './chunk-Q3N5QNRZ.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/wl-skills-ui",
3
- "version": "1.9.12",
3
+ "version": "1.9.14",
4
4
  "description": "企业级 UI 风格对齐框架 — Vue + Element Plus 项目通用化妆/原生双模式(tokens / element / vendors / layouts / runtime / scanner / fixer / skills)",
5
5
  "type": "module",
6
6
  "main": "./es/index.js",
@@ -67,6 +67,9 @@ el-date-picker 默认宽度不会自动撑满 el-form-item,必须显式设置
67
67
  平台默认阴影。
68
68
  - 数字输入框必须同时检查社区版“wrapper 子节点”和 jh-ui“wrapper 与
69
69
  input-number 同节点”两种 DOM,并确保只存在一层可见边框。
70
+ - 带 prepend/append 的 input-group 必须由组合根绘制唯一外轮廓;输入主体、附加段
71
+ 统一 26px,左右图标统一 14px。纯图标附加段使用 32px,文字/单位/按钮保持内容宽度。
72
+ 不允许业务页分别给 `.el-input__inner` 与 `.el-input-group__append` 写不同高度。
70
73
  - 登录页和显式定制页继续使用自身样式,不套用上述高权重规则。
71
74
 
72
75
  ---
@@ -49,7 +49,8 @@ applyTo: "**/*.vue"
49
49
 
50
50
  - ❌ 自行给 `.jh-tree` 写颜色覆盖(应用全局 `vendors/_jh-tree.scss`)
51
51
  - ❌ jh-drag-col 内自定义 padding 破坏拖拽条对齐
52
- - ❌ jh-drag-row 上下分栏缺 `.drager_row { height:100% }` 高度链(拖拽失效),或页面自行重画 `.slider_row`;手柄必须统一使用 `_jh-drag-row.scss` 的细分隔线 + 三点胶囊
52
+ - ❌ jh-drag-row 上下分栏缺可收缩高度链,拖动后仅靠 pane 的 `overflow:hidden` 裁切 AG Grid;必须接入 `runtime/auto`,由 ResizeObserver 通知表格内部重布局,禁止给外层随意加滚动条
53
+ - ❌ 页面自行重画 `.slider_row`;手柄必须统一使用 `_jh-drag-row.scss` 的细分隔线 + 三点胶囊
53
54
  - ❌ jh-pagination 未对齐到右侧(同 R011)
54
55
  - ❌ jh-form 内不用 `size="small"` 控件(同 R006)
55
56
  - ❌ 发现新的复杂 `<jh-*>` 组件后只在页面局部写补丁,而不沉淀到 L2 Project Vendors
@@ -65,6 +66,7 @@ applyTo: "**/*.vue"
65
66
  ### B 类
66
67
 
67
68
  - 直接全局覆盖 `.jh-*` → 改为引入 `wl-skills-ui/styles` 由 vendors 层处理
69
+ - `jh-drag-row + AG Grid` → Skin 项目除样式外在启动入口引入一次 `@agile-team/wl-skills-ui/runtime/auto`;Native 项目使用 `installCommonPreset()`,详见 `docs/split-grid-resize.md`
68
70
  - 新的复杂 `<jh-*>` 组件 → 先判断是否只是 Element Plus 薄封装;若不是,应新增 `styles/vendors/_jh-xxx.scss` 和对应 Skill/检测规则
69
71
 
70
72
  ## 全局样式来源