@fjyueke/arco-mcp 1.0.0

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.
Files changed (191) hide show
  1. package/README.md +85 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +244 -0
  4. package/metaData/components/action-sheet/doc.md +102 -0
  5. package/metaData/components/action-sheet/example/index.tsx +199 -0
  6. package/metaData/components/action-sheet/example/methods.tsx +6 -0
  7. package/metaData/components/avatar/doc.md +57 -0
  8. package/metaData/components/avatar/example/group.tsx +69 -0
  9. package/metaData/components/avatar/example/index.tsx +196 -0
  10. package/metaData/components/badge/doc.md +28 -0
  11. package/metaData/components/badge/example/index.tsx +128 -0
  12. package/metaData/components/button/doc.md +45 -0
  13. package/metaData/components/button/example/index.tsx +264 -0
  14. package/metaData/components/carousel/doc.md +89 -0
  15. package/metaData/components/carousel/example/index.tsx +1481 -0
  16. package/metaData/components/cell/doc.md +68 -0
  17. package/metaData/components/cell/example/arrow.tsx +13 -0
  18. package/metaData/components/cell/example/cell.tsx +71 -0
  19. package/metaData/components/cell/example/group.tsx +63 -0
  20. package/metaData/components/cell/example/index.tsx +19 -0
  21. package/metaData/components/checkbox/doc.md +91 -0
  22. package/metaData/components/checkbox/example/checkbox.tsx +158 -0
  23. package/metaData/components/checkbox/example/group.tsx +103 -0
  24. package/metaData/components/checkbox/example/index.tsx +25 -0
  25. package/metaData/components/circle-progress/doc.md +40 -0
  26. package/metaData/components/circle-progress/example/index.tsx +323 -0
  27. package/metaData/components/collapse/doc.md +74 -0
  28. package/metaData/components/collapse/example/collapse.tsx +183 -0
  29. package/metaData/components/collapse/example/group.tsx +136 -0
  30. package/metaData/components/collapse/example/index.tsx +16 -0
  31. package/metaData/components/collapse/example/utils.tsx +20 -0
  32. package/metaData/components/context-provider/doc.md +44 -0
  33. package/metaData/components/context-provider/example/index.tsx +208 -0
  34. package/metaData/components/count-down/doc.md +40 -0
  35. package/metaData/components/count-down/example/hooks.tsx +118 -0
  36. package/metaData/components/count-down/example/index.tsx +63 -0
  37. package/metaData/components/date-picker/doc.md +102 -0
  38. package/metaData/components/date-picker/example/index.tsx +545 -0
  39. package/metaData/components/dialog/doc.md +200 -0
  40. package/metaData/components/dialog/example/index.tsx +328 -0
  41. package/metaData/components/dialog/example/methods.tsx +56 -0
  42. package/metaData/components/divider/doc.md +25 -0
  43. package/metaData/components/divider/example/index.tsx +87 -0
  44. package/metaData/components/dropdown/doc.md +80 -0
  45. package/metaData/components/dropdown/example/dropdown.tsx +308 -0
  46. package/metaData/components/dropdown/example/index.tsx +19 -0
  47. package/metaData/components/dropdown/example/options.tsx +103 -0
  48. package/metaData/components/dropdown-menu/doc.md +91 -0
  49. package/metaData/components/dropdown-menu/example/dropdown-menu.tsx +270 -0
  50. package/metaData/components/dropdown-menu/example/index.tsx +16 -0
  51. package/metaData/components/ellipsis/doc.md +33 -0
  52. package/metaData/components/ellipsis/example/index.tsx +93 -0
  53. package/metaData/components/ellipsis/example/js-ellipsis.tsx +229 -0
  54. package/metaData/components/ellipsis/example/native-ellipsis.tsx +48 -0
  55. package/metaData/components/form/doc.md +90 -0
  56. package/metaData/components/form/example/form-item-context.tsx +8 -0
  57. package/metaData/components/form/example/form-item.tsx +378 -0
  58. package/metaData/components/form/example/index.tsx +87 -0
  59. package/metaData/components/form/example/linked-container.tsx +66 -0
  60. package/metaData/components/grid/doc.md +39 -0
  61. package/metaData/components/grid/example/index.tsx +252 -0
  62. package/metaData/components/icon/doc.md +15 -0
  63. package/metaData/components/icon/example/index.tsx +32 -0
  64. package/metaData/components/image/doc.md +62 -0
  65. package/metaData/components/image/example/index.tsx +528 -0
  66. package/metaData/components/image-picker/doc.md +116 -0
  67. package/metaData/components/image-picker/example/add-icon.tsx +14 -0
  68. package/metaData/components/image-picker/example/index.tsx +175 -0
  69. package/metaData/components/image-preview/doc.md +119 -0
  70. package/metaData/components/image-preview/example/index.tsx +1290 -0
  71. package/metaData/components/image-preview/example/methods.tsx +72 -0
  72. package/metaData/components/index-bar/doc.md +83 -0
  73. package/metaData/components/index-bar/example/group.tsx +93 -0
  74. package/metaData/components/index-bar/example/index.tsx +271 -0
  75. package/metaData/components/index-bar/example/side-bar.tsx +82 -0
  76. package/metaData/components/input/doc.md +60 -0
  77. package/metaData/components/input/example/hooks.tsx +259 -0
  78. package/metaData/components/input/example/index.tsx +134 -0
  79. package/metaData/components/input/example/props.tsx +183 -0
  80. package/metaData/components/keyboard/doc.md +73 -0
  81. package/metaData/components/keyboard/example/index.tsx +238 -0
  82. package/metaData/components/load-more/doc.md +48 -0
  83. package/metaData/components/load-more/example/index.tsx +395 -0
  84. package/metaData/components/loading/doc.md +34 -0
  85. package/metaData/components/loading/example/index.tsx +312 -0
  86. package/metaData/components/masking/doc.md +93 -0
  87. package/metaData/components/masking/example/index.tsx +410 -0
  88. package/metaData/components/masking/example/methods.tsx +88 -0
  89. package/metaData/components/nav-bar/doc.md +40 -0
  90. package/metaData/components/nav-bar/example/back-icon.tsx +28 -0
  91. package/metaData/components/nav-bar/example/index.tsx +305 -0
  92. package/metaData/components/notice-bar/doc.md +34 -0
  93. package/metaData/components/notice-bar/example/index.tsx +294 -0
  94. package/metaData/components/notify/doc.md +81 -0
  95. package/metaData/components/notify/example/index.tsx +171 -0
  96. package/metaData/components/notify/example/methods.tsx +83 -0
  97. package/metaData/components/pagination/doc.md +41 -0
  98. package/metaData/components/pagination/example/arrow.tsx +14 -0
  99. package/metaData/components/pagination/example/index.tsx +292 -0
  100. package/metaData/components/picker/doc.md +89 -0
  101. package/metaData/components/picker/example/index.tsx +217 -0
  102. package/metaData/components/picker-view/doc.md +57 -0
  103. package/metaData/components/picker-view/example/cascader.tsx +141 -0
  104. package/metaData/components/picker-view/example/index.tsx +297 -0
  105. package/metaData/components/picker-view/example/multi-picker.tsx +66 -0
  106. package/metaData/components/picker-view/example/picker-cell.tsx +416 -0
  107. package/metaData/components/popover/doc.md +144 -0
  108. package/metaData/components/popover/example/index.tsx +23 -0
  109. package/metaData/components/popover/example/menu.tsx +145 -0
  110. package/metaData/components/popover/example/popover-inner.tsx +147 -0
  111. package/metaData/components/popover/example/popover.tsx +268 -0
  112. package/metaData/components/popup/doc.md +101 -0
  113. package/metaData/components/popup/example/index.tsx +125 -0
  114. package/metaData/components/popup/example/methods.tsx +6 -0
  115. package/metaData/components/popup-swiper/doc.md +108 -0
  116. package/metaData/components/popup-swiper/example/index.tsx +332 -0
  117. package/metaData/components/popup-swiper/example/methods.tsx +6 -0
  118. package/metaData/components/portal/doc.md +14 -0
  119. package/metaData/components/portal/example/index.tsx +35 -0
  120. package/metaData/components/progress/doc.md +42 -0
  121. package/metaData/components/progress/example/index.tsx +256 -0
  122. package/metaData/components/pull-refresh/doc.md +37 -0
  123. package/metaData/components/pull-refresh/example/android-pull-refresh.tsx +260 -0
  124. package/metaData/components/pull-refresh/example/index.tsx +44 -0
  125. package/metaData/components/pull-refresh/example/ios-pull-refresh.tsx +216 -0
  126. package/metaData/components/radio/doc.md +89 -0
  127. package/metaData/components/radio/example/group.tsx +92 -0
  128. package/metaData/components/radio/example/index.tsx +25 -0
  129. package/metaData/components/radio/example/radio.tsx +22 -0
  130. package/metaData/components/rate/doc.md +33 -0
  131. package/metaData/components/rate/example/index.tsx +281 -0
  132. package/metaData/components/search-bar/doc.md +97 -0
  133. package/metaData/components/search-bar/example/association.tsx +89 -0
  134. package/metaData/components/search-bar/example/cancel-button.tsx +34 -0
  135. package/metaData/components/search-bar/example/highlight.tsx +66 -0
  136. package/metaData/components/search-bar/example/index.tsx +251 -0
  137. package/metaData/components/show-monitor/doc.md +34 -0
  138. package/metaData/components/show-monitor/example/index.tsx +646 -0
  139. package/metaData/components/skeleton/doc.md +101 -0
  140. package/metaData/components/skeleton/example/elements.tsx +290 -0
  141. package/metaData/components/skeleton/example/index.tsx +96 -0
  142. package/metaData/components/skeleton/example/skeleton-context.tsx +7 -0
  143. package/metaData/components/slider/doc.md +42 -0
  144. package/metaData/components/slider/example/index.tsx +326 -0
  145. package/metaData/components/slider/example/marks.tsx +50 -0
  146. package/metaData/components/slider/example/popover.tsx +38 -0
  147. package/metaData/components/slider/example/thumb.tsx +48 -0
  148. package/metaData/components/slider/example/useSliderIcon.tsx +38 -0
  149. package/metaData/components/slider/example/useSliderInit.tsx +170 -0
  150. package/metaData/components/stepper/doc.md +46 -0
  151. package/metaData/components/stepper/example/index.tsx +166 -0
  152. package/metaData/components/stepper/example/useButtonClick.tsx +74 -0
  153. package/metaData/components/stepper/example/useInputEvent.tsx +65 -0
  154. package/metaData/components/stepper/example/useValue.tsx +43 -0
  155. package/metaData/components/steps/doc.md +57 -0
  156. package/metaData/components/steps/example/index.tsx +123 -0
  157. package/metaData/components/steps/example/step.tsx +126 -0
  158. package/metaData/components/sticky/doc.md +45 -0
  159. package/metaData/components/sticky/example/index.tsx +430 -0
  160. package/metaData/components/swipe-action/doc.md +44 -0
  161. package/metaData/components/swipe-action/example/index.tsx +338 -0
  162. package/metaData/components/swipe-action/example/item.tsx +40 -0
  163. package/metaData/components/swipe-load/doc.md +43 -0
  164. package/metaData/components/swipe-load/example/index.tsx +339 -0
  165. package/metaData/components/swipe-load/example/type.tsx +153 -0
  166. package/metaData/components/switch/doc.md +38 -0
  167. package/metaData/components/switch/example/index.tsx +237 -0
  168. package/metaData/components/tab-bar/doc.md +57 -0
  169. package/metaData/components/tab-bar/example/index.tsx +18 -0
  170. package/metaData/components/tab-bar/example/item.tsx +74 -0
  171. package/metaData/components/tab-bar/example/tab-bar.tsx +105 -0
  172. package/metaData/components/tabs/doc.md +187 -0
  173. package/metaData/components/tabs/example/index.tsx +514 -0
  174. package/metaData/components/tabs/example/tab-cell-underline.tsx +320 -0
  175. package/metaData/components/tabs/example/tab-cell.tsx +433 -0
  176. package/metaData/components/tabs/example/tab-pane.tsx +349 -0
  177. package/metaData/components/tag/doc.md +80 -0
  178. package/metaData/components/tag/example/index.tsx +23 -0
  179. package/metaData/components/tag/example/list.tsx +97 -0
  180. package/metaData/components/tag/example/tag.tsx +85 -0
  181. package/metaData/components/textarea/doc.md +67 -0
  182. package/metaData/components/textarea/example/index.tsx +258 -0
  183. package/metaData/components/toast/doc.md +90 -0
  184. package/metaData/components/toast/example/index.tsx +335 -0
  185. package/metaData/components/toast/example/methods.tsx +87 -0
  186. package/metaData/components/transition/doc.md +19 -0
  187. package/metaData/components/transition/example/index.tsx +113 -0
  188. package/metaData/components/uploader/doc.md +82 -0
  189. package/metaData/components/uploader/example/index.tsx +208 -0
  190. package/metaData/components-index.json +242 -0
  191. package/package.json +56 -0
