@agile-team/wl-skills-ui 1.8.6 → 1.8.7

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,19 +4,15 @@ 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.8.6] - 2026-05-17
8
-
9
- ### Added
10
-
11
- - **`renderOps` 运行时类型守门**:dev 模式下检测到 `OpItem.type` 不在 `view | edit | del | danger | log | ok | send | chip | link` 集合中时,`console.warn` 一次性提示并按 `link` 兜底渲染。修复下游项目(`strict: false`)传错 type 时图标静默降级为纯文字、毫无察觉的隐性体验问题。production 环境无任何副作用。
12
-
13
- ## [1.8.5] - 2026-05-17
7
+ ## [1.8.7] - 2026-05-17
14
8
 
15
9
  ### Added
16
10
 
11
+ - **loading 遮罩质感优化**:`_base-table.scss` 统一覆盖 BaseTable / AG Grid 的 `v-loading` 遮罩,灰色蒙层 → 毛玻璃半透明(`backdrop-filter: blur(1px)` + `rgba(255,255,255,0.45)`),数据切换近乎无感。
17
12
  - **R025**:检测 defineColumns 列中 `options:[]` 纯文本退化,提示升级为 `renderTagSlot` / `renderDictClassifyTag` 彩色标签。
18
13
  - **R026**:检测模板中原生 HTML 元素(`<table>/<input>/<select>/<button>/<textarea>`),提示替换为对应 Element Plus 组件以纳入统一风格体系。
19
- - fixture 测试覆盖 R025/R026(20 条自动化测试)。
14
+ - **R027**:检测业务代码硬编码 `.el-loading-mask` 背景色,提示删除(由 wl-skills-ui 统一覆盖)。
15
+ - fixture 测试覆盖 R025/R026/R027(22 条自动化测试)。
20
16
 
21
17
  ## [1.8.3] - 2026-05-13
22
18
 
package/README.md CHANGED
@@ -213,13 +213,14 @@ yarn add @agile-team/wl-skills-ui
213
213
 
214
214
  ## 版本亮点
215
215
 
216
- 当前 v1.8.5
216
+ 当前 v1.8.7
217
217
 
218
- - **R025** 语义合规:`options:[]` 退化检测 提示升级 `renderTagSlot` / `renderDictClassifyTag`
219
- - **R026** 原生 HTML 拦截:`<table>/<input>/<select>/<button>/<textarea>`提示替换 el-* 组件
218
+ - **loading 遮罩质感优化**:BaseTable / AG Grid v-loading 由灰色蒙层改为毛玻璃半透明(backdrop-filter),数据切换无感
219
+ - **R027** 检测业务代码硬编码 `.el-loading-mask` 背景色提示删除,由包统一覆盖
220
+ - **R025** 语义合规:`options:[]` 退化检测 → 升级 `renderTagSlot` / `renderDictClassifyTag`
221
+ - **R026** 原生 HTML 拦截:`<table>/<input>/<select>/<button>/<textarea>` → 替换 el-* 组件
220
222
  - `scan --only/--skip` 规则过滤 + `exempt init` 智能豁免脚手架
221
- - 搜索区字号统一 12px / 必填星号去重 / 20 fixture 自动化测试
222
- - `scan --baseline` 漂移对比 + SCSS 链路检查 + R-rule 单一事实源(31 条)
223
+ - `scan --baseline` 漂移对比 + SCSS 链路检查 + R-rule 单一事实源(32 条)
223
224
 
224
225
  历史亮点(v1.7.1):
