create-dwy 0.19.0 → 0.20.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 (117) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/package.json +1 -1
  3. package/src/cli-help.js +28 -2
  4. package/src/prompt-style.js +82 -0
  5. package/src/searchable-select.js +12 -29
  6. package/src/sync-all.js +95 -583
  7. package/src/sync-codex.js +14 -7
  8. package/src/sync-opencode.js +8 -22
  9. package/src/sync.js +60 -149
  10. package/src/tab-multiselect.js +21 -64
  11. package/templates/ai-tools/CHANGELOG.md +195 -0
  12. package/templates/ai-tools/CLAUDE.md +39 -58
  13. package/templates/ai-tools/VERSION +1 -1
  14. package/templates/ai-tools/hooks/Git/pre-git-commit-ai-signature-check.sh +5 -4
  15. package/templates/ai-tools/rules/Android/dwy-android-core.md +147 -13
  16. package/templates/ai-tools/rules/Android/dwy-android-layering.md +142 -0
  17. package/templates/ai-tools/rules/Android/dwy-android-mvp.md +55 -0
  18. package/templates/ai-tools/rules/Android/dwy-android-support-only.md +2 -0
  19. package/templates/ai-tools/rules/Docker/dwy-docker.md +23 -1
  20. package/templates/ai-tools/rules/Flutter/dwy-flutter-core.md +2 -0
  21. package/templates/ai-tools/rules/Flutter/dwy-flutter-testing.md +1 -1
  22. package/templates/ai-tools/rules/HarmonyOS/dwy-arkts-ui-build.md +12 -8
  23. package/templates/ai-tools/rules/Python/dwy-python-backend.md +4 -43
  24. package/templates/ai-tools/rules/Python/dwy-python-base-lib.md +1 -1
  25. package/templates/ai-tools/rules/Python/dwy-python-layering.md +169 -0
  26. package/templates/ai-tools/rules/Vue/dwy-vue-core.md +11 -49
  27. package/templates/ai-tools/rules/Vue/dwy-vue-layering.md +153 -0
  28. package/templates/ai-tools/rules/iOS/dwy-apple-layering.md +133 -0
  29. package/templates/ai-tools/rules/iOS/dwy-swift-core.md +2 -0
  30. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-code-craft.md +83 -0
  31. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-dependency-freshness.md +27 -66
  32. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-git-commit.md +8 -219
  33. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-oss-commercial-license.md +27 -123
  34. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-prod-branch.md +31 -0
  35. package/templates/ai-tools/rules//346/225/260/346/215/256/345/272/223/dwy-postgres.md +17 -10
  36. package/templates/ai-tools/rules//346/225/260/346/215/256/345/272/223/dwy-redis.md +6 -3
  37. package/templates/ai-tools/skills/Docker/dwy-deploy-first/SKILL.md +14 -14
  38. package/templates/ai-tools/skills/Docker/dwy-deploy-first/references/chapter-01-mirrors.md +2 -2
  39. package/templates/ai-tools/skills/Docker/dwy-docker/SKILL.md +21 -13
  40. package/templates/ai-tools/skills/Docker/dwy-docker/references/ask-templates.md +13 -12
  41. package/templates/ai-tools/skills/Docker/dwy-docker/references/templates.md +3 -1
  42. package/templates/ai-tools/skills/Docker/dwy-docker/references/version-rules.md +10 -6
  43. package/templates/ai-tools/skills/Docker/dwy-docker/scripts/query_dockerhub.py +21 -6
  44. package/templates/ai-tools/skills/Docker/dwy-docker/scripts/scan_images.sh +2 -2
  45. package/templates/ai-tools/skills/Docker/dwy-mirror-source/SKILL.md +44 -30
  46. package/templates/ai-tools/skills/Docker/dwy-mirror-source/references/dockerfile-snippets.md +2 -0
  47. package/templates/ai-tools/skills/Docker/dwy-mirror-source/references/mirror-providers.md +8 -8
  48. package/templates/ai-tools/skills/Docker/dwy-mirror-source/scripts/apply_mirrors.py +14 -1
  49. package/templates/ai-tools/skills/Docker/dwy-mirror-source/scripts/check_mirrors.py +4 -0
  50. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/SKILL.md +8 -6
  51. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/digest/python-sdk.md +3 -3
  52. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/digest/stream-engine.md +2 -2
  53. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/anti-patterns.md +3 -1
  54. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/change-checklist.md +4 -4
  55. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/lethal-violations.md +5 -5
  56. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/perf-baselines.md +5 -5
  57. package/templates/ai-tools/skills/Python/dwy-eapi/SKILL.md +59 -200
  58. package/templates/ai-tools/skills/Python/dwy-eapi/shared/anticorruption.md +13 -0
  59. package/templates/ai-tools/skills/Python/dwy-eapi/shared/layering.md +5 -0
  60. package/templates/ai-tools/skills/Python/dwy-eapi/shared/response-envelope.md +20 -0
  61. package/templates/ai-tools/skills/Python/dwy-eapi/shared/timezone.md +7 -0
  62. package/templates/ai-tools/skills/Python/dwy-eapi/v0/breaking.md +15 -0
  63. package/templates/ai-tools/skills/Python/dwy-eapi/v0/email-canonical.md +43 -0
  64. package/templates/ai-tools/skills/Python/dwy-eapi/v0/index.md +103 -0
  65. package/templates/ai-tools/skills/Python/dwy-eapi/v0/providers-email.md +49 -0
  66. package/templates/ai-tools/skills/Python/dwy-eapi/versions.yml +13 -0
  67. package/templates/ai-tools/skills/Vue/dwy-eui/SKILL.md +62 -306
  68. package/templates/ai-tools/skills/Vue/dwy-eui/references/eui-design-guide.md +8 -1
  69. package/templates/ai-tools/skills/Vue/dwy-eui/references/eui-integration-guide.md +0 -31
  70. package/templates/ai-tools/skills/Vue/dwy-eui/shared/config-theme.md +8 -0
  71. package/templates/ai-tools/skills/Vue/dwy-eui/shared/form.md +6 -0
  72. package/templates/ai-tools/skills/Vue/dwy-eui/shared/overlay.md +6 -0
  73. package/templates/ai-tools/skills/Vue/dwy-eui/shared/reka.md +5 -0
  74. package/templates/ai-tools/skills/Vue/dwy-eui/v1/index.md +8 -0
  75. package/templates/ai-tools/skills/Vue/dwy-eui/v2/breaking.md +14 -0
  76. package/templates/ai-tools/skills/Vue/dwy-eui/v2/index.md +55 -0
  77. package/templates/ai-tools/skills/Vue/dwy-eui/v2/lookup.md +29 -0
  78. package/templates/ai-tools/skills/Vue/dwy-eui/versions.yml +12 -0
  79. package/templates/ai-tools/skills//344/272/247/345/223/2010/345/210/2601/dwy-architecture/SKILL.md +11 -14
  80. package/templates/ai-tools/skills//344/272/247/345/223/2010/345/210/2601/dwy-product-launcher/references/state-and-contract.md +1 -1
  81. package/templates/ai-tools/skills//344/272/247/345/223/2010/345/210/2601/dwy-prototype/SKILL.md +1 -1
  82. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/SKILL.md +32 -15
  83. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/references/electron-release-workflow-template.yml +3 -1
  84. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/references/release-workflow-template.yml +8 -5
  85. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/SKILL.md +1 -1
  86. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/assets/appstore-submission.yaml +1 -1
  87. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/references/aso.md +2 -0
  88. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/references/in-app-purchase-review.md +1 -1
  89. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/SKILL.md +4 -3
  90. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/android.md +1 -1
  91. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/backend-deploy.md +1 -1
  92. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/changelog.md +45 -27
  93. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/frontend-deploy.md +1 -1
  94. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/generic-release.md +1 -1
  95. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/git-tag.md +1 -1
  96. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/harmony.md +1 -1
  97. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/ios.md +1 -1
  98. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/SKILL.md +8 -0
  99. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/SKILL.md +7 -7
  100. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/references/checks-runtime.md +63 -59
  101. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_base.sh +10 -1
  102. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_capacity.sh +21 -23
  103. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_db.sh +9 -1
  104. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_docker.sh +20 -24
  105. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_logs.sh +3 -3
  106. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/dwy-doubao-tts/SKILL.md +4 -2
  107. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/dwy-doubao-tts/references/api.md +1 -1
  108. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/dwy-doubao-tts/scripts/synthesize.py +1 -0
  109. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/media-platform-packaging/SKILL.md +7 -5
  110. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/media-platform-packaging/references/platform-copy-examples.md +5 -3
  111. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-dependency-choice/SKILL.md +140 -0
  112. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-git-commit/SKILL.md +113 -0
  113. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-shared/SKILL.md +16 -13
  114. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-whiteboard-prototype/SKILL.md +1 -1
  115. package/src/sync-packs.js +0 -223
  116. package/src/sync-scene.js +0 -178
  117. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-tdd-development.md +0 -115
