@morya-ui/setup 0.2.6 → 0.2.8

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/README.md +23 -10
  2. package/package.json +1 -1
  3. package/src/cli.mjs +90 -32
  4. package/src/copy-template.mjs +18 -2
  5. package/src/fs-utils.mjs +2 -1
  6. package/src/styles.mjs +2 -87
  7. package/template/.agents/skills/morya-ui-pages/SKILL.md +1 -3
  8. package/template/.agents/skills/morya-ui-pages/references/component-index.md +7 -1
  9. package/template/.agents/skills/morya-ui-pages/references/design-system.md +1 -1
  10. package/template/.agents/skills/morya-ui-pages/references/feedback.md +1 -1
  11. package/template/.agents/skills/morya-ui-pages/references/page-layouts.md +10 -10
  12. package/template/.agents/skills/morya-ui-pages/references/surfaces.md +3 -3
  13. package/template/.cursor/rules/component-usage.mdc +2 -2
  14. package/template/.cursor/rules/design-system.mdc +5 -5
  15. package/template/.cursor/rules/page-layout.mdc +7 -9
  16. package/template/DESIGN.md +15 -15
  17. package/template/design-tokens/tokens.css +0 -55
  18. package/template/design-tokens/tokens.json +0 -77
  19. package/template/docs/components.md +0 -145
  20. package/template/docs/feedback-message-vs-toast.md +0 -103
  21. package/template/docs/golden-pages/dashboard-page.vue +0 -103
  22. package/template/docs/golden-pages/empty-state.vue +0 -66
  23. package/template/docs/golden-pages/form-page.vue +0 -107
  24. package/template/docs/golden-pages/landing-page.vue +0 -328
  25. package/template/docs/golden-pages/list-page.vue +0 -138
  26. package/template/docs/golden-pages/login-page.vue +0 -191
  27. package/template/src/examples/DashboardPageExample.vue +0 -103
  28. package/template/src/examples/EmptyStateExample.vue +0 -66
  29. package/template/src/examples/FormPageExample.vue +0 -107
  30. package/template/src/examples/LandingPageExample.vue +0 -328
  31. package/template/src/examples/ListPageExample.vue +0 -138
  32. package/template/src/examples/LoginPageExample.vue +0 -191
  33. package/template/src/styles/morya-app-shell.css +0 -6
@@ -7,14 +7,14 @@ alwaysApply: false
7
7
 
8
8
  生成完整页面时,先确定类型并 **复制黄金样例结构**:
9
9
 
10
- | 类型 | 模板 |
10
+ | 类型 | MCP `get_golden_page` |
11
11
  | --- | --- |
12
- | 列表页 | `docs/golden-pages/list-page.vue` |
13
- | 表单页 | `docs/golden-pages/form-page.vue`(仅长表单 / 独立配置页) |
14
- | 仪表盘 | `docs/golden-pages/dashboard-page.vue` |
15
- | 登录页 | `docs/golden-pages/login-page.vue` |
16
- | 营销落地 | `docs/golden-pages/landing-page.vue` |
17
- | 空状态 | `docs/golden-pages/empty-state.vue` |
12
+ | 列表页 | `list-page` |
13
+ | 表单页 | `form-page`(仅长表单 / 独立配置页) |
14
+ | 仪表盘 | `dashboard-page` |
15
+ | 登录页 | `login-page` |
16
+ | 营销落地 | `landing-page` |
17
+ | 空状态 | `empty-state` |
18
18
 
19
19
  ## 列表内新建 / 编辑(默认)
20
20
 
@@ -69,5 +69,3 @@ alwaysApply: false
69
69
  - 整页:`recommend_page` → `get_golden_page` → `get_design_rules`
70
70
  - 局部:`get_page_snippet`(如 `filters` / `toolbar` / `form-actions` / `scrollable-panel`)
71
71
  - 可选:`validate_page`(参考建议,不阻断)
72
-
73
- 引用可运行示例:`src/examples/*PageExample.vue`
@@ -1,6 +1,6 @@
1
1
  # Morya UI 设计系统(AI 第一信源)
2
2
 
3
- > 基于 `morya-ui` v0.1.x。生成或审查业务页面时,**必须先遵守本文**,再查阅 `docs/components.md` 与 `docs/golden-pages/`。
3
+ > 基于 `morya-ui` v0.2.6。生成或审查业务页面时,**必须先遵守本文**。样例用 MCP `get_golden_page`,组件 API 用 MCP,反馈选型见 `morya-ui-pages` skill 的 `references/feedback.md`。
4
4
 
5
5
  ## 1. 设计原则
6
6
 
