@fjyueke/bify-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.
- package/LICENSE +21 -0
- package/README.md +34 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +248 -0
- package/metaData/components/action-sheet/api.md +74 -0
- package/metaData/components/action-sheet/doc.md +243 -0
- package/metaData/components/action-sheet/example/index.tsx +116 -0
- package/metaData/components/area-picker/api.md +25 -0
- package/metaData/components/area-picker/doc.md +132 -0
- package/metaData/components/area-picker/example/index.tsx +60 -0
- package/metaData/components/avatar/api.md +19 -0
- package/metaData/components/avatar/doc.md +170 -0
- package/metaData/components/avatar/example/index.tsx +76 -0
- package/metaData/components/back-top/api.md +21 -0
- package/metaData/components/back-top/doc.md +142 -0
- package/metaData/components/back-top/example/index.tsx +96 -0
- package/metaData/components/backdrop/api.md +20 -0
- package/metaData/components/backdrop/doc.md +98 -0
- package/metaData/components/backdrop/example/index.tsx +33 -0
- package/metaData/components/badge/api.md +10 -0
- package/metaData/components/badge/doc.md +169 -0
- package/metaData/components/badge/example/index.tsx +81 -0
- package/metaData/components/button/api.md +31 -0
- package/metaData/components/button/doc.md +235 -0
- package/metaData/components/button/example/index.tsx +235 -0
- package/metaData/components/calendar/api.md +62 -0
- package/metaData/components/calendar/doc.md +516 -0
- package/metaData/components/calendar/example/index.tsx +501 -0
- package/metaData/components/cascader/api.md +55 -0
- package/metaData/components/cascader/doc.md +358 -0
- package/metaData/components/cascader/example/index.tsx +159 -0
- package/metaData/components/cell/api.md +37 -0
- package/metaData/components/cell/doc.md +158 -0
- package/metaData/components/cell/example/index.tsx +44 -0
- package/metaData/components/checkbox/api.md +35 -0
- package/metaData/components/checkbox/doc.md +203 -0
- package/metaData/components/checkbox/example/index.tsx +94 -0
- package/metaData/components/circle/api.md +17 -0
- package/metaData/components/circle/doc.md +123 -0
- package/metaData/components/circle/example/index.tsx +81 -0
- package/metaData/components/collapse/api.md +31 -0
- package/metaData/components/collapse/doc.md +142 -0
- package/metaData/components/collapse/example/index.tsx +81 -0
- package/metaData/components/config-provider/api.md +7 -0
- package/metaData/components/config-provider/doc.md +193 -0
- package/metaData/components/config-provider/example/index.tsx +54 -0
- package/metaData/components/countdown/api.md +46 -0
- package/metaData/components/countdown/doc.md +167 -0
- package/metaData/components/countdown/example/index.tsx +70 -0
- package/metaData/components/datetime-picker/api.md +25 -0
- package/metaData/components/datetime-picker/doc.md +317 -0
- package/metaData/components/datetime-picker/example/index.tsx +265 -0
- package/metaData/components/dialog/api.md +66 -0
- package/metaData/components/dialog/doc.md +292 -0
- package/metaData/components/dialog/example/index.tsx +138 -0
- package/metaData/components/divider/api.md +15 -0
- package/metaData/components/divider/doc.md +108 -0
- package/metaData/components/divider/example/index.tsx +45 -0
- package/metaData/components/dropdown-menu/api.md +37 -0
- package/metaData/components/dropdown-menu/doc.md +279 -0
- package/metaData/components/dropdown-menu/example/index.tsx +182 -0
- package/metaData/components/empty/api.md +20 -0
- package/metaData/components/empty/doc.md +126 -0
- package/metaData/components/empty/example/index.tsx +66 -0
- package/metaData/components/field/api.md +10 -0
- package/metaData/components/field/doc.md +274 -0
- package/metaData/components/field/example/index.tsx +203 -0
- package/metaData/components/fixed-nav/api.md +21 -0
- package/metaData/components/fixed-nav/doc.md +196 -0
- package/metaData/components/fixed-nav/example/index.tsx +80 -0
- package/metaData/components/fixed-view/api.md +10 -0
- package/metaData/components/fixed-view/doc.md +25 -0
- package/metaData/components/fixed-view/example/index.tsx +12 -0
- package/metaData/components/flex/api.md +18 -0
- package/metaData/components/flex/doc.md +103 -0
- package/metaData/components/flex/example/index.tsx +58 -0
- package/metaData/components/floating-bubble/api.md +18 -0
- package/metaData/components/floating-bubble/doc.md +94 -0
- package/metaData/components/floating-bubble/example/index.tsx +55 -0
- package/metaData/components/floating-panel/api.md +19 -0
- package/metaData/components/floating-panel/doc.md +174 -0
- package/metaData/components/floating-panel/example/index.tsx +131 -0
- package/metaData/components/form/api.md +124 -0
- package/metaData/components/form/doc.md +759 -0
- package/metaData/components/form/example/index.tsx +222 -0
- package/metaData/components/grid/api.md +28 -0
- package/metaData/components/grid/doc.md +167 -0
- package/metaData/components/grid/example/index.tsx +80 -0
- package/metaData/components/image/api.md +42 -0
- package/metaData/components/image/doc.md +117 -0
- package/metaData/components/image/example/index.tsx +76 -0
- package/metaData/components/index-list/api.md +39 -0
- package/metaData/components/index-list/doc.md +176 -0
- package/metaData/components/index-list/example/index.tsx +110 -0
- package/metaData/components/list/api.md +30 -0
- package/metaData/components/list/doc.md +317 -0
- package/metaData/components/list/example/index.tsx +218 -0
- package/metaData/components/loading/api.md +10 -0
- package/metaData/components/loading/doc.md +113 -0
- package/metaData/components/loading/example/index.tsx +47 -0
- package/metaData/components/navbar/api.md +26 -0
- package/metaData/components/navbar/doc.md +85 -0
- package/metaData/components/navbar/example/index.tsx +28 -0
- package/metaData/components/notice-bar/api.md +28 -0
- package/metaData/components/notice-bar/doc.md +154 -0
- package/metaData/components/notice-bar/example/index.tsx +107 -0
- package/metaData/components/notify/api.md +28 -0
- package/metaData/components/notify/doc.md +140 -0
- package/metaData/components/notify/example/index.tsx +89 -0
- package/metaData/components/number-keyboard/api.md +21 -0
- package/metaData/components/number-keyboard/doc.md +247 -0
- package/metaData/components/number-keyboard/example/index.tsx +201 -0
- package/metaData/components/pagination/api.md +18 -0
- package/metaData/components/pagination/doc.md +113 -0
- package/metaData/components/pagination/example/index.tsx +73 -0
- package/metaData/components/password-input/api.md +25 -0
- package/metaData/components/password-input/doc.md +126 -0
- package/metaData/components/password-input/example/index.tsx +124 -0
- package/metaData/components/picker/api.md +61 -0
- package/metaData/components/picker/doc.md +336 -0
- package/metaData/components/picker/example/index.tsx +232 -0
- package/metaData/components/popup/api.md +48 -0
- package/metaData/components/popup/doc.md +150 -0
- package/metaData/components/popup/example/index.tsx +214 -0
- package/metaData/components/progress/api.md +11 -0
- package/metaData/components/progress/doc.md +105 -0
- package/metaData/components/progress/example/index.tsx +58 -0
- package/metaData/components/pull-refresh/api.md +18 -0
- package/metaData/components/pull-refresh/doc.md +198 -0
- package/metaData/components/pull-refresh/example/index.tsx +153 -0
- package/metaData/components/radio/api.md +26 -0
- package/metaData/components/radio/doc.md +201 -0
- package/metaData/components/radio/example/index.tsx +103 -0
- package/metaData/components/rate/api.md +23 -0
- package/metaData/components/rate/doc.md +122 -0
- package/metaData/components/rate/example/index.tsx +36 -0
- package/metaData/components/rolling-text/api.md +23 -0
- package/metaData/components/rolling-text/doc.md +153 -0
- package/metaData/components/rolling-text/example/index.tsx +150 -0
- package/metaData/components/safe-area/api.md +8 -0
- package/metaData/components/safe-area/doc.md +30 -0
- package/metaData/components/safe-area/example/index.tsx +16 -0
- package/metaData/components/search/api.md +35 -0
- package/metaData/components/search/doc.md +185 -0
- package/metaData/components/search/example/index.tsx +101 -0
- package/metaData/components/share-sheet/api.md +48 -0
- package/metaData/components/share-sheet/doc.md +215 -0
- package/metaData/components/share-sheet/example/index.tsx +143 -0
- package/metaData/components/sidebar/api.md +28 -0
- package/metaData/components/sidebar/doc.md +122 -0
- package/metaData/components/sidebar/example/index.tsx +58 -0
- package/metaData/components/signature/api.md +19 -0
- package/metaData/components/signature/doc.md +115 -0
- package/metaData/components/signature/example/index.tsx +56 -0
- package/metaData/components/skeleton/api.md +45 -0
- package/metaData/components/skeleton/doc.md +131 -0
- package/metaData/components/skeleton/example/index.tsx +80 -0
- package/metaData/components/slider/api.md +28 -0
- package/metaData/components/slider/doc.md +151 -0
- package/metaData/components/slider/example/index.tsx +54 -0
- package/metaData/components/space/api.md +12 -0
- package/metaData/components/space/doc.md +125 -0
- package/metaData/components/space/example/index.tsx +75 -0
- package/metaData/components/stepper/api.md +37 -0
- package/metaData/components/stepper/doc.md +152 -0
- package/metaData/components/stepper/example/index.tsx +45 -0
- package/metaData/components/steps/api.md +9 -0
- package/metaData/components/steps/doc.md +143 -0
- package/metaData/components/steps/example/index.tsx +93 -0
- package/metaData/components/sticky/api.md +16 -0
- package/metaData/components/sticky/doc.md +87 -0
- package/metaData/components/sticky/example/index.tsx +62 -0
- package/metaData/components/swipe-cell/api.md +19 -0
- package/metaData/components/swipe-cell/doc.md +105 -0
- package/metaData/components/swipe-cell/example/index.tsx +62 -0
- package/metaData/components/swiper/api.md +22 -0
- package/metaData/components/swiper/doc.md +228 -0
- package/metaData/components/swiper/example/index.tsx +118 -0
- package/metaData/components/switch/api.md +17 -0
- package/metaData/components/switch/doc.md +110 -0
- package/metaData/components/switch/example/index.tsx +57 -0
- package/metaData/components/tabbar/api.md +27 -0
- package/metaData/components/tabbar/doc.md +160 -0
- package/metaData/components/tabbar/example/index.tsx +99 -0
- package/metaData/components/tabs/api.md +36 -0
- package/metaData/components/tabs/doc.md +307 -0
- package/metaData/components/tabs/example/index.tsx +231 -0
- package/metaData/components/tag/api.md +17 -0
- package/metaData/components/tag/doc.md +162 -0
- package/metaData/components/tag/example/index.tsx +84 -0
- package/metaData/components/text-ellipsis/api.md +26 -0
- package/metaData/components/text-ellipsis/doc.md +135 -0
- package/metaData/components/text-ellipsis/example/index.tsx +44 -0
- package/metaData/components/timeline/api.md +20 -0
- package/metaData/components/timeline/doc.md +210 -0
- package/metaData/components/timeline/example/index.tsx +145 -0
- package/metaData/components/toast/api.md +39 -0
- package/metaData/components/toast/doc.md +256 -0
- package/metaData/components/toast/example/index.tsx +136 -0
- package/metaData/components/tree-select/api.md +19 -0
- package/metaData/components/tree-select/doc.md +185 -0
- package/metaData/components/tree-select/example/index.tsx +112 -0
- package/metaData/components/uploader/api.md +32 -0
- package/metaData/components/uploader/doc.md +340 -0
- package/metaData/components/uploader/example/index.tsx +222 -0
- package/metaData/components/watermark/api.md +18 -0
- package/metaData/components/watermark/doc.md +97 -0
- package/metaData/components/watermark/example/index.tsx +62 -0
- package/metaData/components-index.json +274 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Taroify
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img alt="logo" src="https://img.yzcdn.cn/vant/logo.png" width="120" style="margin-bottom: 10px;">
|
|
5
|
+
</p>
|
|
6
|
+
<h3 align="center">可靠的小程序端 Taro React UI 组件库 MCP</h3>
|
|
7
|
+
|
|
8
|
+
## 介绍
|
|
9
|
+
|
|
10
|
+
Tify 是基于 Taroify 的移动端组件库,基于 Vant 视觉规范,提供一致的 API 接口,助力开发者快速搭建小程序应用。
|
|
11
|
+
|
|
12
|
+
Tify MCP 是一项独立的 MCP(模型上下文协议)服务,旨在将 Tify 与大模型连接起来。它使大模型能够直接从文档中检索组件、API数据。
|
|
13
|
+
|
|
14
|
+
- 直接使用 npx 运行
|
|
15
|
+
- 无需外部依赖,只需要 Node 环境
|
|
16
|
+
|
|
17
|
+
## Cursor 用法
|
|
18
|
+
|
|
19
|
+
Cursor Mcp 使用指南参考:<https://docs.cursor.com/context/model-context-protocol#using-mcp-tools-in-agent>
|
|
20
|
+
|
|
21
|
+
``` json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"@fjyueke/tify-mcp": {
|
|
25
|
+
"command": "npx",
|
|
26
|
+
"args": [
|
|
27
|
+
"-y",
|
|
28
|
+
"@fjyueke/tify-mcp",
|
|
29
|
+
],
|
|
30
|
+
"env": {}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
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 "node:fs";
|
|
12
|
+
import { readFile } from "node:fs/promises";
|
|
13
|
+
import { join as join2 } from "node:path";
|
|
14
|
+
|
|
15
|
+
// src/config.ts
|
|
16
|
+
import { dirname, resolve } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node: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: "tify-mcp",
|
|
30
|
+
version: "1.0.0",
|
|
31
|
+
description: "Provides documentation and example for Tify components"
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/utils/logger.ts
|
|
36
|
+
import { appendFile, mkdir } from "node:fs/promises";
|
|
37
|
+
import { dirname as dirname2, resolve as resolve2 } from "node:path";
|
|
38
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
39
|
+
var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
|
|
40
|
+
var logDir = resolve2(__dirname2, "../../logs");
|
|
41
|
+
var logFile = resolve2(logDir, "mcp.log");
|
|
42
|
+
var formatMessage = (level, message) => {
|
|
43
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
44
|
+
return `${timestamp} [${level}] ${message}
|
|
45
|
+
`;
|
|
46
|
+
};
|
|
47
|
+
var writeLog = async (level, message) => {
|
|
48
|
+
try {
|
|
49
|
+
await mkdir(logDir, { recursive: true });
|
|
50
|
+
await appendFile(logFile, formatMessage(level, message));
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var logService = {
|
|
55
|
+
info: async (message) => {
|
|
56
|
+
await writeLog("INFO", message);
|
|
57
|
+
},
|
|
58
|
+
warn: async (message) => {
|
|
59
|
+
await writeLog("WARN", message);
|
|
60
|
+
},
|
|
61
|
+
error: async (message) => {
|
|
62
|
+
await writeLog("ERROR", message);
|
|
63
|
+
},
|
|
64
|
+
debug: async (message) => {
|
|
65
|
+
if (process.env.DEBUG) {
|
|
66
|
+
await writeLog("DEBUG", message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/services/component.service.ts
|
|
72
|
+
var componentRegistryCache = null;
|
|
73
|
+
var fetchComponentRegistry = async () => {
|
|
74
|
+
if (componentRegistryCache) {
|
|
75
|
+
return componentRegistryCache;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const indexData = await readFile(config.paths.componentsIndexPath, "utf-8");
|
|
79
|
+
componentRegistryCache = JSON.parse(indexData);
|
|
80
|
+
return componentRegistryCache;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
await logService.error(error.message);
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var locateComponentByName = async (componentName) => {
|
|
87
|
+
const components = await fetchComponentRegistry();
|
|
88
|
+
return components.find(
|
|
89
|
+
(c) => c.name.toLowerCase() === componentName.toLowerCase() || c.dirName.toLowerCase() === componentName.toLowerCase()
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
var retrieveComponentDocumentation = async (componentName) => {
|
|
93
|
+
const component = await locateComponentByName(componentName);
|
|
94
|
+
if (!component) {
|
|
95
|
+
return `Documentation for component "${componentName}" not found`;
|
|
96
|
+
}
|
|
97
|
+
const docPath = join2(config.paths.componentsDir, component.dirName, "doc.md");
|
|
98
|
+
try {
|
|
99
|
+
if (existsSync(docPath)) {
|
|
100
|
+
return await readFile(docPath, "utf-8");
|
|
101
|
+
} else {
|
|
102
|
+
return `Documentation for ${component.name} not found`;
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
await logService.error(`${component.name}: ${error.message}`);
|
|
106
|
+
return `Failed to load documentation for ${component.name}`;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
var fetchComponentApiDetails = async (componentName) => {
|
|
110
|
+
const component = await locateComponentByName(componentName);
|
|
111
|
+
if (!component) {
|
|
112
|
+
return `API documentation for component "${componentName}" not found`;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const apiPath = join2(
|
|
116
|
+
config.paths.componentsDir,
|
|
117
|
+
component.dirName,
|
|
118
|
+
"api.md"
|
|
119
|
+
);
|
|
120
|
+
if (existsSync(apiPath)) {
|
|
121
|
+
return await readFile(apiPath, "utf-8");
|
|
122
|
+
}
|
|
123
|
+
return `API documentation for ${component.name} not found`;
|
|
124
|
+
} catch (error) {
|
|
125
|
+
await logService.error(`${component.name}: ${error.message}`);
|
|
126
|
+
return `Failed to load API documentation for ${component.name}`;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var fetchComponentExamples = async (componentName) => {
|
|
130
|
+
const component = await locateComponentByName(componentName);
|
|
131
|
+
if (!component) {
|
|
132
|
+
return "Component not found";
|
|
133
|
+
}
|
|
134
|
+
const examplesDir = join2(
|
|
135
|
+
config.paths.componentsDir,
|
|
136
|
+
component.dirName,
|
|
137
|
+
"example"
|
|
138
|
+
);
|
|
139
|
+
if (!existsSync(examplesDir)) {
|
|
140
|
+
return `No example found for ${component.name}`;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const files = readdirSync(examplesDir);
|
|
144
|
+
const tsxFiles = files.filter((file) => file.endsWith(".tsx"));
|
|
145
|
+
if (tsxFiles.length === 0) {
|
|
146
|
+
return `No example found for ${component.name}`;
|
|
147
|
+
}
|
|
148
|
+
const examples = [];
|
|
149
|
+
for (const tsxFile of tsxFiles) {
|
|
150
|
+
const content = await readFile(join2(examplesDir, tsxFile), "utf-8");
|
|
151
|
+
examples.push(`## ${tsxFile}
|
|
152
|
+
|
|
153
|
+
\`\`\`tsx
|
|
154
|
+
${content}
|
|
155
|
+
\`\`\``);
|
|
156
|
+
}
|
|
157
|
+
return examples.join("\n\n");
|
|
158
|
+
} catch (error) {
|
|
159
|
+
await logService.error(`${component.name}: ${error.message}`);
|
|
160
|
+
return `Failed to load examples for ${component.name}`;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// src/tools/components.ts
|
|
165
|
+
function registerTifyTools(server) {
|
|
166
|
+
server.tool(
|
|
167
|
+
"list-components",
|
|
168
|
+
"Lists all available Tify components",
|
|
169
|
+
async () => {
|
|
170
|
+
const components = await fetchComponentRegistry();
|
|
171
|
+
return {
|
|
172
|
+
content: [
|
|
173
|
+
{
|
|
174
|
+
type: "text",
|
|
175
|
+
text: components.map((c) => c.name).join(", ")
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
server.tool(
|
|
182
|
+
"get-component-docs",
|
|
183
|
+
"Gets detailed documentation for a specific component",
|
|
184
|
+
{ componentName: z.string() },
|
|
185
|
+
async (args) => {
|
|
186
|
+
const documentation = await retrieveComponentDocumentation(
|
|
187
|
+
args.componentName
|
|
188
|
+
);
|
|
189
|
+
return {
|
|
190
|
+
content: [
|
|
191
|
+
{
|
|
192
|
+
type: "text",
|
|
193
|
+
text: documentation
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
server.tool(
|
|
200
|
+
"get-component-props",
|
|
201
|
+
"Gets the props and API documentation for a specific component",
|
|
202
|
+
{ componentName: z.string() },
|
|
203
|
+
async (args) => {
|
|
204
|
+
const propsSection = await fetchComponentApiDetails(args.componentName);
|
|
205
|
+
return {
|
|
206
|
+
content: [
|
|
207
|
+
{
|
|
208
|
+
type: "text",
|
|
209
|
+
text: propsSection
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
server.tool(
|
|
216
|
+
"list-component-example",
|
|
217
|
+
"Lists all example available for a specific component with descriptions",
|
|
218
|
+
{ componentName: z.string() },
|
|
219
|
+
async (args) => {
|
|
220
|
+
const examplesMarkdown = await fetchComponentExamples(args.componentName);
|
|
221
|
+
return {
|
|
222
|
+
content: [
|
|
223
|
+
{
|
|
224
|
+
type: "text",
|
|
225
|
+
text: examplesMarkdown
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/index.ts
|
|
234
|
+
async function startMcpServer() {
|
|
235
|
+
const server = new McpServer({
|
|
236
|
+
name: config.server.name,
|
|
237
|
+
version: config.server.version,
|
|
238
|
+
description: config.server.description
|
|
239
|
+
});
|
|
240
|
+
await logService.info("\u670D\u52A1\u542F\u52A8\u6210\u529F");
|
|
241
|
+
registerTifyTools(server);
|
|
242
|
+
const transport = new StdioServerTransport();
|
|
243
|
+
await server.connect(transport);
|
|
244
|
+
}
|
|
245
|
+
startMcpServer().catch(async (error) => {
|
|
246
|
+
await logService.error(`\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${error.message}`);
|
|
247
|
+
process.exit(1);
|
|
248
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
## API
|
|
2
|
+
|
|
3
|
+
### ActionSheet Props
|
|
4
|
+
|
|
5
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
6
|
+
| -------------------------------- | ------------------------------------- | --------------------------- | -------- |
|
|
7
|
+
| defaultOpen | 默认是否显示动作面板 | _boolean_ | `false` |
|
|
8
|
+
| open | 是否显示动作面板 | _boolean_ | `false` |
|
|
9
|
+
| description <br>`v0.3.0-alpha.0` | 选项上方的描述信息 | _ReactNode_ | - |
|
|
10
|
+
| cancelText <br>`v0.3.0-alpha.0` | 取消按钮文字 | _ReactNode_ | - |
|
|
11
|
+
| actions <br>`v0.3.0-alpha.0` | 面板选项列表 | _ActionSheetActionObject[]_ | - |
|
|
12
|
+
| className | 样式类名 | _string_ | - |
|
|
13
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
14
|
+
| rounded | 是否为圆角 | _string_ | - |
|
|
15
|
+
| safeArea | 安全区的位置,可选值为 `top` `bottom` | _string_ | `bottom` |
|
|
16
|
+
|
|
17
|
+
### ActionSheetActionObject 数据结构
|
|
18
|
+
|
|
19
|
+
| 参数 | 说明 | 类型 |
|
|
20
|
+
| --------- | -------------- | ----------- |
|
|
21
|
+
| name | 标题 | _ReactNode_ |
|
|
22
|
+
| subname | 二级标题 | _ReactNode_ |
|
|
23
|
+
| disabled | 是否为禁用状态 | _boolean_ |
|
|
24
|
+
| loading | 是否为加载状态 | _boolean_ |
|
|
25
|
+
| value | 值 | _any_ |
|
|
26
|
+
| style | | |
|
|
27
|
+
| className | | |
|
|
28
|
+
|
|
29
|
+
### ActionSheet.Backdrop Props
|
|
30
|
+
|
|
31
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
32
|
+
| --------- | ------------------ | ------------------ | ------ |
|
|
33
|
+
| className | 样式类名 | _string_ | - |
|
|
34
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
35
|
+
| duration | 动画时长,单位毫秒 | _number \| string_ | `300` |
|
|
36
|
+
| closeable | 点击是否可以关闭 | _boolean_ | `true` |
|
|
37
|
+
|
|
38
|
+
### ActionSheet.Header Props
|
|
39
|
+
|
|
40
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
41
|
+
| --------- | -------- | --------------- | ------ |
|
|
42
|
+
| className | 样式类名 | _string_ | - |
|
|
43
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
44
|
+
| title | 标题 | _string_ | - |
|
|
45
|
+
| children | 描述信息 | _string_ | - |
|
|
46
|
+
|
|
47
|
+
### ActionSheet.Action Props
|
|
48
|
+
|
|
49
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
50
|
+
| --------- | -------------- | --------------- | ------ |
|
|
51
|
+
| className | 样式类名 | _string_ | - |
|
|
52
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
53
|
+
| name | 标题 | _string_ | - |
|
|
54
|
+
| value | 选项值 | _string_ | - |
|
|
55
|
+
| disabled | 是否为禁用状态 | _boolean_ | - |
|
|
56
|
+
| loading | 是否为加载状态 | _boolean_ | - |
|
|
57
|
+
| children | 描述信息 | _string_ | - |
|
|
58
|
+
|
|
59
|
+
### ActionSheet.Button Props
|
|
60
|
+
|
|
61
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
62
|
+
| --------- | --------------------------- | --------------- | -------- |
|
|
63
|
+
| className | 按钮类名 | _string_ | - |
|
|
64
|
+
| style | 按钮样式 | _CSSProperties_ | - |
|
|
65
|
+
| type | 按钮类型,可选值为 `cancel` | _string_ | `button` |
|
|
66
|
+
| children | 按钮内容 | _string_ | - |
|
|
67
|
+
|
|
68
|
+
### ActionSheet Events
|
|
69
|
+
|
|
70
|
+
| 事件名 | 说明 | 回调参数 |
|
|
71
|
+
| -------- | ---------------------------------------- | -------------------------------- |
|
|
72
|
+
| onSelect | 点击选项时触发,禁用或加载状态下不会触发 | _event: ActionSheet.ActionEvent_ |
|
|
73
|
+
| onCancel | 点击取消按钮时触发 | - |
|
|
74
|
+
| onClose | 关闭面板时触发 | - |
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# ActionSheet 动作面板
|
|
2
|
+
|
|
3
|
+
### 介绍
|
|
4
|
+
|
|
5
|
+
底部弹起的模态面板,包含与当前情境相关的多个选项。
|
|
6
|
+
|
|
7
|
+
### 引入
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ActionSheet } from "@fjyueke/bify-core"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 代码演示
|
|
14
|
+
|
|
15
|
+
### 基础用法
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
function BasicActionSheet() {
|
|
19
|
+
const [open, setOpen] = useState(false)
|
|
20
|
+
const actions = useMemo(
|
|
21
|
+
() => [
|
|
22
|
+
{ name: "选项一", value: "1" },
|
|
23
|
+
{ name: "选项二", value: "2" },
|
|
24
|
+
{ name: "选项三", value: "3" },
|
|
25
|
+
],
|
|
26
|
+
[],
|
|
27
|
+
)
|
|
28
|
+
return (
|
|
29
|
+
<>
|
|
30
|
+
<Cell clickable isLink title="基础用法" onClick={() => setOpen(true)} />
|
|
31
|
+
<ActionSheet
|
|
32
|
+
actions={actions}
|
|
33
|
+
open={open}
|
|
34
|
+
onSelect={() => setOpen(false)}
|
|
35
|
+
onClose={setOpen}
|
|
36
|
+
/>
|
|
37
|
+
</>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 展示取消按钮
|
|
43
|
+
|
|
44
|
+
添加`cancelText`后,会在底部展示取消按钮,点击后关闭当前面板并触发 `onCancel` 事件。
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
function ActionSheetWithCancel() {
|
|
48
|
+
const [open, setOpen] = useState(false)
|
|
49
|
+
const actions = useMemo(
|
|
50
|
+
() => [
|
|
51
|
+
{ name: "选项一", value: "1" },
|
|
52
|
+
{ name: "选项二", value: "2" },
|
|
53
|
+
{ name: "选项三", value: "3" },
|
|
54
|
+
],
|
|
55
|
+
[],
|
|
56
|
+
)
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
<Cell clickable isLink title="展示取消按钮" onClick={() => setOpen(true)} />
|
|
60
|
+
<ActionSheet
|
|
61
|
+
cancelText="取消"
|
|
62
|
+
actions={actions}
|
|
63
|
+
open={open}
|
|
64
|
+
onSelect={() => setOpen(false)}
|
|
65
|
+
onCancel={() => setOpen(false)}
|
|
66
|
+
onClose={setOpen}
|
|
67
|
+
/>
|
|
68
|
+
</>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 展示描述信息
|
|
74
|
+
|
|
75
|
+
通过 `description` 和 `subname` 添加描述信息
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
function ActionSheetWithDescription() {
|
|
79
|
+
const [open, setOpen] = useState(false)
|
|
80
|
+
const actions = useMemo(
|
|
81
|
+
() => [
|
|
82
|
+
{ name: "选项一", value: "1", subname: "这是一段描述信息" },
|
|
83
|
+
{ name: "选项二", value: "2" },
|
|
84
|
+
{ name: "选项三", value: "3" },
|
|
85
|
+
],
|
|
86
|
+
[],
|
|
87
|
+
)
|
|
88
|
+
return (
|
|
89
|
+
<>
|
|
90
|
+
<Cell clickable title="展示描述信息" isLink onClick={() => setOpen(true)} />
|
|
91
|
+
<ActionSheet
|
|
92
|
+
description="这是一段描述信息"
|
|
93
|
+
cancelText="取消"
|
|
94
|
+
actions={actions}
|
|
95
|
+
open={open}
|
|
96
|
+
onSelect={() => setOpen(false)}
|
|
97
|
+
onCancel={() => setOpen(false)}
|
|
98
|
+
onClose={setOpen}
|
|
99
|
+
/>
|
|
100
|
+
</>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 选项状态
|
|
106
|
+
|
|
107
|
+
通过 `loading` 和 `disabled` 将选项设置为加载状态或禁用状态,通过 `style`,`className` 修改样式
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
function ActionSheetWithStatuses() {
|
|
111
|
+
const [open, setOpen] = useState(false)
|
|
112
|
+
const actions = useMemo(
|
|
113
|
+
() => [
|
|
114
|
+
{ name: "选项一", value: "1", style: { color: "#ee0a24" } },
|
|
115
|
+
{ name: "选项二", value: "2", disabled: true },
|
|
116
|
+
{ name: "选项三", value: "3", loading: true },
|
|
117
|
+
],
|
|
118
|
+
[],
|
|
119
|
+
)
|
|
120
|
+
return (
|
|
121
|
+
<>
|
|
122
|
+
<Cell clickable title="选项状态" isLink onClick={() => setOpen(true)} />
|
|
123
|
+
<ActionSheet
|
|
124
|
+
actions={actions}
|
|
125
|
+
cancelText="取消"
|
|
126
|
+
open={open}
|
|
127
|
+
onSelect={() => setOpen(false)}
|
|
128
|
+
onCancel={() => setOpen(false)}
|
|
129
|
+
onClose={setOpen}
|
|
130
|
+
/>
|
|
131
|
+
</>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 手动控制 DOM
|
|
137
|
+
|
|
138
|
+
使用 `ActionSheet.Button` 组件后,会在底部展示取消按钮,点击后关闭当前面板并触发 `onCancel` 事件。<br>
|
|
139
|
+
使用`ActionSheet.Action`组件添加选项, 通过 `loading` 和 `disabled` 将选项设置为加载状态或禁用状态 <br>
|
|
140
|
+
通过 `ActionSheet.Header` 组件可以在菜单顶部显示描述信息,通过选项的 `ActionSheet.Action.children` 属性可以在 `Action` 文字的下侧展示描述信息。
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
function ActionSheetWithStatuses() {
|
|
144
|
+
const [open, setOpen] = useState(true)
|
|
145
|
+
return (
|
|
146
|
+
<ActionSheet open={open} onSelect={() => setOpen(false)} onClose={setOpen}>
|
|
147
|
+
<ActionSheet.Action value="1" style={{ color: "#ee0a24" }} name="着色选项" />
|
|
148
|
+
<ActionSheet.Action value="2" disabled name="禁止选项" />
|
|
149
|
+
<ActionSheet.Action value="3" loading name="选项三" />
|
|
150
|
+
<ActionSheet.Button onClick={() => setOpen(false)}>取消</ActionSheet.Button>
|
|
151
|
+
</ActionSheet>
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## API
|
|
157
|
+
|
|
158
|
+
### ActionSheet Props
|
|
159
|
+
|
|
160
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
161
|
+
| -------------------------------- | ------------------------------------- | --------------------------- | -------- |
|
|
162
|
+
| defaultOpen | 默认是否显示动作面板 | _boolean_ | `false` |
|
|
163
|
+
| open | 是否显示动作面板 | _boolean_ | `false` |
|
|
164
|
+
| description <br>`v0.3.0-alpha.0` | 选项上方的描述信息 | _ReactNode_ | - |
|
|
165
|
+
| cancelText <br>`v0.3.0-alpha.0` | 取消按钮文字 | _ReactNode_ | - |
|
|
166
|
+
| actions <br>`v0.3.0-alpha.0` | 面板选项列表 | _ActionSheetActionObject[]_ | - |
|
|
167
|
+
| className | 样式类名 | _string_ | - |
|
|
168
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
169
|
+
| rounded | 是否为圆角 | _string_ | - |
|
|
170
|
+
| safeArea | 安全区的位置,可选值为 `top` `bottom` | _string_ | `bottom` |
|
|
171
|
+
|
|
172
|
+
### ActionSheetActionObject 数据结构
|
|
173
|
+
|
|
174
|
+
| 参数 | 说明 | 类型 |
|
|
175
|
+
| --------- | -------------- | ----------- |
|
|
176
|
+
| name | 标题 | _ReactNode_ |
|
|
177
|
+
| subname | 二级标题 | _ReactNode_ |
|
|
178
|
+
| disabled | 是否为禁用状态 | _boolean_ |
|
|
179
|
+
| loading | 是否为加载状态 | _boolean_ |
|
|
180
|
+
| value | 值 | _any_ |
|
|
181
|
+
| style | | |
|
|
182
|
+
| className | | |
|
|
183
|
+
|
|
184
|
+
### ActionSheet.Backdrop Props
|
|
185
|
+
|
|
186
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
187
|
+
| --------- | ------------------ | ------------------ | ------ |
|
|
188
|
+
| className | 样式类名 | _string_ | - |
|
|
189
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
190
|
+
| duration | 动画时长,单位毫秒 | _number \| string_ | `300` |
|
|
191
|
+
| closeable | 点击是否可以关闭 | _boolean_ | `true` |
|
|
192
|
+
|
|
193
|
+
### ActionSheet.Header Props
|
|
194
|
+
|
|
195
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
196
|
+
| --------- | -------- | --------------- | ------ |
|
|
197
|
+
| className | 样式类名 | _string_ | - |
|
|
198
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
199
|
+
| title | 标题 | _string_ | - |
|
|
200
|
+
| children | 描述信息 | _string_ | - |
|
|
201
|
+
|
|
202
|
+
### ActionSheet.Action Props
|
|
203
|
+
|
|
204
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
205
|
+
| --------- | -------------- | --------------- | ------ |
|
|
206
|
+
| className | 样式类名 | _string_ | - |
|
|
207
|
+
| style | 样式对象 | _CSSProperties_ | - |
|
|
208
|
+
| name | 标题 | _string_ | - |
|
|
209
|
+
| value | 选项值 | _string_ | - |
|
|
210
|
+
| disabled | 是否为禁用状态 | _boolean_ | - |
|
|
211
|
+
| loading | 是否为加载状态 | _boolean_ | - |
|
|
212
|
+
| children | 描述信息 | _string_ | - |
|
|
213
|
+
|
|
214
|
+
### ActionSheet.Button Props
|
|
215
|
+
|
|
216
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
217
|
+
| --------- | --------------------------- | --------------- | -------- |
|
|
218
|
+
| className | 按钮类名 | _string_ | - |
|
|
219
|
+
| style | 按钮样式 | _CSSProperties_ | - |
|
|
220
|
+
| type | 按钮类型,可选值为 `cancel` | _string_ | `button` |
|
|
221
|
+
| children | 按钮内容 | _string_ | - |
|
|
222
|
+
|
|
223
|
+
### ActionSheet Events
|
|
224
|
+
|
|
225
|
+
| 事件名 | 说明 | 回调参数 |
|
|
226
|
+
| -------- | ---------------------------------------- | -------------------------------- |
|
|
227
|
+
| onSelect | 点击选项时触发,禁用或加载状态下不会触发 | _event: ActionSheet.ActionEvent_ |
|
|
228
|
+
| onCancel | 点击取消按钮时触发 | - |
|
|
229
|
+
| onClose | 关闭面板时触发 | - |
|
|
230
|
+
|
|
231
|
+
## 主题定制
|
|
232
|
+
|
|
233
|
+
### 样式变量
|
|
234
|
+
|
|
235
|
+
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider](/components/config-provider/) 组件。
|
|
236
|
+
|
|
237
|
+
| 名称 | 默认值 | 描述 |
|
|
238
|
+
| ----------------------------------------- | ----------------------- | ---- |
|
|
239
|
+
| --action-sheet-description-padding-bottom | _var(--padding-md)_ | - |
|
|
240
|
+
| --action-sheet-subname-margin-top | _var(--padding-xs)_ | - |
|
|
241
|
+
| --action-sheet-subname-color | _var(--gray-6)_ | - |
|
|
242
|
+
| --action-sheet-subname-font-size | _var(--font-size-sm)_ | - |
|
|
243
|
+
| --action-sheet-subname-line-height | _var(--line-height-sm)_ | - |
|