@@ -0,0 +1,49 @@
1
+ # 邮件 Provider(0.x)
2
+
3
+ 内置与自定义走同一注册表。`make_email_provider` 只按 `EMAIL__PROVIDER` 查名。
4
+
5
+ 当前内置仅 `resend`,extra:`dwyeapi[email-resend]`。`dwyeapi[email]` = 全部内置 extra(现在就这一个)。
6
+
7
+ ```python
8
+ from dwyeapi.providers.email import (
9
+ EmailProviderBase,
10
+ EmailSettings,
11
+ make_email_provider,
12
+ register_email_provider,
13
+ )
14
+
15
+ provider = make_email_provider(settings.email)
16
+ await provider.send_code("user@qq.com")
17
+ ```
18
+
19
+ 自定义(**不用改 eapi**):
20
+
21
+ ```python
22
+ class TencentSesProvider(EmailProviderBase):
23
+ async def _send(self, target: str, code: str) -> bool:
24
+ html = self._render_code_html(code)
25
+ text = self._render_code_text(code)
26
+ return True
27
+
28
+ register_email_provider(
29
+ "tencent_ses",
30
+ lambda s: TencentSesProvider(
31
+ code_ttl=s.code_ttl,
32
+ require_common_domain=s.require_common_domain,
33
+ extra_allow_domains=s.extra_allow_domain_list(),
34
+ allow_edu=s.allow_edu,
35
+ allow_edu_cn=s.allow_edu_cn,
36
+ ),
37
+ )
38
+ # .env: EMAIL__PROVIDER=tencent_ses
39
+ ```
40
+
41
+ - 验证码 Redis + 品牌化模板由基类复用,子类只实现 `_send`
42
+ - 内置名 `resend` 不可覆盖
43
+ - 自定义同名二次注册会覆盖并 warning
44
+ - 必须在 `make_email_provider` **之前** register
45
+ - `send_code` / `verify_code` 的 Redis key 自 **0.9.6** 走 `canonicalize_email`;发信信封仍用用户输入地址
46
+ - `send_code` **默认**校验常见邮箱域名(`EMAIL__REQUIRE_COMMON_DOMAIN`,≥0.10.0);失败不发信。详见 `email-canonical.md`
47
+ - 缺 extra 构造内置 provider → `ImportError`,提示 `pip install dwyeapi[email-resend]`
48
+
49
+ 0.9.0 删除了内置 mock / 阿里云占位 / 整个 sms 模块,见 `breaking.md`。
@@ -0,0 +1,13 @@
1
+ # dwyeapi 安装版本 → 文档线。匹配从上到下第一条。
2
+ # 大版本破坏才新开 vN/;0.x 内部 breaking 写 v0/breaking.md,细节 clone 对应 tag。
3
+ repo: https://github.com/danweiyuancircle/dwy-ai-experience.git
4
+ tag_prefix: "dwyeapi@"
5
+ sparse:
6
+ - backend/src/dwyeapi
7
+ lines:
8
+ - match: ">=2.0.0"
9
+ dir: v2
10
+ - match: ">=1.0.0"
11
+ dir: v1
12
+ - match: ">=0.0.0"
13
+ dir: v0
@@ -1,333 +1,89 @@
1
1
  ---