@@ -49,14 +49,14 @@ import 'morya-ui/styles.css'
49
49
 
50
50
  ## 3. 页面类型与黄金样例
51
51
 
52
- | 类型 | 参考文件 | 必备区块 |
52
+ | 类型 | MCP `get_golden_page` | 必备区块 |
53
53
  | --- | --- | --- |
54
- | 列表页 | `docs/golden-pages/list-page.vue` | 面包屑、筛选区、工具栏、表格、分页 |
55
- | 表单页 | `docs/golden-pages/form-page.vue` | 面包屑、分组表单、`MForm` / `MFormItem`、提交/取消 |
56
- | 仪表盘 | `docs/golden-pages/dashboard-page.vue` | 统计卡片栅格、图表区占位、快捷入口 / 最近列表 |
57
- | 登录页 | `docs/golden-pages/login-page.vue` | 品牌区 + `MForm` / `MInputPassword`;表单级错误用 token 告警条 |
58
- | 营销落地 | `docs/golden-pages/landing-page.vue` | 单任务首屏、分节、`MButton` / `MTag` / `MAccordion` |
59
- | 空状态 | `docs/golden-pages/empty-state.vue` | `MEmpty` + 说明 + 主 CTA;可嵌列表 `#empty` |
54
+ | 列表页 | `list-page` | 面包屑、筛选区、工具栏、表格、分页 |
55
+ | 表单页 | `form-page` | 面包屑、分组表单、`MForm` / `MFormItem`、提交/取消 |
56
+ | 仪表盘 | `dashboard-page` | 统计卡片栅格、图表区占位、快捷入口 / 最近列表 |
57
+ | 登录页 | `login-page` | 品牌区 + `MForm` / `MInputPassword`;表单级错误用 token 告警条 |
58
+ | 营销落地 | `landing-page` | 单任务首屏、分节、`MButton` / `MTag` / `MAccordion` |
59
+ | 空状态 | `empty-state` | `MEmpty` + 说明 + 主 CTA;可嵌列表 `#empty` |
60
60
 
61
61
  生成 **Ops** 页面时:结构对齐对应黄金样例,用 `MPage*` 拼装,尽量少写 scoped CSS。
62
62
  生成 **Account / Express / Flow** 页面时:对齐上表样例;允许有节制的 scoped 布局,但颜色/间距仍用 `--m-*`。
@@ -65,7 +65,7 @@ import 'morya-ui/styles.css'
65
65
 
66
66
  - 使用 `MForm` + `MFormItem`,`name` 与校验规则对应。
67
67
  - **从列表新建/编辑(字段约 ≤8、单段表单)默认用 `MDialog` + `MForm`,不要为每个实体再开独立路由表单页。**
68
- - 多分组、长流程、向导式录入再用独立表单页(`docs/golden-pages/form-page.vue`)或 `MDrawer`。
68
+ - 多分组、长流程、向导式录入再用独立表单页(MCP `get_golden_page` `form-page`)或 `MDrawer`。
69
69
  - 字段组件自带 `label` / `invalid` / `helpText` 时优先用组件 prop(如 `MInput`、`MSelect`),复杂表单再用 `MFormItem` 包一层。
70
70
  - 尺寸:默认 medium;密集后台可 `size="small"` 或 ConfigProvider `globalDensity`。
71
71
  - 宽度:筛选项 `fluid` 慎用;独立表单页主栏 `max-width: 40rem` 左右。
@@ -88,11 +88,11 @@ import 'morya-ui/styles.css'
88
88
  | 表单区常驻错误 | token 告警条 / 字段 `errorMessage` |
89
89
  | 字段说明 | `MTooltip` |
90
90
 
91
- **选型细则见 [`docs/feedback-message-vs-toast.md`](docs/feedback-message-vs-toast.md)。AI 生成代码时:无 `detail` 的操作回执一律用 `message`,不要默认 Toast。**
91
+ **选型细则见 `morya-ui-pages` skill 的 `references/feedback.md`。AI 生成代码时:无 `detail` 的操作回执一律用 `message`,不要默认 Toast。**
92
92
 
93
93
  ## 7. 设计令牌(摘要)
94
94
 
95
- 完整定义见 `design-tokens/tokens.json`。
95
+ 完整定义见 MCP `get_design_rules`。运行时以 `morya-ui/styles.css` 为准。
96
96
 
97
97
  | 用途 | 变量 |
98
98
  | --- | --- |
@@ -108,7 +108,7 @@ import 'morya-ui/styles.css'
108
108
 
109
109
  ## 8. 禁止项
110
110
 
