king-design-analyzer 2.2.2 → 2.2.3

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.
@@ -0,0 +1,100 @@
1
+ {
2
+ "id": "aside",
3
+ "name": "Aside",
4
+ "displayName": "侧边栏",
5
+ "category": "layout",
6
+ "description": "布局侧边栏组件,适合承载导航菜单或辅助信息区域,可配置固定定位和折叠宽度。",
7
+ "importStatement": "import { Aside } from '@king-design/vue';",
8
+ "props": [
9
+ {
10
+ "name": "collapse",
11
+ "description": "是否处于折叠状态。",
12
+ "type": {
13
+ "raw": "boolean",
14
+ "kind": "boolean"
15
+ },
16
+ "required": false,
17
+ "default": "false",
18
+ "usageExample": "<Aside collapse>折叠菜单</Aside>"
19
+ },
20
+ {
21
+ "name": "fixed",
22
+ "description": "是否固定在页面左侧。",
23
+ "type": {
24
+ "raw": "boolean",
25
+ "kind": "boolean"
26
+ },
27
+ "required": false,
28
+ "default": "false",
29
+ "usageExample": "<Aside fixed>固定侧边栏</Aside>"
30
+ },
31
+ {
32
+ "name": "theme",
33
+ "description": "侧边栏主题,沿用 Menu 组件的主题配置。",
34
+ "type": {
35
+ "raw": "MenuProps['theme']",
36
+ "kind": "custom"
37
+ },
38
+ "required": false,
39
+ "default": "\"light\"",
40
+ "usageExample": "<Aside theme=\"dark\">深色侧边栏</Aside>"
41
+ },
42
+ {
43
+ "name": "width",
44
+ "description": "侧边栏宽度,支持数字或带单位的字符串。",
45
+ "type": {
46
+ "raw": "number | string",
47
+ "kind": "union"
48
+ },
49
+ "required": false,
50
+ "default": "240",
51
+ "usageExample": "<Aside :width=\"220\">自定义宽度</Aside>"
52
+ },
53
+ {
54
+ "name": "collapsedWidth",
55
+ "description": "折叠状态下的宽度。",
56
+ "type": {
57
+ "raw": "number | string",
58
+ "kind": "union"
59
+ },
60
+ "required": false,
61
+ "default": "64",
62
+ "usageExample": "<Aside :collapsedWidth=\"56\" collapse>折叠侧边栏</Aside>"
63
+ }
64
+ ],
65
+ "events": [],
66
+ "slots": [
67
+ {
68
+ "name": "default",
69
+ "description": "侧边栏内容,通常放置菜单、品牌信息或辅助操作。",
70
+ "bindingType": "none",
71
+ "vueTemplate": "#default",
72
+ "usageExample": "<Aside>\n <Menu>\n <MenuItem key=\"1\">概览</MenuItem>\n </Menu>\n</Aside>"
73
+ }
74
+ ],
75
+ "methods": [],
76
+ "examples": [
77
+ {
78
+ "id": "aside_basic",
79
+ "title": "基础侧边栏",
80
+ "description": "在布局中放置导航菜单。",
81
+ "difficulty": "easy",
82
+ "code": "<script setup lang=\"ts\">\nimport { Layout, Aside, Body, Menu, MenuItem } from '@king-design/vue';\n</script>\n<template>\n <Layout>\n <Aside :width=\"220\">\n <Menu>\n <MenuItem key=\"overview\">概览</MenuItem>\n <MenuItem key=\"instance\">实例列表</MenuItem>\n </Menu>\n </Aside>\n <Body>\n <div style=\"padding: 16px;\">内容区域</div>\n </Body>\n </Layout>\n</template>",
83
+ "tags": [
84
+ "aside",
85
+ "menu"
86
+ ],
87
+ "usedProps": [
88
+ "width"
89
+ ],
90
+ "usedEvents": [],
91
+ "usedMethods": [],
92
+ "scenario": "在后台布局中承载主导航菜单。"
93
+ }
94
+ ],
95
+ "relatedComponents": [
96
+ "Layout",
97
+ "Body",
98
+ "Menu"
99
+ ]
100
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "id": "body",
3
+ "name": "Body",
4
+ "displayName": "布局主体",
5
+ "category": "layout",
6
+ "description": "布局主体容器,用于承载页面主要内容区域,通常与 Header、Aside 组合使用。",
7
+ "importStatement": "import { Body } from '@king-design/vue';",
8
+ "props": [],
9
+ "events": [],
10
+ "slots": [
11
+ {
12
+ "name": "default",
13
+ "description": "主体内容区域。",
14
+ "bindingType": "none",
15
+ "vueTemplate": "#default",
16
+ "usageExample": "<Body>\n <div style=\"padding: 16px;\">页面主体内容</div>\n</Body>"
17
+ }
18
+ ],
19
+ "methods": [],
20
+ "examples": [
21
+ {
22
+ "id": "body_basic",
23
+ "title": "主体内容区",
24
+ "description": "在布局中承载页面正文。",
25
+ "difficulty": "easy",
26
+ "code": "<script setup lang=\"ts\">\nimport { Layout, Header, Body } from '@king-design/vue';\n</script>\n<template>\n <Layout>\n <Header>实例管理</Header>\n <Body>\n <div style=\"padding: 16px;\">这里放页面内容</div>\n </Body>\n </Layout>\n</template>",
27
+ "tags": [
28
+ "body",
29
+ "content"
30
+ ],
31
+ "usedProps": [],
32
+ "usedEvents": [],
33
+ "usedMethods": [],
34
+ "scenario": "作为后台页面的主要内容承载区域。"
35
+ }
36
+ ],
37
+ "relatedComponents": [
38
+ "Layout",
39
+ "Header",
40
+ "Aside",
41
+ "Footer"
42
+ ]
43
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "id": "footer",
3
+ "name": "Footer",
4
+ "displayName": "布局底部",
5
+ "category": "layout",
6
+ "description": "布局底部组件,适合展示版权、说明信息或页面级辅助操作。",
7
+ "importStatement": "import { Footer } from '@king-design/vue';",
8
+ "props": [],
9
+ "events": [],
10
+ "slots": [
11
+ {
12
+ "name": "default",
13
+ "description": "底部内容区域。",
14
+ "bindingType": "none",
15
+ "vueTemplate": "#default",
16
+ "usageExample": "<Footer>\n Copyright 2026 Kingsoft Cloud\n</Footer>"
17
+ }
18
+ ],
19
+ "methods": [],
20
+ "examples": [
21
+ {
22
+ "id": "footer_basic",
23
+ "title": "基础底部",
24
+ "description": "展示底部版权或补充说明。",
25
+ "difficulty": "easy",
26
+ "code": "<script setup lang=\"ts\">\nimport { Layout, Body, Footer } from '@king-design/vue';\n</script>\n<template>\n <Layout>\n <Body>\n <div style=\"padding: 16px; min-height: 200px;\">内容区域</div>\n </Body>\n <Footer>\n Copyright 2026 Kingsoft Cloud\n </Footer>\n </Layout>\n</template>",
27
+ "tags": [
28
+ "footer"
29
+ ],
30
+ "usedProps": [],
31
+ "usedEvents": [],
32
+ "usedMethods": [],
33
+ "scenario": "在控制台页面底部展示版权或补充提示。"
34
+ }
35
+ ],
36
+ "relatedComponents": [
37
+ "Layout",
38
+ "Body"
39
+ ]
40
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "id": "layout",
3
+ "name": "Layout",
4
+ "displayName": "布局容器",
5
+ "category": "layout",
6
+ "description": "页面整体布局容器,用于组合 Header、Aside、Body、Footer 等区域,构建后台或工作台页面结构。",
7
+ "importStatement": "import { Layout } from '@king-design/vue';",
8
+ "props": [],
9
+ "events": [],
10
+ "slots": [
11
+ {
12
+ "name": "default",
13
+ "description": "布局内容区域,通常放置 Header、Aside、Body、Footer 组件。",
14
+ "bindingType": "none",
15
+ "vueTemplate": "#default",
16
+ "usageExample": "<Layout>\n <Header />\n <Body>内容区</Body>\n</Layout>"
17
+ }
18
+ ],
19
+ "methods": [],
20
+ "examples": [
21
+ {
22
+ "id": "layout_basic",
23
+ "title": "基础布局",
24
+ "description": "组合头部、侧边栏和内容区,构建典型后台页面布局。",
25
+ "difficulty": "easy",
26
+ "code": "<script setup lang=\"ts\">\nimport { Layout, Header, Aside, Body, Footer } from '@king-design/vue';\n</script>\n<template>\n <Layout>\n <Header>控制台</Header>\n <Layout>\n <Aside>导航菜单</Aside>\n <Body>\n <div style=\"padding: 16px;\">页面内容</div>\n </Body>\n </Layout>\n <Footer>Copyright 2026</Footer>\n </Layout>\n</template>",
27
+ "tags": [
28
+ "layout",
29
+ "basic"
30
+ ],
31
+ "usedProps": [],
32
+ "usedEvents": [],
33
+ "usedMethods": [],
34
+ "scenario": "用于管理后台和工作台页面的整体结构搭建。"
35
+ }
36
+ ],
37
+ "searchKeywords": [
38
+ "layout",
39
+ "页面布局",
40
+ "布局容器"
41
+ ],
42
+ "useCases": [
43
+ "后台布局",
44
+ "控制台页面",
45
+ "工作台页面"
46
+ ],
47
+ "relatedComponents": [
48
+ "Header",
49
+ "Aside",
50
+ "Body",
51
+ "Footer"
52
+ ]
53
+ }
@@ -0,0 +1,113 @@
1
+ {
2
+ "id": "layout-header",
3
+ "name": "Header",
4
+ "displayName": "布局头部",
5
+ "category": "layout",
6
+ "description": "布局头部组件,常用于放置站点标题、全局导航和操作入口,可配置固定定位、主题和毛玻璃效果。",
7
+ "importStatement": "import { Header } from '@king-design/vue';",
8
+ "props": [
9
+ {
10
+ "name": "fixed",
11
+ "description": "是否固定在页面顶部。",
12
+ "type": {
13
+ "raw": "boolean",
14
+ "kind": "boolean"
15
+ },
16
+ "required": false,
17
+ "default": "false",
18
+ "usageExample": "<Header fixed>固定头部</Header>"
19
+ },
20
+ {
21
+ "name": "height",
22
+ "description": "头部高度,支持数字或带单位的字符串。",
23
+ "type": {
24
+ "raw": "number | string",
25
+ "kind": "union"
26
+ },
27
+ "required": false,
28
+ "default": "64",
29
+ "usageExample": "<Header :height=\"56\">紧凑头部</Header>"
30
+ },
31
+ {
32
+ "name": "style",
33
+ "description": "自定义内联样式。",
34
+ "type": {
35
+ "raw": "string | Record<string, string>",
36
+ "kind": "union"
37
+ },
38
+ "required": false,
39
+ "default": "undefined",
40
+ "usageExample": "<Header :style=\"{ background: '#fff' }\">自定义样式</Header>"
41
+ },
42
+ {
43
+ "name": "theme",
44
+ "description": "头部主题,沿用 Menu 组件的主题配置。",
45
+ "type": {
46
+ "raw": "MenuProps['theme']",
47
+ "kind": "custom"
48
+ },
49
+ "required": false,
50
+ "default": "\"light\"",
51
+ "usageExample": "<Header theme=\"dark\">深色头部</Header>"
52
+ },
53
+ {
54
+ "name": "blur",
55
+ "description": "是否开启毛玻璃背景效果。",
56
+ "type": {
57
+ "raw": "boolean",
58
+ "kind": "boolean"
59
+ },
60
+ "required": false,
61
+ "default": "false",
62
+ "usageExample": "<Header blur>毛玻璃头部</Header>"
63
+ },
64
+ {
65
+ "name": "boxShadow",
66
+ "description": "是否展示底部阴影。",
67
+ "type": {
68
+ "raw": "boolean",
69
+ "kind": "boolean"
70
+ },
71
+ "required": false,
72
+ "default": "false",
73
+ "usageExample": "<Header boxShadow>带阴影头部</Header>"
74
+ }
75
+ ],
76
+ "events": [],
77
+ "slots": [
78
+ {
79
+ "name": "default",
80
+ "description": "头部内容区域,通常放置 Logo、导航或操作按钮。",
81
+ "bindingType": "none",
82
+ "vueTemplate": "#default",
83
+ "usageExample": "<Header>\n <div style=\"display: flex; justify-content: space-between;\">控制台<header-actions /></div>\n</Header>"
84
+ }
85
+ ],
86
+ "methods": [],
87
+ "examples": [
88
+ {
89
+ "id": "layout_header_basic",
90
+ "title": "基础布局头部",
91
+ "description": "作为站点或控制台的全局顶部栏。",
92
+ "difficulty": "easy",
93
+ "code": "<script setup lang=\"ts\">\nimport { Layout, Header, Body, Button } from '@king-design/vue';\n</script>\n<template>\n <Layout>\n <Header fixed theme=\"dark\" :height=\"56\">\n <div style=\"display: flex; align-items: center; justify-content: space-between; height: 100%; padding: 0 16px;\">\n <span>控制台</span>\n <Button type=\"primary\">新建资源</Button>\n </div>\n </Header>\n <Body>\n <div style=\"padding: 16px;\">页面内容</div>\n </Body>\n </Layout>\n</template>",
94
+ "tags": [
95
+ "header",
96
+ "layout"
97
+ ],
98
+ "usedProps": [
99
+ "fixed",
100
+ "theme",
101
+ "height"
102
+ ],
103
+ "usedEvents": [],
104
+ "usedMethods": [],
105
+ "scenario": "用于后台系统的全局固定顶部栏。"
106
+ }
107
+ ],
108
+ "relatedComponents": [
109
+ "Layout",
110
+ "Body",
111
+ "Aside"
112
+ ]
113
+ }
@@ -172,6 +172,17 @@
172
172
  "required": false,
