@morya-ui/setup 0.3.5 → 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.
- package/LICENSE +21 -21
- package/README.md +119 -107
- package/bin/morya-ui-setup.js +14 -14
- package/catalog/skills.json +46 -46
- package/package.json +4 -3
- package/src/__tests__/mcp.test.mjs +141 -0
- package/src/cli.mjs +330 -312
- package/src/copy-template.mjs +78 -78
- package/src/fs-utils.mjs +24 -24
- package/src/install.mjs +134 -134
- package/src/mcp.mjs +220 -50
- package/src/package-json.mjs +30 -30
- package/src/skills.mjs +224 -223
- package/src/styles.mjs +119 -119
- package/template/.agents/skills/morya-ui-pages/SKILL.md +191 -188
- package/template/.agents/skills/morya-ui-pages/evals/evals.json +89 -89
- package/template/.agents/skills/morya-ui-pages/references/component-index.md +99 -99
- package/template/.agents/skills/morya-ui-pages/references/design-system.md +101 -101
- package/template/.agents/skills/morya-ui-pages/references/feedback.md +68 -68
- package/template/.agents/skills/morya-ui-pages/references/optional-companions.md +62 -62
- package/template/.agents/skills/morya-ui-pages/references/page-layouts.md +133 -133
- package/template/.agents/skills/morya-ui-pages/references/review-checklist.md +76 -63
- package/template/.agents/skills/morya-ui-pages/references/style-presets.md +68 -45
- package/template/.agents/skills/morya-ui-pages/references/surfaces.md +91 -91
- package/template/.agents/skills/morya-ui-pages/references/visual-craft.md +131 -129
- package/template/.cursor/rules/coding-style.mdc +41 -41
- package/template/.cursor/rules/component-usage.mdc +41 -41
- package/template/.cursor/rules/design-system.mdc +18 -17
- package/template/.cursor/rules/page-layout.mdc +97 -97
- package/template/AGENTS.md +33 -0
- package/template/DESIGN.md +81 -59
- package/template/scripts/check-raw-colors.mjs +74 -74
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
# Message / Toast / MMessage
|
|
2
|
-
|
|
3
|
-
**Default rule:** operation feedback uses the `message` API. Use `toast` only when you need a title plus detail, or an async / background notification feel.
|
|
4
|
-
|
|
5
|
-
Authoritative selection + key API notes also live in MCP / skill decision **`feedback-choice`** ([decision-recipes.md](./decision-recipes.md)). Keep this file and that decision aligned.
|
|
6
|
-
|
|
7
|
-
## Three different things
|
|
8
|
-
|
|
9
|
-
| Name | Shape | API | Typical use |
|
|
10
|
-
| --- | --- | --- | --- |
|
|
11
|
-
| Message service | Top-centered one-liner | `message.success('已保存')` | Most CRUD results |
|
|
12
|
-
| Toast service | Corner notice with `summary` + optional `detail` | `toast.success({ summary, detail })` | Extra explanation, job results |
|
|
13
|
-
| `MMessage` | Optional host for the `message` service | `<MMessage />` | Custom `appendTo` / placement only. Not an inline alert |
|
|
14
|
-
|
|
15
|
-
## Decision tree
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
Need immediate feedback after a user action?
|
|
19
|
-
├─ No → maybe confirm dialog or field errorMessage only
|
|
20
|
-
└─ Yes → must the error stay in the form until fixed?
|
|
21
|
-
├─ Yes → field invalid / errorMessage; form-level token alert (see login-page)
|
|
22
|
-
└─ No → only one short line (no separate detail)?
|
|
23
|
-
├─ Yes → message.* ← default
|
|
24
|
-
└─ No → summary + detail / async feel → toast.*
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Prefer `message`
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
import { message } from 'morya-ui'
|
|
31
|
-
|
|
32
|
-
message.success('已创建')
|
|
33
|
-
message.info('已移入回收站')
|
|
34
|
-
message.error('操作失败')
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Prefer `toast`
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
import { toast } from 'morya-ui'
|
|
41
|
-
|
|
42
|
-
toast.success({
|
|
43
|
-
summary: '导入完成',
|
|
44
|
-
detail: '成功 128 条,失败 2 条',
|
|
45
|
-
})
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Prefer `<MMessage>` / form-level errors
|
|
49
|
-
|
|
50
|
-
- Field validation: component `invalid` / `errorMessage` (preferred).
|
|
51
|
-
- Form-level persistent errors (login/auth): token-styled `role="alert"` bar as in MCP `get_golden_page` `login-page`.
|
|
52
|
-
- Note: `<MMessage>` today is primarily the **message service host** (`messages` / teleport). Do not invent a `severity` + default-slot Alert API unless docs add it.
|
|
53
|
-
|
|
54
|
-
```vue
|
|
55
|
-
<p v-if="formError" class="form-alert" role="alert">{{ formError }}</p>
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
```css
|
|
59
|
-
.form-alert {
|
|
60
|
-
margin: 0 0 var(--m-space-4);
|
|
61
|
-
padding: var(--m-space-3) var(--m-space-4);
|
|
62
|
-
border: 1px solid color-mix(in srgb, var(--m-color-danger) 40%, var(--m-color-border));
|
|
63
|
-
border-radius: var(--m-radius-md);
|
|
64
|
-
background: color-mix(in srgb, var(--m-color-danger) 10%, var(--m-color-surface));
|
|
65
|
-
color: var(--m-color-danger);
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
1
|
+
# Message / Toast / MMessage
|
|
2
|
+
|
|
3
|
+
**Default rule:** operation feedback uses the `message` API. Use `toast` only when you need a title plus detail, or an async / background notification feel.
|
|
4
|
+
|
|
5
|
+
Authoritative selection + key API notes also live in MCP / skill decision **`feedback-choice`** ([decision-recipes.md](./decision-recipes.md)). Keep this file and that decision aligned.
|
|
6
|
+
|
|
7
|
+
## Three different things
|
|
8
|
+
|
|
9
|
+
| Name | Shape | API | Typical use |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| Message service | Top-centered one-liner | `message.success('已保存')` | Most CRUD results |
|
|
12
|
+
| Toast service | Corner notice with `summary` + optional `detail` | `toast.success({ summary, detail })` | Extra explanation, job results |
|
|
13
|
+
| `MMessage` | Optional host for the `message` service | `<MMessage />` | Custom `appendTo` / placement only. Not an inline alert |
|
|
14
|
+
|
|
15
|
+
## Decision tree
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Need immediate feedback after a user action?
|
|
19
|
+
├─ No → maybe confirm dialog or field errorMessage only
|
|
20
|
+
└─ Yes → must the error stay in the form until fixed?
|
|
21
|
+
├─ Yes → field invalid / errorMessage; form-level token alert (see login-page)
|
|
22
|
+
└─ No → only one short line (no separate detail)?
|
|
23
|
+
├─ Yes → message.* ← default
|
|
24
|
+
└─ No → summary + detail / async feel → toast.*
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Prefer `message`
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { message } from 'morya-ui'
|
|
31
|
+
|
|
32
|
+
message.success('已创建')
|
|
33
|
+
message.info('已移入回收站')
|
|
34
|
+
message.error('操作失败')
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Prefer `toast`
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { toast } from 'morya-ui'
|
|
41
|
+
|
|
42
|
+
toast.success({
|
|
43
|
+
summary: '导入完成',
|
|
44
|
+
detail: '成功 128 条,失败 2 条',
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Prefer `<MMessage>` / form-level errors
|
|
49
|
+
|
|
50
|
+
- Field validation: component `invalid` / `errorMessage` (preferred).
|
|
51
|
+
- Form-level persistent errors (login/auth): token-styled `role="alert"` bar as in MCP `get_golden_page` `login-page`.
|
|
52
|
+
- Note: `<MMessage>` today is primarily the **message service host** (`messages` / teleport). Do not invent a `severity` + default-slot Alert API unless docs add it.
|
|
53
|
+
|
|
54
|
+
```vue
|
|
55
|
+
<p v-if="formError" class="form-alert" role="alert">{{ formError }}</p>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```css
|
|
59
|
+
.form-alert {
|
|
60
|
+
margin: 0 0 var(--m-space-4);
|
|
61
|
+
padding: var(--m-space-3) var(--m-space-4);
|
|
62
|
+
border: 1px solid color-mix(in srgb, var(--m-color-danger) 40%, var(--m-color-border));
|
|
63
|
+
border-radius: var(--m-radius-md);
|
|
64
|
+
background: color-mix(in srgb, var(--m-color-danger) 10%, var(--m-color-surface));
|
|
65
|
+
color: var(--m-color-danger);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
# Optional companions (craft bridge)
|
|
2
|
-
|
|
3
|
-
`morya-ui-pages` is **standalone**: contract + page snippets / decision recipes + block-order checklists + [visual-craft.md](visual-craft.md) + [style-presets.md](style-presets.md) are enough. Golden pages are optional structure demos. **No named style-preset catalog.**
|
|
4
|
-
|
|
5
|
-
Installed market skills are **soft upgrades** — never replace `M*` / `--m-*` / page-layout block order / MCP / the **user’s** style direction.
|
|
6
|
-
|
|
7
|
-
## Conflict rule (hard)
|
|
8
|
-
|
|
9
|
-
**morya-ui-pages + DESIGN.md + MCP win.**
|
|
10
|
-
|
|
11
|
-
Forbidden from any companion:
|
|
12
|
-
|
|
13
|
-
- Second UI kit
|
|
14
|
-
- Invented `M*` props or hex soup
|
|
15
|
-
- Replacing Ops block-order shell with a marketing hero
|
|
16
|
-
- Custom ARIA widgets replacing library overlays
|
|
17
|
-
- **Unearned AI atmosphere** the user did not ask for (aurora, cream-serif-terracotta, dual neon, frosted glass, neumorph on dense tables)
|
|
18
|
-
- Overriding an explicit user reference or description
|
|
19
|
-
|
|
20
|
-
## When to load
|
|
21
|
-
|
|
22
|
-
| Need | Prefer companion | Else |
|
|
23
|
-
| --- | --- | --- |
|
|
24
|
-
| Express / brand POV | `frontend-design` | visual-craft design plan |
|
|
25
|
-
| Named polish / audit / bolder / quieter | `impeccable` | visual-craft polish modes |
|
|
26
|
-
| Mood keywords | `ui-ux-pro-max` (search only) | infer from prompt → `--m-*` |
|
|
27
|
-
| a11y | `fixing-accessibility` | review-checklist |
|
|
28
|
-
| Routine Ops | **none** | Ops polish + resolved direction |
|
|
29
|
-
|
|
30
|
-
Load budget: max one visual companion; a11y may follow. If absent, do not ask to install mid-task.
|
|
31
|
-
|
|
32
|
-
## Frontend Design bridge
|
|
33
|
-
|
|
34
|
-
1. Ground subject / audience / job.
|
|
35
|
-
2. Resolve style direction first ([style-presets.md](style-presets.md)).
|
|
36
|
-
3. Short design plan; signature fits the **user’s** words.
|
|
37
|
-
4. Strip AI-default faces unless the user asked.
|
|
38
|
-
5. Remediate with `M*` + `--m-*`; flat shells by default.
|
|
39
|
-
|
|
40
|
-
## Impeccable bridge
|
|
41
|
-
|
|
42
|
-
| User intent | Pass | Constraint |
|
|
43
|
-
| --- | --- | --- |
|
|
44
|
-
| 太平 / 大胆一点 | `bolder` | One signature inside current direction; ask before changing the whole face |
|
|
45
|
-
| 太花 / 太像 AI | `quieter` | Strip unearned gradients / glow / glass |
|
|
46
|
-
| 提交前 | `polish` | Ops polish + direction + a11y basics |
|
|
47
|
-
| 文案 | `clarify` | Domain verbs |
|
|
48
|
-
| 微交互 | `delight` | 1–2 moments; `useMotion` |
|
|
49
|
-
|
|
50
|
-
**Brief wins.**
|
|
51
|
-
|
|
52
|
-
## Combined workflow
|
|
53
|
-
|
|
54
|
-
```text
|
|
55
|
-
1. Style direction → user reference/description → cues → ask if uncertain
|
|
56
|
-
2. Compose → recommend_page.suggestedSnippets / get_page_snippet + recommend_component
|
|
57
|
-
3. Optional structure → get_golden_page only for whole-page block-order check
|
|
58
|
-
4. Contract → get_component / validate_usage
|
|
59
|
-
5. Craft → visual-craft (flat shells by default)
|
|
60
|
-
6. Companion (opt.) → deepen inside the resolved direction
|
|
61
|
-
7. Gate → validate_usage + validate_page
|
|
62
|
-
```
|
|
1
|
+
# Optional companions (craft bridge)
|
|
2
|
+
|
|
3
|
+
`morya-ui-pages` is **standalone**: contract + page snippets / decision recipes + block-order checklists + [visual-craft.md](visual-craft.md) + [style-presets.md](style-presets.md) are enough. Golden pages are optional structure demos. **No named style-preset catalog.**
|
|
4
|
+
|
|
5
|
+
Installed market skills are **soft upgrades** — never replace `M*` / `--m-*` / page-layout block order / MCP / the **user’s** style direction.
|
|
6
|
+
|
|
7
|
+
## Conflict rule (hard)
|
|
8
|
+
|
|
9
|
+
**morya-ui-pages + DESIGN.md + MCP win.**
|
|
10
|
+
|
|
11
|
+
Forbidden from any companion:
|
|
12
|
+
|
|
13
|
+
- Second UI kit
|
|
14
|
+
- Invented `M*` props or hex soup
|
|
15
|
+
- Replacing Ops block-order shell with a marketing hero
|
|
16
|
+
- Custom ARIA widgets replacing library overlays
|
|
17
|
+
- **Unearned AI atmosphere** the user did not ask for (aurora, cream-serif-terracotta, dual neon, frosted glass, neumorph on dense tables)
|
|
18
|
+
- Overriding an explicit user reference or description
|
|
19
|
+
|
|
20
|
+
## When to load
|
|
21
|
+
|
|
22
|
+
| Need | Prefer companion | Else |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| Express / brand POV | `frontend-design` | visual-craft design plan |
|
|
25
|
+
| Named polish / audit / bolder / quieter | `impeccable` | visual-craft polish modes |
|
|
26
|
+
| Mood keywords | `ui-ux-pro-max` (search only) | infer from prompt → `--m-*` |
|
|
27
|
+
| a11y | `fixing-accessibility` | review-checklist |
|
|
28
|
+
| Routine Ops | **none** | Ops polish + resolved direction |
|
|
29
|
+
|
|
30
|
+
Load budget: max one visual companion; a11y may follow. If absent, do not ask to install mid-task.
|
|
31
|
+
|
|
32
|
+
## Frontend Design bridge
|
|
33
|
+
|
|
34
|
+
1. Ground subject / audience / job.
|
|
35
|
+
2. Resolve style direction first ([style-presets.md](style-presets.md)).
|
|
36
|
+
3. Short design plan; signature fits the **user’s** words.
|
|
37
|
+
4. Strip AI-default faces unless the user asked.
|
|
38
|
+
5. Remediate with `M*` + `--m-*`; flat shells by default.
|
|
39
|
+
|
|
40
|
+
## Impeccable bridge
|
|
41
|
+
|
|
42
|
+
| User intent | Pass | Constraint |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| 太平 / 大胆一点 | `bolder` | One signature inside current direction; ask before changing the whole face |
|
|
45
|
+
| 太花 / 太像 AI | `quieter` | Strip unearned gradients / glow / glass |
|
|
46
|
+
| 提交前 | `polish` | Ops polish + direction + a11y basics |
|
|
47
|
+
| 文案 | `clarify` | Domain verbs |
|
|
48
|
+
| 微交互 | `delight` | 1–2 moments; `useMotion` |
|
|
49
|
+
|
|
50
|
+
**Brief wins.**
|
|
51
|
+
|
|
52
|
+
## Combined workflow
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
1. Style direction → user reference/description → cues → ask if uncertain
|
|
56
|
+
2. Compose → recommend_page.suggestedSnippets / get_page_snippet + recommend_component
|
|
57
|
+
3. Optional structure → get_golden_page only for whole-page block-order check
|
|
58
|
+
4. Contract → get_component / validate_usage
|
|
59
|
+
5. Craft → visual-craft (flat shells by default)
|
|
60
|
+
6. Companion (opt.) → deepen inside the resolved direction
|
|
61
|
+
7. Gate → validate_usage + validate_page
|
|
62
|
+
```
|
|
@@ -1,133 +1,133 @@
|
|
|
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
|
+
# 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.
|