@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,141 +1,133 @@
1
- # Page layouts
2
-
3
- When generating a full page, pick a type and **mirror the golden-page block order**. Source: MCP `get_golden_page`.
4
-
5
- | Type | `get_golden_page` id |
6
- | --- | --- |
7
- | List (structure · soft) | `list-page` |
8
- | List · dense craft | `list-page-dense` |
9
- | List · rail craft | `list-page-rail` |
10
- | Form (long / dedicated) | `form-page` |
11
- | List create/edit dialog | `form-in-dialog` |
12
- | Detail | `detail-page` |
13
- | Dashboard | `dashboard-page` |
14
- | Login | `login-page` |
15
- | Landing | `landing-page` |
16
- | Empty | `empty-state` |
17
- | Result / 403 / terminal | `result-page` |
18
- | Settings | `settings-page` |
19
- | Wizard | `wizard-form` |
20
-
21
- Via MCP: `recommend_page({ style? })` → resolves list craft (`dense`→`list-page-dense`, `rail`→`list-page-rail`, else `list-page`) → `get_golden_page`; then apply `styleDirection` (or a user reference). Local edits: `get_page_snippet` (`filters`, `toolbar`, `form-actions`, `scrollable-panel`, …). Styles: `list_style_presets` / `get_style_preset`.
22
-
23
- **List craft variants** share the same block order; only density / chrome / copy change. Prefer `recommend_page` style routing over hand-picking unless the user named a variant id.
24
-
25
- ## Product defaults
26
-
27
- - **Short create/edit** (about ≤8 fields, single section): same-page `MDialog` + `MForm` — do not invent a new route form for every entity.
28
- - **Long / multi-section / wizard**: dedicated form page (`form-page`) or `MDrawer`.
29
- - **One-line success/error**: `message` API; title + detail or async notify → `toast` (see [feedback.md](feedback.md)).
30
-
31
- ## List page — block order
32
-
33
- 1. `MLayout fillViewport` + optional `MLayoutSider bordered`
34
- 2. Sider `MMenu` (**every item has `icon`**)
35
- 3. `MLayoutHeader` → `MBreadcrumb`
36
- 4. `MLayoutContent` → `MPageContent` (**add `fill` only when the height rule below applies**)
37
- 5. `MPageHeader` — page title + `#actions` primary (**one** filled primary in viewport)
38
- 6. `MPageFilters` — `variant="filled"` optional; inner `MSpace wrap` + Input/Select + query/reset (query/reset → secondary); optional `collapsible` + `#advanced` for secondary fields
39
- 7. Optional `MPageFilterChips` + closable `MTag` when filters are applied (after filters, before table)
40
- 8. Optional `MPageToolbar` — batch actions only (no page title)
41
- 9. `MTable` directly in content (usually **no** wrapping `MCard`); status → `MStatus`; `#empty` → `MEmpty`
42
- 10. Pagination via `MTable paginator` or sibling `MPagination`
43
- 11. Short create/edit → `MDialog` + `MForm` on the same page (default)
44
-
45
- ### List height — decide, don’t always fill
46
-
47
- Use **`MPageContent fill` + `MTable fill paginator`** only when **most** of these are true:
48
-
49
- - The screen is a **full-viewport admin list** (`MLayout fillViewport`) whose **main job** is browsing one data table
50
- - Leaving the table content-sized would leave a large empty band with pagination floating mid-page
51
- - You want **table-body scroll** and pagination pinned to the **bottom of the page**
52
-
53
- Skip `fill` when any of these apply:
54
-
55
- - Embedded / secondary tables (dashboard “recent”, detail related lists, cards)
56
- - Short or sparse pages where a content-sized table looks fine
57
- - The page should **scroll as a whole document** (long filters + notes + table)
58
- - Tables inside `MDialog` / `MDrawer`
59
- - Mixed layouts where the table is not the sole middle region
60
-
61
- Do not invent `min-height` / `calc` hacks when `fill` is the right tool — and do not force `fill` when it isn’t.
62
-
63
- Craft: [visual-craft.md](visual-craft.md) § Ops polish.
64
-
65
- ## Form page — block order
66
-
67
- 1. `MLayout fillViewport` → `MLayoutHeader` → `MBreadcrumb`
68
- 2. `MPageContent width="narrow"`
69
- 3. `MPageHeader` (title + description)
70
- 4. `MPageSection variant="form"` → `MForm`
71
- 5. `MPageSection variant="actions"` — save (`primary`) + cancel (`secondary`)
72
-
73
- ## Dashboard — block order
74
-
75
- 1. `MLayout fillViewport` → `MLayoutHeader` → `MBreadcrumb`
76
- 2. `MPageContent density="spacious"` → `MPageHeader` (title + short domain description when useful)
77
- 3. KPI row: `MGrid` + `MPageStat` (4 columns or responsive) — real metric names, not “Metric 1”
78
- 4. Main split: `MCard shadow="always"` + `MEmpty` (chart pending) and/or recent `MTable` (row status → `MStatus`)
79
-
80
- Craft: spacious density + Ops polish; do not turn the first viewport into a marketing hero.
81
-
82
- ## Composition standards
83
-
84
- | Topic | Prefer | Usually avoid |
85
- | --- | --- | --- |
86
- | Shell | `MLayout fillViewport` + `MPageContent` | Padding on `MLayoutContent` |
87
- | Sections | `MPageFilters` / `MPageToolbar` / `MPageSection` | Custom `.page-*`; extra `MCard` wrappers |
88
- | List table | `MTable` in `MPageContent`; add `fill` only when the height rule applies | Border card solely to wrap the table; forcing `fill` on every table |
89
- | Spacing | `MSpace` / `MFlex` for peers; page gap from `MPageContent` | Nested padded divs stacking gaps |
90
- | Scroll | Full-viewport main lists may use table-body scroll via `fill`; otherwise layout / local `MScrollbar` | Forcing overflow on every content slot; stacked page + table scrollbars without reason |
91
- | Color | `--m-*` | Page-level hex / rgb |
92
- | Feedback | One-line → `message`; danger → confirm dialog | Toast for a single short string |
93
- | A11y | Labels + icon `aria-label` | Unlabeled icon controls |
94
-
95
- Inline style is acceptable for control widths (e.g. filter `width: 14rem`).
96
-
97
- ## Detail page — block order
98
-
99
- 1. Same admin chrome as list (breadcrumb → `MPageContent`)
100
- 2. `MPageHeader` — title, `MStatus` in `#actions` (or chip `MTag` for categories), primary/secondary/danger actions
101
- 3. Summary `MPageSection` + property `MCard` (definition grid with `--m-*` only)
102
- 4. Related data: `MCard` + `MTable` / tabs / timeline
103
- 5. Short edit → same-page `MDialog` (`form-in-dialog`); long edit → `form-page` / `MDrawer`
104
-
105
- Mirror MCP `get_golden_page` `detail-page`.
106
-
107
- ## List create/edit dialog — block order
108
-
109
- 1. Stay on the list page (`MPageHeader` + filters/table; optional batch `MPageToolbar`)
110
- 2. `MDialog` ~`28–36rem` + `MForm` fields
111
- 3. Actions in Dialog `#footer` (cancel secondary/text + save primary)
112
- 4. Success → `message.success` one-liner, then close
113
-
114
- Mirror MCP `get_golden_page` `form-in-dialog`.
115
-
116
- ## Settings page — block order
117
-
118
- 1. Admin chrome + `MPageContent width="narrow"`
119
- 2. `MPageHeader` (title + short description)
120
- 3. `MTabs` with **`v-model` + `:tabs`** (not `:items` / `:value`)
121
- 4. Per tab: `MPageSection variant="form"` + `MForm` + save in `variant="actions"`
122
- 5. Dangerous zone last: `severity="danger"` + confirm
123
-
124
- Mirror MCP `get_golden_page` `settings-page`.
125
-
126
- ## Wizard — block order
127
-
128
- 1. Narrow `MPageContent` + `MPageHeader`
129
- 2. `MStepper v-model` + **`:steps`** (not `:items`)
130
- 3. One form/job per step; sticky `上一步` / `下一步` / `创建`
131
- 4. Success → `result-page` / `MResult`
132
-
133
- Mirror MCP `get_golden_page` `wizard-form`.
134
-
135
- ## Hybrids
136
-
137
- - List + row edit dialog → `form-in-dialog` golden (or list golden + dialog body).
138
- - List + side detail → list + `MDrawer`.
139
- - Resource detail → `detail-page` golden.
140
- - Settings without admin chrome → still use `MPageContent` + `MPageSection`; omit sider only if the host app already provides chrome.
141
- - Non-Ops surfaces (auth, landing, empty, wizard) → [surfaces.md](surfaces.md), not these golden orders.
1
+ # Page layouts
2
+
3
+ When generating a full page, pick a type and follow the **block-order checklist** below. Fill each block with MCP **`get_page_snippet`** / `recommend_page.suggestedSnippets` (composition-first). Optional: `get_golden_page` only to cross-check whole-page order or when the user asks to mirror a golden sample.
4
+
5
+ Golden pages are **assembly demos / structure baselines**, not the default clone source. Do not add new craft variants (`list-page-*`); density / sider cues inform polish via style direction.
6
+
7
+ | Type | Checklist below | Optional `get_golden_page` | Typical snippets |
8
+ | --- | --- | --- | --- |
9
+ | List | List page | `list-page` (`list-page-dense` / `list-page-rail` craft only) | `layout-app-shell`, `page-header-actions`, **`list-filters-stack`** (dense → `list-filters-dense`), `list-table`, `form-in-dialog`, `confirm-delete` |
10
+ | Form (long / dedicated) | Form page | `form-page` | `page-content-form`, `form-header`, `form-body`, `form-actions` |
11
+ | List create/edit dialog | List create/edit dialog | `form-in-dialog` | **`form-in-dialog`** (preferred) |
12
+ | Detail | Detail page | `detail-page` | `detail-toolbar`, `form-in-dialog` |
13
+ | Dashboard | Dashboard | `dashboard-page` | `dashboard-kpi-grid`, `dashboard-chart-card`, `dashboard-recent-table` |
14
+ | Login | — (see [surfaces.md](surfaces.md)) | `login-page` | **`auth-split-shell`** |
15
+ | Landing | — (see [surfaces.md](surfaces.md)) | `landing-page` | — |
16
+ | Empty | — | `empty-state` | **`empty-block`** |
17
+ | Result / 403 / terminal | — | `result-page` | **`result-block`** |
18
+ | Settings | Settings page | `settings-page` | `form-header`, `form-body`, `form-actions` |
19
+ | Wizard | Wizard | `wizard-form` | **`wizard-steps`** |
20
+
21
+ Via MCP: `recommend_page({ style? })` → use **`suggestedSnippets`** + `recommend_component` / `get_page_snippet`; apply `styleDirection` (user reference/description — no preset catalog). Call `get_golden_page` only when needed for block-order check. Style: `get_style_direction`.
22
+
23
+ **List craft variants** share the same block order; only density / chrome / copy change. Prefer style-direction cues over inventing new golden ids.
24
+
25
+ ## Product defaults
26
+
27
+ - **Short create/edit** (about ≤8 fields, single section): same-page `MDialog` + `MForm` — snippet `form-in-dialog`; do not invent a new route form for every entity.
28
+ - **Long / multi-section / wizard**: dedicated form page (`form-page`) or `MDrawer` (`form-in-drawer`).
29
+ - **One-line success/error**: `message` API; title + detail or async notify → `toast` (see [feedback.md](feedback.md)).
30
+
31
+ ## List page — block order
32
+
33
+ 1. `MLayout fillViewport` + optional `MLayoutSider bordered` → snippet `layout-app-shell`
34
+ 2. Sider `MMenu` (**every item has `icon`**)
35
+ 3. `MLayoutHeader` → `MBreadcrumb`
36
+ 4. `MLayoutContent` → `MPageContent` (**add `fill` only when the height rule below applies**) → `page-content-list`
37
+ 5. `MPageHeader` — page title + `#actions` primary (**one** filled primary in viewport) → `page-header-actions`
38
+ 6. `MPageFilters` — 默认 **`list-filters-stack`**(`#actions` 查询/重置 + collapsible「高级筛选/收起」chevron + `#advanced` + FilterChips);条件少无高级区用 `list-filters`;dense craft 用 `list-filters-dense`
39
+ 7. Optional `MPageFilterChips` — 已含在 `list-filters-stack`;单独增量用 `list-filter-chips`
40
+ 8. Optional `MPageToolbar` — batch actions only → `list-toolbar` / `list-batch-toolbar`
41
+ 9. `MTable` directly in content; status → `MStatus`; `#empty` → `MEmpty` → `list-table` + `list-status-dot` + `empty-block`
42
+ 10. Pagination via `MTable paginator` or sibling `MPagination`
43
+ 11. Short create/edit → same-page `MDialog` + `MForm` → **`form-in-dialog`**; delete → **`confirm-delete`**
44
+
45
+ ### List height — decide, don’t always fill
46
+
47
+ Use **`MPageContent fill` + `MTable fill paginator`** only when **most** of these are true:
48
+
49
+ - The screen is a **full-viewport admin list** (`MLayout fillViewport`) whose **main job** is browsing one data table
50
+ - Leaving the table content-sized would leave a large empty band with pagination floating mid-page
51
+ - You want **table-body scroll** and pagination pinned to the **bottom of the page**
52
+
53
+ Skip `fill` when any of these apply:
54
+
55
+ - Embedded / secondary tables (dashboard “recent”, detail related lists, cards)
56
+ - Short or sparse pages where a content-sized table looks fine
57
+ - The page should **scroll as a whole document** (long filters + notes + table)
58
+ - Tables inside `MDialog` / `MDrawer`
59
+ - Mixed layouts where the table is not the sole middle region
60
+
61
+ Do not invent `min-height` / `calc` hacks when `fill` is the right tool — and do not force `fill` when it isn’t.
62
+
63
+ Craft: [visual-craft.md](visual-craft.md) § Ops polish.
64
+
65
+ ## Form page — block order
66
+
67
+ 1. `MLayout fillViewport` → `MLayoutHeader` → `MBreadcrumb`
68
+ 2. `MPageContent width="narrow"` → `page-content-form`
69
+ 3. `MPageHeader` (title + description) → `form-header`
70
+ 4. `MPageSection variant="form"` → `MForm` → `form-body`
71
+ 5. `MPageSection variant="actions"` — save (`primary`) + cancel (`secondary`) → `form-actions`
72
+
73
+ ## Dashboard — block order
74
+
75
+ 1. `MLayout fillViewport` → `MLayoutHeader` → `MBreadcrumb`
76
+ 2. `MPageContent density="spacious"` → `MPageHeader` (title + short domain description when useful)
77
+ 3. KPI row: `MGrid` + `MPageStat` (4 columns or responsive) — `dashboard-kpi-grid`
78
+ 4. Main split: `MCard shadow="always"` + `MEmpty` (chart pending) and/or recent `MTable` — `dashboard-chart-card` / `dashboard-recent-table`
79
+
80
+ Craft: spacious density + Ops polish; do not turn the first viewport into a marketing hero.
81
+
82
+ ## Composition standards
83
+
84
+ | Topic | Prefer | Usually avoid |
85
+ | --- | --- | --- |
86
+ | Shell | `MLayout fillViewport` + `MPageContent` | Padding on `MLayoutContent` |
87
+ | Sections | `MPageFilters` / `MPageToolbar` / `MPageSection` | Custom `.page-*`; extra `MCard` wrappers |
88
+ | List table | `MTable` in `MPageContent`; add `fill` only when the height rule applies | Border card solely to wrap the table; forcing `fill` on every table |
89
+ | Spacing | `MSpace` / `MFlex` for peers; page gap from `MPageContent` | Nested padded divs stacking gaps |
90
+ | Scroll | Full-viewport main lists may use table-body scroll via `fill`; otherwise layout / local `MScrollbar` | Forcing overflow on every content slot; stacked page + table scrollbars without reason |
91
+ | Color | `--m-*` | Page-level hex / rgb |
92
+ | Feedback | One-line → `message`; danger → confirm dialog | Toast for a single short string |
93
+ | A11y | Labels + icon `aria-label` | Unlabeled icon controls |
94
+
95
+ Inline style is acceptable for control widths (e.g. filter `width: 14rem`).
96
+
97
+ ## Detail page — block order
98
+
99
+ 1. Same admin chrome as list (breadcrumb → `MPageContent`)
100
+ 2. `MPageHeader` — title, `MStatus` in `#actions`, primary/secondary/danger → `detail-toolbar`
101
+ 3. Summary `MPageSection` + property `MCard` (definition grid with `--m-*` only)
102
+ 4. Related data: `MCard` + `MTable` / tabs / timeline
103
+ 5. Short edit → `form-in-dialog`; long edit → form page / `form-in-drawer`
104
+
105
+ ## List create/edit dialog — block order
106
+
107
+ 1. Stay on the list page (`MPageHeader` + filters/table; optional batch `MPageToolbar`)
108
+ 2. `MDialog` ~`28–36rem` + `MForm` fields → snippet **`form-in-dialog`**
109
+ 3. Actions in Dialog `#footer` (cancel secondary/text + save primary)
110
+ 4. Success → `message.success` one-liner, then close
111
+
112
+ ## Settings page — block order
113
+
114
+ 1. Admin chrome + `MPageContent width="narrow"`
115
+ 2. `MPageHeader` (title + short description)
116
+ 3. `MTabs` with **`v-model` + `:tabs`** (not `:items` / `:value`)
117
+ 4. Per tab: `MPageSection variant="form"` + `MForm` + save in `variant="actions"`
118
+ 5. Dangerous zone last: `severity="danger"` + confirm
119
+
120
+ ## Wizard — block order
121
+
122
+ 1. Narrow `MPageContent` + `MPageHeader`
123
+ 2. `MStepper v-model` + **`:steps`** (not `:items`) → snippet **`wizard-steps`**
124
+ 3. One form/job per step; sticky `上一步` / `下一步` / `创建`
125
+ 4. Success → `result-block` / `MResult`
126
+
127
+ ## Hybrids
128
+
129
+ - List + row edit dialog → `form-in-dialog` snippet on the list.
130
+ - List + side detail → list + `form-in-drawer`.
131
+ - Resource detail → detail checklist + `detail-toolbar`.
132
+ - Settings without admin chrome → still use `MPageContent` + `MPageSection`; omit sider only if the host app already provides chrome.
133
+ - Non-Ops surfaces (auth, landing, empty, wizard) → [surfaces.md](surfaces.md) + matching snippets, not Ops list chrome.
@@ -1,64 +1,76 @@
1
- # Review checklist
2
-
3
- ## Contract (all lanes)
4
-
5
- - [ ] Only `morya-ui` UI primitives (no second kit)
6
- - [ ] `morya-ui/styles.css` imported at app/demo entry
7
- - [ ] `MConfigProvider` at a sensible root when building a full screen
8
- - [ ] No invented props / events / slots (MCP `get_component` / docs checked)
9
- - [ ] MCP **`validate_usage`** run; no unresolved `unknown-prop` / `unknown-event`
10
- - [ ] Select vs Dropdown roles correct
11
- - [ ] `MTable` uses `rows` (not `data`)
12
- - [ ] One-line results use `message`; summary+detail / async use `toast`
13
- - [ ] Destructive flows use confirm dialogs
14
- - [ ] MCP **`validate_page`** run when generating a full page (advisory suggestions addressed or consciously waived)
15
-
16
- ## Craft (all lanes — default pass)
17
-
18
- - [ ] Style direction resolved (reference / named preset / inferred / offered) — not silent `quiet` every time
19
- - [ ] Lane craft from [visual-craft.md](visual-craft.md) + [style-presets.md](style-presets.md) applied
20
- - [ ] If companions ran: still only `M*` + `--m-*`; no second kit ([optional-companions.md](optional-companions.md))
21
- - [ ] At most one primary filled button in the main viewport
22
- - [ ] Copy is domain-real; empty / error states say what to do next
23
- - [ ] No AI-default look clusters unless the brief asked for them
24
- - [ ] Motion (if any) is 1–3 intentional moments and follows `useMotion` / `data-m-motion` (not OS `prefers-reduced-motion`)
25
-
26
- ## Ops
27
-
28
- - [ ] Matches golden / [page-layouts.md](page-layouts.md) block order
29
- - [ ] `MPage*` used instead of ad-hoc page chrome where applicable
30
- - [ ] List height: if this is a full-viewport main data list, consider `MPageContent fill` + `MTable fill`; if embedded/short/document-scroll, skip `fill`
31
- - [ ] Tables not wrapped in decorative `MCard` solely for borders
32
- - [ ] Filters / toolbar / form actions follow documented patterns
33
- - [ ] Sider `MMenu` items have icons; status cells use `MStatus` (not decorative `MTag`)
34
- - [ ] Empty table uses `MEmpty` (or equivalent next-action empty)
35
- - [ ] No marketing hero bolted onto a CRUD shell
36
-
37
- ## Account / Flow / System
38
-
39
- - [ ] Primary CTA obvious; escape paths present (back / home / support)
40
- - [ ] Auth errors stay on the form via field `errorMessage` or a token `role="alert"` (`<MMessage>` is the message host, not an inline alert)
41
- - [ ] Empty uses `MEmpty` (or table `#empty` with `MEmpty`); success / HTTP errors use `MResult`
42
- - [ ] Empty / success states tell the user the next action
43
- - [ ] Inline status prefers `MStatus`; chip-like labels use `MTag`
44
- - [ ] Wizard steps: one job each; actions labeled clearly
45
- - [ ] Brand / empty atmosphere uses token-only CSS (see visual-craft recipes)
46
-
47
- ## Express
48
-
49
- - [ ] Short design plan existed (subject, palette roles, signature)
50
- - [ ] First viewport has one job (not a dashboard of promos)
51
- - [ ] Controls still `M*`; colors/spacing map to `--m-*` / theme
52
- - [ ] Avoided AI-default looks unless brief requested them ([visual-craft.md](visual-craft.md))
53
- - [ ] Motion limited and respectful of reduced-motion
54
-
55
- ## Tokens, a11y, responsive
56
-
57
- - [ ] No raw hex/rgb theme colors in new CSS (control widths OK inline; `color-mix` from `--m-*` OK)
58
- - [ ] Labels visible; icon buttons have `aria-label`
59
- - [ ] Usable on a narrow viewport
60
- - [ ] Focus visible on interactive elements
61
-
62
- When MCP is available, contract checks above (**`validate_usage`** / **`validate_page`**) are required — not optional.
63
-
64
- If the project has `pnpm check:colors`, suggest running it after edits.
1
+ # Review checklist
2
+
3
+ ## Contract (all lanes)
4
+
5
+ - [ ] Only `morya-ui` UI primitives (no second kit)
6
+ - [ ] `morya-ui/styles.css` imported at app/demo entry
7
+ - [ ] `MConfigProvider` at a sensible root when building a full screen
8
+ - [ ] No invented props / events / slots (MCP `get_component` / docs checked)
9
+ - [ ] MCP **`validate_usage`** run; no unresolved `unknown-prop` / `unknown-event`
10
+ - [ ] Select vs Dropdown roles correct
11
+ - [ ] `MTable` uses `rows` (not `data`)
12
+ - [ ] One-line results use `message`; summary+detail / async use `toast`
13
+ - [ ] Destructive flows use confirm dialogs
14
+ - [ ] MCP **`validate_page`** run when generating a full page — **`ok` must be true** (contract); craft suggestions addressed or consciously waived
15
+ - [ ] Same **`brief`** as `map_reference` / `recommend_page` passed into `validate_page` when a reference exists
16
+
17
+ ## Craft (all lanes — default pass)
18
+
19
+ - [ ] Style direction resolved: followed user reference/description, or inferred from clear cues, or **asked** when uncertain — never silent invent; **no preset catalog**
20
+ - [ ] Reference fidelity: `map_reference` mapping blocks present (filters/table/status/… as required)
21
+ - [ ] Signature shell from `get_style_shells` when Account / Express / Flow need presence
22
+ - [ ] Lane craft from [visual-craft.md](visual-craft.md) applied
23
+ - [ ] If companions ran: still only `M*` + `--m-*`; no second kit ([optional-companions.md](optional-companions.md))
24
+ - [ ] At most one primary filled button in the main viewport
25
+ - [ ] Copy is domain-real; empty / error states say what to do next
26
+ - [ ] Numeric table columns use `align: 'end'` + tabular nums when amounts/counts are shown
27
+ - [ ] No AI-default look clusters unless the user/reference asked for them
28
+ - [ ] No unearned atmosphere: stacked radial+linear washes, purple mesh, frosted glass, neon glow stacks
29
+ - [ ] Motion (if any) is 1–3 intentional moments and follows `useMotion` / `data-m-motion`
30
+ - [ ] Brand differences via theme `--m-*` overrides, not page hex
31
+
32
+ ## Screenshot self-check (optional — when user gave a visual reference)
33
+
34
+ 1. Start the consumer app locally (Vite / Nuxt preview).
35
+ 2. Open the generated route; capture the first viewport.
36
+ 3. Compare to the reference: block order, primary CTA, density, status treatment — not pixel-perfect chrome.
37
+ 4. If blocks are missing, fix via snippets + re-run `validate_page({ brief })`.
38
+
39
+ If Playwright / `webapp-testing` is available in the project, prefer an automated screenshot; otherwise a manual capture is enough.
40
+ ## Ops
41
+
42
+ - [ ] Matches [page-layouts.md](page-layouts.md) block order (snippets composed; golden page optional check only)
43
+ - [ ] `MPage*` used instead of ad-hoc page chrome where applicable
44
+ - [ ] List height: if this is a full-viewport main data list, consider `MPageContent fill` + `MTable fill`; if embedded/short/document-scroll, skip `fill`
45
+ - [ ] Tables not wrapped in decorative `MCard` solely for borders
46
+ - [ ] Filters / toolbar / form actions follow documented patterns
47
+ - [ ] Sider `MMenu` items have icons; status cells use `MStatus` (not decorative `MTag`)
48
+ - [ ] Empty table uses `MEmpty` (or equivalent next-action empty)
49
+ - [ ] No marketing hero bolted onto a CRUD shell
50
+
51
+ ## Account / Flow / System
52
+
53
+ - [ ] Primary CTA obvious; escape paths present (back / home / support)
54
+ - [ ] Auth errors stay on the form via field `errorMessage` or a token `role="alert"`
55
+ - [ ] Empty uses `MEmpty`; success / HTTP errors use `MResult`
56
+ - [ ] Brand / empty atmosphere follows the **resolved direction** (defaults are flat token shells)
57
+ - [ ] Wizard steps: one job each; actions labeled clearly
58
+
59
+ ## Express
60
+
61
+ - [ ] Short design plan existed (subject, palette roles, signature)
62
+ - [ ] First viewport has one job
63
+ - [ ] Controls still `M*`; colors/spacing map to `--m-*`
64
+ - [ ] Avoided AI-default looks unless user/reference requested them
65
+ - [ ] Motion limited and gated by `useMotion` / `data-m-motion`
66
+
67
+ ## Tokens, a11y, responsive
68
+
69
+ - [ ] No raw hex/rgb theme colors in new CSS (control widths OK inline; `color-mix` from `--m-*` OK)
70
+ - [ ] Labels visible; icon buttons have `aria-label`
71
+ - [ ] Usable on a narrow viewport
72
+ - [ ] Focus visible on interactive elements
73
+
74
+ When MCP is available, contract checks (**`validate_usage`** / **`validate_page`**) are required.
75
+
76
+ If the project has `pnpm check:colors`, suggest running it after edits.
@@ -1,73 +1,68 @@
1
- # Style direction & presets
2
-
3
- Golden pages lock **block order and APIs**. They are **not** the only allowed look. Pick a visual direction **before** coding so generated pages stop looking identical and stiff.
4
-
5
- ## Resolution order (required)
6
-
7
- 1. **Reference first** — user supplied a screenshot, mock, existing page, URL, or “像 XX / like X”.
8
- - Extract: density, hierarchy, surfaces (flat vs filled), accent placement, copy tone.
9
- - Remap onto `--m-*` + `M*` only. Do **not** switch UI kits or copy hex themes.
10
- 2. **Named preset** — user asked for `soft` / 柔和留白 / `dense` / …
11
- 3. **Prompt cues** — industry or mood words in the brief → infer the closest preset and **name it** in the reply.
12
- 4. **Offer a choice** — still unclear → ask **one** short question with 3–4 options (ids below). If the user says “直接写 / just ship”, pick by domain heuristic — **do not always use `quiet`**.
13
-
14
- MCP: `list_style_presets` / `get_style_preset` / `recommend_page({ style })` → `styleDirection`.
15
-
16
- ## Presets (user-selectable)
17
-
18
- | Id | 中文 | Best for | Distinct craft | List golden |
19
- | --- | --- | --- | --- | --- |
20
- | `quiet` | 克制经典 | Serious enterprise admin | Flat chrome, golden-like Ops polish | `list-page` |
21
- | `soft` | 柔和留白 | Ops / content admin | `density="spacious"`, filled filters, short descriptions | `list-page` |
22
- | `dense` | 高密度工具台 | Monitoring / power users | `density="compact"`, `size="small"` table, tight filters | `list-page-dense` |
23
- | `rail` | 侧栏强调 | Branded B2B shells | Token `color-mix` wash on sider/header only | `list-page-rail` |
24
- | `studio` | 工作室呼吸感 | Design / collab / knowledge | Stronger header hierarchy; optional one radial wash | `list-page` |
25
- | `ink` | 线框极简 | Tool / docs feel | Plain filters, bordered table, little fill | `list-page` |
26
-
27
- Full apply/avoid lists: MCP `get_style_preset` or `@morya-ui/mcp` `style-presets`. `recommend_page({ style })` routes list scaffolds to the matching golden when a craft variant exists.
28
-
29
- ### Domain heuristics (when user says “直接写”)
30
-
31
- | Cue in brief | Prefer |
32
- | --- | --- |
33
- | 金融 / 合规 / 政务 | `quiet` or `ink` |
34
- | 运营 / 内容 / 教育 | `soft` |
35
- | 监控 / 运维 / 交易 | `dense` |
36
- | 强调品牌色 / LOGO | `rail` |
37
- | 设计 / 协作 / 知识库 | `studio` |
38
- | 登录 / 落地 / 品牌营销 | Account/Express atmosphere — not an Ops preset |
39
-
40
- ## How to apply on Ops pages
41
-
42
- 1. Mirror golden **structure** via `recommend_page` / `get_golden_page` (list: `list-page` / `list-page-dense` / `list-page-rail` by style).
43
- 2. Apply the chosen preset’s density / filter surface / header copy / chrome wash (or follow the craft golden when one exists).
44
- 3. Still run [visual-craft.md](visual-craft.md) § Ops polish (one primary, menu icons, `MStatus`, designed empty).
45
- 4. Fill height remains **conditional** — see [page-layouts.md](page-layouts.md) § List height.
46
-
47
- ## Reference style checklist
48
-
49
- When following a reference:
50
-
51
- - [ ] Hierarchy (what is loud vs quiet) matched with type/space, not random cards
52
- - [ ] Density matched (`compact` / default / `spacious`)
53
- - [ ] Surfaces matched (plain vs filled filters; bordered table or not)
54
- - [ ] Accent placement matched (chrome only vs content) using `--m-*` / `color-mix`
55
- - [ ] Interaction patterns stay morya-ui (`MTable` `rows`, `message`, etc.)
56
-
57
- ## Anti-patterns
58
-
59
- - Treating the golden page as the only allowed aesthetic
60
- - Asking nothing and always emitting `quiet`
61
- - Inventing a second component library to “match the reference”
62
- - Turning Ops into a marketing landing to “look less stiff”
63
- - Letting Frontend Design / Impeccable / UI-UX-Pro-Max swap stacks or ignore `M*` / `--m-*` (see [optional-companions.md](optional-companions.md))
64
-
65
- ## Companion pairing
66
-
67
- | Preset | Pairs well with |
68
- | --- | --- |
69
- | `quiet` / `ink` | Impeccable Operate + `quieter` / `polish` |
70
- | `soft` / `studio` | Frontend Design hierarchy cues; Impeccable `bolder` (one signature only) |
71
- | `dense` | Impeccable Operate — scanability over decoration |
72
- | `rail` | Frontend Design brand panel taste on **chrome only** |
73
- | Express (no Ops preset) | Frontend Design design plan → Impeccable `polish` |
1
+ # Style direction (no preset catalog)
2
+
3
+ Golden pages lock **block order and APIs**. They are **not** the only allowed look. There is **no** named style-preset table (`simple` / `glass` / …). Resolve the look from the **user**, then map onto `M*` + `--m-*`.
4
+
5
+ ## Resolution order (required)
6
+
7
+ 1. **User reference or explicit description (highest)**
8
+ Screenshot / mock / existing page / URL / “像 XX”, or clear words (“毛玻璃一点”、“深蓝科技风”).
9
+ **Must follow.** Remap to `--m-*` + `M*`. Do not switch kits, do not “improve” into another face.
10
+
11
+ 2. **Clear prompt cues (when not explicit)**
12
+ Industry / mood words in the brief → infer and **state your reading in one sentence**.
13
+ Decorative glass / neon / full-page gradients only when the prompt clearly asks.
14
+
15
+ 3. **Uncertain → ask (required)**
16
+ No reference, vague cues → **ask once** for a short description or a reference.
17
+ Do not invent the full look in silence.
18
+
19
+ 4. **Only if user declines**
20
+ “你看着办 / 直接写” with still no cues → quiet flat on-token admin face, **say so**, continue.
21
+ Never default to aurora / neon / unsolicited glass / cream-serif-terracotta.
22
+
23
+ MCP: `get_style_direction` / `recommend_page({ style?, density?, brief? })` → `styleDirection` + optional `referenceMapping`.
24
+ `map_reference` turns a reference description / required blocks into snippet + shell mapping.
25
+ `resolution: "ask"` means **ask the user**, not free-style.
26
+
27
+ ## Density (explicit)
28
+
29
+ Pass `density` to `recommend_page` / `map_reference` — do not rely only on regex in the intent string:
30
+
31
+ | Value | Effect |
32
+ | --- | --- |
33
+ | `compact` | Prefer `list-filters-dense` / `list-page-dense` cues |
34
+ | `default` | Standard Ops polish |
35
+ | `spacious` | More section gap; avoid packing |
36
+
37
+ ## What `style` means
38
+
39
+ - Free-text from the user (or a short paraphrase of their reference).
40
+ - **Not** a preset id.
41
+ - Optional craft cues for list goldens only: words like `dense` / `compact` / `高密` → `list-page-dense`; `rail` / `品牌侧栏` → `list-page-rail`.
42
+
43
+ ## Reference brief (fidelity)
44
+
45
+ When the user provides a screenshot / mock / “像 XX”, call **`map_reference`** (or pass `brief` into `recommend_page`) with:
46
+
47
+ - `description` — what you see (layout, density, primary CTA)
48
+ - `requiredBlocks` — e.g. `filters`, `table`, `status`, `kpi`, `auth`
49
+ - `requiredComponents` — e.g. `Table`, `Status`
50
+ - `density` / `primaryAction` when visible
51
+
52
+ Then compose **only** via returned `mapping[].snippetId`. Pass the **same brief** to `validate_page` so missing blocks fail as contract issues.
53
+
54
+ ## Anti-defaults (unless user/reference asks)
55
+
56
+ - Purple→indigo / aurora / mesh washes
57
+ - Warm cream + serif + terracotta kit
58
+ - Broadsheet newspaper columns
59
+ - Unsolicited glassmorphism, neon glow stacks, neumorph on dense tables
60
+ - Companion “atmosphere” that overrides the user’s words
61
+
62
+ ## How to apply
63
+
64
+ 1. Map reference → snippets (`map_reference` / `recommend_page.referenceMapping`).
65
+ 2. Apply a signature shell when Account / Express / Flow need presence (`get_style_shells`).
66
+ 3. Brand color via theme `--m-color-primary` (DESIGN.md § 主题覆盖), not page hex.
67
+ 4. Run Ops polish when on Operate surfaces.
68
+ 5. Companions deepen **inside** the resolved direction only ([optional-companions.md](optional-companions.md)).