@doubao-dev/plugin-app-dev 0.0.0-stage → 0.0.40-canary-dea0ddc73-20261026073950
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dist/147.js +9 -0
- package/dist/assets.d.ts +5 -0
- package/dist/assets.js +4 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +1378 -0
- package/dist/plugin.d.ts +102 -0
- package/dist/plugin.js +4995 -0
- package/dist/preview.js +16 -0
- package/dist/rslib-runtime.js +33 -0
- package/dist/skills/doubao-plugin-app/SKILL.md +21 -0
- package/dist/skills/doubao-plugin-app/references/app-development.md +85 -0
- package/dist/skills/doubao-plugin-app/references/frontend/components/container-overlay.md +131 -0
- package/dist/skills/doubao-plugin-app/references/frontend/components/form-controls.md +146 -0
- package/dist/skills/doubao-plugin-app/references/frontend/components/interactive-controls.md +120 -0
- package/dist/skills/doubao-plugin-app/references/frontend/components/map-canvas.md +107 -0
- package/dist/skills/doubao-plugin-app/references/frontend/components/overview.md +43 -0
- package/dist/skills/doubao-plugin-app/references/frontend/components/scroll-list.md +149 -0
- package/dist/skills/doubao-plugin-app/references/frontend/components/text-media.md +209 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/01-/345/237/272/347/241/200.md +1389 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/02-/347/263/273/347/273/237.md +1376 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/03-/350/207/252/345/256/232/344/271/211/351/200/232/344/277/241.md +127 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/04-/345/256/232/344/275/215.md +784 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/05-/345/255/230/345/202/250.md +1176 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/06-/350/267/257/347/224/261.md +839 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/07-/347/225/214/351/235/242.md +376 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/08-/344/272/244/344/272/222.md +1319 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/09-/350/276/223/345/205/245.md +192 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/10-/347/275/221/347/273/234.md +900 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/11-/345/252/222/344/275/223.md +1496 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/12-/344/270/232/345/212/241/350/203/275/345/212/233.md +1281 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/13-/347/231/273/345/275/225.md +511 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/14-/346/224/257/344/273/230.md +943 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/15-/346/225/260/346/215/256/345/210/206/346/236/220.md +124 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/16-/350/223/235/347/211/231.md +3364 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/17-wi-fi.md +1028 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/18-/345/212/240/351/200/237/345/272/246/350/256/241.md +354 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/19-ibeacon.md +508 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/20-/347/275/227/347/233/230.md +320 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/21-/350/256/276/345/244/207/346/226/271/345/220/221.md +351 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/22-/351/231/200/350/236/272/344/273/252.md +354 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/23-/345/252/222/344/275/223-/350/256/276/345/244/207-/347/275/221/347/273/234.md +264 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/24-/347/237/255/344/277/241.md +155 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/25-/346/227/240/351/232/234/347/242/215.md +144 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/26-/345/237/272/347/241/200/344/277/241/346/201/257.md +238 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/27-/347/224/265/346/261/240.md +235 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/28-/345/211/252/350/264/264/346/235/277.md +303 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/29-/345/212/240/345/257/206.md +126 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/30-/346/227/245/345/216/206.md +417 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/31-/347/224/265/350/257/235.md +144 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/32-/346/211/253/347/240/201.md +236 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/33-/345/261/217/345/271/225.md +747 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/34-/351/234/207/345/212/250.md +277 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/35-/346/226/207/344/273/266/347/263/273/347/273/237.md +431 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/common-errors.md +69 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/groups.md +43 -0
- package/dist/skills/doubao-plugin-app/references/frontend/doubao-agentic-service-api/quick-reference.md +436 -0
- package/dist/skills/doubao-plugin-app/references/frontend/examples/common-patterns.md +590 -0
- package/dist/skills/doubao-plugin-app/references/frontend/examples/doubao-agentic-service-api-recipes.md +209 -0
- package/dist/skills/doubao-plugin-app/references/frontend/examples/page-widget-basics.md +368 -0
- package/dist/skills/doubao-plugin-app/references/frontend/examples/page-widget-recipes.md +65 -0
- package/dist/skills/doubao-plugin-app/references/frontend/framework/core.md +283 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/auth.md +277 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/best-practices.md +574 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/client-tools-and-events.md +209 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/component-development.md +832 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/debugger-mcp.md +537 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/expired-widget.md +101 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/performance-optimization.md +417 -0
- package/dist/skills/doubao-plugin-app/references/frontend/guides/troubleshooting.md +278 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/best-practices.md +720 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/css/pseudo-classes.md +149 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/css/selectors.md +224 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/css/supported-properties.md +269 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/css/values-and-units.md +314 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/layout/flex-layout.md +334 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/layout/grid-layout.md +408 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/layout/linear-layout.md +355 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/layout/relative-layout.md +189 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/lynx-vs-web/css-differences.md +737 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/lynx-vs-web/migration-guide.md +669 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/lynx-vs-web/unsupported-features.md +290 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/overview.md +60 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/patterns/animation.md +243 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/patterns/responsive.md +194 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/patterns/theming.md +143 -0
- package/dist/skills/doubao-plugin-app/references/frontend/lynx/quick-reference.md +229 -0
- package/dist/skills/doubao-plugin-app/references/frontend/rules/dos-and-donts.md +479 -0
- package/dist/skills/doubao-plugin-app/references/frontend/widget-templates/design-boundary.md +46 -0
- package/dist/skills/doubao-plugin-app/references/frontend/widget-templates/overview.md +118 -0
- package/dist/skills/doubao-plugin-app/references/frontend/widget-templates/props.md +301 -0
- package/dist/skills/doubao-plugin-app/references/mcp-and-cards.md +38 -0
- package/dist/templates/README.md.template +11 -0
- package/dist/templates/com.doubao/app/manifest.yaml +41 -0
- package/dist/templates/com.doubao/app/package.json.template +13 -0
- package/dist/templates/com.doubao/app/src/app.config.ts.template +5 -0
- package/dist/templates/com.doubao/app/src/app.ts.template +3 -0
- package/dist/templates/com.doubao/app/src/pages/home/index.css +14 -0
- package/dist/templates/com.doubao/app/src/pages/home/index.tsx.template +14 -0
- package/dist/templates/com.doubao/app/src/widgets/example/index.tsx.template +29 -0
- package/dist/templates/com.doubao/app/tsconfig.json +19 -0
- package/dist/templates/mcp.json +9 -0
- package/dist/templates/plugin.json.template +29 -0
- package/dist/templates/skills/example/SKILL.md.template +14 -0
- package/dist/upload.d.ts +44 -0
- package/dist/upload.js +38 -0
- package/package.json +60 -3
package/dist/preview.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import qrcode from "qrcode";
|
|
3
|
+
async function printPreview({ url, name, version, expiresAt }) {
|
|
4
|
+
console.log(`预览链接:${url}`);
|
|
5
|
+
if (!process.stdout.isTTY) return;
|
|
6
|
+
const { modules } = qrcode.create(url);
|
|
7
|
+
if (process.stdout.columns && modules.size + 6 > process.stdout.columns) throw new Error('终端宽度不足,请拉宽窗口后重试');
|
|
8
|
+
const qr = await qrcode.toString(url, {
|
|
9
|
+
type: 'utf8',
|
|
10
|
+
margin: 2
|
|
11
|
+
});
|
|
12
|
+
console.log(`\n${chalk.blue.bold('豆包扫码预览')} · ${name} ${version}\n`);
|
|
13
|
+
console.log(qr.split('\n').map((row)=>` \x1b[38;2;0;0;0m\x1b[48;2;255;255;255m${row}\x1b[0m`).join('\n'));
|
|
14
|
+
if (expiresAt) console.log(chalk.dim(`有效期至 ${new Date(Number(expiresAt)).toLocaleString()}`));
|
|
15
|
+
}
|
|
16
|
+
export { printPreview };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
var __webpack_modules__ = {};
|
|
2
|
+
var __webpack_module_cache__ = {};
|
|
3
|
+
function __webpack_require__(moduleId) {
|
|
4
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
5
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
6
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
7
|
+
exports: {}
|
|
8
|
+
};
|
|
9
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
10
|
+
return module.exports;
|
|
11
|
+
}
|
|
12
|
+
__webpack_require__.m = __webpack_modules__;
|
|
13
|
+
(()=>{
|
|
14
|
+
__webpack_require__.d = (exports, getters, values)=>{
|
|
15
|
+
var define = (defs, kind)=>{
|
|
16
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
[kind]: defs[key]
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
define(getters, "get");
|
|
22
|
+
define(values, "value");
|
|
23
|
+
};
|
|
24
|
+
})();
|
|
25
|
+
(()=>{
|
|
26
|
+
__webpack_require__.add = function(modules) {
|
|
27
|
+
Object.assign(__webpack_require__.m, modules);
|
|
28
|
+
};
|
|
29
|
+
})();
|
|
30
|
+
(()=>{
|
|
31
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
32
|
+
})();
|
|
33
|
+
export { __webpack_require__ };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: doubao-plugin-app
|
|
3
|
+
description: 使用 @doubao-dev/plugin-cli 开发应用插件中的 App 页面、Widget 卡片、Manifest 和 MCP 出卡链路,使用 Web、真机和桌面工具调试。适用于包含 com.doubao/app/manifest.yaml 的 Plugin CLI 项目。
|
|
4
|
+
metadata:
|
|
5
|
+
display_name: 应用插件 App 开发
|
|
6
|
+
display_description: 开发和调试应用插件的页面、卡片、Manifest 与 MCP 出卡链路。
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# 应用开发
|
|
10
|
+
|
|
11
|
+
本 Skill 配合 `@doubao-dev/plugin-cli` 使用;CLI 命令先读项目的 `doubao-plugin-cli` Skill。仅用于豆包 App 工程;普通 Skill、MCP 和 MCP Apps 项目不读取此 Skill,也不创建 App Manifest。
|
|
12
|
+
|
|
13
|
+
`dbx init <name> --app` 新建 App,使用共享线上购物 MCP,包含业务 Skill、卡片和页面。运行 `dbx dev --app` 后,在 Web 模拟器发送“搜索牛奶”体验商品卡片。
|
|
14
|
+
|
|
15
|
+
先读 [应用开发指南](references/app-development.md),确认前端目录、依赖安装、Page / Widget 注册和 viewData 用法。开发调试先读其中的 [本地调试](references/app-development.md#本地调试),使用新 Plugin CLI 的 Kit、Web 模拟器和状态命令。
|
|
16
|
+
真机扫码、版本选择、断线恢复和桌面工具操作,阅读 [真机与桌面调试](references/app-development.md#真机与桌面调试)。
|
|
17
|
+
涉及工具调用、运行态 Skill、实体或卡片不显示时,读 [MCP 与出卡配置](references/mcp-and-cards.md),逐项对齐 Skill、MCP 返回、Manifest 和 Widget。
|
|
18
|
+
|
|
19
|
+
App 前端配置以本 Skill 的应用开发指南为准;插件根配置和 CLI 操作统一读取 `doubao-plugin-cli` Skill。组件、Hooks、API、模板和 Lynx 资料复用 SDK 的开发 Skill,随应用开发工具包交付;项目配置以本 Skill 的应用开发指南为准,不要求手填 AppID。只读取当前任务需要的章节。
|
|
20
|
+
|
|
21
|
+
CLI 命令和平台同步操作读取插件根目录下的 `.agents/skills/doubao-plugin-cli/SKILL.md`。
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# 应用开发指南
|
|
2
|
+
|
|
3
|
+
## 项目与配置
|
|
4
|
+
|
|
5
|
+
`plugin.json` 所在目录是插件根目录,前端位于 `com.doubao/app/`;下文的 `src/` 相对此目录。`dbx` 可以在根目录或前端目录运行。
|
|
6
|
+
|
|
7
|
+
- 存在 `manifest.yaml` 才启用 App;CLI 优先按 `plugin.json.id`,其次按 name 查询 AppID,失败使用本地调试 ID。上传返回的插件 ID 自动保存,源清单和前端配置无需填写 AppID,发布时由服务端补齐。
|
|
8
|
+
- `dbx init <name> --app` 准备独立的开发包、Kit 和前端依赖。跳过安装或安装失败时,在前端目录运行 `pnpm install`;工具包不需要加入前端依赖。
|
|
9
|
+
- 新项目从npm registry 安装 `@doubao-dev/framework` 和 `@doubao-dev/template` 的 latest 版本,由项目 lockfile 固定解析结果;已有项目沿用自身包体系和版本。Hooks 从 framework 导入,端能力从 framework/api 导入。
|
|
10
|
+
|
|
11
|
+
`com.doubao/app/src/app.config.ts` 示例:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
export default {
|
|
15
|
+
name: '我的应用插件',
|
|
16
|
+
pages: ['pages/home/index'],
|
|
17
|
+
widgets: ['widgets/example/index']
|
|
18
|
+
};
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
前端配置默认导出普通对象,按需声明 `pages`、`widgets` 和 metadata。AppID 由 CLI 管理,无需手填。
|
|
22
|
+
|
|
23
|
+
## 实现与验证
|
|
24
|
+
|
|
25
|
+
1. 工具调用或出卡变化先按 [MCP 与出卡配置](mcp-and-cards.md) 对齐业务 Skill、MCP 和 Manifest。
|
|
26
|
+
2. 在 `src/widgets/<name>/index.tsx` 实现卡片,在 `src/pages/<name>/index.tsx` 实现全屏页面,在 `src/app.config.ts` 注册入口,保留已有配置。
|
|
27
|
+
3. 使用 Lynx 的 `view`、`text`、`image` 和独立样式文件;布局按 Lynx 文档实现。Widget 优先使用 SDK 卡片模板,核对 props 后映射实体数据。
|
|
28
|
+
4. `useViewData<T>()` 的类型与返回实体一致,并处理数据未到达的空态。字符串入口 `widgets/example/index` 的 Widget ID 为 `example`,显式对象入口使用其 `id`,均须与 Manifest 绑定一致。
|
|
29
|
+
5. 请求放在生命周期或事件回调中并处理失败,密钥放在服务端。用 `dbx dev --app` 验证真实出卡、交互和导航,不能只以编译成功判断链路可用。
|
|
30
|
+
|
|
31
|
+
页面、卡片和配置的完整示例以当前项目模板为准,SDK 用法按下表读取。
|
|
32
|
+
|
|
33
|
+
上传前按项目根目录 `.agents/skills/doubao-plugin-cli/references/upload.md`检查本地图标、尺寸和路径;Web 调试成功不代表平台物料校验已通过。
|
|
34
|
+
|
|
35
|
+
## 本地调试
|
|
36
|
+
|
|
37
|
+
从根目录或 App 目录运行 `dbx dev --app`,复用已有实例。`dbx dev` 在含 App 的项目中会交互选择调试目标;`--plugin` 只调试 Skill / MCP,`--app` 同时调试 App。非 TTY 或指定 `--no-tui` 时不询问,未传 `--app` 默认只调试 Skill / MCP。Kit 缓存缺失时自动安装,默认版本由 CLI 构建时锁定,可用 `DBX_KIT_VERSION=<准确版本>` 覆盖,准备期间 Ctrl+C 可取消。
|
|
38
|
+
|
|
39
|
+
- 源清单未填写 AppID 时,模拟器对话使用 Sandbox 会话创建返回的真实 `sandbox_appid`,会话重建后重新读取,不将占位 ID 写入请求清单。
|
|
40
|
+
- `web` 打开模拟器,`status` 查看详情和 URL;非交互环境从日志获取地址;Agent 使用 `dbx dev --app --no-tui` 后台启动并读取服务状态和地址,保留进程句柄,不等待命令结束。真机和桌面工具按下文操作,命令在 dev 交互界面内输入,不是独立的 `dbx` 子命令。
|
|
41
|
+
- 「本地」编译和「平台」同步并行;AppID 查询最多等待 5 秒。交互终端未登录时,dev 先完成浏览器授权再启动;非交互环境先完成登录。个人开发包只同步接口支持的非 App 模块,完整 App 包用 `dbx upload` 上传。
|
|
42
|
+
- 前端改动由 Kit 热更新;业务 `skills/`、`mcp.json` 改动同步平台。MCP 地址或 headers 变化后自动重启 App 运行时;更改应用身份或 App 配置后重启 dev。
|
|
43
|
+
- Web 模拟器只读取业务 `skills/<name>/SKILL.md` 正文。CLI 操作以项目的 `doubao-plugin-cli` Skill 和 `dbx --help` 为准;打开桌面工具时,在 dev 的 `device` 菜单输入 `desktop`。
|
|
44
|
+
|
|
45
|
+
## 真机与桌面调试
|
|
46
|
+
|
|
47
|
+
前提:CLI 能从平台查询到有效 AppID,手机能访问电脑的局域网资源地址。没有平台 AppID 时先使用 Web 模拟器;不能用 Web Sandbox 的兜底 ID 申请真机授权。
|
|
48
|
+
|
|
49
|
+
1. 运行 `dbx dev --app`,等待应用编译就绪,输入 `device` 进入真机菜单。
|
|
50
|
+
2. 输入 `version`,选择已上传的云端版本以调试对话和工具调用,或选择“本地调试,不绑定云端版本”。上下键选择、Enter 确认、Esc 返回。没有版本时可先使用本地调试。
|
|
51
|
+
3. 使用手机豆包扫描终端中的连接二维码,等待调试包安装和连接就绪。已有可复用连接时不必重新扫码。
|
|
52
|
+
4. 连接后用 `page` 或 `widget`,上下键选择页面或卡片,Enter 确认、Esc 返回。卡片能打开不代表 MCP 出卡成功,对话链路还需验证工具调用和实体数据。
|
|
53
|
+
|
|
54
|
+
| 命令 | 用途 |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `qr` | 沿用当前调试版本,重新生成连接二维码 |
|
|
57
|
+
| `qr-size` | 二维码显示时切换半角/全角,不重新申请票据或断开连接;窗口过窄时拉宽终端 |
|
|
58
|
+
| `version` | 选择云端版本或不绑定版本的本地调试;切换后会重新连接 |
|
|
59
|
+
| `page` / `widget` | 连接后选择页面或卡片 |
|
|
60
|
+
| `desktop` | 按需安装并打开桌面开发工具,与 CLI 共用设备连接,查看日志、截图和页面结构 |
|
|
61
|
+
| `cancel` | 连接过程中取消,已连接时断开;空闲时不显示 |
|
|
62
|
+
| `back` | 返回上级菜单;已连接时保留连接,未连接完成时取消连接 |
|
|
63
|
+
|
|
64
|
+
`status` 在主菜单查看调试详情,不在每个子菜单重复提供。命令可用 Tab 补全,Ctrl+C 退出开发会话并清理连接。
|
|
65
|
+
|
|
66
|
+
连接短暂中断会等待 30 秒恢复,先等待,不要立即重新扫码;超时后按提示执行 `qr`。无法连接时检查 AppID、登录账号、手机到电脑的网络可达性,再查看 `status` 和桌面日志。
|
|
67
|
+
|
|
68
|
+
这里的二维码用于连接本地开发服务,需要保持 dev 运行。`dbx upload` 输出的是云构建成功后的预览二维码;它与本地连接二维码用途不同,上传成功也不代表云构建或预览已成功。
|
|
69
|
+
|
|
70
|
+
## 按需读取 SDK 参考资料
|
|
71
|
+
|
|
72
|
+
| 场景 | 参考资料 |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| Page / Widget、生命周期、viewData | [组件开发](frontend/guides/component-development.md) |
|
|
75
|
+
| 选择卡片模板和核对 props | [模板索引](frontend/widget-templates/overview.md) |
|
|
76
|
+
| 内置组件的 props 和事件 | [组件索引](frontend/components/overview.md) |
|
|
77
|
+
| 网络、导航、位置等端能力 | [API 速查](frontend/doubao-agentic-service-api/quick-reference.md) |
|
|
78
|
+
| Hooks 与框架核心能力 | [Framework](frontend/framework/core.md) |
|
|
79
|
+
| 布局、CSS、Lynx 与 Web 差异 | [Lynx 索引](frontend/lynx/overview.md) |
|
|
80
|
+
| 登录和隐私授权入口 | [前端授权](frontend/guides/auth.md) |
|
|
81
|
+
| 端工具、事件、页面模型上下文 | [端工具与事件](frontend/guides/client-tools-and-events.md) |
|
|
82
|
+
| 模拟器日志、Trace、工具调用现场 | [Debugger MCP](frontend/guides/debugger-mcp.md) |
|
|
83
|
+
| 编译和运行问题 | [排障指南](frontend/guides/troubleshooting.md) |
|
|
84
|
+
|
|
85
|
+
前端项目配置由本 Skill 单独维护,API、组件和样式资料与 SDK 共用。登录、跳转等 API 的 AppID 参数按对应接口说明填写,与项目配置中的 AppID 注入分别处理。
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# 容器与覆层组件
|
|
2
|
+
|
|
3
|
+
## `<view>`
|
|
4
|
+
|
|
5
|
+
基础布局容器,最常用。
|
|
6
|
+
|
|
7
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
8
|
+
|------|------|--------|------|
|
|
9
|
+
| className | string | - | 样式类名 |
|
|
10
|
+
| style | CSSProperties | - | 内联样式 |
|
|
11
|
+
| flatten | boolean | true | 扁平化节点,避免创建真实渲染对象,提升性能 |
|
|
12
|
+
| onClick | (e: TouchEvent) => void | - | 点击 |
|
|
13
|
+
| onLongPress | (e: TouchEvent) => void | - | 长按 |
|
|
14
|
+
| onTouchStart / onTouchEnd / onTouchMove | (e: TouchEvent) => void | - | 触摸事件 |
|
|
15
|
+
| onAppear | (e: UIAppearanceEvent) => void | - | 进入可视区域 |
|
|
16
|
+
| onDisappear | (e: UIAppearanceEvent) => void | - | 离开可视区域 |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## `<popup>`
|
|
21
|
+
|
|
22
|
+
支持拖拽、多位置停靠的弹窗。
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import type { PopupRef } from '@doubao-dev/framework/components';
|
|
26
|
+
import { useRef } from '@doubao-dev/framework';
|
|
27
|
+
|
|
28
|
+
const popupRef = useRef<PopupRef>(null);
|
|
29
|
+
|
|
30
|
+
// 打开弹窗
|
|
31
|
+
popupRef.current?.open(); // 默认中心
|
|
32
|
+
popupRef.current?.open(1); // 顶部
|
|
33
|
+
popupRef.current?.open(-1); // 底部
|
|
34
|
+
popupRef.current?.close();
|
|
35
|
+
|
|
36
|
+
<popup
|
|
37
|
+
ref={popupRef}
|
|
38
|
+
scrollContainerId="popup-scroll"
|
|
39
|
+
maxHeight={lynx.__globalProps.screenHeight}
|
|
40
|
+
closeOnMaskClick
|
|
41
|
+
enableDrag
|
|
42
|
+
onPopupPositionChange={(pos) => {
|
|
43
|
+
// 0=中心, 1=顶部, -1=底部, 4=关闭
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{({ 'main-thread:gesture': gesture }) => (
|
|
47
|
+
<view id="popup-scroll" style={{ height: '100%' }}>
|
|
48
|
+
<text>弹窗内容</text>
|
|
49
|
+
</view>
|
|
50
|
+
)}
|
|
51
|
+
</popup>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### PopupRef 方法
|
|
55
|
+
|
|
56
|
+
| 方法 | 参数 | 说明 |
|
|
57
|
+
|------|------|------|
|
|
58
|
+
| open | position?: 0 \| 1 \| -1 | 打开弹窗。0 中心 / 1 顶部 / -1 底部,默认中心 |
|
|
59
|
+
| close | - | 关闭弹窗 |
|
|
60
|
+
| translateTo | position: number \| string | 移动到指定位置,支持数字或 "px" / "%" / "rpx" |
|
|
61
|
+
|
|
62
|
+
### PopupProps
|
|
63
|
+
|
|
64
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
65
|
+
|------|------|--------|------|
|
|
66
|
+
| scrollContainerId | string | - | **必填**,内部滚动容器 ID |
|
|
67
|
+
| children | (prop: RenderFunction) => ReactElement | - | 渲染函数 |
|
|
68
|
+
| autoHeight | boolean | false | 根据内容高度自动调整 |
|
|
69
|
+
| contentId | string | - | autoHeight 为 true 时需要设置 |
|
|
70
|
+
| enableDrag | boolean | true | 启用拖拽 |
|
|
71
|
+
| enableBounces | boolean | true | 松手回弹 |
|
|
72
|
+
| closeOnMaskClick | boolean | true | 点击遮罩关闭 |
|
|
73
|
+
| maxHeight | number | screenHeight | 最大高度 |
|
|
74
|
+
| heightPercent | HeightPercent | - | `{ init, top, bottom, boundaryArea, flingThreshold }` |
|
|
75
|
+
| bottomNode | ReactElement | - | 固定在弹窗底部的节点,不受拖动影响 |
|
|
76
|
+
| enterDuration / exitDuration | number | 300 | 进入/退出动画时长 (ms) |
|
|
77
|
+
| onPopupPositionChange | (position: number) => void | - | 位置变化回调 |
|
|
78
|
+
| onPopupTopChange | (height: number) => void | - | 高度变化回调 |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## `<movable-area>` / `<movable-view>`
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<movable-area style={{ width: '100%', height: '300px' }}>
|
|
86
|
+
<movable-view direction="all" scale outOfBounds inertia friction={2} damping={20}>
|
|
87
|
+
<text>拖我 / 双指缩放</text>
|
|
88
|
+
</movable-view>
|
|
89
|
+
</movable-area>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### movable-view 属性
|
|
93
|
+
|
|
94
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
95
|
+
|------|------|--------|------|
|
|
96
|
+
| direction | `'all' \| 'vertical' \| 'horizontal' \| 'none'` | `'all'` | 移动方向 |
|
|
97
|
+
| disabled | boolean | false | 禁用 |
|
|
98
|
+
| x / y | number | 0 | 初始偏移 |
|
|
99
|
+
| scale | boolean | false | 双指缩放 |
|
|
100
|
+
| scaleValue | number | 1 | 初始缩放值 |
|
|
101
|
+
| scaleMin / scaleMax | number | 0.5 / 10 | 缩放范围 |
|
|
102
|
+
| outOfBounds | boolean | false | 允许超出区域(松手回弹) |
|
|
103
|
+
| animation | boolean | true | 回弹动画 |
|
|
104
|
+
| damping | number | 20 | 阻尼系数,值越大回弹越快 |
|
|
105
|
+
| inertia | boolean | false | 惯性滑动 |
|
|
106
|
+
| friction | number | 2 | 摩擦系数,值越大越快停止(必须 > 0) |
|
|
107
|
+
| onDrag | (x: number, y: number) => void | - | 拖拽回调 |
|
|
108
|
+
| onScale | (scale: number) => void | - | 缩放回调 |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## `<theme-provider>`
|
|
113
|
+
|
|
114
|
+
让子树消费 `--bg-*` / `--neutral-*` / `--primary-*` 等 CSS 变量时跟随宿主主题(light/dark)。
|
|
115
|
+
|
|
116
|
+
内置组件会自动应用主题,只在业务自定义内容需要主题变量时才需要包裹。
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<theme-provider>
|
|
120
|
+
<view style={{ background: 'var(--bg-1)' }}>
|
|
121
|
+
<text style={{ color: 'var(--neutral-text-1)' }}>跟随主题的文字</text>
|
|
122
|
+
</view>
|
|
123
|
+
</theme-provider>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
127
|
+
|------|------|--------|------|
|
|
128
|
+
| children | ReactNode | - | 子元素 |
|
|
129
|
+
| className | string | - | 样式类名 |
|
|
130
|
+
| style | CSSProperties | - | 内联样式 |
|
|
131
|
+
| flatten | boolean | false | 默认 false,因为该容器需作为 CSS 变量作用域 |
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# 表单组件
|
|
2
|
+
|
|
3
|
+
## `<input>`
|
|
4
|
+
|
|
5
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
6
|
+
|------|------|--------|------|
|
|
7
|
+
| ref | Ref\<InputRef\> | - | 实例 ref |
|
|
8
|
+
| value | string | - | 受控值 |
|
|
9
|
+
| defaultValue | string | - | 非受控默认值 |
|
|
10
|
+
| placeholder | string | - | 占位文本 |
|
|
11
|
+
| type | `'text' \| 'number' \| 'digit' \| 'password' \| 'tel' \| 'email'` | `'text'` | 输入类型 |
|
|
12
|
+
| maxlength | number | 140 | 最大长度 |
|
|
13
|
+
| disabled | boolean | false | 禁用 |
|
|
14
|
+
| readonly | boolean | false | 只读 |
|
|
15
|
+
| confirmType | `'send' \| 'search' \| 'go' \| 'done' \| 'next'` | `'send'` | 键盘确认按钮类型 |
|
|
16
|
+
| showSoftInputOnFocus | boolean | true | 聚焦时是否显示软键盘 |
|
|
17
|
+
| onInput | (e: BaseEvent\<'bindinput', InputInputEvent\>) => void | - | 输入变化,取值 `e.detail.value` |
|
|
18
|
+
| onFocus | (e: BaseEvent\<'bindfocus', InputFocusEvent\>) => void | - | 聚焦 |
|
|
19
|
+
| onBlur | (e: BaseEvent\<'bindblur', InputBlurEvent\>) => void | - | 失焦 |
|
|
20
|
+
| onConfirm | (e: BaseEvent\<'bindconfirm', InputConfirmEvent\>) => void | - | 点击确认按钮 |
|
|
21
|
+
| className | string | - | 样式类名 |
|
|
22
|
+
| style | CSSProperties | - | 内联样式 |
|
|
23
|
+
|
|
24
|
+
### InputRef 方法
|
|
25
|
+
|
|
26
|
+
| 方法 | 类型 | 说明 |
|
|
27
|
+
|------|------|------|
|
|
28
|
+
| setValue | (value: string) => Promise\<void\> | 设置值 |
|
|
29
|
+
| getValue | () => Promise\<{ value: string; selectionStart: number; selectionEnd: number }\> | 获取值和选区 |
|
|
30
|
+
| focus | () => Promise\<void\> | 聚焦 |
|
|
31
|
+
| blur | () => Promise\<void\> | 失焦 |
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import type { InputRef } from '@doubao-dev/framework/components';
|
|
35
|
+
import { useState, useRef } from '@lynx-js/react';
|
|
36
|
+
|
|
37
|
+
// 受控
|
|
38
|
+
const [val, setVal] = useState('');
|
|
39
|
+
<input value={val} onInput={(e) => setVal(e.detail.value)} placeholder="请输入" />
|
|
40
|
+
|
|
41
|
+
// 通过 ref 控制
|
|
42
|
+
const inputRef = useRef<InputRef>(null);
|
|
43
|
+
<input ref={inputRef} placeholder="请输入" />
|
|
44
|
+
<button onClick={() => inputRef.current?.focus()}>聚焦</button>
|
|
45
|
+
|
|
46
|
+
// 密码输入
|
|
47
|
+
<input type="password" maxlength={20} placeholder="请输入密码" />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## `<textarea>`
|
|
53
|
+
|
|
54
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
55
|
+
|------|------|--------|------|
|
|
56
|
+
| placeholder | string | - | 占位文本 |
|
|
57
|
+
| maxlength | number | 140 | 最大长度 |
|
|
58
|
+
| maxlines | number | - | 最大行数 |
|
|
59
|
+
| lineSpacing | number \| `${number}px` \| `${number}rpx` | - | 行间距 |
|
|
60
|
+
| disabled | boolean | false | 禁用 |
|
|
61
|
+
| readonly | boolean | false | 只读 |
|
|
62
|
+
| confirmType | `'send' \| 'search' \| 'go' \| 'done' \| 'next'` | `'done'` | 确认按钮类型 |
|
|
63
|
+
| showSoftInputOnFocus | boolean | true | 聚焦时显示软键盘 |
|
|
64
|
+
| bounces | boolean | true | iOS 弹性效果 |
|
|
65
|
+
| onInput | (e: TextAreaInputEvent) => void | - | 输入变化 |
|
|
66
|
+
| onFocus | (e: TextAreaFocusEvent) => void | - | 聚焦 |
|
|
67
|
+
| onBlur | (e: TextAreaBlurEvent) => void | - | 失焦 |
|
|
68
|
+
| onConfirm | (e: TextAreaConfirmEvent) => void | - | 点击确认按钮 |
|
|
69
|
+
| className | string | - | 样式类名 |
|
|
70
|
+
| style | CSSProperties | - | 内联样式 |
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
<textarea
|
|
74
|
+
placeholder="请输入内容"
|
|
75
|
+
maxlength={500}
|
|
76
|
+
maxlines={5}
|
|
77
|
+
onInput={(e) => console.log(e.detail.value)}
|
|
78
|
+
/>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## `<picker-view>` / `<picker-column>` / `<picker-divider>`
|
|
84
|
+
|
|
85
|
+
嵌入页面的滚动选择器。
|
|
86
|
+
|
|
87
|
+
**关键约束:**
|
|
88
|
+
- `picker-view` 高度必须用 **inline `style.height`** 传入,不能只写在 CSS class 中,否则内部 JS 无法同步读取高度,offset 回退为 108px
|
|
89
|
+
- `itemHeight` 要与 `style.height` 配合设置
|
|
90
|
+
|
|
91
|
+
### picker-view 属性
|
|
92
|
+
|
|
93
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
94
|
+
|------|------|--------|------|
|
|
95
|
+
| style | CSSProperties | - | **height 必须 inline 传入** |
|
|
96
|
+
| itemHeight | number | 36 | 单个选项高度 (px) |
|
|
97
|
+
| theme | `'light' \| 'dark'` | - | 未传时跟随宿主主题 |
|
|
98
|
+
| onChange | (values: (string \| number)[], options: PickerColumnOption[]) => void | - | 所有列选中项变化 |
|
|
99
|
+
| className | string | - | 样式类名 |
|
|
100
|
+
|
|
101
|
+
### picker-column 属性
|
|
102
|
+
|
|
103
|
+
| 属性 | 类型 | 说明 |
|
|
104
|
+
|------|------|------|
|
|
105
|
+
| options | `{ label: string; value: string \| number; disabled?: boolean }[]` | 列数据 |
|
|
106
|
+
| value | string \| number | 受控当前值 |
|
|
107
|
+
| defaultValue | string \| number | 非受控默认值 |
|
|
108
|
+
| onChange | (value: string \| number, option: PickerColumnOption) => void | 当前列变化 |
|
|
109
|
+
| className | string | 列的类名 |
|
|
110
|
+
| style | CSSProperties | 列的样式 |
|
|
111
|
+
|
|
112
|
+
### picker-divider 属性
|
|
113
|
+
|
|
114
|
+
| 属性 | 类型 | 说明 |
|
|
115
|
+
|------|------|------|
|
|
116
|
+
| text | string | 展示文本 |
|
|
117
|
+
| children | ReactNode | 自定义内容,优先级高于 text |
|
|
118
|
+
| className | string | 类名 |
|
|
119
|
+
| style | CSSProperties | 样式 |
|
|
120
|
+
|
|
121
|
+
`picker-divider` 不参与值计算,不会出现在 `onChange` 的 values/options 中。
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
const hours = Array.from({ length: 24 }, (_, i) => ({ label: String(i).padStart(2, '0'), value: i }));
|
|
125
|
+
const minutes = ['00', '15', '30', '45'].map(v => ({ label: v, value: v }));
|
|
126
|
+
|
|
127
|
+
// 时间选择器(带分隔符)
|
|
128
|
+
<picker-view
|
|
129
|
+
style={{ height: '216px' }}
|
|
130
|
+
itemHeight={36}
|
|
131
|
+
onChange={(values) => console.log('选中:', values)}
|
|
132
|
+
>
|
|
133
|
+
<picker-column options={hours} defaultValue={10} />
|
|
134
|
+
<picker-divider text=":" />
|
|
135
|
+
<picker-column options={minutes} defaultValue="00" />
|
|
136
|
+
</picker-view>
|
|
137
|
+
|
|
138
|
+
// 年月日选择器
|
|
139
|
+
const years = Array.from({ length: 10 }, (_, i) => ({ label: `${2020 + i}年`, value: 2020 + i }));
|
|
140
|
+
const months = Array.from({ length: 12 }, (_, i) => ({ label: `${i + 1}月`, value: i + 1 }));
|
|
141
|
+
|
|
142
|
+
<picker-view style={{ height: '216px' }} itemHeight={36}>
|
|
143
|
+
<picker-column options={years} defaultValue={2024} />
|
|
144
|
+
<picker-column options={months} defaultValue={1} />
|
|
145
|
+
</picker-view>
|
|
146
|
+
```
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# 交互控件组件
|
|
2
|
+
|
|
3
|
+
## `<button>`
|
|
4
|
+
|
|
5
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
6
|
+
|------|------|--------|------|
|
|
7
|
+
| text | string | - | 按钮文字 |
|
|
8
|
+
| type | `'primary' \| 'default' \| 'plain'` | `'primary'` | 样式类型 |
|
|
9
|
+
| size | `'default' \| 'large' \| 'mini'` | `'default'` | 尺寸 |
|
|
10
|
+
| disabled | boolean | false | 禁用 |
|
|
11
|
+
| loading | boolean | false | 加载中状态 |
|
|
12
|
+
| icon | ReactNode | - | 文字前的图标 |
|
|
13
|
+
| children | ReactNode | - | 自定义内容,优先级高于 icon/text |
|
|
14
|
+
| throttle | number | 500 | onClick 节流时间 (ms) |
|
|
15
|
+
| onClick | (e?: TouchEvent) => void | - | 点击回调 |
|
|
16
|
+
| onDisabledClick | (e?: TouchEvent) => void | - | 禁用状态下点击回调 |
|
|
17
|
+
| openType | `'getPhoneNumber' \| 'agreePrivacyAuthorization' \| 'agreePrivacyAuthorization\|getPhoneNumber'` | - | 开放能力 |
|
|
18
|
+
| onGetPhoneNumber | (e: GetPhoneNumberResult) => void | - | 获取手机号回调,openType 包含 getPhoneNumber 时有效 |
|
|
19
|
+
| onAgreePrivacyAuthorization | (e: AgreePrivacyResult) => void | - | 隐私授权回调,openType 包含 agreePrivacyAuthorization 时有效 |
|
|
20
|
+
| className | string | - | 样式类名 |
|
|
21
|
+
| style | CSSProperties | - | 内联样式 |
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
// 基础按钮
|
|
25
|
+
<button text="提交" type="primary" onClick={() => handleSubmit()} />
|
|
26
|
+
|
|
27
|
+
// 加载状态
|
|
28
|
+
<button text="加载中" loading />
|
|
29
|
+
|
|
30
|
+
// 自定义内容
|
|
31
|
+
<button>
|
|
32
|
+
<image src="icon.png" style={{ width: '16px', height: '16px' }} />
|
|
33
|
+
<text>自定义按钮</text>
|
|
34
|
+
</button>
|
|
35
|
+
|
|
36
|
+
// 开放能力:获取手机号
|
|
37
|
+
<button
|
|
38
|
+
openType="getPhoneNumber"
|
|
39
|
+
onGetPhoneNumber={(e) => console.log(e)}
|
|
40
|
+
/>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## `<switch>`
|
|
46
|
+
|
|
47
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
48
|
+
|------|------|--------|------|
|
|
49
|
+
| checked | boolean | - | 受控值;设置后 defaultChecked 被忽略 |
|
|
50
|
+
| defaultChecked | boolean | false | 非受控默认值 |
|
|
51
|
+
| disabled | boolean | false | 禁用 |
|
|
52
|
+
| size | `'default' \| 'large'` | `'large'` | 尺寸 |
|
|
53
|
+
| onChange | (checked: boolean) => void | - | 状态变化,直接接收 boolean,不是事件对象 |
|
|
54
|
+
| className | string | - | 样式类名 |
|
|
55
|
+
| style | CSSProperties | - | 内联样式 |
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
// 非受控
|
|
59
|
+
<switch defaultChecked onChange={(checked) => console.log(checked)} />
|
|
60
|
+
|
|
61
|
+
// 受控
|
|
62
|
+
const [on, setOn] = useState(false);
|
|
63
|
+
<switch checked={on} onChange={setOn} />
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## `<slider>`
|
|
69
|
+
|
|
70
|
+
**仅支持受控用法,必须传 `value`。**
|
|
71
|
+
|
|
72
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
73
|
+
|------|------|--------|------|
|
|
74
|
+
| value | number | - | **必填**,当前值 |
|
|
75
|
+
| min | number | 0 | 最小值 |
|
|
76
|
+
| max | number | 100 | 最大值 |
|
|
77
|
+
| showValue | boolean | true | 是否显示当前数值 |
|
|
78
|
+
| disabled | boolean | false | 禁用 |
|
|
79
|
+
| onChange | (value: number) => void | - | 数值变化,直接接收 number |
|
|
80
|
+
| className | string | - | 样式类名 |
|
|
81
|
+
| style | CSSProperties | - | 内联样式 |
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const [volume, setVolume] = useState(50);
|
|
85
|
+
<slider value={volume} min={0} max={100} onChange={setVolume} />
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## `<radio-group>` / `<radio>`
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
const [selected, setSelected] = useState('a');
|
|
94
|
+
|
|
95
|
+
<radio-group value={selected} onChange={(v) => setSelected(v)}>
|
|
96
|
+
<radio value="a">选项 A</radio>
|
|
97
|
+
<radio value="b">选项 B</radio>
|
|
98
|
+
<radio value="c" disabled>选项 C(禁用)</radio>
|
|
99
|
+
</radio-group>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### radio-group 属性
|
|
103
|
+
|
|
104
|
+
| 属性 | 类型 | 说明 |
|
|
105
|
+
|------|------|------|
|
|
106
|
+
| value | string \| number | 当前选中值(受控) |
|
|
107
|
+
| defaultValue | string \| number | 默认值(非受控) |
|
|
108
|
+
| onChange | (value: string \| number) => void | 选中变化回调 |
|
|
109
|
+
| className | string | 样式类名 |
|
|
110
|
+
| style | CSSProperties | 内联样式 |
|
|
111
|
+
|
|
112
|
+
### radio 属性
|
|
113
|
+
|
|
114
|
+
| 属性 | 类型 | 说明 |
|
|
115
|
+
|------|------|------|
|
|
116
|
+
| value | string \| number | 该项的值 |
|
|
117
|
+
| disabled | boolean | 禁用 |
|
|
118
|
+
| children | ReactNode | 标签内容 |
|
|
119
|
+
| className | string | 样式类名 |
|
|
120
|
+
| style | CSSProperties | 内联样式 |
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# 地图与画布组件
|
|
2
|
+
|
|
3
|
+
## `<map>` / `<map-marker>`
|
|
4
|
+
|
|
5
|
+
完整文档见 SDK 的 `map.md`。
|
|
6
|
+
|
|
7
|
+
### map 核心属性
|
|
8
|
+
|
|
9
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
10
|
+
|------|------|--------|------|
|
|
11
|
+
| ref | Ref\<MapRef\> | - | 实例 ref |
|
|
12
|
+
| center | `{ longitude: number; latitude: number }` | - | 地图中心 |
|
|
13
|
+
| scale | number | 16 | 缩放级别(3-20) |
|
|
14
|
+
| minScale / maxScale | number | 3 / 20 | 缩放范围 |
|
|
15
|
+
| polyline | Polyline[] | [] | 路线数组 |
|
|
16
|
+
| polygons | Polygon[] | [] | 多边形数组 |
|
|
17
|
+
| circles | Circle[] | [] | 圆数组 |
|
|
18
|
+
| rotate | number | 0 | 旋转角度(度) |
|
|
19
|
+
| showScale | boolean | false | 显示比例尺 |
|
|
20
|
+
| enableScale | boolean | true | 允许缩放 |
|
|
21
|
+
| enableDrag | boolean | true | 允许拖动 |
|
|
22
|
+
| enableRotate | boolean | false | 允许旋转 |
|
|
23
|
+
| mapStyle | `'normal-light' \| 'normal-dark' \| 'simple-light' \| 'simple-dark' \| string` | `'normal-light'` | 地图主题,支持内置主题;自 0.2.1 起支持自定义样式 ID |
|
|
24
|
+
| onClick | (e: { point: { latitude: number; longitude: number } }) => void | - | 点击地图 |
|
|
25
|
+
| onMapLoaded | () => void | - | 地图加载完成 |
|
|
26
|
+
| onRegionChange | (e) => void | - | 视野变化 |
|
|
27
|
+
| className | string | - | 样式类名 |
|
|
28
|
+
| style | CSSProperties | - | 内联样式 |
|
|
29
|
+
|
|
30
|
+
### MapRef 方法
|
|
31
|
+
|
|
32
|
+
| 方法 | 参数 | 说明 |
|
|
33
|
+
|------|------|------|
|
|
34
|
+
| setCenter | (center, scale?) | 设置中心点 |
|
|
35
|
+
| getCenter | () | 获取当前中心点 |
|
|
36
|
+
| getScale | () | 获取当前缩放级别 |
|
|
37
|
+
| setScale | (scale) | 设置缩放级别 |
|
|
38
|
+
| getBound | () | 获取可见区域边界 |
|
|
39
|
+
| setBound | (bounds) | 设置可见区域边界 |
|
|
40
|
+
| fitPoints | (points, padding?) | 视野适配点集,padding 顺序 `[left, right, top, bottom]` |
|
|
41
|
+
| setAnchor | (position) | 设置地图锚点 |
|
|
42
|
+
|
|
43
|
+
### map-marker 核心属性
|
|
44
|
+
|
|
45
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
46
|
+
|------|------|--------|------|
|
|
47
|
+
| position | `{ longitude: number; latitude: number }` | - | 坐标(必填) |
|
|
48
|
+
| children | ReactNode | - | 自定义标记点 UI(必填) |
|
|
49
|
+
| anchor | [number, number] | [0.5, 1] | 经纬度在图标上的锚点 |
|
|
50
|
+
| alpha | number | 1 | 透明度(0-1) |
|
|
51
|
+
| rotation | number | 0 | 旋转角度(0-360) |
|
|
52
|
+
| clickable | boolean | true | 是否可点击 |
|
|
53
|
+
| draggable | boolean | false | 是否可拖拽 |
|
|
54
|
+
| onClick | () => void | - | 点击回调 |
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import type { MapRef } from '@doubao-dev/framework/components';
|
|
58
|
+
import { useRef } from '@doubao-dev/framework';
|
|
59
|
+
|
|
60
|
+
const mapRef = useRef<MapRef>(null);
|
|
61
|
+
|
|
62
|
+
<map
|
|
63
|
+
ref={mapRef}
|
|
64
|
+
center={{ longitude: 116.397, latitude: 39.916 }}
|
|
65
|
+
scale={15}
|
|
66
|
+
style={{ width: '100%', height: '300px' }}
|
|
67
|
+
onMapLoaded={() => mapRef.current?.fitPoints([
|
|
68
|
+
{ longitude: 116.39, latitude: 39.91 },
|
|
69
|
+
{ longitude: 116.40, latitude: 39.92 },
|
|
70
|
+
])}
|
|
71
|
+
>
|
|
72
|
+
<map-marker position={{ longitude: 116.397, latitude: 39.916 }} onClick={() => console.log('clicked')}>
|
|
73
|
+
<view style={{ width: '24px', height: '24px', background: '#FF3B30', borderRadius: '50%' }} />
|
|
74
|
+
</map-marker>
|
|
75
|
+
</map>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## `<canvas>`
|
|
81
|
+
|
|
82
|
+
| 属性 | 类型 | 说明 |
|
|
83
|
+
|------|------|------|
|
|
84
|
+
| ref | Ref\<CanvasRef\> | 实例 ref,获取绘图上下文 |
|
|
85
|
+
| style | CSSProperties | 内联样式(设置宽高) |
|
|
86
|
+
| className | string | 样式类名 |
|
|
87
|
+
| onResize | (e: CanvasResizeEvent) => void | 尺寸变化回调 |
|
|
88
|
+
|
|
89
|
+
### CanvasRef 方法
|
|
90
|
+
|
|
91
|
+
通过 ref 获取实例后调用 `getContext('2d')` 获取 2D 绘图上下文,API 与 Web Canvas 基本一致。
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import type { CanvasRef } from '@doubao-dev/framework/components';
|
|
95
|
+
import { useRef, useEffect } from '@doubao-dev/framework';
|
|
96
|
+
|
|
97
|
+
const canvasRef = useRef<CanvasRef>(null);
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
const ctx = canvasRef.current?.getContext('2d');
|
|
101
|
+
if (!ctx) return;
|
|
102
|
+
ctx.fillStyle = '#FF3B30';
|
|
103
|
+
ctx.fillRect(10, 10, 100, 100);
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
106
|
+
<canvas ref={canvasRef} style={{ width: '300px', height: '300px' }} />
|
|
107
|
+
```
|