2
2
  name: dwy-eui
3
- description: "@dwydev/eui Vue 3 组件库使用指南。当用户在使用 Vue 3 构建页面、选择 UI 组件、查询组件 API、写表单/表格/弹层/导航、配置主题或国际化、使用中后台或落地页设计规范时,**必须**使用此 skill。即使用户没有明确说 'eui',只要涉及 Vue 3 组件选型、页面布局、表单设计、数据展示、弹层交互、主题切换,也应触发。"
4
- eui_baseline_version: "2.1.0"
3
+ description: "Use when building Vue 3 UI with @dwydev/eui: pick components, forms, tables, overlays, admin layout, theme, i18n, EConfigProvider. The single navigation skill for @dwydev/eui."
5
4
  ---
6
5
 
7
- # @dwydev/eui 组件库使用指南
6
+ # @dwydev/eui
8
7
 
9
- Vue 3 组件库:Reka-ui 原语层 + shadcn-vue 设计风格 + Element Plus 式 API + Tailwind CSS 4。
8
+ Vue 3 组件库(Reka-ui + shadcn 视觉 + Element Plus 式 API + Tailwind 4)。本文件只做**路由**:探测安装版本 → 选文档线 → 不够再读源码(先 clone tag,拿不到再读 `node_modules`)。
10
9
 
