@agile-team/wl-skills-ui 1.9.13 → 1.9.15

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,34 @@ 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.15] - 2026-08-10
8
+
9
+ ### Added
10
+
11
+ - 新增 `normalizeColumnAlignment(s)` 运行时能力,把业务显式声明的 `align/headerAlign` 桥接为 BaseTable/AG Grid 可消费的 `cellStyle/headerClass`,并递归覆盖分组列。
12
+ - 新增行为与样式契约测试,覆盖无声明不接管、左右/居中对齐、分组列以及业务自定义样式优先级。
13
+
14
+ ### Fixed
15
+
16
+ - 修复部分平台 AG Grid 适配器忽略列定义 `align/headerAlign`,导致业务明确要求居中或右对齐却仍按默认布局展示的问题。
17
+
18
+ ### Changed
19
+
20
+ - `defineColumns()` 自动应用显式对齐桥接;未声明对齐的普通列保持原状,已有 `cellStyle/headerClass` 不覆盖,不引入全局居中规则。
21
+
22
+ ## [1.9.14] - 2026-08-10
23
+
24
+ ### Added
25
+
26
+ - 新增受管业务组件字体 Token 与 Edge/Chrome 双浏览器计算样式门禁,统一 Element Table、BaseTable、AG Grid 的中英文数字字体链,同时保持登录页、大屏、编辑器、图表、图标字体和显式豁免区边界。
27
+ - 复合结构清单按 common-core 真实 DOM 补全 `.com-inputNumber-content` 根类,并新增 jh-input-number 高度、对齐、controls、单描边视觉回归。
28
+
29
+ ### Fixed
30
+
31
+ - 修复普通 InputNumber 高权重规则误命中 `jh-input-number`,造成复合数字框高度链、`textAlign` 与 controls 语义被压平的问题;复合根统一 26px 与五态外轮廓,内部 wrapper 不重复描边。
32
+ - 修复 AG Grid 普通单元格强制 flex 居中覆盖 BaseTable `align/headerAlign`,以及透明右边框遮掉焦点单元格一侧描边的问题;普通列重新遵循 AG Grid 原生对齐,仅复选框列保持精准居中。
33
+ - AG Grid 紧凑表头字号由半像素改为整数 13px,降低 Windows Edge 小字号抗锯齿差异。
34
+
7
35
  ## [1.9.13] - 2026-08-07
8
36
 
9
37
  ### Added
package/README.md CHANGED
@@ -213,7 +213,7 @@ yarn add @agile-team/wl-skills-ui
213
213
  |---|---|---|
214
214
  | `element-plus` | **`2.2.6-prod.3`** | 集团 jh- 定制版;EP 2.3.0 起引入 `.el-input__wrapper`,与 jh-ui 3.x 不兼容 |
215
215
  | `@jhlc/jh-ui` | **`3.1.0`** | SCSS 皮肤包,`.com-text` label 包裹 + `.has-colon` 冒号注入(wl-skills-ui 已统一屏蔽表单冒号) |
216
- | `@agile-team/wl-skills-ui` | `^1.9.13` | 已对齐上述组合的 DOM 假设、客户主题锁、圆角契约、input-group 附加段、分屏 AG Grid 重布局、表格长文本兜底与定制页边界 |
216
+ | `@agile-team/wl-skills-ui` | `^1.9.15` | 已对齐上述组合的 DOM 假设、客户主题锁、圆角契约、复合数字框、跨浏览器字体、显式列对齐与定制页边界 |
217
217
 
218
218
  三种识别方式,任选其一:
219
219
 
@@ -227,7 +227,28 @@ yarn add @agile-team/wl-skills-ui
227
227
 
228
228
  ## 版本亮点
229
229
 
230
- 当前 v1.9.13
230
+ 当前 v1.9.15
231
+
232
+ - **显式列对齐跨表格生效**:`defineColumns()` 会把业务明确声明的 `align/headerAlign`
233
+ 桥接为 BaseTable/AG Grid 能稳定消费的 `cellStyle/headerClass`,Element Table 继续读取原属性;
234
+ 无声明时不设置默认对齐,已有业务样式不覆盖,分组列递归处理。
235
+ - **零布局污染边界**:包只修复“显式意图未被平台适配器消费”,不把普通列全局居中,
236
+ 不接管选择列、语义渲染或业务自定义 `cellStyle/headerClass`。
237
+
238
+ 上一版 v1.9.14:
239
+
240
+ - **Edge/Chrome 字体收敛**:受管 Element、BaseTable 与 AG Grid 统一使用覆盖中英文数字的
241
+ `--wk-font-family-sans`,AG 表头/正文使用整数 13px;不改写 `body/*`,登录页、大屏、
242
+ 编辑器、图表、图标字体和显式豁免区不受影响。
243
+ - **jh-input-number 精准解耦**:普通 Element 数字框规则不再误命中
244
+ `.com-inputNumber-content`;复合根统一 26px 和唯一状态描边,同时保留组件自身
245
+ `textAlign`、controls、单位及后缀语义。
246
+ - **BaseTable/AG Grid 原生语义恢复**:焦点单元格四边框完整;取消普通单元格和表头的
247
+ 强制居中,`align/headerAlign` 重新以列配置和 AG Grid 原生样式为准,复选框列仍精准居中。
248
+ - **双浏览器门禁**:Windows Edge 维护像素基准,Edge + Google Chrome 同时验证字体、
249
+ 数字框高度、焦点边框及左右对齐计算样式。
250
+
251
+ 上一版 v1.9.13:
231
252
 
232
253
  - **输入附加段不再割裂**:`el-input-group` 由组合根统一 26px 高度、6px 外圆角和 default/hover/focus/error/disabled 描边;左侧 prefix、右侧 append 图标统一 14px,纯图标附加段 32px,文字/单位/按钮仍按内容宽度。
233
254
  - **新旧 DOM 同时覆盖**:兼容 jh-ui 配套旧版 input 直挂结构和新版 `.el-input__wrapper` 结构,内部输入不再重复描边;普通 input、普通按钮、登录页和显式豁免区保持原行为。