173
173
  "default": "undefined",
174
174
  "usageExample": "<Transfer :enableRemove=\"canRemove\"></Transfer>"
175
+ },
176
+ {
177
+ "name": "pagination",
178
+ "description": "是否启用左右面板分页,也可以传入 Pagination 的配置对象来自定义页码和每页条数。",
179
+ "type": {
180
+ "raw": "boolean | PaginationProps",
181
+ "kind": "union"
182
+ },
183
+ "required": false,
184
+ "default": "false",
185
+ "usageExample": "<Transfer :pagination=\"{ value: 1, limit: 10 }\"></Transfer>"
175
186
  }
176
187
  ],
177
188
  "events": [
@@ -84,6 +84,9 @@ interface ComponentSubComponent {
84
84
  interface ComponentMetadata {
85
85
  id?: string;
86
86
  name: string;
87
+ fileName?: string;
88
+ source?: string;
89
+ importSource?: string;
87
90
  props: ComponentProp[];
88
91
  events: ComponentEvent[];
89
92
  slots: ComponentSlot[];
@@ -117,6 +120,7 @@ declare class ComponentRegistry {
117
120
  * 重新加载所有组件元数据
118
121
  */
119
122
  reload(): Promise<void>;
123
+ private appendComponent;
120
124
  /**
121
125
  * 开始监听文件变化
122
126
  */
@@ -125,9 +129,10 @@ declare class ComponentRegistry {
125
129
  * 停止监听
126
130
  */
127
131
  stopWatching(): void;
128
- getComponent(name: string): ComponentMetadata | undefined;
132
+ getComponent(name: string, importSource?: string): ComponentMetadata | undefined;
133
+ getComponents(name: string): ComponentMetadata[];
129
134
  getAllComponentNames(): string[];
130
- isKnownComponent(name: string): boolean;
135
+ isKnownComponent(name: string, importSource?: string): boolean;
131
136
  }
132
137
  declare const componentRegistry: ComponentRegistry;
133
138
 
@@ -84,6 +84,9 @@ interface ComponentSubComponent {
84
84
  interface ComponentMetadata {
85
85
  id?: string;
86
86
  name: string;
87
+ fileName?: string;
88
+ source?: string;
89
+ importSource?: string;
87
90
  props: ComponentProp[];
88
91
  events: ComponentEvent[];
89
92
  slots: ComponentSlot[];
@@ -117,6 +120,7 @@ declare class ComponentRegistry {
117
120
  * 重新加载所有组件元数据
118
121
  */
119
122
  reload(): Promise<void>;
123
+ private appendComponent;
120
124
  /**
121
125
  * 开始监听文件变化
122
126
  */
@@ -125,9 +129,10 @@ declare class ComponentRegistry {
125
129
  * 停止监听
126
130
  */
127
131
  stopWatching(): void;
128
- getComponent(name: string): ComponentMetadata | undefined;
132
+ getComponent(name: string, importSource?: string): ComponentMetadata | undefined;
133
+ getComponents(name: string): ComponentMetadata[];
129
134
  getAllComponentNames(): string[];
130
- isKnownComponent(name: string): boolean;
135
+ isKnownComponent(name: string, importSource?: string): boolean;
131
136
  }
132
137
  declare const componentRegistry: ComponentRegistry;
133
138
 
package/dist/ast/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  require('../chunk-YTEYDSDW.js');
4
- var chunkXPHDD6XR_js = require('../chunk-XPHDD6XR.js');
4
+ var chunkK6UQSWLC_js = require('../chunk-K6UQSWLC.js');
5
5
  require('../chunk-KF5YBEM5.js');
6
6
  require('../chunk-JSBRDJBE.js');
7
7
 
@@ -9,9 +9,9 @@ require('../chunk-JSBRDJBE.js');
9
9
 
10
10
  Object.defineProperty(exports, "analyzeCodeWithAST", {
11
11
  enumerable: true,
12
- get: function () { return chunkXPHDD6XR_js.analyzeCodeWithAST; }
12
+ get: function () { return chunkK6UQSWLC_js.analyzeCodeWithAST; }
13
13
  });
14
14
  Object.defineProperty(exports, "componentRegistry", {
15
15
  enumerable: true,
16
- get: function () { return chunkXPHDD6XR_js.componentRegistry; }
16
+ get: function () { return chunkK6UQSWLC_js.componentRegistry; }
17
17
  });
@@ -1,4 +1,4 @@
1
1
  import '../chunk-5H7N2A5X.mjs';
2
- export { analyzeCodeWithAST, componentRegistry } from '../chunk-YRGYDK2I.mjs';
2
+ export { analyzeCodeWithAST, componentRegistry } from '../chunk-7YBUXYUI.mjs';
3
3
  import '../chunk-QC6VTSA3.mjs';
4
4
  import '../chunk-UJCSKKID.mjs';
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkXPHDD6XR_js = require('./chunk-XPHDD6XR.js');
3
+ var chunkK6UQSWLC_js = require('./chunk-K6UQSWLC.js');
4
4
  var chunkV5N65MRP_js = require('./chunk-V5N65MRP.js');
5
5
  var chunkDHLWNT53_js = require('./chunk-DHLWNT53.js');
6
6
 
@@ -64,7 +64,7 @@ function validateCompilation(code) {
64
64
  }
65
65
  async function validateAST(code) {
66
66
  try {
67
- const violations = await chunkXPHDD6XR_js.analyzeCodeWithAST(code);
67
+ const violations = await chunkK6UQSWLC_js.analyzeCodeWithAST(code);
68
68
  if (violations.length > 0) {
69
69
  return {
70
70
  name: "AST\u89C4\u5219\u68C0\u67E5",
@@ -32208,6 +32208,11 @@ var require_compiler_core = __commonJS({
32208
32208
  function resolveComponentsPath() {
32209
32209
  return resolvePackageResourceDir("components");
32210
32210
  }
32211
+ function extractImportSource(importStatement) {
32212
+ if (!importStatement) return void 0;
32213
+ const match = importStatement.match(/from\s+['"]([^'"]+)['"]/);
32214
+ return match?.[1];
32215
+ }
32211
32216
  var ComponentRegistry = class {
32212
32217
  constructor() {
32213
32218
  this.components = /* @__PURE__ */ new Map();
@@ -32237,16 +32242,25 @@ var ComponentRegistry = class {
32237
32242
  if (!file.endsWith(".json")) continue;
32238
32243
  const content = await fs.readFile(path.join(this.metadataPath, file), "utf-8");
32239
32244
  const data = JSON.parse(content);
32240
- rawComponents[data.name] = data;
32245
+ const importSource = data.importSource || data.source || extractImportSource(data.importStatement);
32246
+ const normalizedData = {
32247
+ ...data,
32248
+ fileName: data.fileName || file.replace(/\.json$/, ""),
32249
+ importSource,
32250
+ source: data.source || importSource
32251
+ };
32252
+ rawComponents[`${normalizedData.fileName}:${normalizedData.name}:${normalizedData.importSource || ""}`] = normalizedData;
32241
32253
  }
32242
32254
  for (const data of Object.values(rawComponents)) {
32243
32255
  const resolvedData = resolveMetadataInheritance(data, rawComponents);
32244
- newComponents.set(resolvedData.name, resolvedData);
32256
+ this.appendComponent(newComponents, resolvedData);
32245
32257
  if (resolvedData.subComponents) {
32246
32258
  for (const sub of resolvedData.subComponents) {
32247
- newComponents.set(sub.name, {
32259
+ this.appendComponent(newComponents, {
32248
32260
  id: sub.name,
32249
32261
  name: sub.name,
32262
+ source: resolvedData.source,
32263
+ importSource: resolvedData.importSource,
32250
32264
  props: sub.props || [],
32251
32265
  events: sub.events || [],
32252
32266
  slots: sub.slots || [],
@@ -32256,11 +32270,17 @@ var ComponentRegistry = class {
32256
32270
  }
32257
32271
  }
32258
32272
  this.components = newComponents;
32259
- console.log(`[ComponentRegistry] ${this.loaded ? "Reloaded" : "Loaded"} ${this.components.size} components.`);
32273
+ const totalEntries = Array.from(this.components.values()).reduce((sum, items) => sum + items.length, 0);
32274
+ console.log(`[ComponentRegistry] ${this.loaded ? "Reloaded" : "Loaded"} ${totalEntries} components.`);
32260
32275
  } catch (error) {
32261
32276
  console.error("[ComponentRegistry] Failed to load metadata:", error);
32262
32277
  }
32263
32278
  }
32279
+ appendComponent(target, metadata) {
32280
+ const current = target.get(metadata.name) || [];
32281
+ current.push(metadata);
32282
+ target.set(metadata.name, current);
32283
+ }
32264
32284
  /**
32265
32285
  * 开始监听文件变化
32266
32286
  */
@@ -32293,14 +32313,28 @@ var ComponentRegistry = class {
32293
32313
  console.log("[ComponentRegistry] Hot reload disabled.");
32294
32314
  }
32295
32315
  }
32296
- getComponent(name) {
32297
- return this.components.get(name);
32316
+ getComponent(name, importSource) {
32317
+ const candidates = this.components.get(name) || [];
32318
+ if (!importSource) return candidates[0];
32319
+ return candidates.find((item) => {
32320
+ const expectedSource = item.importSource || item.source || extractImportSource(item.importStatement);
32321
+ return expectedSource === importSource;
32322
+ }) || candidates[0];
32323
+ }
32324
+ getComponents(name) {
32325
+ return this.components.get(name) || [];
32298
32326
  }
32299
32327
  getAllComponentNames() {
32300
32328
  return Array.from(this.components.keys());
32301
32329
  }
32302
- isKnownComponent(name) {
32303
- return this.components.has(name);
32330
+ isKnownComponent(name, importSource) {
32331
+ if (!importSource) {
32332
+ return this.components.has(name);
32333
+ }
32334
+ return this.getComponents(name).some((item) => {
32335
+ const expectedSource = item.importSource || item.source || extractImportSource(item.importStatement);
32336
+ return expectedSource === importSource;
32337
+ });
32304
32338
  }
32305
32339
  };
32306
32340
  var componentRegistry = new ComponentRegistry();
@@ -32744,6 +32778,7 @@ async function analyzeCodeWithAST(code) {
32744
32778
  await componentRegistry.load();
32745
32779
  await hooksRegistry.load();
32746
32780
  const violations = [];
32781
+ const componentImportContext = /* @__PURE__ */ new Map();
32747
32782
  const { descriptor, errors } = parse(code);
32748
32783
  if (errors.length > 0) {
32749
32784
  return violations;
@@ -32758,12 +32793,12 @@ async function analyzeCodeWithAST(code) {
32758
32793
  );
32759
32794
  ts.forEachChild(sourceFile, (node) => {
32760
32795
  if (ts.isImportDeclaration(node)) {
32761
- checkImport(node, violations, sourceFile);
32796
+ checkImport(node, violations, sourceFile, componentImportContext);
32762
32797
  }
32763
32798
  });
32764
32799
  }
32765
32800
  if (descriptor.template?.ast) {
32766
- checkTemplate(descriptor.template.ast, violations, []);
32801
+ checkTemplate(descriptor.template.ast, violations, [], componentImportContext);
32767
32802
  }
32768
32803
  if (scriptContent && descriptor.template) {
32769
32804
  const scriptBindings = extractScriptBindings(scriptContent);
@@ -32980,6 +33015,7 @@ function isJsKeyword(id) {
32980
33015
  return JS_KEYWORDS.has(id);
32981
33016
  }
32982
33017
  function resolveExpectedImportSource(metadata) {
33018
+ if (metadata.importSource) return metadata.importSource;
32983
33019
  const importStatement = metadata.importStatement || "";
32984
33020
  if (importStatement.includes("@ksyun-internal/versatile")) {
32985
33021
  return "@ksyun-internal/versatile";
@@ -32989,7 +33025,7 @@ function resolveExpectedImportSource(metadata) {
32989
33025
  }
32990
33026
  return null;
32991
33027
  }
32992
- function checkImport(node, violations, sourceFile) {
33028
+ function checkImport(node, violations, sourceFile, componentImportContext) {
32993
33029
  const moduleSpecifier = node.moduleSpecifier.getText(sourceFile).replace(/['\"]/g, "");
32994
33030
  if (moduleSpecifier === "@king-design/vue" || moduleSpecifier === "@ksyun-internal/versatile") {
32995
33031
  const namedBindings = node.importClause?.namedBindings;
@@ -33032,7 +33068,8 @@ function checkImport(node, violations, sourceFile) {
33032
33068
  suggestion: `\u76F4\u63A5\u4F7F\u7528\u539F\u540D: import { ${originalName} } from '${moduleSpecifier}'`
33033
33069
  });
33034
33070
  }
33035
- const metadata = componentRegistry.getComponent(originalName);
33071
+ componentImportContext.set(localName, moduleSpecifier);
33072
+ const metadata = componentRegistry.getComponent(originalName, moduleSpecifier);
33036
33073
  if (metadata) {
33037
33074
  const expectedPackage = resolveExpectedImportSource(metadata);
33038
33075
  if (expectedPackage && expectedPackage !== moduleSpecifier) {
@@ -33043,11 +33080,21 @@ function checkImport(node, violations, sourceFile) {
33043
33080
  });
33044
33081
  }
33045
33082
  } else {
33046
- violations.push({
33047
- rule: "\u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684\u7EC4\u4EF6/\u5BFC\u51FA",
33048
- match: originalName,
33049
- suggestion: `\u8BF7\u786E\u8BA4 ${originalName} \u662F\u5426\u5B58\u5728\u4E8E ${moduleSpecifier}\u3002\u5EFA\u8BAE\u67E5\u770B\u6587\u6863\u3002`
33050
- });
33083
+ const knownMetadata = componentRegistry.getComponent(originalName);
33084
+ if (knownMetadata) {
33085
+ const expectedPackage = resolveExpectedImportSource(knownMetadata);
33086
+ violations.push({
33087
+ rule: `\u7EC4\u4EF6 ${originalName} \u5BFC\u5165\u6E90\u9519\u8BEF`,
33088
+ match: `import { ... } from '${moduleSpecifier}'`,
33089
+ suggestion: expectedPackage ? `\u5E94\u4ECE '${expectedPackage}' \u5BFC\u5165` : `\u8BF7\u786E\u8BA4 ${originalName} \u7684\u5BFC\u5165\u6765\u6E90`
33090
+ });
33091
+ } else {
33092
+ violations.push({
33093
+ rule: "\u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684\u7EC4\u4EF6/\u5BFC\u51FA",
33094
+ match: originalName,
33095
+ suggestion: `\u8BF7\u786E\u8BA4 ${originalName} \u662F\u5426\u5B58\u5728\u4E8E ${moduleSpecifier}\u3002\u5EFA\u8BAE\u67E5\u770B\u6587\u6863\u3002`
33096
+ });
33097
+ }
33051
33098
  }
33052
33099
  });
33053
33100
  }
@@ -33296,14 +33343,16 @@ function checkEvents(tagName, node, metadata, violations) {
33296
33343
  function kebabTagToPascalTag(tag) {
33297
33344
  return tag.split("-").map((part) => part.length ? part.charAt(0).toUpperCase() + part.slice(1).toLowerCase() : "").join("");
33298
33345
  }
33299
- function resolveRegisteredComponent(tag) {
33300
- if (componentRegistry.isKnownComponent(tag)) {
33301
- return componentRegistry.getComponent(tag);
33346
+ function resolveRegisteredComponent(tag, componentImportContext) {
33347
+ const directImportSource = componentImportContext?.get(tag);
33348
+ if (componentRegistry.isKnownComponent(tag, directImportSource)) {
33349
+ return componentRegistry.getComponent(tag, directImportSource);
33302
33350
  }
33303
33351
  if (tag.includes("-")) {
33304
33352
  const pascal = kebabTagToPascalTag(tag);
33305
- if (componentRegistry.isKnownComponent(pascal)) {
33306
- return componentRegistry.getComponent(pascal);
33353
+ const pascalImportSource = componentImportContext?.get(pascal);
33354
+ if (componentRegistry.isKnownComponent(pascal, pascalImportSource)) {
33355
+ return componentRegistry.getComponent(pascal, pascalImportSource);
33307
33356
  }
33308
33357
  }
33309
33358
  return void 0;
@@ -33350,11 +33399,11 @@ function checkSlots(tagName, node, metadata, violations) {
33350
33399
  });
33351
33400
  }
33352
33401
  }
33353
- function checkTemplate(node, violations, ancestors) {
33402
+ function checkTemplate(node, violations, ancestors, componentImportContext) {
33354
33403
  if (node.type === 1) {
33355
33404
  const elementNode = node;
33356
33405
  const tagName = elementNode.tag;
33357
- const metadata = resolveRegisteredComponent(tagName);
33406
+ const metadata = resolveRegisteredComponent(tagName, componentImportContext);
33358
33407
  const displayTag = metadata?.name ?? tagName;
33359
33408
  if (metadata) {
33360
33409
  checkNestingRules(displayTag, metadata, ancestors, violations);
@@ -33370,12 +33419,12 @@ function checkTemplate(node, violations, ancestors) {
33370
33419
  let newAncestors = ancestors;
33371
33420
  if (node.type === 1 && "tag" in node) {
33372
33421
  const el = node;
33373
- const meta = resolveRegisteredComponent(el.tag);
33422
+ const meta = resolveRegisteredComponent(el.tag, componentImportContext);
33374
33423
  newAncestors = [...ancestors, meta?.name ?? el.tag];
33375
33424
  }
33376
33425
  node.children.forEach((child) => {
33377
33426
  if (typeof child === "object" && child !== null && "type" in child) {
33378
- checkTemplate(child, violations, newAncestors);
33427
+ checkTemplate(child, violations, newAncestors, componentImportContext);
33379
33428
  }
33380
33429
  });
33381
33430
  }
@@ -32233,6 +32233,11 @@ var require_compiler_core = chunkJSBRDJBE_js.__commonJS({
32233
32233
  function resolveComponentsPath() {
32234
32234
  return chunkKF5YBEM5_js.resolvePackageResourceDir("components");
32235
32235
  }
32236
+ function extractImportSource(importStatement) {
32237
+ if (!importStatement) return void 0;
32238
+ const match = importStatement.match(/from\s+['"]([^'"]+)['"]/);
32239
+ return match?.[1];
32240
+ }
32236
32241
  var ComponentRegistry = class {
32237
32242
  constructor() {
32238
32243
  this.components = /* @__PURE__ */ new Map();
@@ -32262,16 +32267,25 @@ var ComponentRegistry = class {
32262
32267
  if (!file.endsWith(".json")) continue;
32263
32268
  const content = await fs__namespace.readFile(path__namespace.join(this.metadataPath, file), "utf-8");
32264
32269
  const data = JSON.parse(content);
32265
- rawComponents[data.name] = data;
32270
+ const importSource = data.importSource || data.source || extractImportSource(data.importStatement);
32271
+ const normalizedData = {
32272
+ ...data,
32273
+ fileName: data.fileName || file.replace(/\.json$/, ""),
32274
+ importSource,
32275
+ source: data.source || importSource
32276
+ };
32277
+ rawComponents[`${normalizedData.fileName}:${normalizedData.name}:${normalizedData.importSource || ""}`] = normalizedData;
32266
32278
  }
32267
32279
  for (const data of Object.values(rawComponents)) {
32268
32280
  const resolvedData = chunkKF5YBEM5_js.resolveMetadataInheritance(data, rawComponents);
32269
- newComponents.set(resolvedData.name, resolvedData);
32281
+ this.appendComponent(newComponents, resolvedData);
32270
32282
  if (resolvedData.subComponents) {
32271
32283
  for (const sub of resolvedData.subComponents) {
32272
- newComponents.set(sub.name, {
32284
+ this.appendComponent(newComponents, {
32273
32285
  id: sub.name,
32274
32286
  name: sub.name,
32287
+ source: resolvedData.source,
32288
+ importSource: resolvedData.importSource,
32275
32289
  props: sub.props || [],
32276
32290
  events: sub.events || [],
32277
32291
  slots: sub.slots || [],
@@ -32281,11 +32295,17 @@ var ComponentRegistry = class {
32281
32295
  }
32282
32296
  }
32283
32297
  this.components = newComponents;
32284
- console.log(`[ComponentRegistry] ${this.loaded ? "Reloaded" : "Loaded"} ${this.components.size} components.`);
32298
+ const totalEntries = Array.from(this.components.values()).reduce((sum, items) => sum + items.length, 0);
32299
+ console.log(`[ComponentRegistry] ${this.loaded ? "Reloaded" : "Loaded"} ${totalEntries} components.`);
32285
32300
  } catch (error) {
32286
32301
  console.error("[ComponentRegistry] Failed to load metadata:", error);
32287
32302
  }
32288
32303
  }
32304
+ appendComponent(target, metadata) {
32305
+ const current = target.get(metadata.name) || [];
32306
+ current.push(metadata);
32307
+ target.set(metadata.name, current);
32308
+ }
32289
32309
  /**
32290
32310
  * 开始监听文件变化
32291
32311
  */
@@ -32318,14 +32338,28 @@ var ComponentRegistry = class {
32318
32338
  console.log("[ComponentRegistry] Hot reload disabled.");
32319
32339
  }
32320
32340
  }
32321
- getComponent(name) {
32322
- return this.components.get(name);
32341
+ getComponent(name, importSource) {
32342
+ const candidates = this.components.get(name) || [];
32343
+ if (!importSource) return candidates[0];
32344
+ return candidates.find((item) => {
32345
+ const expectedSource = item.importSource || item.source || extractImportSource(item.importStatement);
32346
+ return expectedSource === importSource;
32347
+ }) || candidates[0];
32348
+ }
32349
+ getComponents(name) {
32350
+ return this.components.get(name) || [];
32323
32351
  }
32324
32352
  getAllComponentNames() {
32325
32353
  return Array.from(this.components.keys());
32326
32354
  }
32327
- isKnownComponent(name) {
32328
- return this.components.has(name);
32355
+ isKnownComponent(name, importSource) {
32356
+ if (!importSource) {
32357
+ return this.components.has(name);
32358
+ }
32359
+ return this.getComponents(name).some((item) => {
32360
+ const expectedSource = item.importSource || item.source || extractImportSource(item.importStatement);
32361
+ return expectedSource === importSource;
32362
+ });
32329
32363
  }
32330
32364
  };
32331
32365
  var componentRegistry = new ComponentRegistry();
@@ -32769,6 +32803,7 @@ async function analyzeCodeWithAST(code) {
32769
32803
  await componentRegistry.load();
32770
32804
  await hooksRegistry.load();
32771
32805
  const violations = [];
32806
+ const componentImportContext = /* @__PURE__ */ new Map();
32772
32807
  const { descriptor, errors } = compilerSfc.parse(code);
32773
32808
  if (errors.length > 0) {
32774
32809
  return violations;
@@ -32783,12 +32818,12 @@ async function analyzeCodeWithAST(code) {
32783
32818
  );
32784
32819
  ts__namespace.forEachChild(sourceFile, (node) => {
32785
32820
  if (ts__namespace.isImportDeclaration(node)) {
32786
- checkImport(node, violations, sourceFile);
32821
+ checkImport(node, violations, sourceFile, componentImportContext);
32787
32822
  }
32788
32823
  });
32789
32824
  }
32790
32825
  if (descriptor.template?.ast) {
32791
- checkTemplate(descriptor.template.ast, violations, []);
32826
+ checkTemplate(descriptor.template.ast, violations, [], componentImportContext);
32792
32827
  }
32793
32828
  if (scriptContent && descriptor.template) {
32794
32829
  const scriptBindings = extractScriptBindings(scriptContent);
@@ -33005,6 +33040,7 @@ function isJsKeyword(id) {
33005
33040
  return JS_KEYWORDS.has(id);
33006
33041
  }
33007
33042
  function resolveExpectedImportSource(metadata) {
33043
+ if (metadata.importSource) return metadata.importSource;
33008
33044
  const importStatement = metadata.importStatement || "";
33009
33045
  if (importStatement.includes("@ksyun-internal/versatile")) {
33010
33046
  return "@ksyun-internal/versatile";
@@ -33014,7 +33050,7 @@ function resolveExpectedImportSource(metadata) {
33014
33050
  }
33015
33051
  return null;
33016
33052
  }
33017
- function checkImport(node, violations, sourceFile) {
33053
+ function checkImport(node, violations, sourceFile, componentImportContext) {
33018
33054
  const moduleSpecifier = node.moduleSpecifier.getText(sourceFile).replace(/['\"]/g, "");
33019
33055
  if (moduleSpecifier === "@king-design/vue" || moduleSpecifier === "@ksyun-internal/versatile") {
33020
33056
  const namedBindings = node.importClause?.namedBindings;
@@ -33057,7 +33093,8 @@ function checkImport(node, violations, sourceFile) {
33057
33093
  suggestion: `\u76F4\u63A5\u4F7F\u7528\u539F\u540D: import { ${originalName} } from '${moduleSpecifier}'`
33058
33094
  });
33059
33095
  }
33060
- const metadata = componentRegistry.getComponent(originalName);
33096
+ componentImportContext.set(localName, moduleSpecifier);
33097
+ const metadata = componentRegistry.getComponent(originalName, moduleSpecifier);
33061
33098
  if (metadata) {
33062
33099
  const expectedPackage = resolveExpectedImportSource(metadata);
33063
33100
  if (expectedPackage && expectedPackage !== moduleSpecifier) {
@@ -33068,11 +33105,21 @@ function checkImport(node, violations, sourceFile) {
33068
33105
  });
33069
33106
  }
33070
33107
  } else {
33071
- violations.push({
33072
- rule: "\u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684\u7EC4\u4EF6/\u5BFC\u51FA",
33073
- match: originalName,
33074
- suggestion: `\u8BF7\u786E\u8BA4 ${originalName} \u662F\u5426\u5B58\u5728\u4E8E ${moduleSpecifier}\u3002\u5EFA\u8BAE\u67E5\u770B\u6587\u6863\u3002`
33075
- });
33108
+ const knownMetadata = componentRegistry.getComponent(originalName);
33109
+ if (knownMetadata) {
33110
+ const expectedPackage = resolveExpectedImportSource(knownMetadata);
33111
+ violations.push({
33112
+ rule: `\u7EC4\u4EF6 ${originalName} \u5BFC\u5165\u6E90\u9519\u8BEF`,
33113
+ match: `import { ... } from '${moduleSpecifier}'`,
33114
+ suggestion: expectedPackage ? `\u5E94\u4ECE '${expectedPackage}' \u5BFC\u5165` : `\u8BF7\u786E\u8BA4 ${originalName} \u7684\u5BFC\u5165\u6765\u6E90`
33115
+ });
33116
+ } else {
33117
+ violations.push({
33118
+ rule: "\u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684\u7EC4\u4EF6/\u5BFC\u51FA",
33119
+ match: originalName,
33120
+ suggestion: `\u8BF7\u786E\u8BA4 ${originalName} \u662F\u5426\u5B58\u5728\u4E8E ${moduleSpecifier}\u3002\u5EFA\u8BAE\u67E5\u770B\u6587\u6863\u3002`
33121
+ });
33122
+ }
33076
33123
  }
33077
33124
  });
33078
33125
  }
@@ -33321,14 +33368,16 @@ function checkEvents(tagName, node, metadata, violations) {
33321
33368
  function kebabTagToPascalTag(tag) {
33322
33369
  return tag.split("-").map((part) => part.length ? part.charAt(0).toUpperCase() + part.slice(1).toLowerCase() : "").join("");
33323
33370
  }
33324
- function resolveRegisteredComponent(tag) {
33325
- if (componentRegistry.isKnownComponent(tag)) {
33326
- return componentRegistry.getComponent(tag);
33371
+ function resolveRegisteredComponent(tag, componentImportContext) {
33372
+ const directImportSource = componentImportContext?.get(tag);
33373
+ if (componentRegistry.isKnownComponent(tag, directImportSource)) {
33374
+ return componentRegistry.getComponent(tag, directImportSource);
33327
33375
  }
33328
33376
  if (tag.includes("-")) {
33329
33377
  const pascal = kebabTagToPascalTag(tag);
33330
- if (componentRegistry.isKnownComponent(pascal)) {
33331
- return componentRegistry.getComponent(pascal);
33378
+ const pascalImportSource = componentImportContext?.get(pascal);
33379
+ if (componentRegistry.isKnownComponent(pascal, pascalImportSource)) {
33380
+ return componentRegistry.getComponent(pascal, pascalImportSource);
33332
33381
  }
33333
33382
  }
33334
33383
  return void 0;
@@ -33375,11 +33424,11 @@ function checkSlots(tagName, node, metadata, violations) {
33375
33424
  });
33376
33425
  }
33377
33426
  }
33378
- function checkTemplate(node, violations, ancestors) {
33427
+ function checkTemplate(node, violations, ancestors, componentImportContext) {
33379
33428
  if (node.type === 1) {
33380
33429
  const elementNode = node;
33381
33430
  const tagName = elementNode.tag;
33382
- const metadata = resolveRegisteredComponent(tagName);
33431
+ const metadata = resolveRegisteredComponent(tagName, componentImportContext);
33383
33432
  const displayTag = metadata?.name ?? tagName;
33384
33433
  if (metadata) {
33385
33434
  checkNestingRules(displayTag, metadata, ancestors, violations);
@@ -33395,12 +33444,12 @@ function checkTemplate(node, violations, ancestors) {
33395
33444
  let newAncestors = ancestors;
33396
33445
  if (node.type === 1 && "tag" in node) {
33397
33446
  const el = node;
33398
- const meta = resolveRegisteredComponent(el.tag);
33447
+ const meta = resolveRegisteredComponent(el.tag, componentImportContext);
33399
33448
  newAncestors = [...ancestors, meta?.name ?? el.tag];
33400
33449
  }
33401
33450
  node.children.forEach((child) => {
33402
33451
  if (typeof child === "object" && child !== null && "type" in child) {
33403
- checkTemplate(child, violations, newAncestors);
33452
+ checkTemplate(child, violations, newAncestors, componentImportContext);
33404
33453
  }
33405
33454
  });
33406
33455
  }
@@ -1,4 +1,4 @@
1
- import { analyzeCodeWithAST } from './chunk-YRGYDK2I.mjs';
1
+ import { analyzeCodeWithAST } from './chunk-7YBUXYUI.mjs';
2
2
  import { validateRuntimePrecheck } from './chunk-6HOIRUQB.mjs';
3
3
  import { compileSFC } from './chunk-4OTQAQ6J.mjs';
4
4
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkHARQRI4F_js = require('../chunk-HARQRI4F.js');
4
- require('../chunk-XPHDD6XR.js');
3
+ var chunk7CSMAJZ2_js = require('../chunk-7CSMAJZ2.js');
4
+ require('../chunk-K6UQSWLC.js');
5
5
  require('../chunk-V5N65MRP.js');
6
6
  require('../chunk-DHLWNT53.js');
7
7
  require('../chunk-KF5YBEM5.js');
@@ -11,9 +11,9 @@ require('../chunk-JSBRDJBE.js');
11
11
 
12
12
  Object.defineProperty(exports, "validateCode", {
13
13
  enumerable: true,
14
- get: function () { return chunkHARQRI4F_js.validateCode; }
14
+ get: function () { return chunk7CSMAJZ2_js.validateCode; }
15
15
  });
16
16
  Object.defineProperty(exports, "validateCodeSync", {
17
17
  enumerable: true,
18
- get: function () { return chunkHARQRI4F_js.validateCodeSync; }
18
+ get: function () { return chunk7CSMAJZ2_js.validateCodeSync; }
19
19
  });
@@ -1,5 +1,5 @@
1
- export { validateCode, validateCodeSync } from '../chunk-BSCASJTV.mjs';
2
- import '../chunk-YRGYDK2I.mjs';
1
+ export { validateCode, validateCodeSync } from '../chunk-RJQMTGRE.mjs';
2
+ import '../chunk-7YBUXYUI.mjs';
3
3
  import '../chunk-6HOIRUQB.mjs';
4
4
  import '../chunk-4OTQAQ6J.mjs';
5
5
  import '../chunk-QC6VTSA3.mjs';
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  var chunkJJ6AB4ZH_js = require('./chunk-JJ6AB4ZH.js');
4
4
  require('./chunk-YTEYDSDW.js');
5
- var chunkHARQRI4F_js = require('./chunk-HARQRI4F.js');
6
- var chunkXPHDD6XR_js = require('./chunk-XPHDD6XR.js');
5
+ var chunk7CSMAJZ2_js = require('./chunk-7CSMAJZ2.js');
6
+ var chunkK6UQSWLC_js = require('./chunk-K6UQSWLC.js');
7
7
  var chunkV5N65MRP_js = require('./chunk-V5N65MRP.js');
8
8
  var chunkDHLWNT53_js = require('./chunk-DHLWNT53.js');
9
9
  require('./chunk-KF5YBEM5.js');
@@ -17,19 +17,19 @@ Object.defineProperty(exports, "validateCompilation", {
17
17
  });
18
18
  Object.defineProperty(exports, "validateCode", {
19
19
  enumerable: true,
20
- get: function () { return chunkHARQRI4F_js.validateCode; }
20
+ get: function () { return chunk7CSMAJZ2_js.validateCode; }
21
21
  });
22
22
  Object.defineProperty(exports, "validateCodeSync", {
23
23
  enumerable: true,
24
- get: function () { return chunkHARQRI4F_js.validateCodeSync; }
24
+ get: function () { return chunk7CSMAJZ2_js.validateCodeSync; }
25
25
  });
26
26
  Object.defineProperty(exports, "analyzeCodeWithAST", {
27
27
  enumerable: true,
28
- get: function () { return chunkXPHDD6XR_js.analyzeCodeWithAST; }
28
+ get: function () { return chunkK6UQSWLC_js.analyzeCodeWithAST; }
29
29
  });
30
30
  Object.defineProperty(exports, "componentRegistry", {
31
31
  enumerable: true,
32
- get: function () { return chunkXPHDD6XR_js.componentRegistry; }
32
+ get: function () { return chunkK6UQSWLC_js.componentRegistry; }
33
33
  });
34
34
  Object.defineProperty(exports, "validateRuntimePrecheck", {
35
35
  enumerable: true,
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  export { validateCompilation } from './chunk-NZL6T22V.mjs';
2
2
  import './chunk-5H7N2A5X.mjs';
3
- export { validateCode, validateCodeSync } from './chunk-BSCASJTV.mjs';
4
- export { analyzeCodeWithAST, componentRegistry } from './chunk-YRGYDK2I.mjs';
3
+ export { validateCode, validateCodeSync } from './chunk-RJQMTGRE.mjs';
4
+ export { analyzeCodeWithAST, componentRegistry } from './chunk-7YBUXYUI.mjs';
5
5
  export { validateRuntimePrecheck } from './chunk-6HOIRUQB.mjs';
6
6
  export { compileSFC, scopeStyles } from './chunk-4OTQAQ6J.mjs';
7
7
  import './chunk-QC6VTSA3.mjs';
@@ -0,0 +1,62 @@
1
+ # 侧边栏 (Aside)
2
+
3
+ 布局侧边栏组件,适合承载导航菜单或辅助信息区域,可配置固定定位和折叠宽度。
4
+
5
+ ## 导入语句
6
+ ```typescript
7
+ import { Aside } from '@king-design/vue';
8
+ ```
9
+
10
+ ## 属性 (Props)
11
+ | 属性名 | 类型 | 默认值 | 必填 | 说明 | 标签 | 示例 |
12
+ | --- | --- | --- | --- | --- | --- | --- |
13
+ | collapse | `boolean` | `false` | 否 | 是否处于折叠状态。 | - | `<Aside collapse>折叠菜单</Aside>` |
14
+ | fixed | `boolean` | `false` | 否 | 是否固定在页面左侧。 | - | `<Aside fixed>固定侧边栏</Aside>` |
15
+ | theme | `MenuProps['theme']` | `"light"` | 否 | 侧边栏主题,沿用 Menu 组件的主题配置。 | - | `<Aside theme="dark">深色侧边栏</Aside>` |
16
+ | width | `number | string` | `240` | 否 | 侧边栏宽度,支持数字或带单位的字符串。 | - | `<Aside :width="220">自定义宽度</Aside>` |
17
+ | collapsedWidth | `number | string` | `64` | 否 | 折叠状态下的宽度。 | - | `<Aside :collapsedWidth="56" collapse>折叠侧边栏</Aside>` |
18
+
19
+ ## 插槽 (Slots)
20
+ | 插槽名 | 说明 | 模板写法 | 示例 |
21
+ | --- | --- | --- | --- |
22
+ | default | 侧边栏内容,通常放置菜单、品牌信息或辅助操作。 | `#default` | `<Aside>
23
+ <Menu>
24
+ <MenuItem key="1">概览</MenuItem>
25
+ </Menu>
26
+ </Aside>` |
27
+
28
+ ### 插槽参数说明
29
+ **default**
30
+
31
+ - 参数结构: 无参数
32
+
33
+ ## 使用示例
34
+ ### 基础侧边栏
35
+ **场景**: 在后台布局中承载主导航菜单。
36
+
37
+ 在布局中放置导航菜单。
38
+
39
+ **使用的 API**: 属性: width
40
+
41
+ ```vue
42
+ <script setup lang="ts">
43
+ import { Layout, Aside, Body, Menu, MenuItem } from '@king-design/vue';
44
+ </script>
45
+ <template>
46
+ <Layout>
47
+ <Aside :width="220">
48
+ <Menu>
49
+ <MenuItem key="overview">概览</MenuItem>
50
+ <MenuItem key="instance">实例列表</MenuItem>
51
+ </Menu>
52
+ </Aside>
53
+ <Body>
54
+ <div style="padding: 16px;">内容区域</div>
55
+ </Body>
56
+ </Layout>
57
+ </template>
58
+ ```
59
+
60
+ ## 相关组件
61
+ Layout, Body, Menu
62
+
@@ -0,0 +1,44 @@
1
+ # 布局主体 (Body)
2
+
3
+ 布局主体容器,用于承载页面主要内容区域,通常与 Header、Aside 组合使用。
4
+
5
+ ## 导入语句
6
+ ```typescript
7
+ import { Body } from '@king-design/vue';
8
+ ```
9
+
10
+ ## 插槽 (Slots)
11
+ | 插槽名 | 说明 | 模板写法 | 示例 |
12
+ | --- | --- | --- | --- |
13
+ | default | 主体内容区域。 | `#default` | `<Body>
14
+ <div style="padding: 16px;">页面主体内容</div>
15
+ </Body>` |
16
+
17
+ ### 插槽参数说明
18
+ **default**
19
+
20
+ - 参数结构: 无参数
21
+
22
+ ## 使用示例
23
+ ### 主体内容区
24
+ **场景**: 作为后台页面的主要内容承载区域。
25
+
26
+ 在布局中承载页面正文。
27
+
28
+ ```vue
29
+ <script setup lang="ts">
30
+ import { Layout, Header, Body } from '@king-design/vue';
31
+ </script>
32
+ <template>
33
+ <Layout>
34
+ <Header>实例管理</Header>
35
+ <Body>
36
+ <div style="padding: 16px;">这里放页面内容</div>
37
+ </Body>
38
+ </Layout>
39
+ </template>
40
+ ```
41
+
42
+ ## 相关组件
43
+ Layout, Header, Aside, Footer
44
+
@@ -0,0 +1,46 @@
1
+ # 布局底部 (Footer)
2
+
3
+ 布局底部组件,适合展示版权、说明信息或页面级辅助操作。
4
+
5
+ ## 导入语句
6
+ ```typescript
7
+ import { Footer } from '@king-design/vue';
8
+ ```
9
+
10
+ ## 插槽 (Slots)
11
+ | 插槽名 | 说明 | 模板写法 | 示例 |
12
+ | --- | --- | --- | --- |
13
+ | default | 底部内容区域。 | `#default` | `<Footer>
14
+ Copyright 2026 Kingsoft Cloud
15
+ </Footer>` |
16
+
17
+ ### 插槽参数说明
18
+ **default**
19
+
20
+ - 参数结构: 无参数
21
+
22
+ ## 使用示例
23
+ ### 基础底部
24
+ **场景**: 在控制台页面底部展示版权或补充提示。
25
+
26
+ 展示底部版权或补充说明。
27
+
28
+ ```vue
29
+ <script setup lang="ts">
30
+ import { Layout, Body, Footer } from '@king-design/vue';
31
+ </script>
32
+ <template>
33
+ <Layout>
34
+ <Body>
35
+ <div style="padding: 16px; min-height: 200px;">内容区域</div>
36
+ </Body>
37
+ <Footer>
38
+ Copyright 2026 Kingsoft Cloud
39
+ </Footer>
40
+ </Layout>
41
+ </template>
42
+ ```
43
+
44
+ ## 相关组件
45
+ Layout, Body
46
+
@@ -0,0 +1,61 @@
1
+ # 布局头部 (Header)
2
+
3
+ 布局头部组件,常用于放置站点标题、全局导航和操作入口,可配置固定定位、主题和毛玻璃效果。
4
+
5
+ ## 导入语句
6
+ ```typescript
7
+ import { Header } from '@king-design/vue';
8
+ ```
9
+
10
+ ## 属性 (Props)
11
+ | 属性名 | 类型 | 默认值 | 必填 | 说明 | 标签 | 示例 |
12
+ | --- | --- | --- | --- | --- | --- | --- |
13
+ | fixed | `boolean` | `false` | 否 | 是否固定在页面顶部。 | - | `<Header fixed>固定头部</Header>` |
14
+ | height | `number | string` | `64` | 否 | 头部高度,支持数字或带单位的字符串。 | - | `<Header :height="56">紧凑头部</Header>` |
15
+ | style | `string | Record<string, string>` | `undefined` | 否 | 自定义内联样式。 | - | `<Header :style="{ background: '#fff' }">自定义样式</Header>` |
16
+ | theme | `MenuProps['theme']` | `"light"` | 否 | 头部主题,沿用 Menu 组件的主题配置。 | - | `<Header theme="dark">深色头部</Header>` |
17
+ | blur | `boolean` | `false` | 否 | 是否开启毛玻璃背景效果。 | - | `<Header blur>毛玻璃头部</Header>` |
18
+ | boxShadow | `boolean` | `false` | 否 | 是否展示底部阴影。 | - | `<Header boxShadow>带阴影头部</Header>` |
19
+
20
+ ## 插槽 (Slots)
21
+ | 插槽名 | 说明 | 模板写法 | 示例 |
22
+ | --- | --- | --- | --- |
23
+ | default | 头部内容区域,通常放置 Logo、导航或操作按钮。 | `#default` | `<Header>
24
+ <div style="display: flex; justify-content: space-between;">控制台<header-actions /></div>
25
+ </Header>` |
26
+
27
+ ### 插槽参数说明
28
+ **default**
29
+
30
+ - 参数结构: 无参数
31
+
32
+ ## 使用示例
33
+ ### 基础布局头部
34
+ **场景**: 用于后台系统的全局固定顶部栏。
35
+
36
+ 作为站点或控制台的全局顶部栏。
37
+
38
+ **使用的 API**: 属性: fixed, theme, height
39
+
40
+ ```vue
41
+ <script setup lang="ts">
42
+ import { Layout, Header, Body, Button } from '@king-design/vue';
43
+ </script>
44
+ <template>
45
+ <Layout>
46
+ <Header fixed theme="dark" :height="56">
47
+ <div style="display: flex; align-items: center; justify-content: space-between; height: 100%; padding: 0 16px;">
48
+ <span>控制台</span>
49
+ <Button type="primary">新建资源</Button>
50
+ </div>
51
+ </Header>
52
+ <Body>
53
+ <div style="padding: 16px;">页面内容</div>
54
+ </Body>
55
+ </Layout>
56
+ </template>
57
+ ```
58
+
59
+ ## 相关组件
60
+ Layout, Body, Aside
61
+
@@ -0,0 +1,53 @@
1
+ # 布局容器 (Layout)
2
+
3
+ 页面整体布局容器,用于组合 Header、Aside、Body、Footer 等区域,构建后台或工作台页面结构。
4
+
5
+ **关键词**: layout, 页面布局, 布局容器
6
+
7
+ **使用场景**: 后台布局、控制台页面、工作台页面
8
+
9
+ ## 导入语句
10
+ ```typescript
11
+ import { Layout } from '@king-design/vue';
12
+ ```
13
+
14
+ ## 插槽 (Slots)
15
+ | 插槽名 | 说明 | 模板写法 | 示例 |
16
+ | --- | --- | --- | --- |
17
+ | default | 布局内容区域,通常放置 Header、Aside、Body、Footer 组件。 | `#default` | `<Layout>
18
+ <Header />
19
+ <Body>内容区</Body>
20
+ </Layout>` |
21
+
22
+ ### 插槽参数说明
23
+ **default**
24
+
25
+ - 参数结构: 无参数
26
+
27
+ ## 使用示例
28
+ ### 基础布局
29
+ **场景**: 用于管理后台和工作台页面的整体结构搭建。
30
+
31
+ 组合头部、侧边栏和内容区,构建典型后台页面布局。
32
+
33
+ ```vue
34
+ <script setup lang="ts">
35
+ import { Layout, Header, Aside, Body, Footer } from '@king-design/vue';
36
+ </script>
37
+ <template>
38
+ <Layout>
39
+ <Header>控制台</Header>
40
+ <Layout>
41
+ <Aside>导航菜单</Aside>
42
+ <Body>
43
+ <div style="padding: 16px;">页面内容</div>
44
+ </Body>
45
+ </Layout>
46
+ <Footer>Copyright 2026</Footer>
47
+ </Layout>
48
+ </template>
49
+ ```
50
+
51
+ ## 相关组件
52
+ Header, Aside, Body, Footer
53
+
@@ -29,6 +29,7 @@ import { Transfer } from '@king-design/vue';
29
29
  | rightTitle | `string | VNode` | `"已选择"` | 否 | 右侧标题 | - | `<Transfer rightTitle="已选列表"></Transfer>` |
30
30
  | enableAdd | `() => boolean` | `undefined` | 否 | 控制右箭头按钮的可用状态 | - | `<Transfer :enableAdd="canAdd"></Transfer>` |
31
31
  | enableRemove | `() => boolean` | `undefined` | 否 | 控制左箭头按钮的可用状态 | - | `<Transfer :enableRemove="canRemove"></Transfer>` |
32
+ | pagination | `boolean | PaginationProps` | `false` | 否 | 是否启用左右面板分页,也可以传入 Pagination 的配置对象来自定义页码和每页条数。 | - | `<Transfer :pagination="{ value: 1, limit: 10 }"></Transfer>` |
32
33
 
33
34
  ## 事件 (Events)
34
35
  | 事件名 | Vue事件名 | 说明 | 回调参数 | 示例 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "king-design-analyzer",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "description": "AST-based code analyzer for King Design Vue components with on-demand modular imports",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",