225
226
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/wl-skills-ui",
3
- "version": "1.8.6",
3
+ "version": "1.8.7",
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",
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <BaseTable :columns="columns" v-loading="loading" />
3
+ </template>
4
+ <style scoped>
5
+ .el-loading-mask {
6
+ background-color: rgba(0, 0, 0, 0.3);
7
+ }
8
+ </style>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <BaseTable :columns="columns" v-loading="loading" />
3
+ </template>
4
+ <style scoped>
5
+ .my-table {
6
+ border-radius: 6px;
7
+ }
8
+ </style>
@@ -24,9 +24,19 @@ export const semanticRules = [
24
24
  const blockEnd = Math.min(lines.length, i + 5);
25
25
  const block = lines.slice(blockStart, blockEnd).join("\n");
26
26
  // 必须在列定义上下文中(有 label: 或 name: 或 prop:)
27
- if (!/\blabel\s*:/.test(block) && !/\bname\s*:/.test(block) && !/\bprop\s*:/.test(block)) continue;
27
+ if (
28
+ !/\blabel\s*:/.test(block) &&
29
+ !/\bname\s*:/.test(block) &&
30
+ !/\bprop\s*:/.test(block)
31
+ )
32
+ continue;
28
33
  // 已有渲染器则跳过
29
- if (/defaultSlot|defaultNode|renderTag|renderDictClassify|renderBadge|renderEnable|cellRenderer/.test(block)) continue;
34
+ if (
35
+ /defaultSlot|defaultNode|renderTag|renderDictClassify|renderBadge|renderEnable|cellRenderer/.test(
36
+ block,
37
+ )
38
+ )
39
+ continue;
30
40
  // 排除 type: "selection" / "index" / "expand"
31
41
  if (/type\s*:\s*["'](selection|index|expand)["']/.test(block)) continue;
32
42
  const labelMatch = block.match(/label\s*:\s*["']([^"']+)["']/);
@@ -54,11 +64,26 @@ export const semanticRules = [
54
64
  check(template, file, lineOffset) {
55
65
  const issues = [];
56
66
  const NATIVE_TO_EL = {
57
- table: { el: "el-table", reason: "原生 <table> 不受 wl-skills-ui 表格样式覆盖" },
58
- input: { el: "el-input", reason: "原生 <input> 不受统一 size/密度/圆角控制" },
59
- select: { el: "el-select", reason: "原生 <select> 不受统一下拉样式控制" },
60
- textarea: { el: "el-input type=\"textarea\"", reason: "原生 <textarea> 不受统一输入框样式控制" },
61
- button: { el: "el-button", reason: "原生 <button> 不受统一按钮样式控制" },
67
+ table: {
68
+ el: "el-table",
69
+ reason: "原生 <table> 不受 wl-skills-ui 表格样式覆盖",
70
+ },
71
+ input: {
72
+ el: "el-input",
73
+ reason: "原生 <input> 不受统一 size/密度/圆角控制",
74
+ },
75
+ select: {
76
+ el: "el-select",
77
+ reason: "原生 <select> 不受统一下拉样式控制",
78
+ },
79
+ textarea: {
80
+ el: 'el-input type="textarea"',
81
+ reason: "原生 <textarea> 不受统一输入框样式控制",
82
+ },
83
+ button: {
84
+ el: "el-button",
85
+ reason: "原生 <button> 不受统一按钮样式控制",
86
+ },
62
87
  };
63
88
  for (const [nativeTag, { el, reason }] of Object.entries(NATIVE_TO_EL)) {
64
89
  // 匹配 <table / <input / <select 等原生标签,排除 el-table / el-input 等
@@ -71,7 +96,7 @@ export const semanticRules = [
71
96
  // 排除注释
72
97
  const lineStart = template.lastIndexOf("\n", m.index) + 1;
73
98
  const lineText = template.slice(lineStart, m.index);
74
- if (/<!--/.test(lineText) && !(/-->/.test(lineText))) continue;
99
+ if (/<!--/.test(lineText) && !/-->/.test(lineText)) continue;
75
100
  if (/^\s*\/\//.test(lineText)) continue;
76
101
  // 排除 slot/template 内嵌的特殊情况(如 <table> 在 rich-text/markdown 中)
77
102
  // 但不做过度排除,让开发者自行决定豁免
@@ -91,4 +116,48 @@ export const semanticRules = [
91
116
  return issues;
92
117
  },
93
118
  },
119
+
120
+ // R027: 检测业务代码中对 .el-loading-mask 的灰色背景覆盖(应由 wl-skills-ui 统一管控)
121
+ {
122
+ id: "R027",
123
+ category: "style",
124
+ severity: "warning",
125
+ name: "业务代码硬编码 el-loading-mask 背景色(应删除,由 wl-skills-ui 统一覆盖)",
126
+ check() {
127
+ return [];
128
+ },
129
+ checkStyle(styleBlock, file, lineOffset) {
130
+ const issues = [];
131
+ const lines = styleBlock.split("\n");
132
+ for (let i = 0; i < lines.length; i++) {
133
+ const line = lines[i];
134
+ // 检测 .el-loading-mask 相关的 background 硬编码
135
+ if (
136
+ /\.el-loading-mask/.test(line) ||
137
+ (i > 0 &&
138
+ /\.el-loading-mask/.test(
139
+ lines.slice(Math.max(0, i - 5), i).join("\n"),
140
+ ))
141
+ ) {
142
+ if (
143
+ /background(-color)?\s*:/.test(line) &&
144
+ !/transparent/.test(line)
145
+ ) {
146
+ issues.push(
147
+ issue(
148
+ file,
149
+ lineOffset + i + 1,
150
+ "R027",
151
+ "style",
152
+ "warning",
153
+ "业务代码硬编码 .el-loading-mask 背景色,与 wl-skills-ui 统一遮罩层冲突",
154
+ "删除此规则,wl-skills-ui v1.8.5+ 已内置毛玻璃遮罩覆盖(styles/vendors/_base-table.scss)",
155
+ ),
156
+ );
157
+ }
158
+ }
159
+ }
160
+ return issues;
161
+ },
162
+ },
94
163
  ];
@@ -411,6 +411,17 @@
411
411
  "manualReason": "需根据业务场景选择正确的 el-* 组件和属性",
412
412
  "scanner": "scanner/rules/semantic.mjs",
413
413
  "skills": ["element/el-form", "element/el-table"]
414
+ },
415
+ {
416
+ "id": "R027",
417
+ "category": "style",
418
+ "severity": "warning",
419
+ "title": "禁止业务代码硬编码 .el-loading-mask 背景色",
420
+ "rationale": "wl-skills-ui v1.8.5+ 已内置毛玻璃遮罩覆盖(半透明白底 + backdrop-filter),业务侧硬编码会冲突或导致灰色蒙层残留。",
421
+ "appliesTo": [".el-loading-mask"],
422
+ "autoFixable": true,
423
+ "scanner": "scanner/rules/semantic.mjs",
424
+ "skills": ["vendors/base-table", "element/el-table"]
414
425
  }
415
426
  ]
416
427
  }
@@ -5,7 +5,7 @@
5
5
  //
6
6
  // 【识别规则(供 scanner / AI 使用)】
7
7
  // - 标签:<BaseTable> / <base-table> / <BaseDataTable>
8
- // - 类名:.base-table-wrapper / .base-table-container / .base-table-*
8
+ // - 类名:.base-table-wrapper / .base-table-container / .base-table-*
9
9
  // - props:通常包含 columns / data / hook / renderType
10
10
  //
11
11
  // 【设计语言】对齐 Element Plus el-table 的视觉规范(参见 element/_table.scss)
@@ -36,6 +36,42 @@
36
36
  }
37
37
  }
38
38
 
39
+ // ── v-loading 遮罩层质感优化 ──────────────────────────────────────────────────
40
+ // 目的:去除 BaseTable / AG Grid 切换数据时的灰色蒙层,替换为轻量毛玻璃 + 微透明效果
41
+ // 体验:数据切换几乎无感,加载状态通过 spinner 动画暗示,不阻断阅读上下文
42
+ .app-page-container,
43
+ .base-table-wrapper,
44
+ .base-table-container,
45
+ .ag-root-wrapper {
46
+
47
+ >.el-loading-mask,
48
+ .el-loading-mask {
49
+ background-color: rgba(255, 255, 255, 0.45) !important;
50
+ backdrop-filter: blur(1px);
51
+ transition: opacity 0.2s ease;
52
+ }
53
+
54
+ .el-loading-spinner {
55
+
56
+ // 缩小默认 spinner,减少视觉干扰
57
+ .circular {
58
+ width: 28px;
59
+ height: 28px;
60
+ }
61
+
62
+ .el-loading-text {
63
+ font-size: 12px;
64
+ color: var(--el-color-primary);
65
+ margin-top: 4px;
66
+ }
67
+ }
68
+ }
69
+
70
+ // 全屏 loading 也统一(如 v-loading.fullscreen)
71
+ body>.el-loading-mask {
72
+ background-color: rgba(255, 255, 255, 0.6) !important;
73
+ backdrop-filter: blur(2px);
74
+ }
39
75
  // ── 扩展位 ────────────────────────────────────────────────────────────────────
40
76
  // 当业务侧 BaseTable 有更多结构性 class(如 base-table__toolbar / base-table__footer),
41
77
  // 在这里继续追加,不要污染全局选择器。