111
- - 禁止引入第二套 UI 库(Element Plus、Naive UI 等)混用同一页面。
111
+ - 禁止引入第二套 UI 库混用同一页面。
112
112
  - 禁止在业务 CSS 中写死主题色;暗色模式必须能随 `[data-theme="dark"]` 生效。
113
113
  - 禁止用 `<div onclick>` 代替 `<button>` / `MButton`。
114
114
  - 禁止 Select 与 Dropdown 混用:选项选择用 `MSelect` / `MTreeSelect`;动作菜单用 `MDropdown`。
@@ -117,11 +117,11 @@ import 'morya-ui/styles.css'
117
117
  ## 9. AI 工作流
118
118
 
119
119
  1. 读本文 → 确定页面类型(列表 / 表单 / 仪表盘)。
120
- 2. 打开对应 `docs/golden-pages/*.vue` 与 `src/examples/*.vue`。
121
- 3. 查 `docs/components.md` 选型。
120
+ 2. 用 MCP `get_golden_page` 读取对应样例。
121
+ 3. 用 MCP `search` / `get_component` / `recommend_component` 选型。
122
122
  4. 不确定 API 时查文档站或 MCP,**不要臆造 prop 名**。
123
123
  5. 完成后运行 `pnpm check:colors`(若已配置)。
124
- 6. 操作反馈见 `docs/feedback-message-vs-toast.md`:**默认 `message`,有 detail 才用 `toast`**。
124
+ 6. 操作反馈见 skill `references/feedback.md`:**默认 `message`,有 detail 才用 `toast`**。
125
125
 
126
126
  ## 10. 相关资源
127
127
 