package/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # Arco Design Mobile MCP
2
+
3
+ 基于 Model Context Protocol (MCP) 提供 Arco Design Mobile 组件库文档查询能力。
4
+
5
+ ## 介绍
6
+
7
+ Arco Design Mobile MCP 是一项独立的 MCP 服务,旨在将 Arco Design Mobile 与大模型连接起来。它使大模型能够直接从文档中检索组件、API数据。
8
+
9
+ - 直接使用 npx 运行
10
+ - 无需外部依赖,只需要 Node 环境
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ npm install -g @fjyueke/arco-mcp
16
+ ```
17
+
18
+ ## 使用
19
+
20
+ ### Cursor 用法
21
+
22
+ ```json
23
+ {
24
+ "mcpServers": {
25
+ "@fjyueke/arco-mcp": {
26
+ "command": "npx",
27
+ "args": [
28
+ "-y",
29
+ "@fjyueke/arco-mcp"
30
+ ],
31
+ "env": {}
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ### 工具接口
38
+
39
+ | 工具名 | 功能 |
40
+ |--------|------|
41
+ | `list-components` | 列出所有组件 |
42
+ | `get-component-docs` | 获取组件详细文档 |
43
+ | `get-component-props` | 获取组件属性和 API |
44
+ | `list-component-example` | 获取组件示例代码 |
45
+
46
+ ## 同步组件文档
47
+
48
+ ```bash
49
+ npm run sync
50
+ ```
51
+
52
+ ## 构建
53
+
54
+ ```bash
55
+ npm run build
56
+ ```
57
+
58
+ ## 发布
59
+
60
+ ```bash
61
+ npm publish --access public
62
+ ```
63
+
64
+ ## 配置
65
+
66
+ 配置文件位于 `src/config.ts`:
67
+
68
+ ```typescript
69
+ {
70
+ paths: {
71
+ dataDir: "metaData",
72
+ componentsDir: "metaData/components",
73
+ componentsIndexPath: "metaData/components-index.json"
74
+ },
75
+ server: {
76
+ name: "arco-mcp",
77
+ version: "1.0.0",
78
+ description: "Provides documentation, examples for Arco Design Mobile components"
79
+ }
80
+ }
81
+ ```
82
+
83
+ ## License
84
+
85
+ MIT
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+
7
+ // src/tools/components.ts
8
+ import { z } from "zod";
9
+
10
+ // src/services/component.service.ts
11
+ import { existsSync, readdirSync } from "fs";
12
+ import { readFile } from "fs/promises";
13
+ import { join as join3 } from "path";
14
+
15
+ // src/config.ts
16
+ import { dirname, resolve } from "path";
17
+ import { fileURLToPath } from "url";
18
+ var __dirname = dirname(fileURLToPath(import.meta.url));
19
+ var config = {
20
+ paths: {
21
+ dataDir: resolve(__dirname, "../metaData"),
22
+ componentsDir: resolve(__dirname, "../metaData/components"),
23
+ componentsIndexPath: resolve(
24
+ __dirname,
25
+ "../metaData/components-index.json"
26
+ )
27
+ },
28
+ server: {
29
+ name: "arco-mcp",
30
+ version: "1.0.0",
31
+ description: "Provides documentation, examples for Arco Design Mobile components"
32
+ }
33
+ };
34
+
35
+ // src/utils/logger.ts
36
+ import { appendFile, mkdir } from "fs/promises";
37
+ import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
38
+ import { fileURLToPath as fileURLToPath2 } from "url";
39
+ var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
40
+ var LOG_DIR = resolve2(__dirname2, "../../logs");
41
+ var LOG_FILE = join2(LOG_DIR, "mcp.log");
42
+ async function ensureLogDir() {
43
+ try {
44
+ await mkdir(LOG_DIR, { recursive: true });
45
+ } catch {
46
+ }
47
+ }
48
+ async function writeLog(level, message) {
49
+ await ensureLogDir();
50
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
51
+ const logLine = `[${timestamp}] [${level}] ${message}
52
+ `;
53
+ await appendFile(LOG_FILE, logLine);
54
+ }
55
+ var logService = {
56
+ async info(message) {
57
+ await writeLog("INFO", message);
58
+ },
59
+ async error(message) {
60
+ await writeLog("ERROR", message);
61
+ },
62
+ async warn(message) {
63
+ await writeLog("WARN", message);
64
+ }
65
+ };
66
+
67
+ // src/services/component.service.ts
68
+ var componentRegistryCache = null;
69
+ var fetchComponentRegistry = async () => {
70
+ if (componentRegistryCache) {
71
+ return componentRegistryCache;
72
+ }
73
+ try {
74
+ const indexData = await readFile(config.paths.componentsIndexPath, "utf-8");
75
+ componentRegistryCache = JSON.parse(indexData);
76
+ return componentRegistryCache;
77
+ } catch (error) {
78
+ await logService.error(error.message);
79
+ return [];
80
+ }
81
+ };
82
+ var locateComponentByName = async (componentName) => {
83
+ const components = await fetchComponentRegistry();
84
+ return components.find(
85
+ (c) => c.name.toLowerCase() === componentName.toLowerCase() || c.dirName.toLowerCase() === componentName.toLowerCase()
86
+ );
87
+ };
88
+ var retrieveComponentDocumentation = async (componentName) => {
89
+ const component = await locateComponentByName(componentName);
90
+ if (!component) {
91
+ return `Documentation for component "${componentName}" not found`;
92
+ }
93
+ const docPath = join3(config.paths.componentsDir, component.dirName, "doc.md");
94
+ try {
95
+ if (existsSync(docPath)) {
96
+ return await readFile(docPath, "utf-8");
97
+ } else {
98
+ return `Documentation for ${component.name} not found`;
99
+ }
100
+ } catch (error) {
101
+ await logService.error(`${component.name}: ${error.message}`);
102
+ return `Failed to load documentation for ${component.name}`;
103
+ }
104
+ };
105
+ var fetchComponentApiDetails = async (componentName) => {
106
+ const component = await locateComponentByName(componentName);
107
+ if (!component) {
108
+ return `API documentation for component "${componentName}" not found`;
109
+ }
110
+ try {
111
+ const apiPath = join3(
112
+ config.paths.componentsDir,
113
+ component.dirName,
114
+ "api.md"
115
+ );
116
+ if (existsSync(apiPath)) {
117
+ return await readFile(apiPath, "utf-8");
118
+ }
119
+ return `API documentation for ${component.name} not found`;
120
+ } catch (error) {
121
+ await logService.error(`${component.name}: ${error.message}`);
122
+ return `Failed to load API documentation for ${component.name}`;
123
+ }
124
+ };
125
+ var fetchComponentExamples = async (componentName) => {
126
+ const component = await locateComponentByName(componentName);
127
+ if (!component) {
128
+ return "Component not found";
129
+ }
130
+ const examplesDir = join3(
131
+ config.paths.componentsDir,
132
+ component.dirName,
133
+ "example"
134
+ );
135
+ if (!existsSync(examplesDir)) {
136
+ return `No example found for ${component.name}`;
137
+ }
138
+ try {
139
+ const files = readdirSync(examplesDir);
140
+ const tsxFiles = files.filter((file) => file.endsWith(".tsx"));
141
+ if (tsxFiles.length === 0) {
142
+ return `No example found for ${component.name}`;
143
+ }
144
+ const examples = [];
145
+ for (const tsxFile of tsxFiles) {
146
+ const content = await readFile(join3(examplesDir, tsxFile), "utf-8");
147
+ examples.push(`## ${tsxFile}
148
+
149
+ \`\`\`tsx
150
+ ${content}
151
+ \`\`\``);
152
+ }
153
+ return examples.join("\n\n");
154
+ } catch (error) {
155
+ await logService.error(`${component.name}: ${error.message}`);
156
+ return `Failed to load examples for ${component.name}`;
157
+ }
158
+ };
159
+
160
+ // src/tools/components.ts
161
+ function registerArcoTools(server) {
162
+ server.tool(
163
+ "list-components",
164
+ "Lists all available Arco Design Mobile components",
165
+ async () => {
166
+ const components = await fetchComponentRegistry();
167
+ return {
168
+ content: [
169
+ {
170
+ type: "text",
171
+ text: components.map((c) => c.name).join(", ")
172
+ }
173
+ ]
174
+ };
175
+ }
176
+ );
177
+ server.tool(
178
+ "get-component-docs",
179
+ "Gets detailed documentation for a specific Arco Design Mobile component",
180
+ { componentName: z.string() },
181
+ async (args) => {
182
+ const documentation = await retrieveComponentDocumentation(
183
+ args.componentName
184
+ );
185
+ return {
186
+ content: [
187
+ {
188
+ type: "text",
189
+ text: documentation
190
+ }
191
+ ]
192
+ };
193
+ }
194
+ );
195
+ server.tool(
196
+ "get-component-props",
197
+ "Gets the props and API documentation for a specific Arco Design Mobile component",
198
+ { componentName: z.string() },
199
+ async (args) => {
200
+ const propsSection = await fetchComponentApiDetails(args.componentName);
201
+ return {
202
+ content: [
203
+ {
204
+ type: "text",
205
+ text: propsSection
206
+ }
207
+ ]
208
+ };
209
+ }
210
+ );
211
+ server.tool(
212
+ "list-component-example",
213
+ "Lists all example available for a specific Arco Design Mobile component with descriptions",
214
+ { componentName: z.string() },
215
+ async (args) => {
216
+ const examplesMarkdown = await fetchComponentExamples(args.componentName);
217
+ return {
218
+ content: [
219
+ {
220
+ type: "text",
221
+ text: examplesMarkdown
222
+ }
223
+ ]
224
+ };
225
+ }
226
+ );
227
+ }
228
+
229
+ // src/index.ts
230
+ async function startMcpServer() {
231
+ const server = new McpServer({
232
+ name: config.server.name,
233
+ version: config.server.version,
234
+ description: config.server.description
235
+ });
236
+ await logService.info("\u670D\u52A1\u542F\u52A8\u6210\u529F");
237
+ registerArcoTools(server);
238
+ const transport = new StdioServerTransport();
239
+ await server.connect(transport);
240
+ }
241
+ startMcpServer().catch(async (error) => {
242
+ await logService.error(`\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${error.message}`);
243
+ process.exit(1);
244
+ });
@@ -0,0 +1,102 @@
1
+ ### 反馈
2
+
3
+ # 动作面板 ActionSheet
4
+
5
+ 动作面板组件
6
+
7
+ ======
8
+
9
+ > 属性/Props
10
+
11
+ |参数|描述|类型|默认值|
12
+ |----------|-------------|------|------|
13
+ |items|选项配置,详情见 ActionSheetItemOptions|ActionSheetItemOptions\[\]|必填|
14
+ |cancelText|取消按钮内容,传值则会展示,点击后关闭动作面板|ReactNode|-|
15
+ |title|面板标题内容|ReactNode|-|
16
+ |subTitle|面板副标题内容|ReactNode|-|
17
+ |needBottomOffset|从底部滑出的菜单内容是否适配ipx底部|boolean|true|
18
+ |unmountOnExit|是否在退出时卸载内容|boolean|true|
19
+ |getContainer|获取挂载容器|() =\> HTMLElement|-|
20
+ |onClose|关闭后回调(动画执行完毕)|(scene?: string) =\> void|-|
21
+ |visible|是否展示菜单(受控)|boolean|必填|
22
+ |close|关闭菜单方法|(e: MouseEvent\<HTMLElement, MouseEvent\>) =\> void|必填|
23
+ |translateZ|\[即将废弃\] 开启translateZ强制提升|boolean|false|
24
+ |maskTransitionTimeout|菜单蒙层动画时长|number \| \{ appear?: number; enter?: number; exit?: number; \}|{ enter: 450, exit: 240 }|
25
+ |contentTransitionTimeout|菜单内容动画时长|number \| \{ appear?: number; enter?: number; exit?: number; \}|{ enter: 450, exit: 240 }|
26
+ |contentTransitionType|内容过渡动画类名|string|\`slide-from-${props.direction}\`|
27
+ |className|自定义类名|string|-|
28
+ |maskClass|自定义蒙层类名|string|-|
29
+ |maskStyle|自定义蒙层样式|CSSProperties|-|
30
+ |contentClass|自定义内容类名|string|-|
31
+ |contentStyle|自定义内容样式|CSSProperties|-|
32
+ |maskTransitionType|蒙层过渡动画类名|string|"fade"|
33
+ |contentTransitionVarType|内容过渡动画类名变量标识|string|-|
34
+ |maskClosable|点击蒙层是否关闭菜单|boolean|true|
35
+ |animatingClosable|执行进场动画时点击蒙层是否可关闭菜单|boolean|false|
36
+ |mountOnEnter|是否在打开菜单时再加载内容|boolean|true|
37
+ |preventBodyScroll|弹窗打开时是否禁止body的滚动|boolean|true|
38
+ |initialBodyOverflow|页面初始 overflow 状态,即关闭弹窗时 overflow 应该还原的状态|string|第一个全屏组件(弹窗、toast等)打开时页面overflow值|
39
+ |gestureOutOfControl|是否禁用滚动容器手势判断,禁用后交给业务方自己判断|boolean|false|
40
+ |onOpen|打开后回调(动画执行完毕)|() =\> void|-|
41
+ |onMaskClick|点击蒙层回调,maskClosable=false时也会触发|() =\> void|-|
42
+ |onTouchMove|弹窗的touchmove回调|(e: TouchEvent, prevented: boolean, direction: "x" \| "y") =\> void|-|
43
+ |onPreventTouchMove|非滚动区域或滚动到顶部及底部时的触摸事件回调|(e: TouchEvent, direction: "x" \| "y") =\> void|-|
44
+
45
+ > 引用/Refs
46
+
47
+ |参数|描述|类型|
48
+ |----------|-------------|------|
49
+ |dom|最外层元素 DOM|HTMLDivElement|
50
+
51
+ > 方法/Methods
52
+
53
+ |方法名|描述|类型|
54
+ |----------|-------------|------|
55
+ |open|打开动作面板|(config: ActionSheetProps) =\> \{ close: () =\> void; update: (newConfig: ActionSheetProps) =\> void; \}|
56
+
57
+ > ActionSheetItemOptions
58
+
59
+ |参数|描述|类型|
60
+ |----------|-------------|------|
61
+ |content|选项文字内容|ReactNode|
62
+ |status|状态,disabled 状态下不可点,danger 状态字体飘红|"normal" \| "disabled" \| "danger"|
63
+ |className|选项文字自定义类名|string|
64
+ |style|选项文字自定义样式|CSSProperties|
65
+ |onClick|点击选项事件,返回值为 true 时可以阻止动作面板关闭|(e?: MouseEvent\<HTMLElement, MouseEvent\>) =\> boolean \| void \| Promise\<boolean \| void\>|
66
+
67
+ > GlobalContextParams
68
+
69
+ |参数|描述|类型|默认值|
70
+ |----------|-------------|------|------|
71
+ |prefixCls|组件类名前缀|string|"arco"|
72
+ |system|手动控制当前所在系统,传入后将直接使用传入的值,ssr场景需指定系统初始值时适用|"" \| "pc" \| "android" \| "ios"|""|
73
+ |useDarkMode|是否监听系统原生的暗黑模式变化(prefers\-color\-scheme: dark)以判断是否切为暗黑模式|boolean|false|
74
+ |isDarkMode|是否处于暗黑模式,指定后以指定的值为准|boolean|false|
75
+ |darkModeSelector|当处于暗黑模式时,body上挂载的类名,为空值时不挂载类名|string|"arco-theme-dark"|
76
+ |theme|主题变量,传入后将在线替换css变量,需设置less变量 @use\-css\-vars: 1|Record\<string, string\>|-|
77
+ |locale|国际化语言包配置|ILocale|-|
78
+ |useRtl|是否使用Rtl模式|boolean|false|
79
+ |onDarkModeChange|当系统原生暗黑模式发生变化时触发,useDarkMode=true 时有效|(isDark: boolean) =\> void|-|
80
+ |createRoot|React19 修改了 createRoot 的引入路径,导致组件内部无法直接引入(低react版本会找不到模块)。因此使用 react 19 的用户需从外部传入 createRoot 方法|CreateRootFnType|-|
81
+
82
+ > ILocale
83
+
84
+ |参数|描述|类型|
85
+ |----------|-------------|------|
86
+ |locale|语言类型|string|
87
+ |LoadMore|-|\{ loadMoreText: string; loadingText: string; noDataText: string; failLoadText: string; prepareScrollText: string; prepareClickText: string; \}|
88
+ |Picker|-|\{ okText: string; cancelText: string; \}|
89
+ |Tag|-|\{ addTag: string; \}|
90
+ |Dialog|-|\{ okText: string; cancelText: string; \}|
91
+ |SwipeLoad|-|\{ normalText: string; activeText: string; \}|
92
+ |PullRefresh|-|\{ loadingText: string; pullingText: string; finishText: string; loosingText: string; \}|
93
+ |DropdownMenu|-|\{ select: string; \}|
94
+ |Pagination|-|\{ previousPage: string; nextPage: string; \}|
95
+ |Image|-|\{ loadError: string; \}|
96
+ |ImagePicker|-|\{ loadError: string; \}|
97
+ |SearchBar|-|\{ placeholder: string; cancelBtn: string; \}|
98
+ |Stepper|-|\{ minusButtonName: string; addButtonName: string; \}|
99
+ |Keyboard|-|\{ confirm: string; \}|
100
+ |Form|-|\{ required: string; type: \{ email: string; url: string; string: string; number: string; array: string; object: string; boolean: string; \}; number: \{ min: string; max: string; equal: string; range: string; positive: string; negative: string; \}; \.\.\. 4 more \.\.\.; pickerDefaultHint: string; \}|
101
+ |NavBar|-|\{ backBtnAriaLabel: string; \}|
102
+ |Uploader|-|\{ uploadBtn: string; retryUpload: string; \}|
@@ -0,0 +1,199 @@
1
+ import React, {
2
+ useRef,
3
+ forwardRef,
4
+ Ref,
5
+ useImperativeHandle,
6
+ ReactNode,
7
+ CSSProperties,
8
+ } from 'react';
9
+ import { cls, componentWrapper } from '@arco-design/mobile-utils';
10
+ import { Promise } from 'es6-promise';
11
+ import { ContextLayout, CompWithGlobalContext } from '../context-provider';
12
+ import Popup, { PopupProps, PopupRef } from '../popup';
13
+ import { OpenBaseProps } from '../masking';
14
+ import { open } from './methods';
15
+
16
+ export interface ActionSheetItemOptions {
17
+ /**
18
+ * 选项文字内容
19
+ * @en Option text
20
+ */
21
+ content: ReactNode;
22
+ /**
23
+ * 状态,disabled 状态下不可点,danger 状态字体飘红
24
+ * @en Status, it isn't clickable in disabled status, its font is red in danger status
25
+ * */
26
+ status?: 'normal' | 'disabled' | 'danger';
27
+ /**
28
+ * 选项文字自定义类名
29
+ * @en Custom classname for option content
30
+ */
31
+ className?: string;
32
+ /**
33
+ * 选项文字自定义样式
34
+ * @en Custom stylesheet for option content
35
+ */
36
+ style?: CSSProperties;
37
+ /**
38
+ * 点击选项事件,返回值为 true 时可以阻止动作面板关闭
39
+ * @en Click option event, actionSheet will be prevent from closing when returning true
40
+ */
41
+ onClick?: (
42
+ e?: React.MouseEvent<HTMLElement, MouseEvent>,
43
+ ) => (void | boolean) | Promise<void | boolean>;
44
+ }
45
+
46
+ export interface ActionSheetProps
47
+ extends Omit<
48
+ PopupProps,
49
+ 'children' | 'getScrollContainer' | 'orientationDirection' | 'direction'
50
+ > {
51
+ /**
52
+ * 选项配置,详情见 ActionSheetItemOptions
53
+ * @en Option setting, see ActionSheetItemOptions for details
54
+ */
55
+ items: ActionSheetItemOptions[];
56
+ /**
57
+ * 取消按钮内容,传值则会展示,点击后关闭动作面板
58
+ * @en Cancel button content, the value will be shown, actionSheet will be closed when clicked
59
+ */
60
+ cancelText?: ReactNode;
61
+ /**
62
+ * 面板标题内容
63
+ * @en Title content
64
+ */
65
+ title?: ReactNode;
66
+ /**
67
+ * 面板副标题内容
68
+ * @en Sub title content
69
+ */
70
+ subTitle?: ReactNode;
71
+ /**
72
+ * 从底部滑出的菜单内容是否适配ipx底部
73
+ * @en Whether the content of the menu that slides out from the bottom fits the bottom of the iphoneX
74
+ * @default true
75
+ */
76
+ needBottomOffset?: boolean;
77
+ }
78
+
79
+ export interface ActionSheetRef {
80
+ /**
81
+ * 最外层元素 DOM
82
+ * @en The outermost element DOM
83
+ */
84
+ dom: HTMLDivElement | null;
85
+ }
86
+
87
+ const ActionSheet = forwardRef((props: ActionSheetProps, ref: Ref<ActionSheetRef>) => {
88
+ const {
89
+ className = '',
90
+ items,
91
+ cancelText,
92
+ close,
93
+ title,
94
+ subTitle,
95
+ needBottomOffset = true,
96
+ ...otherProps
97
+ } = props;
98
+ const popupRef = useRef<PopupRef>(null);
99
+
100
+ useImperativeHandle(ref, () => popupRef.current!);
101
+
102
+ function handleItemClick(
103
+ e: React.MouseEvent<HTMLElement, MouseEvent>,
104
+ item: ActionSheetItemOptions,
105
+ ) {
106
+ e.stopPropagation();
107
+ if (item.status === 'disabled') {
108
+ return;
109
+ }
110
+ const result = item.onClick ? item.onClick(e) : null;
111
+ if (!result || typeof result === 'boolean') {
112
+ !result && close?.(e);
113
+ } else if (result && result.then) {
114
+ result.then(res => !res && close?.(e));
115
+ }
116
+ }
117
+
118
+ return (
119
+ <ContextLayout>
120
+ {({ prefixCls }) => (
121
+ <Popup
122
+ ref={popupRef}
123
+ className={cls(`${prefixCls}-action-sheet`, className)}
124
+ contentClass={`${prefixCls}-action-sheet-content`}
125
+ close={close}
126
+ direction="bottom"
127
+ needBottomOffset={needBottomOffset}
128
+ {...otherProps}
129
+ >
130
+ {title || subTitle ? (
131
+ <div className={`${prefixCls}-action-sheet-header`}>
132
+ {title ? (
133
+ <div className={`${prefixCls}-action-sheet-title`}>{title}</div>
134
+ ) : null}
135
+ {subTitle ? (
136
+ <div className={`${prefixCls}-action-sheet-sub-title`}>
137
+ {subTitle}
138
+ </div>
139
+ ) : null}
140
+ </div>
141
+ ) : null}
142
+ <div className={`${prefixCls}-action-sheet-list`}>
143
+ {(items || []).map((item, index) =>
144
+ item.content ? (
145
+ <div
146
+ className={cls(
147
+ `${prefixCls}-action-sheet-item`,
148
+ item.className,
149
+ item.status || 'normal',
150
+ )}
151
+ key={index}
152
+ style={item.style}
153
+ onClick={e => handleItemClick(e, item)}
154
+ >
155
+ {item.content}
156
+ </div>
157
+ ) : null,
158
+ )}
159
+ </div>
160
+ {cancelText ? (
161
+ <div
162
+ className={`${prefixCls}-action-sheet-item cancel-item`}
163
+ onClick={e => {
164
+ e.stopPropagation();
165
+ close?.(e);
166
+ }}
167
+ >
168
+ {cancelText}
169
+ </div>
170
+ ) : null}
171
+ </Popup>
172
+ )}
173
+ </ContextLayout>
174
+ );
175
+ });
176
+
177
+ export function methodsGenerator<P extends OpenBaseProps>(Comp: React.FunctionComponent<P>) {
178
+ return {
179
+ /**
180
+ * 打开动作面板
181
+ * @desc {en} Open actionsheet
182
+ * @param {ActionSheetProps} config setting
183
+ * @returns {{ close: () => void; update: (newConfig: ActionSheetProps) => void; }}
184
+ */
185
+ open: open(Comp),
186
+ };
187
+ }
188
+
189
+ const ActionSheetWithGlobalContext = CompWithGlobalContext(ActionSheet);
190
+
191
+ /**
192
+ * 动作面板组件
193
+ * @en ActionSheet Component
194
+ * @type 反馈
195
+ * @type_en FeedBack
196
+ * @name 动作面板
197
+ * @name_en ActionSheet
198
+ */
199
+ export default componentWrapper(ActionSheet, methodsGenerator(ActionSheetWithGlobalContext));
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { open as maskingOpen, OpenBaseProps } from '../masking/methods';
3
+
4
+ export function open<P extends OpenBaseProps>(Component: React.FunctionComponent<P>) {
5
+ return maskingOpen(Component, 'ARCO_ACTION_SHEET');
6
+ }
@@ -0,0 +1,57 @@
1
+ ### 信息展示
2
+
3
+ # 头像 Avatar
4
+
5
+ 头像展示组件,支持圆形和方形两种形状,支持图片文字头像,支持五种尺寸。
6
+
7
+ ======
8
+
9
+ > 属性/Props
10
+
11
+ |参数|描述|类型|默认值|
12
+ |----------|-------------|------|------|
13
+ |shape|形状|"circle" \| "square"|"circle"|
14
+ |size|尺寸|"medium" \| "large" \| "small" \| "smaller" \| "ultra\-small"|"small"|
15
+ |src|图片头像的资源地址|string|-|
16
+ |imageProps|图片头像组件参数,透传给Image组件|Partial\<ImageProps & RefAttributes\<ImageRef\>\>|-|
17
+ |decoration|图片头像上的装饰|ReactNode|null|
18
+ |textAvatar|文字头像,中文建议取两个字,英文建议在三个字以下|string|""|
19
+ |avatarStyle|头像元素的自定义样式|CSSProperties|{}|
20
+ |avatarClass|头像元素的自定义类名|string|""|
21
+ |autoFixFontSize|是否自动根据头像尺寸调整字体大小|boolean|true|
22
+ |autoFixFontOffset|自动调整文字头像大小时,文字距离头像容器左右的安全距离|number|2|
23
+ |avatarName|头像旁的用户名信息|string|""|
24
+ |avatarDesc|头像旁的辅助信息,需要和用户名一起出现|string|""|
25
+ |renderInfo|自定义头像描述信息|ReactNode|null|
26
+ |defaultOverLap|头像组件为空时默认的状态|ReactNode|用户图标|
27
+ |onClick|点击头像的回调事件|(e: MouseEvent\<HTMLElement, MouseEvent\>) =\> void|() => {}|
28
+ |onClickDecoration|点击头像上的装饰|(e: MouseEvent\<HTMLElement, MouseEvent\>) =\> void|() => {}|
29
+ |children|自定义组件内容|ReactNode|null|
30
+ |className|自定义类名|string|""|
31
+ |style|自定义样式|CSSProperties|{}|
32
+
33
+ > 引用/Refs
34
+
35
+ |参数|描述|类型|
36
+ |----------|-------------|------|
37
+ |dom|组件外层dom元素|HTMLDivElement|
38
+
39
+ > Avatar.Group
40
+
41
+ 头像叠层
42
+
43
+ |参数|描述|类型|默认值|
44
+ |----------|-------------|------|------|
45
+ |isGroup|是否为头像组|boolean|必填|
46
+ |shape|形状,优先级低于Avatar组件本身|"circle" \| "square"|"circle"|
47
+ |size|尺寸,优先级低于Avatar组件本身|"medium" \| "large" \| "small" \| "smaller" \| "ultra\-small"|"medium"|
48
+ |zIndexOrder|头像组叠层层级顺序,z\-index值大小,desc \- 降序,asc \- 升序|"desc" \| "asc"|"desc"|
49
+ |children|自定义组件内容|ReactNode|null|
50
+ |className|自定义类名|string|""|
51
+ |style|自定义样式|CSSProperties|{}|
52
+
53
+ > AvatarGroupRef
54
+
55
+ |参数|描述|类型|
56
+ |----------|-------------|------|
57
+ |dom|组件外层dom元素|HTMLDivElement|