@morya-ui/mcp 0.3.5 → 0.3.7

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,231 +1,231 @@
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
- MSpace,
14
- zhCN,
15
- } from 'morya-ui'
16
- import { reactive, ref } from 'vue'
17
-
18
- const submitting = ref(false)
19
- const formError = ref('')
20
-
21
- const model = reactive({
22
- email: '',
23
- password: '',
24
- })
25
-
26
- async function onSubmit() {
27
- formError.value = ''
28
- submitting.value = true
29
- try {
30
- // await api.login(model)
31
- if (!model.email || !model.password) {
32
- formError.value = '请输入邮箱和密码后再试。'
33
- return
34
- }
35
- } finally {
36
- submitting.value = false
37
- }
38
- }
39
- </script>
40
-
41
- <template>
42
- <MConfigProvider :locale="zhCN">
43
- <div class="login-shell">
44
- <aside class="login-brand" aria-label="品牌">
45
- <p class="login-brand__mark">青禾书房</p>
46
- <h1 class="login-brand__title">把好书留在手边</h1>
47
- <p class="login-brand__lead">
48
- 店员与会员共用同一套账户。登录后继续进货、上架与会员服务。
49
- </p>
50
- </aside>
51
-
52
- <main class="login-main">
53
- <div class="login-panel">
54
- <header class="login-panel__header">
55
- <h2>登录</h2>
56
- <p>使用工作邮箱进入后台。</p>
57
- </header>
58
-
59
- <p v-if="formError" class="login-alert" role="alert">
60
- {{ formError }}
61
- </p>
62
-
63
- <MForm @submit="onSubmit">
64
- <MFormItem label="邮箱" name="email" required>
65
- <MInput
66
- v-model="model.email"
67
- type="email"
68
- placeholder="name@qinghe.example"
69
- autocomplete="username"
70
- fluid
71
- />
72
- </MFormItem>
73
-
74
- <MFormItem label="密码" name="password" required>
75
- <MInputPassword
76
- v-model="model.password"
77
- placeholder="请输入密码"
78
- autocomplete="current-password"
79
- fluid
80
- />
81
- </MFormItem>
82
-
83
- <MSpace style="margin-top: var(--m-space-2)" alignment="center">
84
- <MButton type="submit" label="登录" severity="primary" :loading="submitting" />
85
- <MButton type="button" label="忘记密码" severity="secondary" text />
86
- </MSpace>
87
- </MForm>
88
- </div>
89
- </main>
90
- </div>
91
- </MConfigProvider>
92
- </template>
93
-
94
- <style scoped>
95
- .login-shell {
96
- display: grid;
97
- grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
98
- min-height: 100vh;
99
- background: var(--m-color-surface);
100
- color: var(--m-color-text);
101
- }
102
-
103
- .login-brand {
104
- position: relative;
105
- display: flex;
106
- flex-direction: column;
107
- justify-content: flex-end;
108
- gap: var(--m-space-4);
109
- padding: clamp(2rem, 6vw, 4.5rem);
110
- overflow: hidden;
111
- background:
112
- radial-gradient(
113
- 80% 60% at 10% 20%,
114
- color-mix(in srgb, var(--m-color-primary) 22%, transparent),
115
- transparent 55%
116
- ),
117
- linear-gradient(
118
- 165deg,
119
- color-mix(in srgb, var(--m-color-primary) 16%, var(--m-color-surface)) 0%,
120
- var(--m-color-surface) 55%,
121
- color-mix(in srgb, var(--m-color-border) 35%, var(--m-color-surface)) 100%
122
- );
123
- border-right: 1px solid var(--m-color-border);
124
- }
125
-
126
- .login-brand::after {
127
- content: '';
128
- position: absolute;
129
- inset: auto -10% -20% 40%;
130
- height: 55%;
131
- border-radius: 50%;
132
- background: color-mix(in srgb, var(--m-color-primary) 12%, transparent);
133
- pointer-events: none;
134
- }
135
-
136
- .login-brand__mark,
137
- .login-brand__title,
138
- .login-brand__lead {
139
- position: relative;
140
- z-index: 1;
141
- }
142
-
143
- .login-brand__mark {
144
- margin: 0;
145
- font-size: 0.8125rem;
146
- letter-spacing: 0.14em;
147
- text-transform: uppercase;
148
- color: var(--m-color-text-muted);
149
- }
150
-
151
- .login-brand__title {
152
- margin: 0;
153
- max-width: 12em;
154
- font-size: clamp(2rem, 4vw, 3rem);
155
- font-weight: 650;
156
- line-height: 1.15;
157
- letter-spacing: -0.03em;
158
- }
159
-
160
- .login-brand__lead {
161
- margin: 0;
162
- max-width: 28rem;
163
- color: var(--m-color-text-muted);
164
- line-height: 1.6;
165
- }
166
-
167
- .login-main {
168
- display: grid;
169
- place-items: center;
170
- padding: var(--m-space-6);
171
- }
172
-
173
- .login-panel {
174
- width: min(100%, 22rem);
175
- }
176
-
177
- .login-panel__header {
178
- margin-bottom: var(--m-space-5);
179
- }
180
-
181
- .login-panel__header h2 {
182
- margin: 0 0 var(--m-space-2);
183
- font-size: 1.5rem;
184
- font-weight: 650;
185
- }
186
-
187
- .login-panel__header p {
188
- margin: 0;
189
- color: var(--m-color-text-muted);
190
- }
191
-
192
- .login-alert {
193
- margin: 0 0 var(--m-space-4);
194
- padding: var(--m-space-3) var(--m-space-4);
195
- border: 1px solid color-mix(in srgb, var(--m-color-danger) 40%, var(--m-color-border));
196
- border-radius: var(--m-radius-md);
197
- background: color-mix(in srgb, var(--m-color-danger) 10%, var(--m-color-surface));
198
- color: var(--m-color-danger);
199
- font-size: 0.875rem;
200
- line-height: 1.45;
201
- }
202
-
203
- @media (prefers-reduced-motion: no-preference) {
204
- .login-panel {
205
- animation: login-panel-in 420ms ease both;
206
- }
207
- }
208
-
209
- @keyframes login-panel-in {
210
- from {
211
- opacity: 0;
212
- transform: translateY(0.5rem);
213
- }
214
- to {
215
- opacity: 1;
216
- transform: translateY(0);
217
- }
218
- }
219
-
220
- @media (max-width: 768px) {
221
- .login-shell {
222
- grid-template-columns: 1fr;
223
- }
224
-
225
- .login-brand {
226
- border-right: 0;
227
- border-bottom: 1px solid var(--m-color-border);
228
- min-height: 12rem;
229
- }
230
- }
231
- </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
+ MSpace,
14
+ zhCN,
15
+ } from 'morya-ui'
16
+ import { reactive, ref } from 'vue'
17
+
18
+ const submitting = ref(false)
19
+ const formError = ref('')
20
+
21
+ const model = reactive({
22
+ email: '',
23
+ password: '',
24
+ })
25
+
26
+ async function onSubmit() {
27
+ formError.value = ''
28
+ submitting.value = true
29
+ try {
30
+ // await api.login(model)
31
+ if (!model.email || !model.password) {
32
+ formError.value = '请输入邮箱和密码后再试。'
33
+ return
34
+ }
35
+ } finally {
36
+ submitting.value = false
37
+ }
38
+ }
39
+ </script>
40
+
41
+ <template>
42
+ <MConfigProvider :locale="zhCN">
43
+ <div class="login-shell">
44
+ <aside class="login-brand" aria-label="品牌">
45
+ <p class="login-brand__mark">青禾书房</p>
46
+ <h1 class="login-brand__title">把好书留在手边</h1>
47
+ <p class="login-brand__lead">
48
+ 店员与会员共用同一套账户。登录后继续进货、上架与会员服务。
49
+ </p>
50
+ </aside>
51
+
52
+ <main class="login-main">
53
+ <div class="login-panel">
54
+ <header class="login-panel__header">
55
+ <h2>登录</h2>
56
+ <p>使用工作邮箱进入后台。</p>
57
+ </header>
58
+
59
+ <p v-if="formError" class="login-alert" role="alert">
60
+ {{ formError }}
61
+ </p>
62
+
63
+ <MForm @submit="onSubmit">
64
+ <MFormItem label="邮箱" name="email" required>
65
+ <MInput
66
+ v-model="model.email"
67
+ type="email"
68
+ placeholder="name@qinghe.example"
69
+ autocomplete="username"
70
+ fluid
71
+ />
72
+ </MFormItem>
73
+
74
+ <MFormItem label="密码" name="password" required>
75
+ <MInputPassword
76
+ v-model="model.password"
77
+ placeholder="请输入密码"
78
+ autocomplete="current-password"
79
+ fluid
80
+ />
81
+ </MFormItem>
82
+
83
+ <MSpace style="margin-top: var(--m-space-2)" alignment="center">
84
+ <MButton type="submit" label="登录" severity="primary" :loading="submitting" />
85
+ <MButton type="button" label="忘记密码" severity="secondary" text />
86
+ </MSpace>
87
+ </MForm>
88
+ </div>
89
+ </main>
90
+ </div>
91
+ </MConfigProvider>
92
+ </template>
93
+
94
+ <style scoped>
95
+ .login-shell {
96
+ display: grid;
97
+ grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
98
+ min-height: 100vh;
99
+ background: var(--m-color-surface);
100
+ color: var(--m-color-text);
101
+ }
102
+
103
+ .login-brand {
104
+ position: relative;
105
+ display: flex;
106
+ flex-direction: column;
107
+ justify-content: flex-end;
108
+ gap: var(--m-space-4);
109
+ padding: clamp(2rem, 6vw, 4.5rem);
110
+ overflow: hidden;
111
+ background:
112
+ radial-gradient(
113
+ 80% 60% at 10% 20%,
114
+ color-mix(in srgb, var(--m-color-primary) 22%, transparent),
115
+ transparent 55%
116
+ ),
117
+ linear-gradient(
118
+ 165deg,
119
+ color-mix(in srgb, var(--m-color-primary) 16%, var(--m-color-surface)) 0%,
120
+ var(--m-color-surface) 55%,
121
+ color-mix(in srgb, var(--m-color-border) 35%, var(--m-color-surface)) 100%
122
+ );
123
+ border-right: 1px solid var(--m-color-border);
124
+ }
125
+
126
+ .login-brand::after {
127
+ content: '';
128
+ position: absolute;
129
+ inset: auto -10% -20% 40%;
130
+ height: 55%;
131
+ border-radius: 50%;
132
+ background: color-mix(in srgb, var(--m-color-primary) 12%, transparent);
133
+ pointer-events: none;
134
+ }
135
+
136
+ .login-brand__mark,
137
+ .login-brand__title,
138
+ .login-brand__lead {
139
+ position: relative;
140
+ z-index: 1;
141
+ }
142
+
143
+ .login-brand__mark {
144
+ margin: 0;
145
+ font-size: 0.8125rem;
146
+ letter-spacing: 0.14em;
147
+ text-transform: uppercase;
148
+ color: var(--m-color-text-muted);
149
+ }
150
+
151
+ .login-brand__title {
152
+ margin: 0;
153
+ max-width: 12em;
154
+ font-size: clamp(2rem, 4vw, 3rem);
155
+ font-weight: 650;
156
+ line-height: 1.15;
157
+ letter-spacing: -0.03em;
158
+ }
159
+
160
+ .login-brand__lead {
161
+ margin: 0;
162
+ max-width: 28rem;
163
+ color: var(--m-color-text-muted);
164
+ line-height: 1.6;
165
+ }
166
+
167
+ .login-main {
168
+ display: grid;
169
+ place-items: center;
170
+ padding: var(--m-space-6);
171
+ }
172
+
173
+ .login-panel {
174
+ width: min(100%, 22rem);
175
+ }
176
+
177
+ .login-panel__header {
178
+ margin-bottom: var(--m-space-5);
179
+ }
180
+
181
+ .login-panel__header h2 {
182
+ margin: 0 0 var(--m-space-2);
183
+ font-size: 1.5rem;
184
+ font-weight: 650;
185
+ }
186
+
187
+ .login-panel__header p {
188
+ margin: 0;
189
+ color: var(--m-color-text-muted);
190
+ }
191
+
192
+ .login-alert {
193
+ margin: 0 0 var(--m-space-4);
194
+ padding: var(--m-space-3) var(--m-space-4);
195
+ border: 1px solid color-mix(in srgb, var(--m-color-danger) 40%, var(--m-color-border));
196
+ border-radius: var(--m-radius-md);
197
+ background: color-mix(in srgb, var(--m-color-danger) 10%, var(--m-color-surface));
198
+ color: var(--m-color-danger);
199
+ font-size: 0.875rem;
200
+ line-height: 1.45;
201
+ }
202
+
203
+ @media (prefers-reduced-motion: no-preference) {
204
+ .login-panel {
205
+ animation: login-panel-in 420ms ease both;
206
+ }
207
+ }
208
+
209
+ @keyframes login-panel-in {
210
+ from {
211
+ opacity: 0;
212
+ transform: translateY(0.5rem);
213
+ }
214
+ to {
215
+ opacity: 1;
216
+ transform: translateY(0);
217
+ }
218
+ }
219
+
220
+ @media (max-width: 768px) {
221
+ .login-shell {
222
+ grid-template-columns: 1fr;
223
+ }
224
+
225
+ .login-brand {
226
+ border-right: 0;
227
+ border-bottom: 1px solid var(--m-color-border);
228
+ min-height: 12rem;
229
+ }
230
+ }
231
+ </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 severity="primary">
47
- 返回上一页
48
- </MButton>
49
- <MButton severity="secondary" 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 severity="primary">
47
+ 返回上一页
48
+ </MButton>
49
+ <MButton severity="secondary" 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>