@@ -1,55 +0,0 @@
1
- /**
2
- * Morya UI design tokens (compiled view for AI / static tooling).
3
- * Runtime source of truth: morya-ui/styles.css
4
- * Do not hand-edit hex values in business code — use --m-* variables.
5
- */
6
- :root {
7
- --m-color-primary: #2563eb;
8
- --m-color-primary-hover: #1d4ed8;
9
- --m-color-surface: #ffffff;
10
- --m-color-text: #0f172a;
11
- --m-color-text-muted: #64748b;
12
- --m-color-border: #e2e8f0;
13
- --m-color-focus-ring: #2563eb;
14
- --m-color-success: #159570;
15
- --m-color-info: #2563eb;
16
- --m-color-warning: #d97706;
17
- --m-color-help: #9333ea;
18
- --m-color-danger: #dc2626;
19
- --m-color-contrast: #0f172a;
20
- --m-color-contrast-fg: #ffffff;
21
- --m-overlay-scrim: rgb(15 23 42 / 0.55);
22
-
23
- --m-control-height-small: 28px;
24
- --m-control-height-medium: 34px;
25
- --m-control-height-large: 40px;
26
- --m-radius-control: 3px;
27
- --m-space-1: 0.25rem;
28
- --m-space-2: 0.5rem;
29
- --m-space-3: 0.75rem;
30
- --m-space-4: 1rem;
31
- --m-space-6: 1.5rem;
32
- --m-space-8: 2rem;
33
- --m-radius-sm: 0.25rem;
34
- --m-radius-md: 0.5rem;
35
- --m-radius-lg: 0.75rem;
36
- --m-shadow-sm: 0 1px 2px rgb(15 23 42 / 0.25);
37
- --m-shadow-md: 0 0.75rem 2rem rgb(15 23 42 / 0.16);
38
- --m-shadow-lg: 0 1rem 3rem rgb(15 23 42 / 0.25);
39
- --m-font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
40
- --m-motion-fast: 150ms;
41
- --m-motion-normal: 250ms;
42
- --m-motion-ease: cubic-bezier(0.2, 0, 0, 1);
43
- --m-z-base: 1000;
44
- }
45
-
46
- [data-theme="dark"] {
47
- --m-color-primary: #60a5fa;
48
- --m-color-primary-hover: #93c5fd;
49
- --m-color-surface: #0f172a;
50
- --m-color-text: #f8fafc;
51
- --m-color-text-muted: #94a3b8;
52
- --m-color-border: #334155;
53
- --m-color-danger: #fca5a5;
54
- --m-overlay-scrim: rgb(2 6 23 / 0.72);
55
- }
@@ -1,77 +0,0 @@
1
- {
2
- "$schema": "https://design-tokens.github.io/community-group/format/",
3
- "meta": {
4
- "name": "morya-ui",
5
- "version": "0.1.1",
6
- "source": "morya-ui/src/theme/styles.css",
7
- "prefix": "m"
8
- },
9
- "color": {
10
- "primary": { "value": "#2563eb", "dark": "#60a5fa" },
11
- "primary-hover": { "value": "#1d4ed8", "dark": "#93c5fd" },
12
- "surface": { "value": "#ffffff", "dark": "#0f172a" },
13
- "text": { "value": "#0f172a", "dark": "#f8fafc" },
14
- "text-muted": { "value": "#64748b", "dark": "#94a3b8" },
15
- "border": { "value": "#e2e8f0", "dark": "#334155" },
16
- "focus-ring": { "value": "#2563eb", "dark": "#93c5fd" },
17
- "success": { "value": "#159570", "dark": "#5eead4" },
18
- "info": { "value": "#2563eb", "dark": "#93c5fd" },
19
- "warning": { "value": "#d97706", "dark": "#fbbf24" },
20
- "help": { "value": "#9333ea", "dark": "#c084fc" },
21
- "danger": { "value": "#dc2626", "dark": "#fca5a5" },
22
- "contrast": { "value": "#0f172a", "dark": "#f8fafc" },
23
- "contrast-fg": { "value": "#ffffff", "dark": "#0f172a" },
24
- "overlay-scrim": { "value": "rgb(15 23 42 / 0.55)", "dark": "rgb(2 6 23 / 0.72)" }
25
- },
26
- "control": {
27
- "height": { "small": "28px", "medium": "34px", "large": "40px" },
28
- "font": { "small": "14px", "medium": "14px", "large": "15px" },
29
- "padding-x": { "small": "10px", "medium": "12px", "large": "14px" },
30
- "affix-size": "2rem"
31
- },
32
- "space": {
33
- "1": "0.25rem",
34
- "2": "0.5rem",
35
- "3": "0.75rem",
36
- "4": "1rem",
37
- "6": "1.5rem",
38
- "8": "2rem"
39
- },
40
- "radius": {
41
- "control": "3px",
42
- "sm": "0.25rem",
43
- "md": "0.5rem",
44
- "lg": "0.75rem",
45
- "full": "9999px"
46
- },
47
- "shadow": {
48
- "sm": "0 1px 2px rgb(15 23 42 / 0.25)",
49
- "md": "0 0.75rem 2rem rgb(15 23 42 / 0.16)",
50
- "lg": "0 1rem 3rem rgb(15 23 42 / 0.25)"
51
- },
52
- "font": {
53
- "sans": "Inter, ui-sans-serif, system-ui, sans-serif",
54
- "size": { "xs": "0.75rem", "sm": "0.8125rem", "md": "0.875rem", "lg": "1.125rem" }
55
- },
56
- "motion": {
57
- "fast": "150ms",
58
- "normal": "250ms",
59
- "ease": "cubic-bezier(0.2, 0, 0, 1)"
60
- },
61
- "zIndex": {
62
- "base": 1000,
63
- "dropdown": "calc(var(--m-z-base) + 50)",
64
- "toast": "calc(var(--m-z-base) + 100)"
65
- },
66
- "cssVarMap": {
67
- "color.primary": "--m-color-primary",
68
- "color.surface": "--m-color-surface",
69
- "color.text": "--m-color-text",
70
- "color.textMuted": "--m-color-text-muted",
71
- "color.border": "--m-color-border",
72
- "color.danger": "--m-color-danger",
73
- "space.4": "--m-space-4",
74
- "radius.md": "--m-radius-md",
75
- "shadow.md": "--m-shadow-md"
76
- }
77
- }
@@ -1,145 +0,0 @@
1
- # Morya UI 组件清单(AI 选型索引)
2
-
3
- > 完整 API 以文档站 `/components` 或 MCP 为准。下表用于**场景选型**,不是 prop 手册。
4
-
5
- ## 应用壳层
6
-
7
- | 组件 | 用途 |
8
- | --- | --- |
9
- | `MConfigProvider` | 根配置:locale、主题、密度、浮层挂载、组件默认 props |
10
- | `MLayout` / `MLayoutHeader` / `MLayoutSider` / `MLayoutContent` / `MLayoutFooter` | 后台整体布局 |
11
- | `MSidebar` | 独立侧栏容器(非 Layout 子项场景) |
12
- | `MBreadcrumb` | 页面路径 |
13
- | `MToolbar` | 顶栏工具区 |
14
-
15
- ## 表单 · 输入
16
-
17
- | 组件 | 用途 |
18
- | --- | --- |
19
- | `MForm` / `MFormItem` | 表单容器、校验、提交 |
20
- | `MInput` | 单行文本 |
21
- | `MInputPassword` | 密码 |
22
- | `MInputNumber` | 数字 |
23
- | `MTextarea` | 多行文本 |
24
- | `MSelect` | 下拉选择(单选/多选/远程/filter) |
25
- | `MTreeSelect` | 树形选择 |
26
- | `MCascadeSelect` | 级联选择 |
27
- | `MDatePicker` | 日期 / 日期范围 |
28
- | `MAutoComplete` | 自动完成 |
29
- | `MCheckbox` / `MCheckboxGroup` | 多选 |
30
- | `MRadio` / `MRadioGroup` | 单选组 |
31
- | `MSwitch` | 开关 |
32
- | `MSlider` | 滑块 |
33
- | `MRating` | 评分 |
34
- | `MInputTags` | 标签输入 |
35
- | `MFileUpload` | 文件上传 |
36
- | `MFloatLabel` | 浮动标签包装 |
37
- | `MIconField` | 输入框前缀/后缀图标 |
38
-
39
- ## 表单 · 布局
40
-
41
- | 组件 | 用途 |
42
- | --- | --- |
43
- | `MGrid` / `MGridItem` | 响应式栅格 |
44
- | `MFlex` | Flex 布局 |
45
- | `MSpace` | 间距 |
46
- | `MFluid` | 子项撑满宽度 |
47
- | `MDivider` | 分隔线 |
48
- | `MFieldset` | 分组fieldset |
49
-
50
- ## 数据展示
51
-
52
- | 组件 | 用途 |
53
- | --- | --- |
54
- | `MTable` | 数据表格 |
55
- | `MTreeTable` | 树形表格 |
56
- | `MDataView` | 卡片/列表数据视图 |
57
- | `MTree` | 树 |
58
- | `MPagination` | 分页 |
59
- | `MStatus` | 行内状态(圆点 + 文案) |
60
- | `MTag` / `MChip` / `MBadge` | 标签、徽章 |
61
- | `MAvatar` / `MAvatarGroup` | 头像 |
62
- | `MTimeline` | 时间线 |
63
- | `MMeterGroup` | 多段进度条 |
64
- | `MVirtualScroller` | 虚拟滚动长列表 |
65
-
66
- ## 反馈
67
-
68
- | API / 组件 | 用途 | 优先级 |
69
- | --- | --- | --- |
70
- | `message` | **默认**:单行操作回执(已保存 / 已删除) | ★ 首选 |
71
- | `toast` | 仅当需要 `summary` + `detail` 或异步通知 | 次要 |
72
- | `<MMessage>` | 表单/认证区**常驻**错误条 | 内嵌场景 |
73
- | `MEmpty` | 无数据 / 首次使用 / 筛选无结果 | 空态 |
74
- | `MResult` | 提交结果、403 / 404 / 500 等阻断页 | 结果页 |
75
- | `MProgressBar` / `MProgressSpinner` | 加载进度 | |
76
- | `MSkeleton` | 骨架屏 | |
77
- | `MBlockUI` | 遮罩阻塞 | |
78
-
79
- 选型细则:[`feedback-message-vs-toast.md`](./feedback-message-vs-toast.md)
80
-
81
- ## 浮层
82
-
83
- | 组件 | 用途 |
84
- | --- | --- |
85
- | `MDialog` | 模态对话框 |
86
- | `MDrawer` | 抽屉 |
87
- | `MConfirmDialog` / `MConfirmPopup` | 二次确认 |
88
- | `MPopover` | 气泡卡片 |
89
- | `MTooltip` | 文字提示 |
90
- | `MDropdown` | **动作**下拉菜单(非表单选项) |
91
-
92
- ## 导航 · 菜单
93
-
94
- | 组件 | 用途 |
95
- | --- | --- |
96
- | `MMenu` / `MMenubar` / `MTieredMenu` / `MMegaMenu` | 菜单 |
97
- | `MTabs` | 标签页 |
98
- | `MStepper` | 步骤条 |
99
- | `MCommandMenu` | 命令面板 |
100
- | `MSplitButton` / `MSelectButton` / `MToggleButton` | 复合按钮 |
101
-
102
- ## 展示 · 媒体
103
-
104
- | 组件 | 用途 |
105
- | --- | --- |
106
- | `MCard` / `MPanel` | 卡片、面板 |
107
- | `MAccordion` | 折叠面板 |
108
- | `MCarousel` / `MGallery` | 轮播、图库 |
109
- | `MIcon` | 图标(Tabler 集) |
110
- | `MScrollbar` | 主题化滚动条;供组件内置滚动壳与业务显式选用;不要塞进用户可定制插槽 |
111
-
112
- ## 场景速查
113
-
114
- | 我要做… | 首选组件 |
115
- | --- | --- |
116
- | 用户列表 + 搜索 + 分页 | `MTable` + `MInput` + `MPagination` |
117
- | 新建/编辑实体(短表单,列表内) | **`MDialog` + `MForm` + 字段组件**(首选) |
118
- | 新建/编辑实体(长表单 / 多分组) | `MForm` + 独立表单页或 `MDrawer` |
119
- | 删除确认 | `MConfirmDialog` |
120
- | 筛选侧栏 | `MDrawer` + 表单控件 |
121
- | 状态指示(行内) | `MStatus`(圆点 + 文案) |
122
- | 状态芯片 / 可关闭标签 | `MTag`(`severity`: success/warn/danger/info) |
123
- | 空数据 / 首次使用 | `MEmpty` |
124
- | 提交结果 / 403 / 404 / 500 | `MResult` |
125
- | 主/次按钮组 | `MSpace` + `MButton`(primary / secondary text) |
126
- | 后台首页 KPI | `MGrid` + `MCard` |
127
- | 组织架构 | `MTree` 或 `MTreeSelect` |
128
- | 整页后台页(MCP 生成) | `MLayout fillViewport`(主滚动内置 `MScrollbar`) |
129
- | 业务局部限高滚动 | 业务自行使用 `MScrollbar`(可选:`get_page_snippet("scrollable-panel")`) |
130
-
131
- ## 页面标准
132
-
133
- MCP `get_design_rules` → `standards` 汇总推荐实践(非强制)。`validate_page` 仅给参考建议。
134
-
135
- ## 常见对照
136
-
137
- | 错误 | 正确 |
138
- | --- | --- |
139
- | 用 `MDropdown` 做表单枚举 | 用 `MSelect` |
140
- | 手写 `<table>` | 用 `MTable` |
141
- | 手写 modal div | 用 `MDialog` |
142
- | `showClear` 与 `clearable` 混用概念 | Select 两者等价;其他组件看文档是否支持 `clearable` |
143
- | 页面壳手写 `overflow: auto` 替代 Layout 内置滚动 | 依赖 `MLayout` 内置滚动;业务局部滚动再显式用 `MScrollbar` |
144
- | `MPage*` 外包 `MCard` 或 padded `div` | 直接使用 `MPage*` 组件自带间距与表面 |
145
- | 嵌套菜单被滚动容器裁剪 | Dropdown / ContextMenu / TieredMenu 侧向子菜单已 Teleport;Menu 水平/折叠飞出层用 Popover |
@@ -1,103 +0,0 @@
1
- # Message / Toast / MMessage 选型指南
2
-
3
- > **AI 默认规则:操作反馈优先用 `message` API;只有需要「标题 + 详情」或异步通知时才用 `toast`。**
4
-
5
- ## 三个不同的东西
6
-
7
- | 名称 | 形态 | API / 组件 | 典型场景 |
8
- | --- | --- | --- | --- |
9
- | **Message 服务** | 顶部居中(可改 placement)单行浮层 | `message.success('已保存')` | **大多数** CRUD / 保存 / 删除回执 |
10
- | **Toast 服务** | 四角通知,带 `summary` + 可选 `detail` | `toast.success({ summary, detail })` | 需要补充说明的通知、后台任务结果 |
11
- | **MMessage 组件** | 页面内嵌条,不自动消失 | `<MMessage severity="error">…</MMessage>` | 表单/认证区**常驻**错误、警告 |
12
-
13
- ## 决策树(按顺序判断)
14
-
15
- ```
16
- 用户操作完成,需要即时反馈?
17
- ├─ 否 → 不需要 Message/Toast(可能用 MConfirmDialog / 字段 errorMessage)
18
- └─ 是 → 错误需留在表单区域直到用户修正?
19
- ├─ 是 → 字段 invalid / errorMessage;表单级用 token 告警条(见 login-page)
20
- └─ 否 → 只有一句短文案(无独立 detail)?
21
- ├─ 是 → message.success / info / warn / error ← 默认选这个
22
- └─ 否 → 有 summary + detail,或异步/后台通知感 → toast.*
23
- ```
24
-
25
- ## 优先用 Message 的场景(占多数)
26
-
27
- - 创建 / 更新 / 删除成功:`message.success('已保存')`
28
- - 移入回收站、批量操作完成(单行概括):`message.info('已移入回收站')`
29
- - 轻量警告(非表单绑定):`message.warn('请先选择记录')`
30
- - 请求失败(单行):`message.error('保存失败,请重试')`
31
- - 复制成功、导入触发等**一句话**反馈
32
-
33
- ```ts
34
- import { message } from 'morya-ui'
35
-
36
- message.success('已创建')
37
- message.info('已移入回收站')
38
- message.error('操作失败')
39
- ```
40
-
41
- ## 应该用 Toast 的场景(较少)
42
-
43
- - **同时**需要标题与补充说明:
44
-
45
- ```ts
46
- toast.success({
47
- summary: '选课申请已提交',
48
- detail: '请等待教务审核',
49
- })
50
- ```
51
-
52
- - 后台任务 / 批量结果含统计明细:
53
-
54
- ```ts
55
- toast.success({
56
- summary: '导入完成',
57
- detail: '成功 128 条,失败 2 条',
58
- })
59
- ```
60
-
61
- - 登录成功且需欢迎语 + 副文案
62
- - 需要角落堆叠、用户可能稍后查看的多条**通知**(非即时操作回执)
63
-
64
- ## 应该用表单区常驻错误的场景
65
-
66
- - 登录 / 注册表单上方的**持久**错误(用户修正前不消失)
67
- - 页面级配置错误、需要与表单同区域的警告条
68
- - **不要**把字段校验错误只丢到 Toast/Message 浮层——优先字段 `errorMessage`
69
-
70
- 字段级:
71
-
72
- ```vue
73
- <MInput v-model="email" invalid :error-message="emailError" />
74
- ```
75
-
76
- 表单级(见 `docs/golden-pages/login-page.vue`):用 `--m-*` 样式的 `role="alert"` 条。
77
- 说明:`<MMessage>` 当前主要是 `message` 服务的挂载宿主,**不要**臆造 `severity` + 默认插槽的 Alert API。
78
-
79
- ```vue
80
- <p v-if="error" class="form-alert" role="alert">{{ error }}</p>
81
- ```
82
- ## 反模式(AI 禁止)
83
-
84
- | 反模式 | 应改为 |
85
- | --- | --- |
86
- | `toast.add({ summary: '已保存' })` 无 detail | `message.success('已保存')` |
87
- | 表单校验失败只弹 Toast | 字段 `errorMessage` 或 `<MMessage>` |
88
- | 删除确认用 Message/Toast | `MConfirmDialog` |
89
- | 所有反馈都用 Toast | 默认改 Message,仅 detail 场景保留 Toast |
90
-
91
- ## 与 Naive / Element Plus 的对应
92
-
93
- | Morya UI | 近似概念 |
94
- | --- | --- |
95
- | `message` | Naive `message` / Element `ElMessage` |
96
- | `toast` | Naive `notification` / Element `ElNotification` |
97
- | `<MMessage>` | 页面内 `el-alert` / 表单顶部错误条 |
98
-
99
- ## 相关文档
100
-
101
- - [Message 组件文档](../../src/components/Message/docs/index.md)
102
- - [Toast 组件文档](../../src/components/Toast/docs/index.md)
103
- - [DESIGN.md §6 浮层与反馈](../DESIGN.md#6-浮层与反馈)
@@ -1,103 +0,0 @@
1
- <script setup lang="ts">
2
- /**
3
- * 黄金样例:仪表盘页
4
- * @see DESIGN.md §3
5
- */
6
- import {
7
- MBreadcrumb,
8
- MCard,
9
- MConfigProvider,
10
- MGrid,
11
- MGridItem,
12
- MLayout,
13
- MLayoutContent,
14
- MLayoutHeader,
15
- MPageContent,
16
- MPageHeader,
17
- MPagePlaceholder,
18
- MPageStat,
19
- MTable,
20
- MTag,
21
- zhCN,
22
- } from 'morya-ui'
23
-
24
- const stats = [
25
- { label: '总用户', value: '12,480', trend: '+8.2%', icon: 'users' },
26
- { label: '今日活跃', value: '1,926', trend: '+3.1%', icon: 'activity' },
27
- { label: '待处理工单', value: '47', trend: '-12%', trendSeverity: 'warn' as const, icon: 'clipboard' },
28
- { label: '系统健康', value: '99.9%', trend: '稳定', trendSeverity: 'secondary' as const, icon: 'heart' },
29
- ]
30
-
31
- const recentColumns = [
32
- { key: 'id', label: '工单号', width: 96 },
33
- { key: 'title', label: '标题' },
34
- { key: 'priority', label: '优先级', width: 96 },
35
- { key: 'status', label: '状态', width: 96 },
36
- ]
37
-
38
- const recentRows = [
39
- { id: 'WO-1024', title: '登录异常反馈', priority: 'high', status: 'open' },
40
- { id: 'WO-1023', title: '导出任务超时', priority: 'medium', status: 'progress' },
41
- { id: 'WO-1022', title: '权限配置咨询', priority: 'low', status: 'done' },
42
- ]
43
-
44
- function prioritySeverity(p: string) {
45
- if (p === 'high') return 'danger'
46
- if (p === 'medium') return 'warn'
47
- return 'secondary'
48
- }
49
-
50
- function statusLabel(s: string) {
51
- if (s === 'open') return '待处理'
52
- if (s === 'progress') return '进行中'
53
- return '已完成'
54
- }
55
- </script>
56
-
57
- <template>
58
- <MConfigProvider :locale="zhCN">
59
- <MLayout fill-viewport>
60
- <MLayoutHeader padding="var(--m-space-4) var(--m-space-6)">
61
- <MBreadcrumb :model="[{ label: '首页' }, { label: '仪表盘' }]" />
62
- </MLayoutHeader>
63
-
64
- <MLayoutContent>
65
- <MPageContent density="spacious">
66
- <MPageHeader title="仪表盘" />
67
-
68
- <MGrid :cols="4" :x-gap="16" :y-gap="16" responsive="screen">
69
- <MGridItem v-for="item in stats" :key="item.label" :span="1">
70
- <MPageStat
71
- :label="item.label"
72
- :value="item.value"
73
- :trend="item.trend"
74
- :trend-severity="item.trendSeverity ?? 'primary'"
75
- :icon="item.icon"
76
- />
77
- </MGridItem>
78
- </MGrid>
79
-
80
- <MGrid :cols="2" :x-gap="16" :y-gap="16">
81
- <MGridItem :span="1">
82
- <MCard title="趋势概览">
83
- <MPagePlaceholder aria-label="图表占位" description="图表区域(接入 ECharts / 业务组件)" />
84
- </MCard>
85
- </MGridItem>
86
- <MGridItem :span="1">
87
- <MCard title="最近工单">
88
- <MTable :columns="recentColumns" :rows="recentRows" size="small" :paginator="false" bordered>
89
- <template #cell-priority="{ value }">
90
- <MTag :value="String(value)" :severity="prioritySeverity(String(value))" />
91
- </template>
92
- <template #cell-status="{ value }">
93
- <MTag :value="statusLabel(String(value))" severity="info" />
94
- </template>
95
- </MTable>
96
- </MCard>
97
- </MGridItem>
98
- </MGrid>
99
- </MPageContent>
100
- </MLayoutContent>
101
- </MLayout>
102
- </MConfigProvider>
103
- </template>
@@ -1,66 +0,0 @@
1
- <script setup lang="ts">
2
- /**
3
- * 黄金样例:列表空状态(Flow)
4
- * @see DESIGN.md §3 · morya-ui-pages surfaces § Flow
5
- * 可嵌在列表页 MPageContent / MTable #empty 中;此处给出完整可运行骨架。
6
- */
7
- import {
8
- MBreadcrumb,
9
- MButton,
10
- MConfigProvider,
11
- MEmpty,
12
- MLayout,
13
- MLayoutContent,
14
- MLayoutHeader,
15
- MPageContent,
16
- MPageToolbar,
17
- zhCN,
18
- } from 'morya-ui'
19
- </script>
20
-
21
- <template>
22
- <MConfigProvider :locale="zhCN">
23
- <MLayout fill-viewport>
24
- <MLayoutHeader padding="var(--m-space-4) var(--m-space-6)">
25
- <MBreadcrumb :model="[{ label: '首页', to: '/' }, { label: '课程' }]" />
26
- </MLayoutHeader>
27
-
28
- <MLayoutContent>
29
- <MPageContent>
30
- <MPageToolbar title="课程">
31
- <template #actions>
32
- <MButton label="新建课程" />
33
- </template>
34
- </MPageToolbar>
35
-
36
- <div class="empty-state-shell">
37
- <MEmpty
38
- title="还没有课程"
39
- description="创建第一门课程后,学员就能在目录里看到它。也可以稍后从模板导入。"
40
- icon="book"
41
- >
42
- <template #extra>
43
- <MButton label="创建第一门课程" />
44
- <MButton label="从模板导入" severity="secondary" text />
45
- </template>
46
- </MEmpty>
47
- </div>
48
- </MPageContent>
49
- </MLayoutContent>
50
- </MLayout>
51
- </MConfigProvider>
52
- </template>
53
-
54
- <style scoped>
55
- .empty-state-shell {
56
- border: 1px dashed color-mix(in srgb, var(--m-color-border) 80%, var(--m-color-primary));
57
- border-radius: var(--m-radius-md);
58
- background:
59
- radial-gradient(
60
- 120% 80% at 50% 0%,
61
- color-mix(in srgb, var(--m-color-primary) 10%, transparent),
62
- transparent 55%
63
- ),
64
- var(--m-color-surface);
65
- }
66
- </style>