@qilitt-mickey/vue3-temp-skill 1.1.35 → 1.1.36
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/README.md +6 -36
- package/SKILL.md +11 -19
- package/bin/cli.js +19 -65
- package/dist/mapping-type.d.ts +33 -0
- package/dist/theme-vars.js +61 -0
- package/dist/theme-vars.ts +111 -0
- package/dist/theme.css +72 -0
- package/mapping/basic/color.json +34 -0
- package/mapping/basic/radius.json +17 -0
- package/mapping/basic/semantic-values.json +72 -0
- package/mapping/basic/spacing.json +21 -0
- package/mapping/basic/typography.json +21 -0
- package/mapping/component/button.json +59 -0
- package/mapping/component/input.json +39 -0
- package/mapping/component/overlay.json +63 -0
- package/mapping/component/table.json +42 -0
- package/mapping/layout/breakpoint.json +20 -0
- package/mapping/layout/shell-geometry.json +26 -0
- package/mapping/scenes/admin/content.json +112 -0
- package/mapping/scenes/admin/layout.json +331 -0
- package/package.json +8 -4
- package/parser/fixtures/changeset-legacy.json +11 -0
- package/parser/fixtures/changeset-neg1.json +17 -0
- package/parser/fixtures/changeset-neg2.json +10 -0
- package/parser/fixtures/changeset-neg3.json +22 -0
- package/parser/fixtures/changeset-pos.json +43 -0
- package/parser/generator.js +178 -0
- package/parser/index.js +553 -0
- package/parser/loader.js +66 -0
- package/parser/override.js +119 -0
- package/parser/regression.js +137 -0
- package/parser/validator.js +137 -0
- package/parser/watch.js +103 -0
- package/references/code-quality.md +24 -23
- package/references/core-kernel.md +2 -4
- package/references/crud-pages.md +18 -290
- package/references/data-mapping.md +229 -229
- package/references/data-screen.md +102 -102
- package/references/design-apply.md +177 -0
- package/references/flowchart-g6.md +260 -260
- package/references/form-advanced.md +1 -1
- package/references/graph-relation.md +1 -1
- package/references/layout-theme.md +513 -520
- package/references/qrcode-barcode.md +117 -117
- package/references/workflow-bpmn.md +214 -214
- package/scripts/check.mjs +84 -90
- package/scripts/cli.mjs +115 -120
- package/scripts/match.py +134 -134
- package/scripts/modules.json +109 -103
- package/scripts/validate.mjs +106 -106
- package/references/design-handoff.md +0 -767
- package/references/design-system.md +0 -142
- package/references/design-verify.md +0 -469
- package/scripts/check.cmd +0 -9
- package/scripts/field-schema-audit.mjs +0 -246
- package/scripts/handoff.mjs +0 -474
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "admin 场景 · 布局模块语义 ID 全属性映射(vue3-web-temp 框架组件实证)。每条含结构定位(selector/file)、形态切换(forms)、样式映射(css_vars 优先 + custom_style_map 兜底)。style_scope 为样式必须包裹的容器类名;:root 表示全局令牌层。",
|
|
3
|
+
"meta": {
|
|
4
|
+
"layer": "scene",
|
|
5
|
+
"scene": "admin",
|
|
6
|
+
"domain": "layout",
|
|
7
|
+
"version": "1.0.0",
|
|
8
|
+
"tech_stack": "vue3 + element-plus + vue3-web-temp"
|
|
9
|
+
},
|
|
10
|
+
"mappings": {
|
|
11
|
+
"admin.layout.sidebar": {
|
|
12
|
+
"type": "module",
|
|
13
|
+
"selector": ".sidebar-container",
|
|
14
|
+
"file": "src/layout/components/lay-sidebar/NavVertical.vue",
|
|
15
|
+
"style_scope": ".sidebar-container",
|
|
16
|
+
"default_props": { "width": "var(--sidebar-width, 208px)" },
|
|
17
|
+
"children": [
|
|
18
|
+
"admin.layout.sidebar.logo_area",
|
|
19
|
+
"admin.layout.sidebar.menu",
|
|
20
|
+
"admin.layout.sidebar.collapse_trigger"
|
|
21
|
+
],
|
|
22
|
+
"css_vars": {
|
|
23
|
+
"width": "--sidebar-width",
|
|
24
|
+
"collapsed_width": "--sidebar-collapsed-width",
|
|
25
|
+
"collapse_bar_height": "--sidebar-collapse-bar-height",
|
|
26
|
+
"menu_item_height": "--el-menu-item-height"
|
|
27
|
+
},
|
|
28
|
+
"custom_style_map": {
|
|
29
|
+
"bg": "background-color",
|
|
30
|
+
"border_right": "border-right",
|
|
31
|
+
"box_shadow": "box-shadow"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"admin.layout.sidebar.logo_area": {
|
|
35
|
+
"type": "element",
|
|
36
|
+
"selector": ".sidebar-logo",
|
|
37
|
+
"file": "src/layout/components/lay-sidebar/components/SidebarLogo.vue",
|
|
38
|
+
"style_scope": ".sidebar-container",
|
|
39
|
+
"visible_prop": "ShowLogo(platform-config.json / emitter logoChange)",
|
|
40
|
+
"css_vars": {
|
|
41
|
+
"height": "--vts-bar-height",
|
|
42
|
+
"bg": "--vts-theme-sidebar-logo",
|
|
43
|
+
"title_color": "--vts-theme-sub-menu-active-text"
|
|
44
|
+
},
|
|
45
|
+
"custom_style_map": {
|
|
46
|
+
"title_font_size": "font-size",
|
|
47
|
+
"title_font_weight": "font-weight"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"admin.layout.sidebar.menu": {
|
|
51
|
+
"type": "component",
|
|
52
|
+
"component": "ElMenu",
|
|
53
|
+
"selector": ".sidebar-container .el-menu",
|
|
54
|
+
"file": "src/layout/components/lay-sidebar/NavVertical.vue",
|
|
55
|
+
"style_scope": ".sidebar-container",
|
|
56
|
+
"css_vars": {
|
|
57
|
+
"menu_bg": "--vts-theme-menu-bg",
|
|
58
|
+
"menu_text": "--vts-theme-menu-text",
|
|
59
|
+
"menu_hover_bg": "--vts-theme-menu-hover",
|
|
60
|
+
"menu_title_hover": "--vts-theme-menu-title-hover",
|
|
61
|
+
"sub_menu_bg": "--vts-theme-sub-menu-bg",
|
|
62
|
+
"sub_menu_active_text": "--vts-theme-sub-menu-active-text",
|
|
63
|
+
"menu_active_bg": "--vts-theme-menu-active-bg",
|
|
64
|
+
"menu_active_indicator": "--vts-theme-menu-active-before",
|
|
65
|
+
"sidebar_border": "--vts-sidebar-border-color",
|
|
66
|
+
"item_height": "--el-menu-item-height"
|
|
67
|
+
},
|
|
68
|
+
"custom_style_map": {
|
|
69
|
+
"active_indicator_width": "width",
|
|
70
|
+
"active_indicator_style": "border-radius"
|
|
71
|
+
},
|
|
72
|
+
"$note": "侧栏配色挂载点为 html[data-theme='xxx'](theme.scss 8 套预设);设计输出深色侧栏 → Theme=default + Version++(useTheme 规则),浅色 → Theme=light。menu_active_* 主题变量可被 --sidebar-* 覆写变量替换"
|
|
73
|
+
},
|
|
74
|
+
"admin.layout.sidebar.collapse_trigger": {
|
|
75
|
+
"type": "element",
|
|
76
|
+
"selector": ".left-collapse / .center-collapse",
|
|
77
|
+
"file": "src/layout/components/lay-sidebar/components/SidebarLeftCollapse.vue + SidebarCenterCollapse.vue",
|
|
78
|
+
"style_scope": ".sidebar-container",
|
|
79
|
+
"forms": {
|
|
80
|
+
"bottom_bar": "SidebarLeftCollapse(底部条,出厂默认)",
|
|
81
|
+
"center_edge": "SidebarCenterCollapse(侧缘中点,折叠/悬停时显示)"
|
|
82
|
+
},
|
|
83
|
+
"css_vars": {
|
|
84
|
+
"bar_height": "--sidebar-collapse-bar-height"
|
|
85
|
+
},
|
|
86
|
+
"custom_style_map": {
|
|
87
|
+
"trigger_width": "width",
|
|
88
|
+
"trigger_height": "height",
|
|
89
|
+
"trigger_color": "color"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"admin.layout.header": {
|
|
93
|
+
"type": "module",
|
|
94
|
+
"selector": ".navbar",
|
|
95
|
+
"file": "src/layout/components/lay-navbar/index.vue",
|
|
96
|
+
"style_scope": ".navbar",
|
|
97
|
+
"default_props": { "height": "var(--vts-bar-height)" },
|
|
98
|
+
"children": [
|
|
99
|
+
"admin.layout.header.logo_area",
|
|
100
|
+
"admin.layout.header.breadcrumb",
|
|
101
|
+
"admin.layout.header.lang_switch",
|
|
102
|
+
"admin.layout.header.fullscreen",
|
|
103
|
+
"admin.layout.header.setting_button",
|
|
104
|
+
"admin.layout.header.user_profile"
|
|
105
|
+
],
|
|
106
|
+
"css_vars": {
|
|
107
|
+
"height": "--header-height",
|
|
108
|
+
"padding_x": "--header-padding-x"
|
|
109
|
+
},
|
|
110
|
+
"custom_style_map": {
|
|
111
|
+
"bg": "background-color",
|
|
112
|
+
"box_shadow": "box-shadow"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"admin.layout.header.logo_area": {
|
|
116
|
+
"type": "element",
|
|
117
|
+
"selector": ".navbar .siderLogo",
|
|
118
|
+
"file": "src/layout/components/lay-sidebar/components/SidebarLogo.vue(navbar 内复用)",
|
|
119
|
+
"style_scope": ".navbar",
|
|
120
|
+
"visible_note": "仅 horizontal 布局在顶栏渲染 logo(v-if layout==='horizontal' && showLogo)",
|
|
121
|
+
"css_vars": {},
|
|
122
|
+
"custom_style_map": {
|
|
123
|
+
"min_width": "min-width",
|
|
124
|
+
"height": "height"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"admin.layout.header.breadcrumb": {
|
|
128
|
+
"type": "component",
|
|
129
|
+
"component": "SidebarBreadCrumb",
|
|
130
|
+
"selector": ".navbar-breadcrumb-wrap",
|
|
131
|
+
"file": "src/layout/components/lay-sidebar/components/SidebarBreadCrumb.vue",
|
|
132
|
+
"style_scope": ".navbar",
|
|
133
|
+
"visible_note": "v-if layout!=='mix' && layout!=='horizontal' && device!=='mobile'",
|
|
134
|
+
"css_vars": {
|
|
135
|
+
"text_color": "--el-text-color-regular"
|
|
136
|
+
},
|
|
137
|
+
"custom_style_map": {
|
|
138
|
+
"font_size": "font-size"
|
|
139
|
+
},
|
|
140
|
+
"$note": "分隔符为结构属性(breadcrumb separator 字符),不在样式映射范围"
|
|
141
|
+
},
|
|
142
|
+
"admin.layout.header.lang_switch": {
|
|
143
|
+
"type": "component",
|
|
144
|
+
"component": "ReLanguageSwitch(ElDropdown 包裹)",
|
|
145
|
+
"selector": ".navbar .language-trigger",
|
|
146
|
+
"file": "src/components/ReLanguageSwitch/src/index.vue",
|
|
147
|
+
"style_scope": ".navbar",
|
|
148
|
+
"forms": {
|
|
149
|
+
"icon_only": "出厂现状:纯图标触发器(.language-trigger > .language-icon),下拉菜单选语言"
|
|
150
|
+
},
|
|
151
|
+
"css_vars": {
|
|
152
|
+
"icon_color": "--el-text-color-regular",
|
|
153
|
+
"hover_bg": "--el-fill-color-light"
|
|
154
|
+
},
|
|
155
|
+
"sub_selectors": {
|
|
156
|
+
"icon": ".language-trigger .language-icon",
|
|
157
|
+
"text": ".language-trigger .language-text"
|
|
158
|
+
},
|
|
159
|
+
"custom_style_map": {
|
|
160
|
+
"icon_size": "font-size",
|
|
161
|
+
"gap": "gap",
|
|
162
|
+
"text_font_size": "font-size"
|
|
163
|
+
},
|
|
164
|
+
"$note": "inline_switch 并排切换形态需增量插入片段(变更集 form=inline_switch 时按 V3.0 §4.2 v-if 保形切换,不删原代码)"
|
|
165
|
+
},
|
|
166
|
+
"admin.layout.header.fullscreen": {
|
|
167
|
+
"type": "component",
|
|
168
|
+
"component": "SidebarFullScreen",
|
|
169
|
+
"selector": "#full-screen",
|
|
170
|
+
"file": "src/layout/components/lay-sidebar/components/SidebarFullScreen.vue",
|
|
171
|
+
"style_scope": ".navbar",
|
|
172
|
+
"css_vars": {
|
|
173
|
+
"text_color": "--el-text-color-primary",
|
|
174
|
+
"hover_bg": "--el-fill-color-light"
|
|
175
|
+
},
|
|
176
|
+
"custom_style_map": {
|
|
177
|
+
"icon_size": "font-size"
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"admin.layout.header.setting_button": {
|
|
181
|
+
"type": "element",
|
|
182
|
+
"selector": ".set-icon",
|
|
183
|
+
"file": "src/layout/components/lay-navbar/index.vue",
|
|
184
|
+
"style_scope": ".navbar",
|
|
185
|
+
"css_vars": {
|
|
186
|
+
"height": "--vts-bar-height"
|
|
187
|
+
},
|
|
188
|
+
"custom_style_map": {
|
|
189
|
+
"icon_size": "font-size",
|
|
190
|
+
"width": "width"
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"admin.layout.header.user_profile": {
|
|
194
|
+
"type": "component",
|
|
195
|
+
"component": "ElDropdown",
|
|
196
|
+
"selector": ".navbar-right .el-dropdown-link",
|
|
197
|
+
"file": "src/layout/components/lay-navbar/index.vue",
|
|
198
|
+
"style_scope": ".navbar",
|
|
199
|
+
"sub_selectors": {
|
|
200
|
+
"$comment": "avatar/name 为点位内部部件,不设独立语义 ID(符合 4 段 ID 上限);样式字段按前缀路由到对应选择器",
|
|
201
|
+
"avatar": ".navbar-right .el-dropdown-link img",
|
|
202
|
+
"name": ".navbar-right .el-dropdown-link p"
|
|
203
|
+
},
|
|
204
|
+
"css_vars": {
|
|
205
|
+
"height": "--vts-bar-height",
|
|
206
|
+
"text_color": "--el-text-color-primary"
|
|
207
|
+
},
|
|
208
|
+
"custom_style_map": {
|
|
209
|
+
"avatar_width": "width",
|
|
210
|
+
"avatar_height": "height",
|
|
211
|
+
"avatar_radius": "border-radius",
|
|
212
|
+
"name_font_size": "font-size",
|
|
213
|
+
"name_font_weight": "font-weight",
|
|
214
|
+
"gap": "gap"
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
"admin.layout.tabs": {
|
|
218
|
+
"type": "module",
|
|
219
|
+
"selector": ".tags-view",
|
|
220
|
+
"file": "src/layout/components/lay-tag/index.vue",
|
|
221
|
+
"style_scope": ".tags-view",
|
|
222
|
+
"visible_prop": "HideTabs(platform-config.json)",
|
|
223
|
+
"children": ["admin.layout.tabs.home_tab", "admin.layout.tabs.item", "admin.layout.tabs.context_menu"],
|
|
224
|
+
"forms": {
|
|
225
|
+
"chrome": "谷歌页签(出厂 ShowModel=chrome)",
|
|
226
|
+
"card": "卡片页签(ShowModel=card)"
|
|
227
|
+
},
|
|
228
|
+
"css_vars": {
|
|
229
|
+
"height": "--tabs-height",
|
|
230
|
+
"chrome_inset_top": "--vts-tag-chrome-inset-top",
|
|
231
|
+
"card_height": "--vts-tag-card-height",
|
|
232
|
+
"card_radius": "--vts-tag-card-radius",
|
|
233
|
+
"card_gap": "--vts-tag-card-gap",
|
|
234
|
+
"card_idle_bg": "--vts-tag-card-idle-bg",
|
|
235
|
+
"card_active_bg": "--vts-tag-card-active-bg",
|
|
236
|
+
"card_hover_bg": "--vts-tag-card-hover-bg",
|
|
237
|
+
"card_active_text": "--vts-tag-card-active-text",
|
|
238
|
+
"card_idle_text": "--vts-tag-card-idle-text",
|
|
239
|
+
"card_close_color": "--vts-tag-card-close-color"
|
|
240
|
+
},
|
|
241
|
+
"custom_style_map": {
|
|
242
|
+
"bg": "background-color",
|
|
243
|
+
"border_bottom": "border-bottom"
|
|
244
|
+
},
|
|
245
|
+
"$note": "showModel 由 platform-config.json ShowModel 字段切换;smart/line 模板未实现,映射层按 chrome/card 两形态处理"
|
|
246
|
+
},
|
|
247
|
+
"admin.layout.tabs.home_tab": {
|
|
248
|
+
"type": "element",
|
|
249
|
+
"selector": ".tags-view .tags-view-item.is-active.home-item, .tags-view .home-item",
|
|
250
|
+
"file": "src/layout/components/lay-tag/index.vue(首页页签,固定首位)",
|
|
251
|
+
"style_scope": ".tags-view",
|
|
252
|
+
"$comment": "设计侧描述(unified-framework §3):40×40 纯图标按钮(16px home 图标),不可关闭、不可拖拽。项目侧选择器按 vue3-web-temp lay-tag 实证类名核;若类名不符,落地时以源码实证为准并回写本条目",
|
|
253
|
+
"css_vars": {
|
|
254
|
+
"width": "--vts-tag-card-height",
|
|
255
|
+
"height": "--vts-tag-card-height"
|
|
256
|
+
},
|
|
257
|
+
"custom_style_map": {
|
|
258
|
+
"icon_size": "font-size",
|
|
259
|
+
"icon_color": "color",
|
|
260
|
+
"divider_color": "border-left-color"
|
|
261
|
+
},
|
|
262
|
+
"$note": "divider(首页页签与首个业务页签间的 1px 竖线分割)属子元素结构样式,设计侧通过 divider_color 表达视觉意图"
|
|
263
|
+
},
|
|
264
|
+
"admin.layout.tabs.item": {
|
|
265
|
+
"type": "element",
|
|
266
|
+
"selector": ".tags-view .tags-view-item:not(.home-item)",
|
|
267
|
+
"file": "src/layout/components/lay-tag/index.vue(业务页签)",
|
|
268
|
+
"style_scope": ".tags-view",
|
|
269
|
+
"$comment": "设计侧描述(unified-framework §3):点击菜单新增、同路由不重复,padding 0 12px;激活态仅文字变主色+字重 500,无下划线/背景变化;关闭钮 12×12 始终可见,hover 变 #FF4D4F。样式字段优先走 --vts-tag-card-*(layout-theme.md:card 改色/几何优先改 --vts-tag-card-*,勿另复制选择器)",
|
|
270
|
+
"css_vars": {
|
|
271
|
+
"card_height": "--vts-tag-card-height",
|
|
272
|
+
"card_radius": "--vts-tag-card-radius",
|
|
273
|
+
"card_gap": "--vts-tag-card-gap",
|
|
274
|
+
"card_idle_bg": "--vts-tag-card-idle-bg",
|
|
275
|
+
"card_active_bg": "--vts-tag-card-active-bg",
|
|
276
|
+
"card_hover_bg": "--vts-tag-card-hover-bg",
|
|
277
|
+
"card_active_text": "--vts-tag-card-active-text",
|
|
278
|
+
"card_idle_text": "--vts-tag-card-idle-text",
|
|
279
|
+
"card_close_color": "--vts-tag-card-close-color"
|
|
280
|
+
},
|
|
281
|
+
"custom_style_map": {
|
|
282
|
+
"padding_x": "padding-inline",
|
|
283
|
+
"divider_color": "border-left-color",
|
|
284
|
+
"close_size": "font-size",
|
|
285
|
+
"close_hover_color": "color"
|
|
286
|
+
},
|
|
287
|
+
"$note": "card 形态专属令牌挂在父级 admin.layout.tabs 的 css_vars(整组切换);本条目为页签项级字段补充。chrome 形态梯形样式为模板结构样式,不走样式映射"
|
|
288
|
+
},
|
|
289
|
+
"admin.layout.tabs.context_menu": {
|
|
290
|
+
"type": "element",
|
|
291
|
+
"selector": ".tags-view .tags-options",
|
|
292
|
+
"file": "src/layout/components/lay-tag/index.vue(右键菜单容器)",
|
|
293
|
+
"style_scope": ".tags-view",
|
|
294
|
+
"$comment": "设计侧描述(unified-framework §3):右键菜单含刷新/关闭左侧/关闭右侧/关闭其他,宽 160px,圆角 8px。vue3-web-temp 实证容器类名为 .tags-options(lay-tag/index.vue 结构实证)",
|
|
295
|
+
"css_vars": {
|
|
296
|
+
"radius": "--el-popper-border-radius",
|
|
297
|
+
"item_height": "--el-dropdown-menuItem-height"
|
|
298
|
+
},
|
|
299
|
+
"custom_style_map": {
|
|
300
|
+
"width": "width",
|
|
301
|
+
"bg": "background-color",
|
|
302
|
+
"item_font_size": "font-size"
|
|
303
|
+
},
|
|
304
|
+
"$note": "item_height 若 EP 未暴露 popper 级变量,AI 施工时以 .tags-options li { height } 自定义实现并回写本条目——两层机制天然兜底"
|
|
305
|
+
},
|
|
306
|
+
"admin.layout.content": {
|
|
307
|
+
"type": "module",
|
|
308
|
+
"selector": ".app-main",
|
|
309
|
+
"file": "src/layout/components/lay-content/index.vue",
|
|
310
|
+
"style_scope": ".app-main",
|
|
311
|
+
"css_vars": {
|
|
312
|
+
"padding": "--layout-content-padding"
|
|
313
|
+
},
|
|
314
|
+
"custom_style_map": {
|
|
315
|
+
"bg": "background-color"
|
|
316
|
+
},
|
|
317
|
+
"$note": "内容区高度链为壳层定高体系(vts-page-card/vts-page-fill),业务页面布局语义见 content.* 语义 ID"
|
|
318
|
+
},
|
|
319
|
+
"admin.layout.footer": {
|
|
320
|
+
"type": "module",
|
|
321
|
+
"selector": ".main-content 之后的 footer 区(出厂未常驻渲染)",
|
|
322
|
+
"file": "—",
|
|
323
|
+
"style_scope": ":root",
|
|
324
|
+
"visible_prop": "HideFooter(platform-config.json)",
|
|
325
|
+
"css_vars": {
|
|
326
|
+
"height": "--layout-footer-height"
|
|
327
|
+
},
|
|
328
|
+
"custom_style_map": {}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qilitt-mickey/vue3-temp-skill",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.36",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Vue 3 企业级中后台项目开发规范技能包 — core-kernel 架构、按需功能模块",
|
|
5
6
|
"bin": {
|
|
6
7
|
"vue3-temp-skill": "./bin/cli.js"
|
|
@@ -13,6 +14,9 @@
|
|
|
13
14
|
"bin/",
|
|
14
15
|
"references/",
|
|
15
16
|
"scripts/",
|
|
17
|
+
"mapping/",
|
|
18
|
+
"parser/",
|
|
19
|
+
"dist/",
|
|
16
20
|
"SKILL.md",
|
|
17
21
|
"README.md"
|
|
18
22
|
],
|
|
@@ -25,12 +29,12 @@
|
|
|
25
29
|
"release:major": "node release.js major",
|
|
26
30
|
"check": "node scripts/check.mjs",
|
|
27
31
|
"prepack": "node scripts/check.mjs",
|
|
28
|
-
"audit": "node scripts/field-schema-audit.mjs",
|
|
29
32
|
"validate": "node scripts/validate.mjs",
|
|
30
33
|
"match": "python scripts/match.py",
|
|
31
34
|
"match:batch": "python scripts/match.py --batch",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
35
|
+
"mapping:build": "node parser/index.js build",
|
|
36
|
+
"mapping:watch": "node parser/watch.js",
|
|
37
|
+
"regression": "node parser/regression.js",
|
|
34
38
|
"postpublish": "echo 'Published @qilitt-mickey/vue3-temp-skill to npmjs.org'"
|
|
35
39
|
},
|
|
36
40
|
"keywords": [
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "端到端验证夹具 · 旧协议兼容:v0.2 曾用的顶层 layout 键(应触发告警但按值处理)+ 历史值 schema design-changeset/v1(应告警不阻断)。预期 exit 0 + 两条 ⚠ 告警。",
|
|
3
|
+
"schema": "design-changeset/v1",
|
|
4
|
+
"changeset_version": "0.2.0",
|
|
5
|
+
"mapping_version": "1.0.0",
|
|
6
|
+
"scene": "admin",
|
|
7
|
+
"layout": "mix",
|
|
8
|
+
"changes": [
|
|
9
|
+
{ "id": "admin.layout.tabs", "style": { "card_radius": "小圆角" } }
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "端到端验证夹具 · 负例 1:缺 schema + 禁词/hex 位置违规 + 非法 ID。预期被 parser 阻断(exit 1,输出违规清单:缺 mapping_version 提示会在 schema 检查前?不会——schema 先检)。注意本夹具故意缺 schema 与 mapping_version:parser 应在第一步 schema 校验即拒绝。",
|
|
3
|
+
"changeset_version": "1.0.0",
|
|
4
|
+
"scene": "admin",
|
|
5
|
+
"changes": [
|
|
6
|
+
{
|
|
7
|
+
"id": "admin.layout.sidebar.menu",
|
|
8
|
+
"position": "left 20px margin-left .sidebar",
|
|
9
|
+
"form": "card",
|
|
10
|
+
"style": { "menu_bg": "#1d223a" }
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "admin.content.sidebar.ElMenu",
|
|
14
|
+
"style": { "bg": "红色" }
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "端到端验证夹具 · 负例 2:mapping_version 不匹配。预期被 parser 拒绝(exit 1,提示当前映射集版本与依赖版本不一致)。",
|
|
3
|
+
"schema": "design.changeset/1.0",
|
|
4
|
+
"changeset_version": "1.0.0",
|
|
5
|
+
"mapping_version": "9.9.9",
|
|
6
|
+
"scene": "admin",
|
|
7
|
+
"changes": [
|
|
8
|
+
{ "id": "admin.layout.tabs", "form": "card" }
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "端到端验证夹具 · 负例 3:禁词/非法 ID/位置违规(schema 与版本均合法,专测 checkBannedWords)。预期被阻断并列出:position 含 .sidebar 选择器写法与像素坐标、id 含 ElMenu 技术词与大写、id 不符合命名规范。",
|
|
3
|
+
"schema": "design.changeset/1.0",
|
|
4
|
+
"changeset_version": "1.0.0",
|
|
5
|
+
"mapping_version": "1.0.0",
|
|
6
|
+
"scene": "admin",
|
|
7
|
+
"changes": [
|
|
8
|
+
{
|
|
9
|
+
"id": "admin.layout.sidebar.menu",
|
|
10
|
+
"position": "left 20px .sidebar-container",
|
|
11
|
+
"style": { "menu_bg": "#1d223a" }
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "admin.content.sidebar.ElMenu",
|
|
15
|
+
"style": { "bg": "红色" }
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "admin.layout.tabs.item.v2.extra",
|
|
19
|
+
"style": { "padding_x": "宽松" }
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "端到端验证夹具 · 正例:语义值 + 临时主题 hex + pending + layout_type + global 全通道覆盖。预期全部通过(L1/L2 命中、钴蓝-5→#245BFF 译表解析、pending 携带功能描述、无阻断)。运行:node parser/index.js match parser/fixtures/changeset-pos.json(cwd 为 skill 根)。",
|
|
3
|
+
"schema": "design.changeset/1.0",
|
|
4
|
+
"changeset_version": "1.0.0",
|
|
5
|
+
"mapping_version": "1.0.0",
|
|
6
|
+
"scene": "admin",
|
|
7
|
+
"layout_type": "horizontal",
|
|
8
|
+
"global": { "brand_primary": "钴蓝-5" },
|
|
9
|
+
"changes": [
|
|
10
|
+
{
|
|
11
|
+
"id": "admin.layout.sidebar.menu",
|
|
12
|
+
"style": { "menu_bg": "钴蓝-9", "menu_active_bg": "钴蓝-5" }
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "component.button.primary",
|
|
16
|
+
"style": { "bg_color": "钴蓝-5", "font_weight": "中等" }
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "admin.layout.tabs",
|
|
20
|
+
"form": "card"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "admin.layout.sidebar.collapse_trigger",
|
|
24
|
+
"visible": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "portal.content.banner.carousel",
|
|
28
|
+
"style": { "bg": "#7C3AED" }
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "admin.layout.header.user_profile",
|
|
32
|
+
"style": { "avatar_radius": "全圆角", "unknown_field": "应进字段级待补充" }
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"pending": [
|
|
36
|
+
{
|
|
37
|
+
"proposed_id": "portal.content.banner.carousel",
|
|
38
|
+
"function": "门户首页顶部轮播横幅",
|
|
39
|
+
"parent": "portal.content.banner"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"notes": "临时主题:主色 #7C3AED,hover 取 85% 不透明度"
|
|
43
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generator.js — 多格式产物生成器
|
|
3
|
+
*
|
|
4
|
+
* 校验通过后,从 mapping/ 数据集生成 dist/ 下四种可交付产物:
|
|
5
|
+
* 1. dist/theme.css CSS 变量全局基线(:root 层,链路 A 空白项目按需引入)
|
|
6
|
+
* 2. dist/theme-vars.ts TypeScript 类型化主题变量对象
|
|
7
|
+
* 3. dist/theme-vars.js ESM 运行时入口(themeVars + overrideMapping,§3.4.4.3)
|
|
8
|
+
* 4. dist/mapping-type.d.ts 映射类型声明
|
|
9
|
+
*
|
|
10
|
+
* 链路 A(业务项目直接消费产物)按 V3.1 §4.5.3 后置:产物随 NPM 包发布但不被
|
|
11
|
+
* vue3-web-temp 引入(其自有 design-tokens.scss 为权威令牌源,避免双令牌源冲突)。
|
|
12
|
+
*
|
|
13
|
+
* 用法:node parser/generator.js [--out <dir>] [--dry]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { mkdirSync, writeFileSync, existsSync } from "node:fs";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
import { buildMappingDataset } from "./loader.js";
|
|
20
|
+
import { buildMergedIndex } from "./validator.js";
|
|
21
|
+
|
|
22
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const ROOT = path.resolve(__dirname, "..");
|
|
24
|
+
|
|
25
|
+
// ---- CLI ----
|
|
26
|
+
if (process.argv[1] && process.argv[1].endsWith("generator.js")) {
|
|
27
|
+
const outIdx = process.argv.indexOf("--out");
|
|
28
|
+
const outDir = outIdx > -1 ? path.resolve(process.argv[outIdx + 1]) : path.join(ROOT, "dist");
|
|
29
|
+
const dry = process.argv.includes("--dry");
|
|
30
|
+
const result = generateAll(outDir, dry);
|
|
31
|
+
if (!dry) {
|
|
32
|
+
console.log(`✔ 产物生成完成 → ${outDir}`);
|
|
33
|
+
for (const f of result.written)
|
|
34
|
+
console.log(` · ${f}`);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(`[dry-run] 将生成 ${result.written.length} 个文件 → ${outDir}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** 汇总所有 tokens(basic/layout 域的令牌定义),返回 { abstractField, token, default } 数组 */
|
|
42
|
+
export function collectTokens(dataset) {
|
|
43
|
+
const rows = [];
|
|
44
|
+
for (const [file, data] of Object.entries(dataset.files)) {
|
|
45
|
+
if (!data.tokens)
|
|
46
|
+
continue;
|
|
47
|
+
for (const [field, def] of Object.entries(data.tokens)) {
|
|
48
|
+
if (field.startsWith("$"))
|
|
49
|
+
continue;
|
|
50
|
+
// token 链("A → B")拆为数组:链上每个实现令牌都要生成
|
|
51
|
+
const tokenChain = typeof def.token === "string" && def.token.includes(" → ")
|
|
52
|
+
? def.token.split(" → ").map(s => s.trim()).filter(Boolean)
|
|
53
|
+
: [def.token || ""];
|
|
54
|
+
rows.push({
|
|
55
|
+
abstract: field,
|
|
56
|
+
token: tokenChain[0],
|
|
57
|
+
tokenChain,
|
|
58
|
+
default: def.default ?? "",
|
|
59
|
+
file,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return rows;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function generateAll(outDir, dry = false) {
|
|
67
|
+
const dataset = buildMappingDataset();
|
|
68
|
+
const tokens = collectTokens(dataset);
|
|
69
|
+
const written = [];
|
|
70
|
+
|
|
71
|
+
// ---- 1. theme.css:链路 A 变量基线(V3.1 §4.5.3)----
|
|
72
|
+
// 有出厂值的令牌生成真实 CSS 自定义属性(空白项目引入即得完整基线);
|
|
73
|
+
// 无出厂值的仅生成注释索引(需项目侧自行定值)。
|
|
74
|
+
const cssBody = [];
|
|
75
|
+
for (const t of tokens) {
|
|
76
|
+
if (!t.default) {
|
|
77
|
+
cssBody.push(` /* ${t.abstract} → ${t.token || "(value token)"}(无出厂值,需项目侧定值) */`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
for (const token of t.tokenChain) {
|
|
81
|
+
if (!token)
|
|
82
|
+
continue;
|
|
83
|
+
cssBody.push(` ${token}: ${t.default}; /* ← ${t.abstract} */`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const cssLines = [
|
|
87
|
+
"/* AUTO-GENERATED by vue3-temp-skill parser/generator.js — DO NOT EDIT */",
|
|
88
|
+
"/* 链路 A(基线注入)产物:全局令牌变量基线(V3.1 §4.5.3)。",
|
|
89
|
+
" * 仅空白新项目从零接入 Skill 主题体系时在样式入口引入一次;",
|
|
90
|
+
" * 成熟模板项目(自有 design-tokens.scss 权威令牌源)不得引入,避免双令牌源冲突。 */",
|
|
91
|
+
":root {",
|
|
92
|
+
...cssBody,
|
|
93
|
+
"}",
|
|
94
|
+
"",
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
// ---- 2. theme-vars.ts:类型化变量对象 ----
|
|
98
|
+
const tsLines = [
|
|
99
|
+
"// AUTO-GENERATED by vue3-temp-skill parser/generator.js — DO NOT EDIT",
|
|
100
|
+
"export const themeVars = {",
|
|
101
|
+
...tokens.map(t => ` /** ${t.tokenChain.join(" → ") || "value token"}${t.default ? ` 出厂 ${t.default}` : ""} */`),
|
|
102
|
+
...tokens.map(t => ` ${toCamel(t.abstract)}: '${t.default}' as string,`),
|
|
103
|
+
"} as const;",
|
|
104
|
+
"",
|
|
105
|
+
"export type ThemeVarKey = keyof typeof themeVars;",
|
|
106
|
+
"",
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
// ---- 2.5 theme-vars.js:ESM 运行时入口(链路 A 配套,业务级覆写 API 挂载点 §3.4.4.3)----
|
|
110
|
+
const jsLines = [
|
|
111
|
+
"// AUTO-GENERATED by vue3-temp-skill parser/generator.js — DO NOT EDIT",
|
|
112
|
+
"// 链路 A 运行时入口:themeVars + overrideMapping(业务级覆写,V3.1 §3.4.4.3)",
|
|
113
|
+
"// 用法:import { themeVars, overrideMapping } from '@qilitt-mickey/vue3-temp-skill/dist/theme-vars.js';",
|
|
114
|
+
"// const custom = overrideMapping(themeVars, { color: { brandPrimary: '#ff6600' } });",
|
|
115
|
+
"export const themeVars = {",
|
|
116
|
+
...tokens.map(t => ` ${toCamel(t.abstract)}: '${t.default}',`),
|
|
117
|
+
"};",
|
|
118
|
+
"",
|
|
119
|
+
"export { overrideMapping, overrideMappings } from '../parser/override.js';",
|
|
120
|
+
"",
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
// ---- 3. mapping-type.d.ts:映射条目类型声明 ----
|
|
124
|
+
const dtsLines = [
|
|
125
|
+
"// AUTO-GENERATED by vue3-temp-skill parser/generator.js — DO NOT EDIT",
|
|
126
|
+
"",
|
|
127
|
+
"/** 语义 ID 映射条目(结构与 mapping/scenes/**.json 条目一致) */",
|
|
128
|
+
"export interface SemanticMappingEntry {",
|
|
129
|
+
" type: 'module' | 'component' | 'element' | 'global_component' | 'global_token';",
|
|
130
|
+
" selector?: string;",
|
|
131
|
+
" component?: string;",
|
|
132
|
+
" file?: string;",
|
|
133
|
+
" style_scope: string;",
|
|
134
|
+
" default_props?: Record<string, unknown>;",
|
|
135
|
+
" children?: string[];",
|
|
136
|
+
" forms?: Record<string, string>;",
|
|
137
|
+
" visible_prop?: string;",
|
|
138
|
+
" css_vars?: Record<string, string>;",
|
|
139
|
+
" custom_style_map?: Record<string, string>;",
|
|
140
|
+
" [key: string]: unknown;",
|
|
141
|
+
"}",
|
|
142
|
+
"",
|
|
143
|
+
"/** 设计变更集(design.changeset/1.0 输入,兼容历史值 design-changeset/v1) */",
|
|
144
|
+
"export interface DesignChangeset {",
|
|
145
|
+
" schema: 'design.changeset/1.0' | 'design-changeset/v1';",
|
|
146
|
+
" mapping_version?: string;",
|
|
147
|
+
" scene: string;",
|
|
148
|
+
" layout_type?: string;",
|
|
149
|
+
" global?: Record<string, Record<string, string | number>>;",
|
|
150
|
+
" changes: Array<{",
|
|
151
|
+
" id: string;",
|
|
152
|
+
" visible?: boolean;",
|
|
153
|
+
" position?: Record<string, string>;",
|
|
154
|
+
" form?: string;",
|
|
155
|
+
" style?: Record<string, string | number>;",
|
|
156
|
+
" }>;",
|
|
157
|
+
"}",
|
|
158
|
+
"",
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
if (!dry) {
|
|
162
|
+
mkdirSync(outDir, { recursive: true });
|
|
163
|
+
writeFileSync(path.join(outDir, "theme.css"), cssLines.join("\n"), "utf-8");
|
|
164
|
+
writeFileSync(path.join(outDir, "theme-vars.ts"), tsLines.join("\n"), "utf-8");
|
|
165
|
+
writeFileSync(path.join(outDir, "theme-vars.js"), jsLines.join("\n"), "utf-8");
|
|
166
|
+
writeFileSync(path.join(outDir, "mapping-type.d.ts"), dtsLines.join("\n"), "utf-8");
|
|
167
|
+
written.push("theme.css", "theme-vars.ts", "theme-vars.js", "mapping-type.d.ts");
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
written.push("theme.css", "theme-vars.ts", "theme-vars.js", "mapping-type.d.ts");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { written, tokenCount: tokens.length };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function toCamel(s) {
|
|
177
|
+
return s.replaceAll(/[_-](\w)/g, (_, c) => c.toUpperCase());
|
|
178
|
+
}
|