@morya-ui/mcp 0.4.4 → 0.4.5

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.
@@ -1,244 +1,244 @@
1
- <script setup lang="ts">
2
- /**
3
- * 黄金样例:登录页(Account + 轻量品牌)
4
- * @see DESIGN.md · surfaces § Account · visual-craft § Atmosphere
5
- */
6
- import {
7
- MButton,
8
- MConfigProvider,
9
- MForm,
10
- MFormItem,
11
- MInput,
12
- MInputPassword,
13
- MParagraph,
14
- MSpace,
15
- MTitle,
16
- zhCN,
17
- } from 'morya-ui'
18
- import { reactive, ref } from 'vue'
19
-
20
- const submitting = ref(false)
21
- const formError = ref('')
22
-
23
- const model = reactive({
24
- email: '',
25
- password: '',
26
- })
27
-
28
- /** Brand seed for Account surfaces — prefer themeConfig over page-level hex. */
29
- const themeConfig = {
30
- seed: { colorPrimary: '#0b6e4f' },
31
- }
32
-
33
- async function onSubmit() {
34
- formError.value = ''
35
- submitting.value = true
36
- try {
37
- // await api.login(model)
38
- if (!model.email || !model.password) {
39
- formError.value = '请输入邮箱和密码后再试。'
40
- return
41
- }
42
- } finally {
43
- submitting.value = false
44
- }
45
- }
46
- </script>
47
-
48
- <template>
49
- <MConfigProvider
50
- :locale="zhCN"
51
- input-variant="filled"
52
- :theme-config="themeConfig"
53
- >
54
- <div class="login-shell">
55
- <aside class="login-brand" aria-label="品牌">
56
- <p class="login-brand__mark">青禾书房</p>
57
- <h1 class="login-brand__title">把好书留在手边</h1>
58
- <p class="login-brand__lead">
59
- 店员与会员共用同一套账户。登录后继续进货、上架与会员服务。
60
- </p>
61
- </aside>
62
-
63
- <main class="login-main">
64
- <div class="login-panel">
65
- <header class="login-panel__header">
66
- <MTitle :level="3">
67
- 登录
68
- </MTitle>
69
- <MParagraph type="secondary">
70
- 使用工作邮箱进入后台。
71
- </MParagraph>
72
- </header>
73
-
74
- <p v-if="formError" class="login-alert" role="alert">
75
- {{ formError }}
76
- </p>
77
-
78
- <MForm @submit="onSubmit">
79
- <MFormItem label="邮箱" name="email" required>
80
- <MInput
81
- v-model="model.email"
82
- type="email"
83
- placeholder="name@qinghe.example"
84
- autocomplete="username"
85
- fluid
86
- />
87
- </MFormItem>
88
-
89
- <MFormItem label="密码" name="password" required>
90
- <MInputPassword
91
- v-model="model.password"
92
- placeholder="请输入密码"
93
- autocomplete="current-password"
94
- fluid
95
- />
96
- </MFormItem>
97
-
98
- <MSpace style="margin-top: var(--m-space-2)" alignment="center">
99
- <MButton type="primary" html-type="submit" label="登录" :loading="submitting" />
100
- <MButton type="text" label="忘记密码" />
101
- </MSpace>
102
- </MForm>
103
- </div>
104
- </main>
105
- </div>
106
- </MConfigProvider>
107
- </template>
108
-
109
- <style scoped>
110
- .login-shell {
111
- display: grid;
112
- grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
113
- min-height: 100vh;
114
- background: var(--m-color-surface);
115
- color: var(--m-color-text);
116
- }
117
-
118
- .login-brand {
119
- position: relative;
120
- display: flex;
121
- flex-direction: column;
122
- justify-content: flex-end;
123
- gap: var(--m-space-4);
124
- padding: clamp(2rem, 6vw, 4.5rem);
125
- overflow: hidden;
126
- background:
127
- radial-gradient(
128
- 80% 60% at 10% 20%,
129
- color-mix(in srgb, var(--m-color-primary) 22%, transparent),
130
- transparent 55%
131
- ),
132
- linear-gradient(
133
- 165deg,
134
- color-mix(in srgb, var(--m-color-primary) 16%, var(--m-color-surface)) 0%,
135
- var(--m-color-surface) 55%,
136
- color-mix(in srgb, var(--m-color-border) 35%, var(--m-color-surface)) 100%
137
- );
138
- border-right: 1px solid var(--m-color-border);
139
- }
140
-
141
- .login-brand::after {
142
- content: '';
143
- position: absolute;
144
- inset: auto -10% -20% 40%;
145
- height: 55%;
146
- border-radius: 50%;
147
- background: color-mix(in srgb, var(--m-color-primary) 12%, transparent);
148
- pointer-events: none;
149
- }
150
-
151
- .login-brand__mark,
152
- .login-brand__title,
153
- .login-brand__lead {
154
- position: relative;
155
- z-index: 1;
156
- }
157
-
158
- .login-brand__mark {
159
- margin: 0;
160
- font-size: 0.8125rem;
161
- letter-spacing: 0.14em;
162
- text-transform: uppercase;
163
- color: var(--m-color-text-muted);
164
- }
165
-
166
- .login-brand__title {
167
- margin: 0;
168
- max-width: 12em;
169
- font-size: clamp(2rem, 4vw, 3rem);
170
- font-weight: 650;
171
- line-height: 1.15;
172
- letter-spacing: -0.03em;
173
- }
174
-
175
- .login-brand__lead {
176
- margin: 0;
177
- max-width: 28rem;
178
- color: var(--m-color-text-muted);
179
- line-height: 1.6;
180
- }
181
-
182
- .login-main {
183
- display: grid;
184
- place-items: center;
185
- padding: var(--m-space-6);
186
- }
187
-
188
- .login-panel {
189
- width: min(100%, 22rem);
190
- }
191
-
192
- .login-panel__header {
193
- margin-bottom: var(--m-space-5);
194
- }
195
-
196
- .login-panel__header :deep(.m-typography-title),
197
- .login-panel__header :deep(.m-typography) {
198
- margin: 0;
199
- }
200
-
201
- .login-panel__header :deep(.m-typography-title) {
202
- margin-bottom: var(--m-space-2);
203
- }
204
-
205
- .login-alert {
206
- margin: 0 0 var(--m-space-4);
207
- padding: var(--m-space-3) var(--m-space-4);
208
- border: 1px solid color-mix(in srgb, var(--m-color-danger) 40%, var(--m-color-border));
209
- border-radius: var(--m-radius-md);
210
- background: color-mix(in srgb, var(--m-color-danger) 10%, var(--m-color-surface));
211
- color: var(--m-color-danger);
212
- font-size: 0.875rem;
213
- line-height: 1.45;
214
- }
215
-
216
- @media (prefers-reduced-motion: no-preference) {
217
- .login-panel {
218
- animation: login-panel-in 420ms ease both;
219
- }
220
- }
221
-
222
- @keyframes login-panel-in {
223
- from {
224
- opacity: 0;
225
- transform: translateY(0.5rem);
226
- }
227
- to {
228
- opacity: 1;
229
- transform: translateY(0);
230
- }
231
- }
232
-
233
- @media (max-width: 768px) {
234
- .login-shell {
235
- grid-template-columns: 1fr;
236
- }
237
-
238
- .login-brand {
239
- border-right: 0;
240
- border-bottom: 1px solid var(--m-color-border);
241
- min-height: 12rem;
242
- }
243
- }
244
- </style>
1
+ <script setup lang="ts">
2
+ /**
3
+ * 黄金样例:登录页(Account + 轻量品牌)
4
+ * @see DESIGN.md · surfaces § Account · visual-craft § Atmosphere
5
+ */
6
+ import {
7
+ MButton,
8
+ MConfigProvider,
9
+ MForm,
10
+ MFormItem,
11
+ MInput,
12
+ MInputPassword,
13
+ MParagraph,
14
+ MSpace,
15
+ MTitle,
16
+ zhCN,
17
+ } from 'morya-ui'
18
+ import { reactive, ref } from 'vue'
19
+
20
+ const submitting = ref(false)
21
+ const formError = ref('')
22
+
23
+ const model = reactive({
24
+ email: '',
25
+ password: '',
26
+ })
27
+
28
+ /** Brand seed for Account surfaces — prefer themeConfig over page-level hex. */
29
+ const themeConfig = {
30
+ seed: { colorPrimary: '#0b6e4f' },
31
+ }
32
+
33
+ async function onSubmit() {
34
+ formError.value = ''
35
+ submitting.value = true
36
+ try {
37
+ // await api.login(model)
38
+ if (!model.email || !model.password) {
39
+ formError.value = '请输入邮箱和密码后再试。'
40
+ return
41
+ }
42
+ } finally {
43
+ submitting.value = false
44
+ }
45
+ }
46
+ </script>
47
+
48
+ <template>
49
+ <MConfigProvider
50
+ :locale="zhCN"
51
+ input-variant="filled"
52
+ :theme-config="themeConfig"
53
+ >
54
+ <div class="login-shell">
55
+ <aside class="login-brand" aria-label="品牌">
56
+ <p class="login-brand__mark">青禾书房</p>
57
+ <h1 class="login-brand__title">把好书留在手边</h1>
58
+ <p class="login-brand__lead">
59
+ 店员与会员共用同一套账户。登录后继续进货、上架与会员服务。
60
+ </p>
61
+ </aside>
62
+
63
+ <main class="login-main">
64
+ <div class="login-panel">
65
+ <header class="login-panel__header">
66
+ <MTitle :level="3">
67
+ 登录
68
+ </MTitle>
69
+ <MParagraph type="secondary">
70
+ 使用工作邮箱进入后台。
71
+ </MParagraph>
72
+ </header>
73
+
74
+ <p v-if="formError" class="login-alert" role="alert">
75
+ {{ formError }}
76
+ </p>
77
+
78
+ <MForm @submit="onSubmit">
79
+ <MFormItem label="邮箱" name="email" required>
80
+ <MInput
81
+ v-model="model.email"
82
+ type="email"
83
+ placeholder="name@qinghe.example"
84
+ autocomplete="username"
85
+ fluid
86
+ />
87
+ </MFormItem>
88
+
89
+ <MFormItem label="密码" name="password" required>
90
+ <MInputPassword
91
+ v-model="model.password"
92
+ placeholder="请输入密码"
93
+ autocomplete="current-password"
94
+ fluid
95
+ />
96
+ </MFormItem>
97
+
98
+ <MSpace style="margin-top: var(--m-space-2)" alignment="center">
99
+ <MButton type="primary" html-type="submit" label="登录" :loading="submitting" />
100
+ <MButton type="text" label="忘记密码" />
101
+ </MSpace>
102
+ </MForm>
103
+ </div>
104
+ </main>
105
+ </div>
106
+ </MConfigProvider>
107
+ </template>
108
+
109
+ <style scoped>
110
+ .login-shell {
111
+ display: grid;
112
+ grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
113
+ min-height: 100vh;
114
+ background: var(--m-color-surface);
115
+ color: var(--m-color-text);
116
+ }
117
+
118
+ .login-brand {
119
+ position: relative;
120
+ display: flex;
121
+ flex-direction: column;
122
+ justify-content: flex-end;
123
+ gap: var(--m-space-4);
124
+ padding: clamp(2rem, 6vw, 4.5rem);
125
+ overflow: hidden;
126
+ background:
127
+ radial-gradient(
128
+ 80% 60% at 10% 20%,
129
+ color-mix(in srgb, var(--m-color-primary) 22%, transparent),
130
+ transparent 55%
131
+ ),
132
+ linear-gradient(
133
+ 165deg,
134
+ color-mix(in srgb, var(--m-color-primary) 16%, var(--m-color-surface)) 0%,
135
+ var(--m-color-surface) 55%,
136
+ color-mix(in srgb, var(--m-color-border) 35%, var(--m-color-surface)) 100%
137
+ );
138
+ border-right: 1px solid var(--m-color-border);
139
+ }
140
+
141
+ .login-brand::after {
142
+ content: '';
143
+ position: absolute;
144
+ inset: auto -10% -20% 40%;
145
+ height: 55%;
146
+ border-radius: 50%;
147
+ background: color-mix(in srgb, var(--m-color-primary) 12%, transparent);
148
+ pointer-events: none;
149
+ }
150
+
151
+ .login-brand__mark,
152
+ .login-brand__title,
153
+ .login-brand__lead {
154
+ position: relative;
155
+ z-index: 1;
156
+ }
157
+
158
+ .login-brand__mark {
159
+ margin: 0;
160
+ font-size: 0.8125rem;
161
+ letter-spacing: 0.14em;
162
+ text-transform: uppercase;
163
+ color: var(--m-color-text-muted);
164
+ }
165
+
166
+ .login-brand__title {
167
+ margin: 0;
168
+ max-width: 12em;
169
+ font-size: clamp(2rem, 4vw, 3rem);
170
+ font-weight: 650;
171
+ line-height: 1.15;
172
+ letter-spacing: -0.03em;
173
+ }
174
+
175
+ .login-brand__lead {
176
+ margin: 0;
177
+ max-width: 28rem;
178
+ color: var(--m-color-text-muted);
179
+ line-height: 1.6;
180
+ }
181
+
182
+ .login-main {
183
+ display: grid;
184
+ place-items: center;
185
+ padding: var(--m-space-6);
186
+ }
187
+
188
+ .login-panel {
189
+ width: min(100%, 22rem);
190
+ }
191
+
192
+ .login-panel__header {
193
+ margin-bottom: var(--m-space-5);
194
+ }
195
+
196
+ .login-panel__header :deep(.m-typography-title),
197
+ .login-panel__header :deep(.m-typography) {
198
+ margin: 0;
199
+ }
200
+
201
+ .login-panel__header :deep(.m-typography-title) {
202
+ margin-bottom: var(--m-space-2);
203
+ }
204
+
205
+ .login-alert {
206
+ margin: 0 0 var(--m-space-4);
207
+ padding: var(--m-space-3) var(--m-space-4);
208
+ border: 1px solid color-mix(in srgb, var(--m-color-danger) 40%, var(--m-color-border));
209
+ border-radius: var(--m-radius-md);
210
+ background: color-mix(in srgb, var(--m-color-danger) 10%, var(--m-color-surface));
211
+ color: var(--m-color-danger);
212
+ font-size: 0.875rem;
213
+ line-height: 1.45;
214
+ }
215
+
216
+ @media (prefers-reduced-motion: no-preference) {
217
+ .login-panel {
218
+ animation: login-panel-in 420ms ease both;
219
+ }
220
+ }
221
+
222
+ @keyframes login-panel-in {
223
+ from {
224
+ opacity: 0;
225
+ transform: translateY(0.5rem);
226
+ }
227
+ to {
228
+ opacity: 1;
229
+ transform: translateY(0);
230
+ }
231
+ }
232
+
233
+ @media (max-width: 768px) {
234
+ .login-shell {
235
+ grid-template-columns: 1fr;
236
+ }
237
+
238
+ .login-brand {
239
+ border-right: 0;
240
+ border-bottom: 1px solid var(--m-color-border);
241
+ min-height: 12rem;
242
+ }
243
+ }
244
+ </style>
@@ -1,84 +1,84 @@
1
- <script setup lang="ts">
2
- /**
3
- * 黄金样例:结果 / 阻断页(System)
4
- * 默认展示 403;换成 success / 404 / 500 时只改 status + 文案 + #footer 动作。
5
- * 无数据空态请用 empty-state / MEmpty,不要用 MResult。
6
- * @see DESIGN.md · surfaces § System · MResult API(操作用 #footer)
7
- */
8
- import {
9
- MBreadcrumb,
10
- MButton,
11
- MConfigProvider,
12
- MLayout,
13
- MLayoutContent,
14
- MLayoutHeader,
15
- MPageContent,
16
- MResult,
17
- MSpace,
18
- zhCN,
19
- } from 'morya-ui'
20
- </script>
21
-
22
- <template>
23
- <MConfigProvider :locale="zhCN">
24
- <MLayout fill-viewport>
25
- <MLayoutHeader padding="var(--m-space-4) var(--m-space-6)">
26
- <MBreadcrumb
27
- :model="[
28
- { label: '首页', to: '/' },
29
- { label: '项目管理', to: '/projects' },
30
- { label: '无权限' },
31
- ]"
32
- />
33
- </MLayoutHeader>
34
-
35
- <MLayoutContent>
36
- <MPageContent>
37
- <div class="result-shell">
38
- <MResult
39
- status="403"
40
- title="没有权限查看该项目"
41
- description="当前账号无权访问「青禾书房」工作区。可返回上一页,或联系管理员开通权限。"
42
- size="large"
43
- >
44
- <template #footer>
45
- <MSpace>
46
- <MButton type="primary">
47
- 返回上一页
48
- </MButton>
49
- <MButton type="text">
50
- 联系管理员
51
- </MButton>
52
- </MSpace>
53
- </template>
54
- </MResult>
55
- </div>
56
- </MPageContent>
57
- </MLayoutContent>
58
- </MLayout>
59
- </MConfigProvider>
60
- </template>
61
-
62
- <style scoped>
63
- .result-shell {
64
- display: grid;
65
- place-items: center;
66
- min-height: min(28rem, 70vh);
67
- padding: var(--m-space-8) var(--m-space-4);
68
- border-radius: var(--m-radius-lg);
69
- background:
70
- radial-gradient(
71
- 70% 55% at 50% 0%,
72
- color-mix(in srgb, var(--m-color-primary) 10%, transparent),
73
- transparent 60%
74
- ),
75
- var(--m-color-surface);
76
- border: 1px dashed color-mix(in srgb, var(--m-color-border) 80%, transparent);
77
- }
78
-
79
- @media (prefers-reduced-motion: reduce) {
80
- .result-shell {
81
- background: var(--m-color-surface);
82
- }
83
- }
84
- </style>
1
+ <script setup lang="ts">
2
+ /**
3
+ * 黄金样例:结果 / 阻断页(System)
4
+ * 默认展示 403;换成 success / 404 / 500 时只改 status + 文案 + #footer 动作。
5
+ * 无数据空态请用 empty-state / MEmpty,不要用 MResult。
6
+ * @see DESIGN.md · surfaces § System · MResult API(操作用 #footer)
7
+ */
8
+ import {
9
+ MBreadcrumb,
10
+ MButton,
11
+ MConfigProvider,
12
+ MLayout,
13
+ MLayoutContent,
14
+ MLayoutHeader,
15
+ MPageContent,
16
+ MResult,
17
+ MSpace,
18
+ zhCN,
19
+ } from 'morya-ui'
20
+ </script>
21
+
22
+ <template>
23
+ <MConfigProvider :locale="zhCN">
24
+ <MLayout fill-viewport>
25
+ <MLayoutHeader padding="var(--m-space-4) var(--m-space-6)">
26
+ <MBreadcrumb
27
+ :model="[
28
+ { label: '首页', to: '/' },
29
+ { label: '项目管理', to: '/projects' },
30
+ { label: '无权限' },
31
+ ]"
32
+ />
33
+ </MLayoutHeader>
34
+
35
+ <MLayoutContent>
36
+ <MPageContent>
37
+ <div class="result-shell">
38
+ <MResult
39
+ status="403"
40
+ title="没有权限查看该项目"
41
+ description="当前账号无权访问「青禾书房」工作区。可返回上一页,或联系管理员开通权限。"
42
+ size="large"
43
+ >
44
+ <template #footer>
45
+ <MSpace>
46
+ <MButton type="primary">
47
+ 返回上一页
48
+ </MButton>
49
+ <MButton type="text">
50
+ 联系管理员
51
+ </MButton>
52
+ </MSpace>
53
+ </template>
54
+ </MResult>
55
+ </div>
56
+ </MPageContent>
57
+ </MLayoutContent>
58
+ </MLayout>
59
+ </MConfigProvider>
60
+ </template>
61
+
62
+ <style scoped>
63
+ .result-shell {
64
+ display: grid;
65
+ place-items: center;
66
+ min-height: min(28rem, 70vh);
67
+ padding: var(--m-space-8) var(--m-space-4);
68
+ border-radius: var(--m-radius-lg);
69
+ background:
70
+ radial-gradient(
71
+ 70% 55% at 50% 0%,
72
+ color-mix(in srgb, var(--m-color-primary) 10%, transparent),
73
+ transparent 60%
74
+ ),
75
+ var(--m-color-surface);
76
+ border: 1px dashed color-mix(in srgb, var(--m-color-border) 80%, transparent);
77
+ }
78
+
79
+ @media (prefers-reduced-motion: reduce) {
80
+ .result-shell {
81
+ background: var(--m-color-surface);
82
+ }
83
+ }
84
+ </style>