11
- 本 skill 的索引信息基于 EUI **2.1.0**。消费方项目实际版本可能不同 — 见 [版本兼容规则](#版本兼容规则)。
10
+ 对外只有这一个 skill。`v1/` `v2/` 不是独立 skill,禁止当多个入口用。
12
11
 
13
- ---
14
-
15
- ## 集成与设计规范
16
-
17
- | 场景 | 读取文件 |
18
- |------|---------|
19
- | 新项目集成 EUI | `references/eui-integration-guide.md` |
20
- | 中后台页面设计规范 | `references/eui-design-guide.md` |
21
- | 落地页/营销页设计规范 | `references/eui-landing-design-guide.md` |
22
-
23
- ---
24
-
25
- ## 查 API 标准动作(核心:每次用组件前都做)
26
-
27
- EUI 有 87 个组件目录、117 个对外组件。**本文档不再镜像 props/emits 列表** —— 因为它们会随版本漂移。AI 想用某个组件时,按下面顺序拿到精确 API:
28
-
29
- ### 第一步:定位 EUI 真实版本
30
-
31
- 读消费方项目的 `package.json`,找 `dependencies["@dwydev/eui"]` 或 `peerDependencies["@dwydev/eui"]`。这个版本号才是 AI 写代码的依据,不是 skill frontmatter 里的 baseline。
12
+ ## 每次写 @dwydev/eui 代码前(强制)
32
13
 
33
- ### 第二步:读 component-manifest.json(一次拿组件地图)
14
+ 1. **探测安装版本**(按顺序,命中即停)
15
+ ```bash
16
+ node -p "require('@dwydev/eui/package.json').version"
17
+ ```
18
+ 失败则读 `pnpm-workspace.yaml` catalog `'@dwydev/eui'`,再读 `package.json` 的 `dependencies` / `peerDependencies`。
19
+ 仍失败:按 `v2` 给脚手架,并声明「未探测到安装版本」。
34
20
 
35
- 从 EUI 2.1.0 起,npm 包带一份组件清单:
21
+ 2. **选线**:读同目录 `versions.yml`。`2.y.z` → `v2/`,`1.y.z` → `v1/`。目录不存在(例如装了 3.x 但还没有 `v3/`)→ 不要用 `v2` 冒充;按下面「读源码」拿该版本代码,并说明文档线未建。
36
22
 
37
- ```
38
- <project-root>/node_modules/@dwydev/eui/dist/component-manifest.json
39
- ```
23
+ 3. **读文档**:先 `shared/`(跨大版本不变),再该线 `vN/`。能力标了版本下限(如 `component-manifest.json` ≥2.1.0、`useEuiMobile` ≥2.4)时,安装版本低于下限 → 当不存在。
40
24
 
41
- 结构(精简示例):
42
- ```json
43
- {
44
- "version": "2.1.0",
45
- "componentToDir": { "EButton": "button", "ECommandInput": "command" },
46
- "directories": {
47
- "button": { "types": "components/button/types.d.ts", "components": ["EButton"] },
48
- "command": { "types": null, "components": ["ECommand", "ECommandInput", "..."] }
49
- },
50
- "composables": ["useMessage", "useTheme", "..."]
51
- }
52
- ```
25
+ 4. **文档不够 / 和记忆冲突 / 下限对不上** → 读代码,顺序如下(命中即停):
26
+ 1. clone 安装版本对应 tag(见下)
27
+ 2. tag 不存在 / clone 失败 → 读**当前项目** `node_modules/@dwydev/eui`
28
+ 3. `node_modules` 也没有 → **停下来问人**,禁止猜 props,禁止拿旁边 dwy-shared master 冒充
53
29
 
54
- 用法:
55
- - 知道组件名(如 `EButton`) → 查 `componentToDir["EButton"]` 拿到目录 `"button"`
56
- - 查 `directories["button"].types` 拿到类型文件相对路径
57
- - 拼接:`<project-root>/node_modules/@dwydev/eui/dist/{types}` 就是要读的 .d.ts
30
+ ## 读源码
58
31
 
59
- manifest 不存在的回退:
60
- - 消费方装的是 EUI < 2.1.0(旧版本没有 manifest) → 直接走第三步用约定路径
61
- - 仓库无 node_modules(裸 monorepo / 未 install) → 走第三步的 dwy-shared 路径
32
+ ### 1. clone tag(优先)
62
33
 
63
- ### 第三步:读组件 types.d.ts(精确 props + emits)
64
-
65
- 按存在性回退:
34
+ ```bash
35
+ VER=2.4.0 # 换成第 1 步探测到的版本
36
+ TAG="@dwydev/eui@${VER}"
37
+ DEST=".dwy/eui-src/${VER}" # 项目内缓存,已 gitignore
66
38
 
39
+ if [ ! -d "$DEST/frontend/eui/src" ]; then
40
+ git clone --depth 1 --branch "$TAG" \
41
+ --filter=blob:none --sparse \
42
+ https://github.com/danweiyuancircle/dwy-ai-experience.git \
43
+ "$DEST"
44
+ git -C "$DEST" sparse-checkout set frontend/eui/src frontend/eui/package.json
45
+ fi
46
+ # 只读 $DEST/frontend/eui/src/ 的组件 types.ts / .vue
67
47
  ```
68
- a. 优先:<project-root>/node_modules/@dwydev/eui/dist/components/{kebab}/types.d.ts
69
- —— 下游消费方默认场景,含完整 props + emits + JSDoc 注释
70
-
71
- b. 次选:<dwy-shared-root>/frontend/eui/src/components/{kebab}/types.ts
72
- —— 仅当在 dwy-shared monorepo 内或并列 clone 时可用,等价信息
73
-
74
- c. 都拿不到 → 退到本文档下方的 [组件目录索引](#组件目录索引)(粗略,仅做导航)
75
- ```
76
-
77
- `{kebab}` 是目录名规则:组件名去 `E` 前缀后转 kebab-case。
78
- - `EButton` → `button`
79
- - `EDatePicker` → `date-picker`
80
- - `EAdminLayout` → `admin-layout`
81
- - `EAIChat` → `ai-chat`(连续大写视为整体)
82
-
83
- **不确定目录名时**:`ls node_modules/@dwydev/eui/dist/components/` 或 `ls frontend/eui/src/components/`,**不要靠猜**。
84
-
85
- ### 第四步:slots 看 .vue 模板(不在 .d.ts 里)
86
-
87
- vue-tsc 输出的 `.d.ts` 中,slots 类型大多被擦平成 `any`。需要 slot 用法(默认插槽、具名插槽、作用域插槽)时,读源码 `.vue` 文件,搜索 `<slot` 看模板里实际定义。
88
-
89
- - node_modules 路径下 `.vue` 文件**不存在**(只有 .d.ts),slots 必须回 dwy-shared 源码看
90
- - 拿不到源码时:参考 reka-ui / shadcn-vue 的同名组件 slots 规范,多数 EUI 组件直接转发
91
-
92
- ### 第五步:冲突时永远信 node_modules
93
-
94
- 当本 SKILL.md 的描述与消费方项目的 node_modules `.d.ts` 不一致:**无条件以 node_modules 为准**。本文档是导航与心智模型,不是 API 真相。
95
-
96
- ---
97
-
98
- ## 版本兼容规则
99
-
100
- - 本 skill `eui_baseline_version: 2.1.0`,组件索引、composables 列表、踩坑提示都基于这个版本
101
- - 消费方项目用的是不同版本时(无论更新或更旧),**必须按"查 API 标准动作"流程读 .d.ts**,不要默认本文档准确
102
- - EUI < 2.1.0 没有 `component-manifest.json`:直接走第三步的 types.d.ts 约定路径
103
- - 主版本号变更(1.x → 2.x、2.x → 3.x)时,本文档的索引可能完全失效:必须先 `ls node_modules/@dwydev/eui/dist/components/` 重建认知
104
-
105
- ---
106
-
107
- ## 命名约定
108
-
109
- - 组件前缀 `E`:`EButton`、`EInput`、`EDialog`
110
- - Props 类型:`E{Name}Props`(如 `EButtonProps`)
111
- - Events 类型:`E{Name}Emits`(如 `EInputEmits`)
112
- - CVA 变体:`{name}Variants`(如 `buttonVariants`)
113
- - 样式合并工具:`cn()` = clsx + tailwind-merge
114
- - 尺寸统一类型:`Size = 'sm' | 'default' | 'lg'`
115
- - 复合组件用 `provide/inject` 共享状态,子组件目录与主组件同处(如 `command/` 下含 ECommand、ECommandInput、ECommandList...)
116
-
117
- ---
118
-
119
- ## 重要约束与已知陷阱
120
-
121
- 源码读不出来的"踩坑经验",每次写 EUI 代码都遵守:
122
-
123
- ### 表单
124
- - **禁止用原生 `<form>` 标签**,所有表单必须用 `<EForm>`。EForm 内置 vee-validate 校验、provide/inject 上下文、统一 label 布局和 reset/validate API,原生 `<form>` 无法集成
125
- - `ESelect` 的 `option.value` **不能为空字符串**,reka-ui 不支持
126
- - 表单校验优先用 zod schema 传给 `EForm` 的 `rules` prop
127
48
 
128
- ### 弹层
129
- - `EDialog` body 区域有 `overflow-y-auto`,**首尾位置的 input/select 等表单控件的 focus-ring 会被裁切**。规避:在内容区域加 `p-1` 或 `py-1` padding
130
- - 弹层组件统一用 `v-model:open` 控制显隐,不要用 `:visible` / `@update:visible`
49
+ - `--branch` 必须是 `@dwydev/eui@x.y.z`(含 `-beta.N`),禁止 clone 默认 branch。
50
+ - 必须 sparse,只要 `frontend/eui/src`。
131
51
 
132
- ### reka-ui 绑定约定
133
- - 封装 reka-ui 组件时统一用 `v-model`(`modelValue` / `update:modelValue`),**不是** `:checked` / `@update:checked`
134
- - 自己写组件包 reka-ui 原语时必须用 `v-model` 或 writable computed 绑定
52
+ ### 2. node_modules(clone 拿不到时)
135
53
 
136
- ### 全局配置
137
- - `EConfigProvider` 必须包裹 App 根组件,提供国际化(locale)/ 默认尺寸 / zIndex
138
- - `locale.name` 字段必须是 BCP 47 语言标签(如 `zh-CN`、`en-US`),默认 `zh-CN`
139
-
140
- ### 样式
141
- - 使用 `cn()` 合并 Tailwind 类名(解决冲突):`cn('px-2 py-1', isActive && 'bg-primary text-white', className)`
142
- - 主题切换通过 `useTheme()` 的 `setColorTheme()` / `toggleDark()`,**不要**手动操作 `<html class="dark">`
143
-
144
- ---
145
-
146
- ## Composables 速查
147
-
148
- | Composable | 用途 |
149
- |------------|------|
150
- | `useMessage()` | 全局消息提示(success / warning / error / info) |
151
- | `useNotification()` | 通知(含 title / message / position / duration) |
152
- | `useMessageBox()` | 对话确认(alert / confirm / prompt),返回 Promise |
153
- | `useTheme()` | 主题管理(isDark / setTheme / setColorTheme / toggleDark) |
154
- | `useConfigProvider()` | 读取全局配置(size / zIndex / locale) |
155
- | `useFormField()` | 表单字段上下文(id / name / valid / error),需在 FormField 内使用 |
156
- | `useSecureValue()` | 敏感输入安全绑定(DOM property 赋值,避免密码泄露到 HTML attribute) |
157
-
158
- 精确签名读 `<project-root>/node_modules/@dwydev/eui/dist/composables/{name}.d.ts`。
159
-
160
- ---
161
-
162
- ## 主题系统
163
-
164
- - **Design Tokens**:CSS 自定义属性,定义在 `tokens.css`,前缀 `--`(如 `--primary`、`--background`)
165
- - **暗色模式**:`dark.css`,通过 `<html class="dark">` 切换(用 `useTheme().toggleDark()`,不手写)
166
- - **色彩主题**:7 种(neutral / blue / green / rose / orange / violet / slate),通过 `useTheme().setColorTheme()` 切换
167
- - 样式入口:`import '@dwydev/eui/theme'`
168
-
169
- ---
170
-
171
- ## 通用类型速查
172
-
173
- 精确定义读 `<project-root>/node_modules/@dwydev/eui/dist/types.d.ts`。常用:
174
-
175
- ```ts
176
- type Size = 'sm' | 'default' | 'lg'
177
-
178
- interface Option {
179
- label: string
180
- value: string | number // ⚠️ 不能为空字符串
181
- disabled?: boolean
182
- }
183
-
184
- interface MenuItem {
185
- key: string
186
- label: string
187
- icon?: string
188
- path?: string // router 模式下的路由路径
189
- children?: MenuItem[]
190
- disabled?: boolean
191
- }
192
-
193
- interface TableColumn<T = any> {
194
- key: string
195
- title: string
196
- width?: number | string
197
- minWidth?: number
198
- sortable?: boolean
199
- fixed?: 'left' | 'right'
200
- align?: 'left' | 'center' | 'right'
201
- render?: (row: T, index: number) => any
202
- }
54
+ ```bash
55
+ # 版本与清单
56
+ node -p "require('@dwydev/eui/package.json').version"
57
+ ls node_modules/@dwydev/eui/dist/component-manifest.json
58
+ # props/emits:dist/components/{kebab}/types.d.ts
59
+ # slots:.d.ts 常被擦成 any,clone 源码搜 <slot
203
60
  ```
204
61
 
205
- ---
206
-
207
- ## 组件目录索引
208
-
209
- 按用途分类的导航表,**只提供组件名 + 一句话用途**,精确 props/emits 一律按 [查 API 标准动作](#查-api-标准动作核心每次用组件前都做) 读 `types.d.ts`。
210
-
211
- ### 基础展示
212
-
213
- | 组件 | 用途 |
214
- |------|------|
215
- | `EButton` | 按钮(含 loading 状态) |
216
- | `EButtonGroup` | 按钮组 |
217
- | `EBadge` | 标签徽章 |
218
- | `EAlert` | 警告提示 |
219
- | `ECard` | 卡片容器 |
220
- | `ELabel` | 标签文本 |
221
- | `ESeparator` | 分隔线 |
222
- | `ETypography` | 排版文本 |
223
- | `EKbd` | 键盘按键展示 |
224
- | `ESpinner` | 加载动画 |
225
- | `EProgress` | 进度条 |
226
- | `ESkeleton` | 骨架屏 |
227
- | `EEmpty` | 空状态 |
228
- | `EAvatar` | 头像 |
229
- | `EImage` | 图片(含懒加载/预览) |
230
- | `EAspectRatio` | 宽高比容器 |
231
- | `EAffix` | 固钉 |
232
- | `EWatermark` | 水印 |
233
-
234
- ### 表单输入
235
-
236
- | 组件 | 用途 |
237
- |------|------|
238
- | `EForm` / `EFormItem` | 表单容器与表单项(必用,禁用原生 form) |
239
- | `EField` | 字段布局(垂直/水平/响应式) |
240
- | `EInput` | 输入框(含 password / clearable / 字数统计) |
241
- | `EInputGroup` | 输入组(含 prefix/suffix addon) |
242
- | `ETextarea` | 多行输入(含自适应高度) |
243
- | `ENumberField` | 数字输入 |
244
- | `ESelect` | 下拉选择(option.value ≠ '') |
245
- | `ENativeSelect` | 原生 select |
246
- | `ECombobox` | 组合框(可输入下拉) |
247
- | `EAutocomplete` | 自动补全 |
248
- | `ECheckbox` | 复选框/复选组 |
249
- | `ERadio` | 单选组 |
250
- | `ESwitch` | 开关 |
251
- | `ETagsInput` | 标签输入 |
252
- | `EDatePicker` | 日期/范围/月/年选择 |
253
- | `ETimePicker` | 时间选择 |
254
- | `EColorPicker` | 颜色选择 |
255
- | `ERate` | 评分 |
256
- | `ESlider` | 滑块 |
257
- | `ECascader` | 级联选择 |
258
- | `ETreeSelect` | 树选择 |
259
- | `EMention` | @提及输入 |
260
- | `EInputOTP` | OTP 验证码 |
261
- | `EPinInput` | PIN 输入 |
262
- | `EUpload` | 文件上传(含拖拽/图片墙) |
263
- | `ETransfer` | 穿梭框 |
264
-
265
- ### 数据展示
266
-
267
- | 组件 | 用途 |
268
- |------|------|
269
- | `ETable` | 表格(含排序/选择/展开/虚拟滚动/列固定) |
270
- | `EVirtualTable` | 虚拟滚动表格(大数据专用) |
271
- | `EDescriptions` | 描述列表 |
272
- | `ETimeline` | 时间线 |
273
- | `EStatistic` | 统计数值 |
274
- | `ETree` | 树形控件 |
275
- | `ECalendar` | 日历 |
276
- | `ERangeCalendar` | 日期范围日历 |
277
- | `EPagination` | 分页 |
278
- | `EBreadcrumb` | 面包屑 |
279
- | `EChartContainer` | 图表容器 |
280
-
281
- ### 弹层与反馈
282
-
283
- | 组件 | 用途 |
284
- |------|------|
285
- | `EDialog` | 对话框(v-model:open,body 区域 padding 见踩坑提示) |
286
- | `EDrawer` | 抽屉 |
287
- | `ESheet` | 侧边面板 |
288
- | `EAlertDialog` | 确认对话框 |
289
- | `ETooltip` | 提示气泡 |
290
- | `EPopover` | 弹出卡片 |
291
- | `EHoverCard` | 悬停卡片 |
292
- | `EToast` | 轻提示(配合 useToast / `toast()`) |
293
- | `EContextMenu` | 右键菜单 |
294
-
295
- ### 导航与布局
296
-
297
- | 组件 | 用途 |
298
- |------|------|
299
- | `ETabs` | 标签页 |
300
- | `EMenu` | 侧边菜单 |
301
- | `EDropdown` | 下拉菜单 |
302
- | `EAccordion` | 手风琴 |
303
- | `ECollapsible` | 折叠面板 |
304
- | `EStepper` | 步骤条 |
305
- | `ECarousel` | 轮播 |
306
- | `EScrollArea` | 自定义滚动区 |
307
- | `EInfiniteScroll` | 无限滚动 |
308
- | `EToggle` / `EToggleGroup` | 切换按钮 |
309
- | `EItem` | 列表项 |
310
- | `EResizablePanelGroup` 等 | 可调整大小面板(复合组件) |
62
+ `node_modules` 是消费方正在跑的代码,当作安装版本真相。
311
63
 
312
- ### 复合组件(子组件需配合使用)
64
+ 文档与源码冲突:信源码。clone 与 node_modules 都读到且不一致:以 **node_modules** 为准,回复里写明。
313
65
 
314
- | 主组件 | 用途 |
315
- |--------|------|
316
- | `ECommand` | 命令面板(含 ECommandInput / List / Empty / Group / Item / Separator / Shortcut) |
317
- | `ENavigationMenu` | 导航菜单(含 List / Item / Trigger / Content / Link / Viewport) |
318
- | `EMenubar` | 菜单栏(含 Menu / Trigger / Content / Item / Separator / Checkbox / Radio / Sub) |
319
- | `EResizable` | 可调整大小(含 PanelGroup / Panel / Handle) |
66
+ ## 文档地图
320
67
 
321
- 复合组件的全部子组件名查 `component-manifest.json` 的 `directories[{kebab}].components`。
68
+ | 路径 | 何时读 |
69
+ |------|--------|
70
+ | `shared/form.md` | 禁原生 form、ESelect 空 value、zod rules |
71
+ | `shared/overlay.md` | `v-model:open`、Dialog padding、Sheet zIndex |
72
+ | `shared/reka.md` | 封装 reka 必须 v-model |
73
+ | `shared/config-theme.md` | EConfigProvider、useTheme、cn() |
74
+ | `v2/index.md` | 2.x 组件导航、composables、陷阱 |
75
+ | `v2/lookup.md` | manifest / types.d.ts 怎么查 |
76
+ | `v2/breaking.md` | 2.x 内部 breaking(含 2.4.0 删组件) |
77
+ | `v1/index.md` | 1.x 导航;无 manifest 时怎么查 |
78
+ | `references/eui-integration-guide.md` | 新项目接入 |
79
+ | `references/eui-design-guide.md` | 中后台设计 |
80
+ | `references/eui-landing-design-guide.md` | 落地页设计 |
322
81
 
323
- ### 业务组件
82
+ ## 禁止
324
83
 
325
- | 组件 | 用途 |
84
+ | 借口 | 实际 |
326
85
  |------|------|
327
- | `EDataPage` | 数据列表页(内置表格 + 分页 + 搜索) |
328
- | `EFormDialog` | 表单弹窗 |
329
- | `EConfirmDialog` | 确认弹窗(类型: info / warning / error) |
330
- | `EAdminLayout` | 后台管理布局(顶部 + 侧边栏 + 主内容) |
331
- | `EAIChat` | AI 对话 |
332
- | `ETimetableGrid` | 课程表/时间表 |
333
- | `EConfigProvider` | 全局配置(必须包裹 App 根) |
86
+ | 读旁边 dwy-shared master | 消费方版本可能不同。先 clone 安装版本的 tag,不行再读本项目 node_modules |
87
+ | 文档是 2.1,装的 2.4.0,差不多 | 有下限的能力必须对照版本;已删组件当不存在 |
88
+ | tag 没有就猜 / 直接停 | clone 失败后读 node_modules;也没有才停 |
89
+ | 再开一个 `dwy-eui-v2` skill | 对外只有 `dwy-eui` |
@@ -213,7 +213,14 @@ neutral(默认)| blue | green | rose | orange | violet | slate
213
213
  | lg | 1024px | 小桌面 |
214
214
  | xl | 1280px | 标准桌面 |
215
215
 
216
- 中后台页面最小支持 `md`(768px),不强求手机适配。
216
+ 中后台**壳**必须在 375px 可用:`EAdminLayout` 默认窄屏抽屉,不要再假设最小 `md`。
217
+
218
+ | 场景 | 要求 |
219
+ |------|------|
220
+ | 布局壳 | `EAdminLayout` 375px 可开抽屉;顶栏不裁切 |
221
+ | 列表 | 默认横滑。内容型列表(摘要、说明)用 `mobile-layout="stack"` 出卡片键值。操作密的后台表保持 `scroll`。**禁止**页面 `if (isMobile) 删 columns`。`EPagination` 默认 `mode="auto"` |
222
+ | 表单 | 标签置顶 / `EField orientation="responsive"` |
223
+ | 提示 | 禁止 hover-only 作为唯一入口(`ETooltip trigger="auto"`) |
217
224
 
218
225
  ## 八、ESelect 特殊约束
219
226
 
@@ -210,37 +210,6 @@ const { isDark, toggleDark, colorTheme, setColorTheme } = useTheme()
210
210
 
211
211
  ## 7. Composables
212
212
 
213
- ### useToast
214
-
215
- 轻量 toast 通知。需要在根组件挂载 `<EToast />` 容器:
216
-
217
- ```vue
218
- <!-- App.vue -->
219
- <template>
220
- <router-view />
221
- <EToast rich-colors />
222
- </template>
223
- ```
224
-
225
- 使用:
226
-
227
- ```ts
228
- import { useToast } from '@dwydev/eui'
229
-
230
- const toast = useToast()
231
-
232
- toast.success('操作成功')
233
- toast.error('操作失败')
234
- toast.warning('警告信息')
235
- toast.info('提示信息')
236
-
237
- // 带描述
238
- toast.success('保存成功', { description: '数据已持久化' })
239
-
240
- // 自定义时长(毫秒)
241
- toast.info('处理中...', { duration: 5000 })
242
- ```
243
-
244
213
  ### useMessage
245
214
 
246
215
  ```ts
@@ -0,0 +1,8 @@
1
+ # 配置与主题
2
+
3
+ - **必须**在 App 根包 `EConfigProvider`(locale / 默认尺寸 / zIndex)。缺了日期英文、z-index 乱、文案回退。
4
+ - `locale.name` 用 BCP 47(`zh-CN` / `en-US`),默认 `zh-CN`。
5
+ - 类名合并走 `cn()`(clsx + tailwind-merge)。
6
+ - 主题走 `useTheme()` 的 `setColorTheme` / `toggleDark`,**不要**手改 `<html class="dark">`。
7
+ - 样式入口:`import '@dwydev/eui/theme'`。
8
+ - 轻提示用 `useMessage()`,不要当 Toast 再包一层。
@@ -0,0 +1,6 @@
1
+ # 表单
2
+
3
+ - **禁止原生 `<form>`**,一律 `<EForm>`。EForm 带 vee-validate、provide/inject、label 布局、`reset` / `validate`。
4
+ - `ESelect` 的 `option.value` **不能是 `''`**,reka-ui 不支持。筛选项用哨兵(如 `'all'`),请求时再转 `undefined`。
5
+ - 校验优先 zod schema 交给 `EForm` 的 `rules`。
6
+ - `useFormField` 只在 `EFormItem` 内有值;表单外返回 `null`,不要当 vee-validate `<FormField>` 用。
@@ -0,0 +1,6 @@
1
+ # 弹层
2
+
3
+ - 显隐统一 `v-model:open`,不要 `:visible` / `@update:visible`。
4
+ - `EDialog` body 有 `overflow-y-auto`,首尾表单控件的 focus-ring 会被裁。内容区加 `p-1` / `py-1`。
5
+ - `ESheet` 与 `EDrawer` 场景不同:Sheet 侧向覆盖(手机导航),Drawer 底部抓手。不要合成一个组件。
6
+ - `EAlertDialog` / `EConfirmDialog` / `useMessageBox` 场景不同,不要互相替换当「唯一确认框」。
@@ -0,0 +1,5 @@
1
+ # reka-ui 绑定
2
+
3
+ 封装 reka-ui 原语时统一 `v-model`(`modelValue` / `update:modelValue`),**不是** `:checked` / `@update:checked`。
4
+
5
+ 自己写包一层时用 `v-model` 或 writable computed。
@@ -0,0 +1,8 @@
1
+ # @dwydev/eui 1.x
2
+
3
+ 1.x 没有 `v2/` 那套删减。精确 API clone `@dwydev/eui@1.y.z` 或读该版本 `node_modules`。
4
+
5
+ - **没有** `component-manifest.json`(2.1.0 才有)。`ls node_modules/@dwydev/eui/dist/components/` 定位目录。
6
+ - 轻提示可能是 `useToast`,不是 `useMessage`。
7
+ - 可能仍有 `EInputOTP`、`EVirtualTable`、`EDataPage`、`EAIChat` 等;不要按 2.4.0 清单当成已删除。
8
+ - 升 2.4.0 前读 `v2/breaking.md`,全仓替换已删符号。
@@ -0,0 +1,14 @@
1
+ # 2.x 内部 breaking
2
+
3
+ 2.x 的 minor / beta 也可以不兼容。整条线仍用 `v2/`,破坏点记在这里。细节 clone `@dwydev/eui@x.y.z`,不要另开 `v2.4/` 目录。
4
+
5
+ 完整段落以该 tag 的 `frontend/eui/CHANGELOG.md` 为准。
6
+
7
+ | 版本 | 破坏点 |
8
+ |------|--------|
9
+ | 2.4.0 | 正式线。删除 `EAIChat`、`ETimetableGrid`、`EDataPage`、`EVirtualTable`、`EInputOTP`、`EChartContainer`、`useToast`。OTP 用 `EPinInput` + `otp`;虚拟表用 `ETable virtual`;轻提示用 `useMessage`。`ETable` 不用 `w-max`,列宽之和写入 `minWidth` |
10
+ | 2.4.0-beta.8 | 上表删除在 beta 线落地;停在 beta.1–7 的项目按此行 |
11
+ | 2.4.0-beta.9 | `ETable` 去掉 `w-max`,长单元格不再把末列撑出视口 |
12
+ | 2.4.0-beta.4 | 曾把表改成 `w-max` 以支持窄屏横滑;被 beta.9 / 2.4.0 修正 |
13
+
14
+ 2.3.0 仍有上表删除前的组件。从 2.3 升 2.4 先全仓搜这些符号。仍停在 2.4.0-beta.N 的项目对照上表对应行,不要用 2.4.0 正式线冒充。
@@ -0,0 +1,55 @@
1
+ # @dwydev/eui 2.x
2
+
3
+ 精确签名以安装版本为准(见上级 SKILL.md:先 clone tag,拿不到再读 node_modules)。本页是 2.x 导航与陷阱。
4
+
5
+ 跨大版本不变的表单 / 弹层 / reka / 主题在 `shared/`。查 props 走 `lookup.md`。
6
+
7
+ ## Composables
8
+
9
+ | 名 | 用途 | 下限 |
10
+ |----|------|------|
11
+ | `useMessage` | 轻提示 success / error / warning / info | |
12
+ | `useNotification` | 带标题通知 | |
13
+ | `useMessageBox` | alert / confirm / prompt,返回 Promise | |
14
+ | `useTheme` | 亮暗与色板 | |
15
+ | `useConfigProvider` | size / zIndex / locale | |
16
+ | `useFormField` | EFormItem 内 id / error;表单外 `null` | 2.4 起不依赖 vee-validate FormField |
17
+ | `useSecureValue` | 密码不写进 HTML attribute | |
18
+ | `useEuiMobile` | `max-width: 767` 是否手机布局 | ≥2.4 |
19
+
20
+ 2.4.0 **删除** `useToast`,改 `useMessage`。仍停在 2.3 的项目读 `breaking.md`。
21
+
22
+ ## 组件导航(只列名)
23
+
24
+ 用途一句话够导航;props 读 types.d.ts。
25
+
26
+ **展示**:EButton、EButtonGroup、EBadge、EAlert、ECard、ELabel、ESeparator、ETypography、EKbd、ESpinner、EProgress、ESkeleton、EEmpty、EAvatar、EImage、EAspectRatio、EAffix、EWatermark
27
+
28
+ **表单**:EForm / EFormItem、EField、EInput、EInputGroup、ETextarea、ENumberField、ESelect、ENativeSelect、ECombobox、EAutocomplete、ECheckbox、ERadio、ESwitch、ETagsInput、EDatePicker、ETimePicker、EColorPicker、ERate、ESlider、ECascader、ETreeSelect、EMention、EPinInput(OTP 用 `otp` + `mask`)、EUpload、ETransfer
29
+
30
+ **数据**:ETable(`virtual` 走 TanStack Virtual)、EDescriptions、ETimeline、EStatistic、ETree、ECalendar、ERangeCalendar、EPagination、EBreadcrumb
31
+
32
+ **弹层**:EDialog、EDrawer、ESheet、EAlertDialog、ETooltip、EPopover、EHoverCard、EToast(Toaster 挂载点)、EContextMenu、EFormDialog、EConfirmDialog
33
+
34
+ **布局**:ETabs、EMenu、EDropdown、EAccordion、ECollapsible、EStepper、ECarousel、EScrollArea、EInfiniteScroll、EToggle / EToggleGroup、EItem、EResizable*、ECommand*、ENavigationMenu*、EMenubar*、EAdminLayout、EConfigProvider
35
+
36
+ 已删组件见 `breaking.md`,不要再 import。
37
+
38
+ ## 2.x 陷阱
39
+
40
+ ### 汉堡 / 抽屉
41
+
42
+ - `ESheet` / `EAdminLayout` 的 Boolean `open` / `mobileOpen` **缺省必须是 `undefined`**,不能是 `false`。`false` 会让非受控开关永远打不开(≥2.4.0)。
43
+ - 关闭态 overlay 必须卸掉(`unmountOnHide`),否则挡住汉堡。
44
+ - 打开态 overlay 用 `EConfigProvider.zIndex`(默认 2000),压过应用顶栏 `z-50`(≥2.4.0)。
45
+ - 手机抽屉打开时 `EAdminLayout` 把 header 槽设 `invisible`,避免用户名和关闭钮抢角(≥2.4.0)。
46
+
47
+ ### ETable
48
+
49
+ - 列 `width` 用数字 px,不要百分比。表 `minWidth` = 列宽之和:宽于容器横滑,窄于容器铺满(≥2.4.0)。
50
+ - 不要再上 `EVirtualTable`,用 `ETable` 的 `virtual`。
51
+ - 排序对外仍 `@sort` + `TableColumn.sortable`。
52
+
53
+ ### 手机布局
54
+
55
+ - 断点与 Tailwind `md` 对齐:`max-width: 767`。`useEuiMobile()` 与 `EAdminLayout` / `EPagination` 同一套。
@@ -0,0 +1,29 @@
1
+ # 2.x 查 API
2
+
3
+ 精确 props/emits **不要**写进 skill。按安装版本读类型。
4
+
5
+ ## manifest(≥2.1.0)
6
+
7
+ ```
8
+ node_modules/@dwydev/eui/dist/component-manifest.json
9
+ ```
10
+
11
+ - 组件名 → `componentToDir["EButton"]` → 目录 `button`
12
+ - `directories["button"].types` → `components/button/types.d.ts`
13
+ - 拼接 `node_modules/@dwydev/eui/dist/` + 该路径
14
+
15
+ `<2.1.0` 没有 manifest:直接 `ls dist/components/`。
16
+
17
+ ## types
18
+
19
+ ```
20
+ node_modules/@dwydev/eui/dist/components/{kebab}/types.d.ts
21
+ ```
22
+
23
+ `{kebab}`:去 `E` 前缀后 kebab-case(`EDatePicker` → `date-picker`)。不确定就 `ls`,不要猜。
24
+
25
+ ## slots
26
+
27
+ `.d.ts` 里 slot 常是 `any`。需要具名/作用域插槽时 clone 该版本 tag,在 `frontend/eui/src/components/{kebab}/*.vue` 搜 `<slot`。
28
+
29
+ npm 包 `files` 不含 `.vue`,`node_modules` 里没有模板。