@morya-ui/setup 0.3.4 → 0.3.6

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 (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -103
  3. package/bin/morya-ui-setup.js +14 -14
  4. package/catalog/skills.json +46 -46
  5. package/package.json +4 -5
  6. package/src/__tests__/mcp.test.mjs +141 -0
  7. package/src/cli.mjs +330 -335
  8. package/src/copy-template.mjs +78 -78
  9. package/src/fs-utils.mjs +24 -24
  10. package/src/install.mjs +134 -63
  11. package/src/mcp.mjs +220 -50
  12. package/src/package-json.mjs +30 -30
  13. package/src/skills.mjs +224 -223
  14. package/src/styles.mjs +119 -119
  15. package/template/.agents/skills/morya-ui-pages/SKILL.md +191 -184
  16. package/template/.agents/skills/morya-ui-pages/evals/evals.json +89 -89
  17. package/template/.agents/skills/morya-ui-pages/references/component-index.md +99 -99
  18. package/template/.agents/skills/morya-ui-pages/references/decision-recipes.md +72 -5
  19. package/template/.agents/skills/morya-ui-pages/references/design-system.md +101 -101
  20. package/template/.agents/skills/morya-ui-pages/references/feedback.md +68 -68
  21. package/template/.agents/skills/morya-ui-pages/references/optional-companions.md +62 -107
  22. package/template/.agents/skills/morya-ui-pages/references/page-layouts.md +133 -141
  23. package/template/.agents/skills/morya-ui-pages/references/review-checklist.md +76 -64
  24. package/template/.agents/skills/morya-ui-pages/references/style-presets.md +68 -73
  25. package/template/.agents/skills/morya-ui-pages/references/surfaces.md +91 -91
  26. package/template/.agents/skills/morya-ui-pages/references/visual-craft.md +131 -221
  27. package/template/.cursor/rules/coding-style.mdc +41 -41
  28. package/template/.cursor/rules/component-usage.mdc +41 -41
  29. package/template/.cursor/rules/design-system.mdc +18 -17
  30. package/template/.cursor/rules/page-layout.mdc +97 -97
  31. package/template/AGENTS.md +33 -0
  32. package/template/DESIGN.md +81 -59
  33. package/template/scripts/check-raw-colors.mjs +74 -74
@@ -1,89 +1,89 @@
1
- {
2
- "skill_name": "morya-ui-pages",
3
- "evals": [
4
- {
5
- "id": 1,
6
- "prompt": "我们内部教务系统用 Vue3 + morya-ui。请做一个「课程列表」后台页:按课程名搜索、按开课状态(全部/开课中/已结课)筛选;表格列:名称、状态、学分、更新时间;行内「编辑」进抽屉表单,「删除」要二次确认;右上角「新建课程」。保存/删除成功只要一句话提示。输出单个 Vue SFC,结构对齐列表黄金样例,并做 Ops 精致化(侧栏图标、状态用 MStatus、空态用 MEmpty、行操作不要一排实心按钮)。",
7
- "expected_output": "Ops list: MLayout/MPageHeader/MPageFilters/MTable rows, optional batch MPageToolbar, MSelect status, MDrawer edit, MConfirmDialog delete, message not toast, MStatus for status, MEmpty in #empty, menu icons, text/small row actions, craft pass applied, no second UI kit.",
8
- "files": []
9
- },
10
- {
11
- "id": 2,
12
- "prompt": "同一个 morya-ui 项目里,生成「新建员工」独立表单页:姓名、工作邮箱、部门(下拉)、入职日期;窄栏;页头有标题和一句说明;底栏保存(primary)/取消(secondary)。不要做成营销落地页,不要用 Toast 提示「已保存」。输出单个 Vue SFC。",
13
- "expected_output": "Ops form golden: narrow MPageContent, MPageHeader, MPageSection form/actions, MForm + MSelect/MDatePicker, message for success if shown, one primary, no landing hero.",
14
- "files": []
15
- },
16
- {
17
- "id": 3,
18
- "prompt": "运营后台首页仪表盘:四个 KPI(今日订单、待处理、转化率、退款率)、中间一块图表占位、右侧或下方「最近告警」表格(级别、内容、时间)。Vue3 + morya-ui,可先用静态假数据;告警级别可用 Tag,状态用 MStatus。",
19
- "expected_output": "Dashboard: MPageStat grid with domain labels, MCard shadow=always + MEmpty chart pending, recent MTable with MStatus, MLayout shell, --m-* only, spacious density.",
20
- "files": []
21
- },
22
- {
23
- "id": 4,
24
- "prompt": "给「青禾书房」这个独立书店品牌做登录页:左品牌、右表单(邮箱+密码+登录)。要有一点品牌感(token 氛围即可),但控件必须用 morya-ui;登录失败用表单区常驻错误(字段 errorMessage 或 token role=alert),不要一闪而过的 Toast,也不要把 MMessage 当成内嵌 Alert。输出单个 Vue SFC。",
25
- "expected_output": "Account+craft: split shell, MForm/MInputPassword/MButton, token role=alert or field error for failure, brand panel with --m-* color-mix, no MMessage severity alert, no second UI kit.",
26
- "files": []
27
- },
28
- {
29
- "id": 5,
30
- "prompt": "课程列表在零数据时太空了。请设计一个空状态区块(可嵌在列表页内容区):说明还没有课程、引导「创建第一门课程」;视觉克制,用 morya-ui 默认空态即可,不要自定义 dashed 框或径向光晕。只要空状态相关模板片段或带空状态的列表 SFC 均可。",
31
- "expected_output": "Flow empty: MPageHeader + MEmpty + next-action MButton, short copy, no custom dashed/radial shell, fits list content slot.",
32
- "files": []
33
- },
34
- {
35
- "id": 6,
36
- "prompt": "为「流水线 CI」产品写一个营销落地首页(不是后台):首屏只有品牌名、一句主标题、一句副文、一组 CTA;下面再分「为何选择」「能力」「客户」三节。技术实现用 Vue3 + morya-ui 组件做按钮/标签/折叠 FAQ;颜色走 --m-*,避免紫渐变和奶油衬线陶土那套 AI 默认脸。可有 1–2 个微动效,强度跟 useMotion / data-m-motion。输出单个 Vue SFC。",
37
- "expected_output": "Express landing: single-job hero, MButton CTAs, sections with one job each, MAccordion FAQ optional, no purple/cream-terracotta defaults, no admin MPageFilters shell, motion gated by useMotion / data-m-motion.",
38
- "files": []
39
- },
40
- {
41
- "id": 7,
42
- "prompt": "做一个三步「创建工作空间」向导:1 名称与地区 2 邀请成员(邮箱标签)3 确认。用 morya-ui 的 Stepper + Form;每步一个主任务;最后提交成功进入结果页(查看工作空间 / 返回)。输出一个或两个 SFC。",
43
- "expected_output": "Flow wizard: wizard-form golden — MStepper :steps, per-step MForm, MInputTags invites, clear next/back/submit, message success, validate_usage clean.",
44
- "files": []
45
- },
46
- {
47
- "id": 8,
48
- "prompt": "用户点了删除项目但权限不足:做一张「无权限」系统页(或全页占位),说明原因,并提供返回上一页、联系管理员。用 morya-ui,文案直接别玩梗。",
49
- "expected_output": "System surface: result-page golden — MResult status=403, #footer escape actions, no jokey 404 essay, on-token, validate_usage clean.",
50
- "files": []
51
- },
52
- {
53
- "id": 9,
54
- "prompt": "把上面的课程列表再 polish 一轮:去掉多余实心按钮、保证只有一个主按钮、表格状态改成 MStatus、补上 MEmpty。不要改成营销页。",
55
- "expected_output": "Ops quieter polish: one primary, MStatus, MEmpty, text row actions, still list golden structure.",
56
- "files": []
57
- },
58
- {
59
- "id": 10,
60
- "prompt": "给「用户管理」做资源详情页:面包屑、标题旁启用状态、编辑/返回/删除;摘要标签;基本信息属性网格;下方近期活动表。Vue3 + morya-ui,对齐详情黄金样例,不要做成落地页。",
61
- "expected_output": "Ops detail: MPageHeader + MStatus, property MCard, related MTable rows, --m-* only, no marketing hero.",
62
- "files": []
63
- },
64
- {
65
- "id": 11,
66
- "prompt": "用户列表页上「新建/编辑」不要另开路由:同页 MDialog(约 32rem)里放短表单(姓名、邮箱、角色),页脚取消/保存;保存成功用 message 一句话。输出单个 Vue SFC。",
67
- "expected_output": "form-in-dialog: list stays, MDialog + MForm + #footer, message.success not toast string, MTable rows.",
68
- "files": []
69
- },
70
- {
71
- "id": 12,
72
- "prompt": "做一个用户列表表格页:列姓名、角色、状态。状态列必须用 MStatus;行数据绑定用 rows(不要写 data prop);空表用 #empty + MEmpty。Vue3 + morya-ui,输出单个 SFC。",
73
- "expected_output": "Prop accuracy: MTable columns+rows (not :data), #cell or Status for status, #empty+MEmpty, validate_usage clean.",
74
- "files": []
75
- },
76
- {
77
- "id": 13,
78
- "prompt": "列表行删除:点删除后用 MConfirmDialog(危险确认),确认后 message.success('已删除')。不要用 toast,也不要手写 Dialog 当确认框。输出片段或 SFC 均可。",
79
- "expected_output": "confirm-choice + feedback-choice: MConfirmDialog v-model header/message acceptSeverity=danger @accept, message.success not toast, no hand Dialog confirm.",
80
- "files": []
81
- },
82
- {
83
- "id": 14,
84
- "prompt": "短新建弹窗:MDialog v-model + header + #footer(取消 secondary、保存 primary);表单字段 fluid。保存成功 message 一句话。不要用 v-model:visible。",
85
- "expected_output": "form-surface Dialog recipe: v-model not visible, #footer actions, fluid fields, message.success.",
86
- "files": []
87
- }
88
- ]
89
- }
1
+ {
2
+ "skill_name": "morya-ui-pages",
3
+ "evals": [
4
+ {
5
+ "id": 1,
6
+ "prompt": "我们内部教务系统用 Vue3 + morya-ui。请做一个「课程列表」后台页:按课程名搜索、按开课状态(全部/开课中/已结课)筛选;表格列:名称、状态、学分、更新时间;行内「编辑」进抽屉表单,「删除」要二次确认;右上角「新建课程」。保存/删除成功只要一句话提示。输出单个 Vue SFC,用 list-filters-stack / list-table / form-in-drawer / confirm-delete / page-header-actions 等 snippets 拼装并对齐 page-layouts 块顺序,并做 Ops 精致化(侧栏图标、状态用 MStatus、空态用 MEmpty、行操作不要一排实心按钮)。",
7
+ "expected_output": "Ops list composition-first: MLayout/MPageHeader/list-filters-stack (collapsible+#advanced+FilterChips)/MTable rows, page-header-actions one primary, form-in-drawer edit, confirm-delete, message not toast, MStatus, MEmpty in #empty, menu icons, text/small row actions, craft pass, no second UI kit; do not require whole golden-page clone.",
8
+ "files": []
9
+ },
10
+ {
11
+ "id": 2,
12
+ "prompt": "同一个 morya-ui 项目里,生成「新建员工」独立表单页:姓名、工作邮箱、部门(下拉)、入职日期;窄栏;页头有标题和一句说明;底栏保存(primary)/取消(secondary)。不要做成营销落地页,不要用 Toast 提示「已保存」。输出单个 Vue SFC。",
13
+ "expected_output": "Ops form snippets: page-content-form + form-header/body/actions, narrow MPageContent, MForm + MSelect/MDatePicker, message for success if shown, one primary, no landing hero.",
14
+ "files": []
15
+ },
16
+ {
17
+ "id": 3,
18
+ "prompt": "运营后台首页仪表盘:四个 KPI(今日订单、待处理、转化率、退款率)、中间一块图表占位、右侧或下方「最近告警」表格(级别、内容、时间)。Vue3 + morya-ui,可先用静态假数据;告警级别可用 Tag,状态用 MStatus。",
19
+ "expected_output": "Dashboard snippets: dashboard-kpi-grid, dashboard-chart-card, dashboard-recent-table, MLayout shell, --m-* only, spacious density.",
20
+ "files": []
21
+ },
22
+ {
23
+ "id": 4,
24
+ "prompt": "给「青禾书房」这个独立书店品牌做登录页:左品牌、右表单(邮箱+密码+登录)。要有一点品牌感(token 氛围即可),但控件必须用 morya-ui;登录失败用表单区常驻错误(字段 errorMessage 或 token role=alert),不要一闪而过的 Toast,也不要把 MMessage 当成内嵌 Alert。输出单个 Vue SFC。",
25
+ "expected_output": "Account+craft via auth-split-shell: split shell, MForm/MInputPassword/MButton, token role=alert or field error for failure, brand panel with flat --m-* color-mix (no stacked radial+linear aurora), no MMessage severity alert, no second UI kit.",
26
+ "files": []
27
+ },
28
+ {
29
+ "id": 5,
30
+ "prompt": "课程列表在零数据时太空了。请设计一个空状态区块(可嵌在列表页内容区):说明还没有课程、引导「创建第一门课程」;视觉克制,用 morya-ui 默认空态即可,不要自定义 dashed 框或径向光晕。只要空状态相关模板片段或带空状态的列表 SFC 均可。",
31
+ "expected_output": "Flow empty via empty-block: MEmpty + next-action MButton, short copy, no custom dashed/radial shell, fits list content slot.",
32
+ "files": []
33
+ },
34
+ {
35
+ "id": 6,
36
+ "prompt": "为「流水线 CI」产品写一个营销落地首页(不是后台):首屏只有品牌名、一句主标题、一句副文、一组 CTA;下面再分「为何选择」「能力」「客户」三节。技术实现用 Vue3 + morya-ui 组件做按钮/标签/折叠 FAQ;颜色走 --m-*,风格偏简洁扁平(不要紫渐变 aurora、奶油衬线陶土、霓虹毛玻璃)。可有 1–2 个微动效,强度跟 useMotion / data-m-motion。输出单个 Vue SFC。",
37
+ "expected_output": "Express landing: single-job hero, MButton CTAs, sections with one job each, MAccordion FAQ optional, flat/simple surfaces (no purple aurora / cream-terracotta / unsolicited glass-neon), no admin MPageFilters shell, motion gated by useMotion / data-m-motion.",
38
+ "files": []
39
+ },
40
+ {
41
+ "id": 7,
42
+ "prompt": "做一个三步「创建工作空间」向导:1 名称与地区 2 邀请成员(邮箱标签)3 确认。用 morya-ui 的 Stepper + Form;每步一个主任务;最后提交成功进入结果页(查看工作空间 / 返回)。输出一个或两个 SFC。",
43
+ "expected_output": "Flow wizard via wizard-steps (+ result-block): MStepper :steps, per-step MForm, MInputTags invites, clear next/back/submit, message success, validate_usage clean.",
44
+ "files": []
45
+ },
46
+ {
47
+ "id": 8,
48
+ "prompt": "用户点了删除项目但权限不足:做一张「无权限」系统页(或全页占位),说明原因,并提供返回上一页、联系管理员。用 morya-ui,文案直接别玩梗。",
49
+ "expected_output": "System surface via result-block: MResult status=403, #footer escape actions, no jokey 404 essay, on-token, validate_usage clean.",
50
+ "files": []
51
+ },
52
+ {
53
+ "id": 9,
54
+ "prompt": "把上面的课程列表再 polish 一轮:去掉多余实心按钮、保证只有一个主按钮、表格状态改成 MStatus、补上 MEmpty。不要改成营销页。",
55
+ "expected_output": "Ops quieter polish: one primary, MStatus, MEmpty, text row actions, still list block-order / snippets structure.",
56
+ "files": []
57
+ },
58
+ {
59
+ "id": 10,
60
+ "prompt": "给「用户管理」做资源详情页:面包屑、标题旁启用状态、编辑/返回/删除;摘要标签;基本信息属性网格;下方近期活动表。Vue3 + morya-ui,按 detail 块顺序 + detail-toolbar 拼装,不要做成落地页。",
61
+ "expected_output": "Ops detail composition: detail-toolbar MPageHeader + MStatus, property MCard, related MTable rows, --m-* only, no marketing hero.",
62
+ "files": []
63
+ },
64
+ {
65
+ "id": 11,
66
+ "prompt": "用户列表页上「新建/编辑」不要另开路由:同页 MDialog(约 32rem)里放短表单(姓名、邮箱、角色),页脚取消/保存;保存成功用 message 一句话。输出单个 Vue SFC。",
67
+ "expected_output": "form-in-dialog snippet: list stays, MDialog + MForm + #footer, message.success not toast string, MTable rows.",
68
+ "files": []
69
+ },
70
+ {
71
+ "id": 12,
72
+ "prompt": "做一个用户列表表格页:列姓名、角色、状态。状态列必须用 MStatus;行数据绑定用 rows(不要写 data prop);空表用 #empty + MEmpty。Vue3 + morya-ui,输出单个 SFC。",
73
+ "expected_output": "Prop accuracy: MTable columns+rows (not :data), #cell or Status for status, #empty+MEmpty, validate_usage clean.",
74
+ "files": []
75
+ },
76
+ {
77
+ "id": 13,
78
+ "prompt": "列表行删除:点删除后用 MConfirmDialog(危险确认),确认后 message.success('已删除')。不要用 toast,也不要手写 Dialog 当确认框。输出片段或 SFC 均可。",
79
+ "expected_output": "confirm-delete snippet + feedback-choice: MConfirmDialog v-model header/message acceptSeverity=danger @accept, message.success not toast, no hand Dialog confirm.",
80
+ "files": []
81
+ },
82
+ {
83
+ "id": 14,
84
+ "prompt": "短新建弹窗:MDialog v-model + header + #footer(取消 secondary、保存 primary);表单字段 fluid。保存成功 message 一句话。不要用 v-model:visible。",
85
+ "expected_output": "form-in-dialog / form-surface Dialog recipe: v-model not visible, #footer actions, fluid fields, message.success, relatedSnippets include form-in-dialog.",
86
+ "files": []
87
+ }
88
+ ]
89
+ }
@@ -1,99 +1,99 @@
1
- # Component index (scenario map)
2
-
3
- Full API: docs site `/components` or MCP (`get_component`, `search`, `validate_usage`).
4
-
5
- - **Selection + key props**: MCP `recommend_component`, or offline [decision-recipes.md](./decision-recipes.md) (generated from `packages/ui-mcp/src/decisions.ts`).
6
- - This file is a **catalog + decision-id index**, not a prop manual.
7
-
8
- ## Shell
9
-
10
- | Component | Use |
11
- | --- | --- |
12
- | `MConfigProvider` | Root locale / theme / density / defaults |
13
- | `MLayout` family | Admin chrome (`MLayoutSider` is the layout sider) |
14
- | `MSidebar` | Standalone nav rail (not a `MDrawer`, not a substitute for `MLayoutSider` inside `MLayout`) |
15
- | `MBreadcrumb` | Path |
16
- | `MPageContent` / `MPageFilters` / `MPageToolbar` / `MPageHeader` / `MPageSection` / `MPageStat` / `MPagePlaceholder` | Page composition |
17
- | `MDock` | App dock / launcher, not page actions |
18
-
19
- ## Actions
20
-
21
- `MButton` / `MButtonGroup` (primary `severity="primary"`, danger `severity="danger"`), `MSplitButton` (main action + menu), `MSpeedDial` (floating action cluster)
22
-
23
- ## Forms · inputs
24
-
25
- `MForm`, `MFormItem`, `MInput`, `MInputPassword`, `MInputNumber`, `MTextarea`, `MInputOtp`, `MInputColor`, `MInputGroup`, `MInputTags`, `MSelect`, `MTreeSelect`, `MCascadeSelect`, `MListbox`, `MSelectButton`, `MDatePicker`, `MAutoComplete`, `MCheckbox` / `MCheckboxGroup`, `MRadio` / `MRadioGroup`, `MSwitch`, `MToggleButton`, `MSlider`, `MRating`, `MKnob`, `MFileUpload`, `MFloatLabel`, `MIconField`, `MLabel`
26
-
27
- ## Layout helpers
28
-
29
- `MGrid` / `MGridItem`, `MFlex`, `MSpace`, `MFluid`, `MDivider`, `MFieldset`, `MSplitter`, `MToolbar`
30
-
31
- ## Data
32
-
33
- `MTable` (`columns` + **`rows`**, not `data`), `MTreeTable`, `MDataView`, `MTree`, `MPagination`, `MOrderList`, `MPickList`, `MStatus` / `MTag` / `MChip` / `MBadge`, `MAvatar` / `MAvatarGroup`, `MTimeline`, `MMeterGroup`, `MVirtualScroller`
34
-
35
- ## Feedback
36
-
37
- | API / component | When | Decision |
38
- | --- | --- | --- |
39
- | `message` | **Default** one-line CRUD result | `feedback-choice` |
40
- | `toast` | `summary` + `detail`, or async / background feel | `feedback-choice` |
41
- | `<MMessage>` | Optional host for the `message` service. **Not** an inline alert | `feedback-choice` |
42
- | field `errorMessage` or token `role="alert"` | Persistent form / auth error | `feedback-choice` |
43
- | `MEmpty` | No-data / first-use / filtered empty | `empty-result-choice` |
44
- | `MResult` | Terminal outcome: success, failure, 403 / 404 / 500 | `empty-result-choice` |
45
- | `MLoading` / `v-loading` / `loading.service` | **Default** region or fullscreen loading mask | `loading-choice` |
46
- | `MSkeleton` | Layout known; placeholder while content arrives | `loading-choice` |
47
- | `MProgressBar` | Determinate progress | `loading-choice` |
48
- | `MProgressSpinner` | Inline spinner only, not a region mask | `loading-choice` |
49
- | `MBlockUI` | Block interaction without a loading message | `loading-choice` |
50
-
51
- ## Overlays & menus
52
-
53
- `MDialog`, `MDrawer`, `MConfirmDialog` / `MConfirmPopup`, `MPopover`, `MTooltip`, `MDropdown` (**actions only**), `MContextMenu`, `MCommandMenu`, `MMenu` / `MMenubar` / `MTieredMenu` / `MMegaMenu`, `MTabs`, `MStepper`
54
-
55
- ## Surfaces / media
56
-
57
- `MCard`, `MPanel`, `MAccordion`, `MCarousel`, `MGallery`, `MIcon`, `MScrollbar`, `MInplace`, `MScrollTop`, `MTerminal`
58
-
59
- ## Scenario → decision
60
-
61
- Open MCP `recommend_component({ decision })` or the matching section in [decision-recipes.md](./decision-recipes.md) for **when / avoid / recipe props / anti-patterns**.
62
-
63
- | Intent | Decision id |
64
- | --- | --- |
65
- | Create / edit from a list (few–medium fields) vs long form page | `form-surface-choice` |
66
- | Dialog vs Drawer vs Popover vs Tooltip | `overlay-choice` |
67
- | Table vs DataView vs Tree / TreeTable | `data-display-choice` |
68
- | Select vs TreeSelect vs AutoComplete vs Radio / … | `selection-choice` |
69
- | Card vs Panel vs Fieldset | `surface-choice` |
70
- | PageContent vs Flex vs Space vs Grid | `layout-spacing-choice` |
71
- | PageFilters / Toolbar / Header / Section / Stat / Placeholder | `page-section-choice` |
72
- | Layout scroll vs MScrollbar vs built-in | `page-scroll-choice` |
73
- | Avoid double borders / extra Card wrappers | `surface-nesting-choice` |
74
- | Loading vs Skeleton vs Progress* vs BlockUI | `loading-choice` |
75
- | Status vs Tag vs Chip vs Badge | `status-label-choice` |
76
- | Empty vs Result | `empty-result-choice` |
77
- | Dropdown vs Menu vs ContextMenu vs CommandMenu | `action-menu-choice` |
78
- | message vs toast vs field / form alert | `feedback-choice` |
79
- | ConfirmDialog vs ConfirmPopup | `confirm-choice` |
80
- | Searchable list + paging | `page-section-choice` + `data-display-choice` (+ list golden) |
81
- | Delete / destructive | `confirm-choice` |
82
- | Login / auth | `feedback-choice` + `login-page` golden |
83
- | Marketing landing | `landing-page` golden (Express) |
84
- | Multi-step create | `wizard-form` golden |
85
- | Preferences / settings | `settings-page` golden |
86
- | Resizable two-pane | use `MSplitter` (see docs / `get_component`) |
87
-
88
- ## Common mistakes
89
-
90
- | Wrong | Right |
91
- | --- | --- |
92
- | `MDropdown` as form enum | `MSelect` (`selection-choice`) |
93
- | `MTable` `:data` | `:rows` (`data-display-choice`) |
94
- | `<MMessage severity>` as an inline alert | Field `errorMessage`, or token `role="alert"` (`feedback-choice`) |
95
- | Hand `<table>` | `MTable` |
96
- | Hand modal div | `MDialog` / `MConfirmDialog` |
97
- | Hand spinner or `MProgressSpinner` as a region / page mask | `MLoading` / `v-loading` (`loading-choice`) |
98
- | Extra `MCard` around every `MPage*` block | `surface-nesting-choice` |
99
- | Assume undocumented props | MCP / docs lookup + `validate_usage` |
1
+ # Component index (scenario map)
2
+
3
+ Full API: docs site `/components` or MCP (`get_component`, `search`, `validate_usage`).
4
+
5
+ - **Selection + key props**: MCP `recommend_component`, or offline [decision-recipes.md](./decision-recipes.md) (generated from `packages/ui-mcp/src/decisions.ts`).
6
+ - This file is a **catalog + decision-id index**, not a prop manual.
7
+
8
+ ## Shell
9
+
10
+ | Component | Use |
11
+ | --- | --- |
12
+ | `MConfigProvider` | Root locale / theme / density / defaults |
13
+ | `MLayout` family | Admin chrome (`MLayoutSider` is the layout sider) |
14
+ | `MSidebar` | Standalone nav rail (not a `MDrawer`, not a substitute for `MLayoutSider` inside `MLayout`) |
15
+ | `MBreadcrumb` | Path |
16
+ | `MPageContent` / `MPageFilters` / `MPageToolbar` / `MPageHeader` / `MPageSection` / `MPageStat` / `MPagePlaceholder` | Page composition |
17
+ | `MDock` | App dock / launcher, not page actions |
18
+
19
+ ## Actions
20
+
21
+ `MButton` / `MButtonGroup` (primary `severity="primary"`, danger `severity="danger"`), `MSplitButton` (main action + menu), `MSpeedDial` (floating action cluster)
22
+
23
+ ## Forms · inputs
24
+
25
+ `MForm`, `MFormItem`, `MInput`, `MInputPassword`, `MInputNumber`, `MTextarea`, `MInputOtp`, `MInputColor`, `MInputGroup`, `MInputTags`, `MSelect`, `MTreeSelect`, `MCascadeSelect`, `MListbox`, `MSelectButton`, `MDatePicker`, `MAutoComplete`, `MCheckbox` / `MCheckboxGroup`, `MRadio` / `MRadioGroup`, `MSwitch`, `MToggleButton`, `MSlider`, `MRating`, `MKnob`, `MFileUpload`, `MFloatLabel`, `MIconField`, `MLabel`
26
+
27
+ ## Layout helpers
28
+
29
+ `MGrid` / `MGridItem`, `MFlex`, `MSpace`, `MFluid`, `MDivider`, `MFieldset`, `MSplitter`, `MToolbar`
30
+
31
+ ## Data
32
+
33
+ `MTable` (`columns` + **`rows`**, not `data`), `MTreeTable`, `MDataView`, `MTree`, `MPagination`, `MOrderList`, `MPickList`, `MStatus` / `MTag` / `MChip` / `MBadge`, `MAvatar` / `MAvatarGroup`, `MTimeline`, `MMeterGroup`, `MVirtualScroller`
34
+
35
+ ## Feedback
36
+
37
+ | API / component | When | Decision |
38
+ | --- | --- | --- |
39
+ | `message` | **Default** one-line CRUD result | `feedback-choice` |
40
+ | `toast` | `summary` + `detail`, or async / background feel | `feedback-choice` |
41
+ | `<MMessage>` | Optional host for the `message` service. **Not** an inline alert | `feedback-choice` |
42
+ | field `errorMessage` or token `role="alert"` | Persistent form / auth error | `feedback-choice` |
43
+ | `MEmpty` | No-data / first-use / filtered empty | `empty-result-choice` |
44
+ | `MResult` | Terminal outcome: success, failure, 403 / 404 / 500 | `empty-result-choice` |
45
+ | `MLoading` / `v-loading` / `loading.service` | **Default** region or fullscreen loading mask | `loading-choice` |
46
+ | `MSkeleton` | Layout known; placeholder while content arrives | `loading-choice` |
47
+ | `MProgressBar` | Determinate progress | `loading-choice` |
48
+ | `MProgressSpinner` | Inline spinner only, not a region mask | `loading-choice` |
49
+ | `MBlockUI` | Block interaction without a loading message | `loading-choice` |
50
+
51
+ ## Overlays & menus
52
+
53
+ `MDialog`, `MDrawer`, `MConfirmDialog` / `MConfirmPopup`, `MPopover`, `MTooltip`, `MDropdown` (**actions only**), `MContextMenu`, `MCommandMenu`, `MMenu` / `MMenubar` / `MTieredMenu` / `MMegaMenu`, `MTabs`, `MStepper`
54
+
55
+ ## Surfaces / media
56
+
57
+ `MCard`, `MPanel`, `MAccordion`, `MCarousel`, `MGallery`, `MIcon`, `MScrollbar`, `MInplace`, `MScrollTop`, `MTerminal`
58
+
59
+ ## Scenario → decision
60
+
61
+ Open MCP `recommend_component({ decision })` or the matching section in [decision-recipes.md](./decision-recipes.md) for **when / avoid / recipe props / anti-patterns**.
62
+
63
+ | Intent | Decision id |
64
+ | --- | --- |
65
+ | Create / edit from a list (few–medium fields) vs long form page | `form-surface-choice` |
66
+ | Dialog vs Drawer vs Popover vs Tooltip | `overlay-choice` |
67
+ | Table vs DataView vs Tree / TreeTable | `data-display-choice` |
68
+ | Select vs TreeSelect vs AutoComplete vs Radio / … | `selection-choice` |
69
+ | Card vs Panel vs Fieldset | `surface-choice` |
70
+ | PageContent vs Flex vs Space vs Grid | `layout-spacing-choice` |
71
+ | PageFilters / Toolbar / Header / Section / Stat / Placeholder | `page-section-choice` |
72
+ | Layout scroll vs MScrollbar vs built-in | `page-scroll-choice` |
73
+ | Avoid double borders / extra Card wrappers | `surface-nesting-choice` |
74
+ | Loading vs Skeleton vs Progress* vs BlockUI | `loading-choice` |
75
+ | Status vs Tag vs Chip vs Badge | `status-label-choice` |
76
+ | Empty vs Result | `empty-result-choice` |
77
+ | Dropdown vs Menu vs ContextMenu vs CommandMenu | `action-menu-choice` |
78
+ | message vs toast vs field / form alert | `feedback-choice` |
79
+ | ConfirmDialog vs ConfirmPopup | `confirm-choice` |
80
+ | Searchable list + paging | `page-section-choice` + `data-display-choice` (+ list golden) |
81
+ | Delete / destructive | `confirm-choice` |
82
+ | Login / auth | `feedback-choice` + `login-page` golden |
83
+ | Marketing landing | `landing-page` golden (Express) |
84
+ | Multi-step create | `wizard-form` golden |
85
+ | Preferences / settings | `settings-page` golden |
86
+ | Resizable two-pane | use `MSplitter` (see docs / `get_component`) |
87
+
88
+ ## Common mistakes
89
+
90
+ | Wrong | Right |
91
+ | --- | --- |
92
+ | `MDropdown` as form enum | `MSelect` (`selection-choice`) |
93
+ | `MTable` `:data` | `:rows` (`data-display-choice`) |
94
+ | `<MMessage severity>` as an inline alert | Field `errorMessage`, or token `role="alert"` (`feedback-choice`) |
95
+ | Hand `<table>` | `MTable` |
96
+ | Hand modal div | `MDialog` / `MConfirmDialog` |
97
+ | Hand spinner or `MProgressSpinner` as a region / page mask | `MLoading` / `v-loading` (`loading-choice`) |
98
+ | Extra `MCard` around every `MPage*` block | `surface-nesting-choice` |
99
+ | Assume undocumented props | MCP / docs lookup + `validate_usage` |
@@ -6,7 +6,7 @@ Generated from `packages/ui-mcp/src/decisions.ts`. **Do not hand-edit** this fil
6
6
  pnpm --filter @morya-ui/mcp generate:recipes
7
7
  ```
8
8
 
9
- MCP: `recommend_component` (list / read by `decision` / query). Full prop manuals still come from `get_component` + `validate_usage`.
9
+ MCP: `recommend_component` (list / read by `decision` / query; options may include `relatedSnippets`). Full prop manuals still come from `get_component` + `validate_usage`. Prefer page snippets for composition; golden pages are optional block-order checks.
10
10
 
11
11
  This file is the **offline** mirror for agents without MCP.
12
12
 
@@ -31,7 +31,7 @@ This file is the **offline** mirror for agents without MCP.
31
31
 
32
32
  - v-model / modelValue 控制开关(不要用 visible)
33
33
  - header 或 title 设弹窗标题
34
- - width 约 32rem 适配短表单(见 form-in-dialog 黄金样例)
34
+ - width 约 32rem 适配短表单(见 form-in-dialog snippet)
35
35
  - 表单字段用 fluid;主按钮 severity="primary"
36
36
 
37
37
  **Recipe · slots**
@@ -44,6 +44,11 @@ This file is the **offline** mirror for agents without MCP.
44
44
  - @close 重置表单模型
45
45
  - 保存可用按钮 @click,或 MForm @submit + type="submit"
46
46
 
47
+ **Related snippets**
48
+
49
+ - `form-in-dialog`
50
+ - `page-header-actions`
51
+
47
52
  **Anti-patterns**
48
53
 
49
54
  - 用普通 Dialog 手写删除确认 → MConfirmDialog
@@ -77,6 +82,10 @@ This file is the **offline** mirror for agents without MCP.
77
82
 
78
83
  - @close 清理草稿
79
84
 
85
+ **Related snippets**
86
+
87
+ - `form-in-drawer`
88
+
80
89
  **Anti-patterns**
81
90
 
82
91
  - 极短 2–3 字段也用 Drawer → Dialog
@@ -110,6 +119,13 @@ This file is the **offline** mirror for agents without MCP.
110
119
  - MForm @submit(或 @submit.prevent)
111
120
  - 提交按钮 type="submit" + severity="primary"
112
121
 
122
+ **Related snippets**
123
+
124
+ - `page-content-form`
125
+ - `form-header`
126
+ - `form-body`
127
+ - `form-actions`
128
+
113
129
  **Anti-patterns**
114
130
 
115
131
  - 列表短 CRUD 开独立路由 → form-in-dialog
@@ -151,6 +167,10 @@ This file is the **offline** mirror for agents without MCP.
151
167
 
152
168
  - @close / @update:modelValue
153
169
 
170
+ **Related snippets**
171
+
172
+ - `form-in-dialog`
173
+
154
174
  **Anti-patterns**
155
175
 
156
176
  - Dialog + 手写「确定删除」→ MConfirmDialog
@@ -184,6 +204,10 @@ This file is the **offline** mirror for agents without MCP.
184
204
 
185
205
  - @close
186
206
 
207
+ **Related snippets**
208
+
209
+ - `form-in-drawer`
210
+
187
211
  **Anti-patterns**
188
212
 
189
213
  - 简单 Yes/No 确认用 Drawer → ConfirmDialog / ConfirmPopup
@@ -727,17 +751,30 @@ This file is the **offline** mirror for agents without MCP.
727
751
 
728
752
  **Recipe · props**
729
753
 
730
- - 内放 MInput / MSelect 等筛选控件
731
- - 可 collapsible + #advanced
732
- - 不要外包 MCard
754
+ - 内放 MInput / MSelect;同行用 MSpace wrap
755
+ - 查询/重置放 #actions(与折叠切换同列)
756
+ - 默认 variant="filled";dense craft 用 plain + size="small"
757
+ - 有次要条件:collapsible + v-model:expanded + #advanced
758
+ - toggle 默认「高级筛选/收起」+ chevron;已选用 FilterChips
733
759
 
734
760
  **Recipe · slots**
735
761
 
762
+ - #actions 查询/重置
736
763
  - #advanced 高级筛选
764
+ - #active 可选;更常见是下方 FilterChips
765
+
766
+ **Related snippets**
767
+
768
+ - `list-filters-stack`
769
+ - `list-filters`
770
+ - `list-filters-collapsible`
771
+ - `list-filter-chips`
772
+ - `list-filters-dense`
737
773
 
738
774
  **Anti-patterns**
739
775
 
740
776
  - 表单字段组用 PageFilters → PageSection form / Fieldset
777
+ - 手写已选条 → list-filter-chips / list-filters-stack
741
778
 
742
779
 
743
780
  ### PageToolbar
@@ -1299,6 +1336,10 @@ This file is the **offline** mirror for agents without MCP.
1299
1336
 
1300
1337
  - #extra 放下一步按钮(创建…)
1301
1338
 
1339
+ **Related snippets**
1340
+
1341
+ - `empty-block`
1342
+
1302
1343
  **Anti-patterns**
1303
1344
 
1304
1345
  - 403/404 用 Empty → Result
@@ -1328,6 +1369,10 @@ This file is the **offline** mirror for agents without MCP.
1328
1369
 
1329
1370
  - #footer 逃逸/下一步按钮
1330
1371
 
1372
+ **Related snippets**
1373
+
1374
+ - `result-block`
1375
+
1331
1376
  **Anti-patterns**
1332
1377
 
1333
1378
  - 表格无数据用 Result → Empty
@@ -1358,6 +1403,11 @@ This file is the **offline** mirror for agents without MCP.
1358
1403
  - 触发器放默认插槽(按钮/图标)
1359
1404
  - 危险项用文档 severity / 确认流
1360
1405
 
1406
+ **Related snippets**
1407
+
1408
+ - `row-actions-menu`
1409
+ - `list-row-actions`
1410
+
1361
1411
  **Anti-patterns**
1362
1412
 
1363
1413
  - 表单枚举用 Dropdown → Select
@@ -1475,6 +1525,11 @@ This file is the **offline** mirror for agents without MCP.
1475
1525
  - message.success('已保存') / info / warn / error
1476
1526
  - 大多数操作反馈的默认选择
1477
1527
 
1528
+ **Related snippets**
1529
+
1530
+ - `confirm-delete`
1531
+ - `form-in-dialog`
1532
+
1478
1533
  **Anti-patterns**
1479
1534
 
1480
1535
  - toast.add({ summary: '已保存' }) → message.success('已保存')
@@ -1520,6 +1575,10 @@ This file is the **offline** mirror for agents without MCP.
1520
1575
  - 表单级:token 样式的 role="alert" 条(见 login-page)
1521
1576
  - <MMessage> 只是 message 宿主,不是内嵌 Alert
1522
1577
 
1578
+ **Related snippets**
1579
+
1580
+ - `auth-split-shell`
1581
+
1523
1582
  **Anti-patterns**
1524
1583
 
1525
1584
  - 登录失败只闪 Toast → 表单区 alert / errorMessage
@@ -1557,6 +1616,10 @@ This file is the **offline** mirror for agents without MCP.
1557
1616
  - @accept 执行删除
1558
1617
  - @reject 关闭
1559
1618
 
1619
+ **Related snippets**
1620
+
1621
+ - `confirm-delete`
1622
+
1560
1623
  **Anti-patterns**
1561
1624
 
1562
1625
  - 普通 Dialog 手写「确定/取消」删除 → ConfirmDialog
@@ -1586,6 +1649,10 @@ This file is the **offline** mirror for agents without MCP.
1586
1649
 
1587
1650
  - @accept / @reject
1588
1651
 
1652
+ **Related snippets**
1653
+
1654
+ - `confirm-delete`
1655
+
1589
1656
  **Anti-patterns**
1590
1657
 
1591
1658
  - 无 target 的全局危险确认 → ConfirmDialog