@@ -701,7 +722,8 @@ export const myRules = [
701
722
 
702
723
  | API | 说明 |
703
724
  | ------------------------------------------------ | -------------------------------------------------- |
704
- | `defineColumns(cols)` | 列定义,自动应用 `COLUMN_AUTO_MAP` |
725
+ | `defineColumns(cols)` | 列定义,应用自动映射并桥接显式列对齐 |
726
+ | `normalizeColumnAlignments(cols)` | 仅桥接显式 `align/headerAlign`,不设置默认对齐 |
705
727
  | `renderOps(items)` | 操作列图标按钮组(view/edit/del/log/ok/send 预设) |
706
728
  | `renderTagNode(v, map)` | 状态 Tag 渲染 |
707
729
  | `renderClassifyTag(v, map)` | 分类 Tag 渲染 |
@@ -772,7 +794,8 @@ export const myRules = [
772
794
 
773
795
  ### 维护者防回归
774
796
 
775
- 复合控件必须先登记结构契约,再增加精准样式;包发版必须经过 Chromium 基准图对比:
797
+ 复合控件必须先登记结构契约,再增加精准样式;包发版必须经过 Edge 基准图与
798
+ Edge/Chrome 双浏览器计算样式验证:
776
799
 
777
800
  ```bash
778
801
  # 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.13` | 已对齐 jh-ui 3.1.0 + EP 2.2.6-prod.3 的 DOM 假设、客户主题锁、6px 基础圆角、紧凑表单、input-group 附加段、分屏 AG Grid 重布局、复合结构契约、表格长文本提示与定制页边界 |
14
+ | `@agile-team/wl-skills-ui` | `^1.9.15` | 已对齐 jh-ui 3.1.0 + EP 2.2.6-prod.3 的 DOM 假设、客户主题锁、6px 基础圆角、紧凑表单、复合数字框、跨浏览器字体、显式列对齐与定制页边界 |
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.13 三方对齐。
38
+ - 集团内项目:**统一锚定 `element-plus@2.2.6-prod.3` + `@jhlc/jh-ui@3.1.0`**,与 wl-skills-ui v1.9.15 三方对齐。
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,7 +36,10 @@ 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 出口。
41
44
  - Element Plus 新旧两种 input-group prepend/append DOM:组合根负责唯一外轮廓,
42
45
  输入主体与附加段统一 26px,纯图标附加段 32px、图标 14px。
@@ -17,6 +17,11 @@
17
17
  - jh-drag-row 收缩后 AG Grid host 跟随变高,纵向滚动只发生在内部 viewport。
18
18
  - Element Table 长文本真实溢出、省略号与按需完整提示。
19
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 基准。
20
25
 
21
26
  ## 使用
22
27
 
@@ -38,7 +43,8 @@ pnpm release:check
38
43
  ```
39
44
 
40
45
  截图基准按 Playwright 的浏览器/平台规则保存,不随 npm 包发布。Windows 默认使用企业
41
- 环境已有的 Edge Chromium,也可通过 `WL_UI_BROWSER_CHANNEL` 显式指定 Playwright 通道。
46
+ 环境已有的 Edge Chromium,也可通过 `WL_UI_BROWSER_CHANNEL` 显式指定截图通道;无截图的
47
+ 字体、尺寸、焦点与对齐契约会额外启动系统 Edge 和 Google Chrome 各验证一次。
42
48
  视觉像素受操作系统、浏览器版本和字体渲染影响,生成与比较必须使用相同环境;当前
43
49
  基准为 Windows Edge Chromium。
44
50
  升级 Playwright、Chromium 或字体后,应单独提交基准变化并人工审图,不能把更新截图当成
@@ -2,7 +2,33 @@ import { h } from 'vue';
2
2
  import { ElTag } from 'element-plus';
3
3
  import { Upload, CircleCheck, Document, Delete, Edit, View } from '@element-plus/icons-vue';
4
4
 
5
- // runtime/core/renderers.ts
5
+ // runtime/core/alignment.ts
6
+ var HEADER_ALIGNMENT_CLASS = {
7
+ left: "wl-ui-table-header-align--left",
8
+ center: "wl-ui-table-header-align--center",
9
+ right: "wl-ui-table-header-align--right"
10
+ };
11
+ function isColumnAlignment(value) {
12
+ return value === "left" || value === "center" || value === "right";
13
+ }
14
+ function normalizeColumnAlignment(column) {
15
+ const normalizedChildren = Array.isArray(column.children) ? normalizeColumnAlignments(column.children) : column.children;
16
+ const align = isColumnAlignment(column.align) ? column.align : void 0;
17
+ const headerAlign = isColumnAlignment(column.headerAlign) ? column.headerAlign : align;
18
+ const needsChildren = normalizedChildren !== column.children;
19
+ const needsCellStyle = Boolean(align) && column.cellStyle === void 0;
20
+ const needsHeaderClass = Boolean(headerAlign) && column.headerClass === void 0;
21
+ if (!needsChildren && !needsCellStyle && !needsHeaderClass) return column;
22
+ return {
23
+ ...column,
24
+ ...needsChildren ? { children: normalizedChildren } : {},
25
+ ...needsCellStyle ? { cellStyle: { textAlign: align } } : {},
26
+ ...needsHeaderClass ? { headerClass: HEADER_ALIGNMENT_CLASS[headerAlign] } : {}
27
+ };
28
+ }
29
+ function normalizeColumnAlignments(columns) {
30
+ return columns.map((column) => normalizeColumnAlignment(column));
31
+ }
6
32
  var ENABLE_STATUS_MAP = {
7
33
  0: { label: "\u505C\u7528", type: "danger" },
8
34
  1: { label: "\u542F\u7528", type: "success" }
@@ -286,18 +312,20 @@ function defineColumns(columns) {
286
312
  const fieldName = normalized.name ?? normalized.label ?? "";
287
313
  const preset = COLUMN_AUTO_MAP[fieldName];
288
314
  const hasRenderer = normalized.defaultNode !== void 0 || normalized.defaultSlot !== void 0;
289
- if (hasRenderer) return normalized;
315
+ if (hasRenderer) return normalizeColumnAlignment(normalized);
290
316
  if (!preset && isDictColumn(normalized)) {
291
- return {
317
+ return normalizeColumnAlignment({
292
318
  ...normalized,
293
319
  defaultSlot: ({ row }) => renderDictClassifyTag(
294
320
  row?.[fieldName],
295
321
  String(normalized.logicValue)
296
322
  )
297
- };
323
+ });
298
324
  }
299
- if (!preset) return withOverflowTooltip(normalized);
300
- return withOverflowTooltip({ ...preset, ...normalized });
325
+ if (!preset) return normalizeColumnAlignment(withOverflowTooltip(normalized));
326
+ return normalizeColumnAlignment(
327
+ withOverflowTooltip({ ...preset, ...normalized })
328
+ );
301
329
  });
302
330
  }
303
331
  function isDictColumn(col) {
@@ -328,4 +356,4 @@ registerColumnAutoMaps({
328
356
  }
329
357
  });
330
358
 
331
- 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 };
359
+ export { AUDIT_STATUS_MAP, ENABLE_STATUS_MAP, RATING_LEVEL_COLORS, VERIFY_STATUS_MAP, clearColumnAutoMap, defineColumns, getColumnAutoMap, normalizeColumnAlignment, normalizeColumnAlignments, registerColumnAutoMap, registerColumnAutoMaps, registerDictColorMap, registerDictColorMaps, renderAuditStatus, renderBadge, renderClassifyTag, renderCountBadge, renderDangerText, renderDictClassifyTag, renderEnableStatus, renderOps, renderRatingLevel, renderTagNode, renderTagSlot, renderVerifyStatus, setDictResolver };
@@ -1,7 +1,7 @@
1
1
  import * as vue from 'vue';
2
2
  import { VNode } from 'vue';
3
- import { T as TagMapItem, J as JhTagNode } from './types-Dnh4U0hw.js';
4
- export { r as registerDictColorMap, a as registerDictColorMaps, b as renderDictClassifyTag, s as setDictResolver } from './renderers-B3uUAze8.js';
3
+ import { T as TagMapItem, J as JhTagNode } from './types-DtmxwMWV.js';
4
+ export { r as registerDictColorMap, a as registerDictColorMaps, b as renderDictClassifyTag, s as setDictResolver } from './renderers-DlFRBX9K.js';
5
5
 
6
6
  declare const RISK_LEVEL_MAP: Record<string | number, TagMapItem>;
7
7
  declare const renderRiskLevel: (v: string | number | null | undefined) => JhTagNode | null;
@@ -1,6 +1,6 @@
1
1
  import { installUiRuntimeGuards } from './chunk-QLPJLXY6.js';
2
- import { renderTagNode, renderClassifyTag, registerColumnAutoMaps, renderRatingLevel, renderBadge } from './chunk-4IOYRBW4.js';
3
- export { registerDictColorMap, registerDictColorMaps, renderDictClassifyTag, setDictResolver } from './chunk-4IOYRBW4.js';
2
+ import { renderTagNode, renderClassifyTag, registerColumnAutoMaps, renderRatingLevel, renderBadge } from './chunk-53TF2NQQ.js';
3
+ export { registerDictColorMap, registerDictColorMaps, renderDictClassifyTag, setDictResolver } from './chunk-53TF2NQQ.js';
4
4
  import './chunk-Q3N5QNRZ.js';
5
5
 
6
6
  // runtime/presets/common.ts
package/es/index.d.ts CHANGED
@@ -1,8 +1,21 @@
1
- import { C as ColumnLike } from './types-Dnh4U0hw.js';
2
- export { E as ElTagType, J as JhTagNode, a as OpChip, O as OpItem, b as OpLink, c as OpPreset, T as TagMapItem } from './types-Dnh4U0hw.js';
3
- export { A as AUDIT_STATUS_MAP, E as ENABLE_STATUS_MAP, R as RATING_LEVEL_COLORS, V as VERIFY_STATUS_MAP, r as registerDictColorMap, a as registerDictColorMaps, c as renderAuditStatus, d as renderBadge, e as renderClassifyTag, f as renderCountBadge, g as renderDangerText, b as renderDictClassifyTag, h as renderEnableStatus, i as renderOps, j as renderRatingLevel, k as renderTagNode, l as renderTagSlot, m as renderVerifyStatus, s as setDictResolver } from './renderers-B3uUAze8.js';
1
+ import { C as ColumnLike } from './types-DtmxwMWV.js';
2
+ export { E as ElTagType, J as JhTagNode, a as OpChip, O as OpItem, b as OpLink, c as OpPreset, T as TagMapItem } from './types-DtmxwMWV.js';
3
+ export { A as AUDIT_STATUS_MAP, E as ENABLE_STATUS_MAP, R as RATING_LEVEL_COLORS, V as VERIFY_STATUS_MAP, r as registerDictColorMap, a as registerDictColorMaps, c as renderAuditStatus, d as renderBadge, e as renderClassifyTag, f as renderCountBadge, g as renderDangerText, b as renderDictClassifyTag, h as renderEnableStatus, i as renderOps, j as renderRatingLevel, k as renderTagNode, l as renderTagSlot, m as renderVerifyStatus, s as setDictResolver } from './renderers-DlFRBX9K.js';
4
4
  import 'vue';
5
5
 
6
+ type ColumnAlignment = "left" | "center" | "right";
7
+ /**
8
+ * 将业务显式声明的 align/headerAlign 转换为 BaseTable/AG Grid 能稳定消费的配置。
9
+ *
10
+ * - 没有显式对齐声明时原样返回,不改变项目默认布局;
11
+ * - 已有 cellStyle/headerClass 时尊重业务配置,不覆盖;
12
+ * - 递归处理分组列 children;
13
+ * - Element Table 仍直接消费原有 align/headerAlign。
14
+ */
15
+ declare function normalizeColumnAlignment<T extends ColumnLike>(column: T): T;
16
+ /** 批量规范化列定义;只桥接显式对齐意图,不设置全局默认对齐。 */
17
+ declare function normalizeColumnAlignments<T extends ColumnLike>(columns: T[]): T[];
18
+
6
19
  /**
7
20
  * runtime/core/registry.ts — COLUMN_AUTO_MAP 注册中心 + defineColumns
8
21
  *
@@ -196,4 +209,4 @@ declare function uninstallSplitGridResizeGuard(): void;
196
209
  */
197
210
  declare function installUiRuntimeGuards(): void;
198
211
 
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 };
212
+ export { BRAND_THEME_TOKENS, type ColumnAlignment, ColumnLike, type OverflowTooltipGuardOptions, type PresetConfig, SPLIT_GRID_RESIZE_EVENT, type SplitGridResizeDetail, clearColumnAutoMap, createPreset, defineColumns, getColumnAutoMap, getInstalledPresets, installBrandThemeLock, installOverflowTooltipGuard, installPreset, installSplitGridResizeGuard, installUiRuntimeGuards, normalizeColumnAlignment, normalizeColumnAlignments, registerColumnAutoMap, registerColumnAutoMaps, uninstallOverflowTooltipGuard, uninstallSplitGridResizeGuard };
package/es/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export { SPLIT_GRID_RESIZE_EVENT, installOverflowTooltipGuard, installSplitGridResizeGuard, installUiRuntimeGuards, uninstallOverflowTooltipGuard, uninstallSplitGridResizeGuard } from './chunk-QLPJLXY6.js';
2
- import { registerColumnAutoMaps } from './chunk-4IOYRBW4.js';
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';
2
+ import { registerColumnAutoMaps } from './chunk-53TF2NQQ.js';
3
+ export { AUDIT_STATUS_MAP, ENABLE_STATUS_MAP, RATING_LEVEL_COLORS, VERIFY_STATUS_MAP, clearColumnAutoMap, defineColumns, getColumnAutoMap, normalizeColumnAlignment, normalizeColumnAlignments, registerColumnAutoMap, registerColumnAutoMaps, registerDictColorMap, registerDictColorMaps, renderAuditStatus, renderBadge, renderClassifyTag, renderCountBadge, renderDangerText, renderDictClassifyTag, renderEnableStatus, renderOps, renderRatingLevel, renderTagNode, renderTagSlot, renderVerifyStatus, setDictResolver } from './chunk-53TF2NQQ.js';
4
4
  export { BRAND_THEME_TOKENS, installBrandThemeLock } from './chunk-Q3N5QNRZ.js';
5
5
 
6
6
  // runtime/presets/registry.ts
@@ -1,4 +1,4 @@
1
- import { T as TagMapItem, J as JhTagNode } from '../types-Dnh4U0hw.js';
1
+ import { T as TagMapItem, J as JhTagNode } from '../types-DtmxwMWV.js';
2
2
  import 'vue';
3
3
 
4
4
  declare const VIOLATION_STATUS_MAP: Record<string | number, TagMapItem>;
@@ -1,4 +1,4 @@
1
- import { renderTagNode, registerDictColorMaps, registerColumnAutoMaps } from '../chunk-4IOYRBW4.js';
1
+ import { renderTagNode, registerDictColorMaps, registerColumnAutoMaps } from '../chunk-53TF2NQQ.js';
2
2
  import { installBrandThemeLock } from '../chunk-Q3N5QNRZ.js';
3
3
 
4
4
  // runtime/presets/security.ts
@@ -1,5 +1,5 @@
1
1
  import { VNode } from 'vue';
2
- import { T as TagMapItem, J as JhTagNode, O as OpItem } from './types-Dnh4U0hw.js';
2
+ import { T as TagMapItem, J as JhTagNode, O as OpItem } from './types-DtmxwMWV.js';
3
3
 
4
4
  /**
5
5
  * runtime/core/renderers.ts — 通用渲染器 + 通用状态映射
@@ -27,6 +27,11 @@ interface ColumnLike {
27
27
  width?: number | string;
28
28
  fixed?: string | boolean;
29
29
  type?: string;
30
+ align?: "left" | "center" | "right";
31
+ headerAlign?: "left" | "center" | "right";
32
+ cellStyle?: Record<string, unknown> | ((params: any) => Record<string, unknown>);
33
+ headerClass?: string | string[] | ((params: any) => string | string[]);
34
+ children?: ColumnLike[];
30
35
  defaultNode?: (ctx: {
31
36
  row: any;
32
37
  }) => any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/wl-skills-ui",
3
- "version": "1.9.13",
3
+ "version": "1.9.15",
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",
@@ -158,12 +158,13 @@
158
158
  "family": "number-composite",
159
159
  "source": "lowcode-engine/packages/common/common-lowcode/components/src/schema-component/base-input-group/input-number/com/input-number.vue",
160
160
  "fixture": "scanner/__tests__/component-fixtures/common-core-input-number-mixed.html",
161
- "rootSelector": ".el-input-number.el-input__wrapper",
162
- "ownerSelector": ".el-input-number.el-input__wrapper",
161
+ "rootSelector": ".com-inputNumber-content.el-input-number.el-input__wrapper",
162
+ "ownerSelector": ".com-inputNumber-content.el-input-number.el-input__wrapper",
163
163
  "innerBorderlessSelectors": [
164
- ".el-input-number.el-input__wrapper > .el-input > .el-input__wrapper"
164
+ ".com-inputNumber-content.el-input-number.el-input__wrapper > .el-input > .el-input__wrapper"
165
165
  ],
166
166
  "knownRootClasses": [
167
+ "com-inputNumber-content",
167
168
  "el-input-number"
168
169
  ],
169
170
  "heightPolicy": "fixed-control-height",
@@ -177,16 +178,16 @@
177
178
  "assertions": [
178
179
  {
179
180
  "target": "root",
180
- "selector": ".el-input-number.el-input__wrapper",
181
+ "selector": ".com-inputNumber-content.el-input-number.el-input__wrapper",
181
182
  "matches": true
182
183
  },
183
184
  {
184
185
  "target": "inner",
185
- "selector": ".el-input-number.el-input__wrapper > .el-input > .el-input__wrapper",
186
+ "selector": ".com-inputNumber-content.el-input-number.el-input__wrapper > .el-input > .el-input__wrapper",
186
187
  "matches": true
187
188
  }
188
189
  ],
189
- "risk": "根节点本身是 wrapper,内部仍含 Element input wrapper;只能由根节点绘制唯一状态边框。"
190
+ "risk": "jh-input-number 根节点本身是 wrapper,内部仍含 Element input wrapper;只能由根节点绘制唯一状态边框,同时必须保留 textAlign、controls 与单位附加段语义。"
190
191
  },
191
192
  {
192
193
  "id": "common-core.base-toolbar-split-button",
@@ -52,12 +52,12 @@ html body {
52
52
 
53
53
  // 复合多标签输入把外壳复用了 .el-input__wrapper,但它需要随标签换行自然增高;
54
54
  // 这里只固定真正的单行 wrapper,复合外壳交给 L2 vendor 适配。
55
- &.el-input__wrapper:not(.com-input-multi-tag-wrap),
55
+ &.el-input__wrapper:not(.com-input-multi-tag-wrap):not(.com-inputNumber-content),
56
56
  &.el-select__wrapper,
57
57
  &.el-select .el-select__wrapper,
58
58
  &.el-date-editor.el-input__wrapper,
59
59
  &.el-date-editor .el-input__wrapper,
60
- &.el-input-number .el-input__wrapper,
60
+ &.el-input-number:not(.com-inputNumber-content) .el-input__wrapper,
61
61
  &.el-cascader .el-input__wrapper,
62
62
  &.el-autocomplete .el-input__wrapper {
63
63
  height: var(--wk-form-control-height) !important;
@@ -68,7 +68,7 @@ html body {
68
68
  &.el-input__inner,
69
69
  &.el-select__selected-item,
70
70
  &.el-date-editor .el-input__inner,
71
- &.el-input-number .el-input__inner,
71
+ &.el-input-number:not(.com-inputNumber-content) .el-input__inner,
72
72
  &.el-cascader .el-input__inner,
73
73
  &.el-autocomplete .el-input__inner {
74
74
  height: calc(var(--wk-form-control-height) - 2px) !important;
@@ -203,9 +203,9 @@ html body {
203
203
  // A. .el-input-number > .el-input > .el-input__wrapper(社区版)
204
204
  // B. .el-input-number.el-input__wrapper > .el-input(jh 同节点 wrapper)
205
205
  // 两种结构都只允许 wrapper 层绘制唯一可见边框。
206
- &.el-input-number,
207
- &.el-input-number:focus,
208
- &.el-input-number:focus-within {
206
+ &.el-input-number:not(.com-inputNumber-content),
207
+ &.el-input-number:not(.com-inputNumber-content):focus,
208
+ &.el-input-number:not(.com-inputNumber-content):focus-within {
209
209
  width: 100% !important;
210
210
  height: var(--wk-form-control-height) !important;
211
211
  line-height: var(--wk-form-control-height) !important;
@@ -216,13 +216,13 @@ html body {
216
216
  background: transparent !important;
217
217
  }
218
218
 
219
- &.el-input-number:not(.el-input__wrapper),
220
- &.el-input-number:not(.el-input__wrapper):focus,
221
- &.el-input-number:not(.el-input__wrapper):focus-within {
219
+ &.el-input-number:not(.com-inputNumber-content):not(.el-input__wrapper),
220
+ &.el-input-number:not(.com-inputNumber-content):not(.el-input__wrapper):focus,
221
+ &.el-input-number:not(.com-inputNumber-content):not(.el-input__wrapper):focus-within {
222
222
  box-shadow: none !important;
223
223
  }
224
224
 
225
- &.el-input-number .el-input {
225
+ &.el-input-number:not(.com-inputNumber-content) .el-input {
226
226
  width: 100% !important;
227
227
  height: 100% !important;
228
228
  border: 0 !important;
@@ -231,8 +231,8 @@ html body {
231
231
  box-shadow: none !important;
232
232
  }
233
233
 
234
- &.el-input-number .el-input__wrapper,
235
- &.el-input-number.el-input__wrapper {
234
+ &.el-input-number:not(.com-inputNumber-content) .el-input__wrapper,
235
+ &.el-input-number.el-input__wrapper:not(.com-inputNumber-content) {
236
236
  width: 100% !important;
237
237
  height: 100% !important;
238
238
  min-height: 0 !important;
@@ -245,23 +245,23 @@ html body {
245
245
  transition: box-shadow 0.15s ease !important;
246
246
  }
247
247
 
248
- &.el-input-number:not(.is-disabled):hover .el-input__wrapper,
249
- &.el-input-number.el-input__wrapper:not(.is-disabled):hover {
248
+ &.el-input-number:not(.com-inputNumber-content):not(.is-disabled):hover .el-input__wrapper,
249
+ &.el-input-number.el-input__wrapper:not(.com-inputNumber-content):not(.is-disabled):hover {
250
250
  box-shadow:
251
251
  0 0 0 1px var(--el-border-color-hover, #c0c4cc) inset !important;
252
252
  }
253
253
 
254
- &.el-input-number:not(.is-disabled) .el-input__wrapper.is-focus,
255
- &.el-input-number:not(.is-disabled):focus-within .el-input__wrapper,
256
- &.el-input-number.el-input__wrapper:not(.is-disabled).is-focus,
257
- &.el-input-number.el-input__wrapper:not(.is-disabled):focus,
258
- &.el-input-number.el-input__wrapper:not(.is-disabled):focus-within {
254
+ &.el-input-number:not(.com-inputNumber-content):not(.is-disabled) .el-input__wrapper.is-focus,
255
+ &.el-input-number:not(.com-inputNumber-content):not(.is-disabled):focus-within .el-input__wrapper,
256
+ &.el-input-number.el-input__wrapper:not(.com-inputNumber-content):not(.is-disabled).is-focus,
257
+ &.el-input-number.el-input__wrapper:not(.com-inputNumber-content):not(.is-disabled):focus,
258
+ &.el-input-number.el-input__wrapper:not(.com-inputNumber-content):not(.is-disabled):focus-within {
259
259
  box-shadow:
260
260
  0 0 0 1.5px var(--el-color-primary, #002a8f) inset !important;
261
261
  }
262
262
 
263
- &.el-input-number.is-disabled .el-input__wrapper,
264
- &.el-input-number.el-input__wrapper.is-disabled {
263
+ &.el-input-number:not(.com-inputNumber-content).is-disabled .el-input__wrapper,
264
+ &.el-input-number.el-input__wrapper:not(.com-inputNumber-content).is-disabled {
265
265
  background: var(--el-disabled-bg-color, #f5f7fa) !important;
266
266
  box-shadow:
267
267
  0 0 0 1px var(--el-disabled-border-color, #e4e7ed) inset !important;
@@ -269,14 +269,16 @@ html body {
269
269
 
270
270
  // 极少数过渡版本会同时输出“同节点 wrapper + 子 wrapper”;
271
271
  // 此时由外层绘制边框,明确清掉内层,防止双描边。
272
- &.el-input-number.el-input__wrapper > .el-input > .el-input__wrapper {
272
+ &.el-input-number.el-input__wrapper:not(.com-inputNumber-content)
273
+ > .el-input
274
+ > .el-input__wrapper {
273
275
  background: transparent !important;
274
276
  box-shadow: none !important;
275
277
  }
276
278
 
277
- &.el-input-number .el-input__inner,
278
- &.el-input-number .el-input__inner:focus,
279
- &.el-input-number .el-input__inner:focus-visible {
279
+ &.el-input-number:not(.com-inputNumber-content) .el-input__inner,
280
+ &.el-input-number:not(.com-inputNumber-content) .el-input__inner:focus,
281
+ &.el-input-number:not(.com-inputNumber-content) .el-input__inner:focus-visible {
280
282
  width: 100% !important;
281
283
  height: 100% !important;
282
284
  line-height: calc(var(--wk-form-control-height) - 2px) !important;
@@ -289,23 +291,27 @@ html body {
289
291
  text-align: left !important;
290
292
  }
291
293
 
292
- &.el-input-number .el-input__wrapper .el-input__inner {
294
+ &.el-input-number:not(.com-inputNumber-content)
295
+ .el-input__wrapper
296
+ .el-input__inner {
293
297
  padding: 0 !important;
294
298
  }
295
299
 
296
- &.el-input-number .el-input-number__increase,
297
- &.el-input-number .el-input-number__decrease {
300
+ &.el-input-number:not(.com-inputNumber-content) .el-input-number__increase,
301
+ &.el-input-number:not(.com-inputNumber-content) .el-input-number__decrease {
298
302
  display: none !important;
299
303
  }
300
304
 
301
- &.el-input-number .el-input__inner::-webkit-inner-spin-button,
302
- &.el-input-number .el-input__inner::-webkit-outer-spin-button {
305
+ &.el-input-number:not(.com-inputNumber-content)
306
+ .el-input__inner::-webkit-inner-spin-button,
307
+ &.el-input-number:not(.com-inputNumber-content)
308
+ .el-input__inner::-webkit-outer-spin-button {
303
309
  margin: 0 !important;
304
310
  appearance: none !important;
305
311
  -webkit-appearance: none !important;
306
312
  }
307
313
 
308
- &.el-input-number .el-input__inner[type="number"] {
314
+ &.el-input-number:not(.com-inputNumber-content) .el-input__inner[type="number"] {
309
315
  appearance: textfield !important;
310
316
  -moz-appearance: textfield !important;
311
317
  }
@@ -0,0 +1,26 @@
1
+ // styles/element/_typography.scss — 受管业务组件字体链
2
+ //
3
+ // Edge 在 Windows 上使用增强文本对比度;如果字体栈把英文/数字先分配给
4
+ // Helvetica/Segoe UI,再把中文逐字符 fallback 到微软雅黑,同一行会显得粗细、字面
5
+ // 高度不一致。这里仅在业务组件根统一字体变量与继承起点,不使用全局 * 选择器,
6
+ // 图标字体、编辑器、图表及定制页面仍可使用自己的显式 font-family。
7
+
8
+ @use "../scope" as skin;
9
+
10
+ #{skin.$managed-scope-selector} {
11
+ &:where(
12
+ .el-form,
13
+ .el-table,
14
+ .el-dialog,
15
+ .el-drawer,
16
+ .el-message-box,
17
+ .el-message,
18
+ .el-notification,
19
+ .el-popper,
20
+ .el-button,
21
+ .el-pagination
22
+ ) {
23
+ --el-font-family: var(--wk-font-family-sans) !important;
24
+ font-family: var(--wk-font-family-sans) !important;
25
+ }
26
+ }
@@ -1,6 +1,7 @@
1
1
  // styles/element/index.scss — Element Plus 覆盖层汇总
2
2
  // 前置:design/tokens/base.css 必须最先在 index.html 中加载
3
3
 
4
+ @forward './typography';
4
5
  @forward './button';
5
6
  @forward './pagination';
6
7
  @forward './form';
@@ -85,6 +85,9 @@ $wk-sidebar-width: var(--el-sidebar-width) !default;
85
85
  // 选择器特异性负责压过普通样式表,!important 负责压过平台运行时写入 body
86
86
  // 的普通内联变量;runtime/theme-lock.ts 再兜底处理后续动态改写。
87
87
  :root body {
88
+ // 仅定义字体 Token,不直接覆盖 body。由 L1/L2 受管组件根按需消费,
89
+ // 避免登录页、大屏、代码编辑器与图标字体被全局字体规则污染。
90
+ --wk-font-family-sans: "Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", Arial, sans-serif !important;
88
91
  --el-color-primary: #002a8f !important;
89
92
  --el-color-primary-rgb: 0, 42, 143 !important;
90
93
  --el-color-primary-light-1: #1a3f9a !important;
@@ -6,6 +6,23 @@
6
6
  // 维护:只改这一个文件,全项目生效
7
7
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
8
8
 
9
+ // 字体只落在真实 BaseTable / AG Grid 根上;不修改 body,也不覆盖 renderer 内部
10
+ // 显式声明的图标/代码字体。宿主与 root 同时设变量,兼容不同 AG Grid 版本的继承点。
11
+ #{skin.$managed-scope-selector} {
12
+ &:where(
13
+ .base-table,
14
+ .base-table-wrapper,
15
+ .base-table-container,
16
+ .ag-theme-quartz,
17
+ .ag-theme-quartz-dark,
18
+ .ag-theme-quartz-auto-dark,
19
+ .ag-root-wrapper
20
+ ) {
21
+ --ag-font-family: var(--wk-font-family-sans) !important;
22
+ font-family: var(--wk-font-family-sans) !important;
23
+ }
24
+ }
25
+
9
26
  // ── CSS 变量注入(AG Grid 28+ 支持)──────────────────────────────────────────
10
27
  .ag-root-wrapper {
11
28
  // 深品牌蓝在大面积行底色中只保留轻提示:hover 4%,selected 7%。
@@ -22,7 +39,7 @@
22
39
  --ag-selected-row-background-color: var(--wk-grid-row-selected-bg) !important;
23
40
  --ag-range-selection-border-color: rgba(var(--el-color-primary-rgb), 0.4);
24
41
  --ag-font-size: 13px;
25
- --ag-font-family: inherit;
42
+ --ag-font-family: var(--wk-font-family-sans);
26
43
  --ag-row-height: 26px;
27
44
  --ag-header-height: 36px;
28
45
  --ag-cell-horizontal-padding: 8px;
@@ -49,7 +66,7 @@
49
66
  .ag-header-cell {
50
67
  height: 36px !important;
51
68
  padding: 0 8px !important;
52
- font-size: 12.5px !important;
69
+ font-size: 13px !important;
53
70
  font-weight: 600 !important;
54
71
  color: #374151 !important;
55
72
  letter-spacing: 0.02em;
@@ -73,13 +90,26 @@
73
90
  height: 100%;
74
91
  display: flex !important;
75
92
  align-items: center !important;
76
- justify-content: center !important;
77
93
  padding: 0 !important;
78
94
  width: 100%;
79
95
  }
80
96
 
97
+ // 仅响应列定义显式声明的 headerAlign/align;不设置全局默认对齐。
98
+ // runtime/defineColumns 会把该意图桥接为下列类,兼容平台 BaseTable 的 AG Grid 适配层。
99
+ .ag-header-cell.wl-ui-table-header-align--left .ag-header-cell-label {
100
+ justify-content: flex-start;
101
+ }
102
+
103
+ .ag-header-cell.wl-ui-table-header-align--center .ag-header-cell-label {
104
+ justify-content: center;
105
+ }
106
+
107
+ .ag-header-cell.wl-ui-table-header-align--right .ag-header-cell-label {
108
+ justify-content: flex-end;
109
+ }
110
+
81
111
  .ag-header-cell-text {
82
- font-size: 12.5px;
112
+ font-size: 13px;
83
113
  font-weight: 600;
84
114
  color: #374151;
85
115
  white-space: nowrap;
@@ -126,12 +156,18 @@
126
156
  font-size: 13px !important;
127
157
  color: #374151;
128
158
  padding: 0 8px !important;
129
- display: flex !important;
130
- align-items: center !important;
131
- justify-content: center !important;
132
159
  border-right-color: transparent !important;
133
160
  }
134
161
 
162
+ // 普通单元格保持无竖线的轻量外观;真正获得焦点时恢复 AG Grid 自己的焦点色,
163
+ // 避免上面的透明右边框把选中单元格描边切掉一侧。
164
+ .ag-cell.ag-cell-focus {
165
+ border-color: var(
166
+ --ag-range-selection-border-color,
167
+ rgba(var(--el-color-primary-rgb, 0, 42, 143), 0.4)
168
+ ) !important;
169
+ }
170
+
135
171
  .ag-cell-value {
136
172
  min-width: 0;
137
173
  overflow: hidden;
@@ -140,9 +176,9 @@
140
176
  max-width: 100%;
141
177
  }
142
178
 
143
- // 平台把 .ag-cell 与 .ag-cell-value 复用在同一个 flex 节点上;flex 容器的
144
- // 直接文本不会稳定绘制 text-overflow。仅对没有子元素的普通文本单元格切回
145
- // block,编辑器、操作列、自定义 renderer、复选框与主动换行列保持原结构。
179
+ // 平台会把 .ag-cell 与 .ag-cell-value 复用在同一个节点上;直接文本需要 block
180
+ // 才能稳定绘制 text-overflow。仅命中没有子元素的普通文本单元格,编辑器、操作列、
181
+ // 自定义 renderer、复选框与主动换行列继续遵循 AG Grid / BaseTable 自身布局。
146
182
  #{skin.$managed-scope-selector} {
147
183
  &.ag-root-wrapper
148
184
  .ag-cell-value:not(.editable-cell):not(.always-editable-cell):not(
@@ -170,6 +206,9 @@
170
206
  // 复选框单元格(header 与 body 使用相同规则,确保视觉对齐)
171
207
  .ag-cell.ag-checkbox-cell {
172
208
  padding: 0 !important;
209
+ display: flex !important;
210
+ align-items: center !important;
211
+ justify-content: center !important;
173
212
  }
174
213
 
175
214
  // 多选列表头:精准命中 ag-header-select-all,与 body checkbox 保持相同居中方式
@@ -178,8 +217,8 @@
178
217
  justify-content: center !important;
179
218
  }
180
219
 
181
- .ag-header-cell.ag-header-cell-sortable:first-child,
182
- .ag-pinned-left-header .ag-header-cell:first-child {
220
+ .ag-header-cell.ag-header-cell-sortable:first-child:has(.ag-header-select-all),
221
+ .ag-pinned-left-header .ag-header-cell:first-child:has(.ag-checkbox) {
183
222
  padding: 0 !important;
184
223
  justify-content: center !important;
185
224
  }
@@ -360,6 +399,13 @@
360
399
 
361
400
  // 用 ::before 注入 SVG 动画徽标
362
401
  .ag-overlay-loading-center {
402
+ // AG Grid 默认插入 Loading...;统一文字层级并避免声明落在嵌套规则之后。
403
+ font-size: 13px !important;
404
+ font-weight: 500 !important;
405
+ color: #57606a !important;
406
+ letter-spacing: 0.02em !important;
407
+ line-height: 1.4 !important;
408
+
363
409
  &::before {
364
410
  content: "";
365
411
  display: block;
@@ -369,12 +415,6 @@
369
415
  center/contain no-repeat;
370
416
  }
371
417
 
372
- // 省略号文字(AG Grid 默认插入"Loading...",此处做字体优化)
373
- font-size: 13px !important;
374
- font-weight: 500 !important;
375
- color: #57606a !important;
376
- letter-spacing: 0.02em !important;
377
- line-height: 1.4 !important;
378
418
  }
379
419
 
380
420
  // 三个跳动小点(补充到文字后面,用 ::after 伪元素模拟)
@@ -197,6 +197,89 @@
197
197
  box-shadow: none !important;
198
198
  }
199
199
 
200
+ // common-core jh-input-number 是“数字框根节点同时复用 el-input__wrapper”的复合结构:
201
+ // .com-inputNumber-content.el-input-number.el-input__wrapper > .el-input。
202
+ // 普通 Element InputNumber 的根/子 wrapper 规则不能套到这里,否则会同时压缩外壳、
203
+ // 清空组件自己的 textAlign/controls 语义。复合根只统一外轮廓和高度,内部继续由
204
+ // jh-input-number 自己负责左右对齐、单位附加段与步进按钮。
205
+ &.com-inputNumber-content.el-input-number.el-input__wrapper {
206
+ display: inline-flex !important;
207
+ align-items: stretch !important;
208
+ width: 100% !important;
209
+ height: var(--wk-form-control-height, 26px) !important;
210
+ min-height: var(--wk-form-control-height, 26px) !important;
211
+ line-height: normal !important;
212
+ padding: 0 !important;
213
+ border: 0 !important;
214
+ border-radius: var(--wk-form-control-radius, var(--el-border-radius-base, 6px)) !important;
215
+ box-sizing: border-box !important;
216
+ background: var(--el-input-bg-color, var(--el-fill-color-blank, #fff)) !important;
217
+ box-shadow:
218
+ 0 0 0 1px var(--el-input-border-color, var(--el-border-color, #dcdfe6)) inset !important;
219
+ transition: box-shadow 0.15s ease !important;
220
+ }
221
+
222
+ &.com-inputNumber-content.el-input-number.el-input__wrapper:not(.is-disabled):hover {
223
+ box-shadow:
224
+ 0 0 0 1px var(--el-input-hover-border-color, var(--el-border-color-hover, #c0c4cc)) inset !important;
225
+ }
226
+
227
+ &.com-inputNumber-content.el-input-number.el-input__wrapper:not(.is-disabled):focus-within {
228
+ box-shadow:
229
+ 0 0 0 1.5px var(--el-color-primary, #002a8f) inset !important;
230
+ }
231
+
232
+ &.com-inputNumber-content.el-input-number.el-input__wrapper.is-disabled {
233
+ background: var(--el-disabled-bg-color, #f5f7fa) !important;
234
+ box-shadow:
235
+ 0 0 0 1px var(--el-disabled-border-color, #e4e7ed) inset !important;
236
+ }
237
+
238
+ &.com-inputNumber-content.el-input-number.el-input__wrapper > .el-input {
239
+ flex: 1 1 auto !important;
240
+ width: 100% !important;
241
+ min-width: 0 !important;
242
+ height: 100% !important;
243
+ min-height: 0 !important;
244
+ border: 0 !important;
245
+ outline: none !important;
246
+ background: transparent !important;
247
+ box-shadow: none !important;
248
+ }
249
+
250
+ &.com-inputNumber-content.el-input-number.el-input__wrapper
251
+ > .el-input
252
+ > .el-input__wrapper {
253
+ height: 100% !important;
254
+ min-height: 0 !important;
255
+ border: 0 !important;
256
+ border-radius: 0 !important;
257
+ background: transparent !important;
258
+ box-shadow: none !important;
259
+ }
260
+
261
+ &.com-inputNumber-content.el-input-number.el-input__wrapper
262
+ > .el-input
263
+ .el-input__inner {
264
+ height: 100% !important;
265
+ line-height: calc(var(--wk-form-control-height, 26px) - 2px) !important;
266
+ border: 0 !important;
267
+ outline: none !important;
268
+ background: transparent !important;
269
+ box-shadow: none !important;
270
+ }
271
+
272
+ // 带单位/后缀时,外层数字框仍是唯一描边所有者;子 input-group 只负责布局和分隔线。
273
+ &.com-inputNumber-content.el-input-number.el-input__wrapper
274
+ > .el-input.el-input-group {
275
+ height: 100% !important;
276
+ min-height: 0 !important;
277
+ border: 0 !important;
278
+ border-radius: 0 !important;
279
+ background: transparent !important;
280
+ box-shadow: none !important;
281
+ }
282
+
200
283
  &.com-picker .el-input > .el-input__inner,
201
284
  &.com-reference-picker .el-input > .el-input__inner,
202
285
  &.com-reference-picker-input .el-input > .el-input__inner,