@manohub/ui 0.10.4 → 1.0.0

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 (72) hide show
  1. package/README.md +155 -155
  2. package/dist/components/form/index.js +8 -1
  3. package/dist/components/tabs/index.d.ts +9 -6
  4. package/dist/components/tabs/index.js +6 -1
  5. package/dist/styles/components/avatar.css +131 -131
  6. package/dist/styles/components/avatar.tokens.css +24 -24
  7. package/dist/styles/components/badge.css +266 -266
  8. package/dist/styles/components/badge.tokens.css +24 -24
  9. package/dist/styles/components/button.css +460 -460
  10. package/dist/styles/components/capsule.css +128 -128
  11. package/dist/styles/components/capsule.tokens.css +27 -27
  12. package/dist/styles/components/card.css +198 -198
  13. package/dist/styles/components/checkbox.css +145 -145
  14. package/dist/styles/components/checkbox.tokens.css +26 -26
  15. package/dist/styles/components/code-block.css +216 -216
  16. package/dist/styles/components/code-block.tokens.css +40 -40
  17. package/dist/styles/components/collapse.css +62 -62
  18. package/dist/styles/components/collapse.tokens.css +20 -20
  19. package/dist/styles/components/dialog.css +158 -158
  20. package/dist/styles/components/dialog.tokens.css +24 -24
  21. package/dist/styles/components/divider.css +75 -75
  22. package/dist/styles/components/divider.tokens.css +22 -22
  23. package/dist/styles/components/drawer.css +143 -143
  24. package/dist/styles/components/drawer.tokens.css +22 -22
  25. package/dist/styles/components/filter.css +29 -29
  26. package/dist/styles/components/form.css +442 -430
  27. package/dist/styles/components/form.tokens.css +15 -15
  28. package/dist/styles/components/input.css +538 -533
  29. package/dist/styles/components/input.tokens.css +43 -43
  30. package/dist/styles/components/layout.css +200 -200
  31. package/dist/styles/components/list-view.css +244 -244
  32. package/dist/styles/components/loading.css +76 -76
  33. package/dist/styles/components/loading.tokens.css +23 -23
  34. package/dist/styles/components/nav.css +48 -48
  35. package/dist/styles/components/notice.css +153 -153
  36. package/dist/styles/components/notice.tokens.css +17 -17
  37. package/dist/styles/components/notification.css +159 -159
  38. package/dist/styles/components/notification.tokens.css +37 -37
  39. package/dist/styles/components/page.css +473 -473
  40. package/dist/styles/components/pagination.css +303 -303
  41. package/dist/styles/components/pagination.tokens.css +32 -32
  42. package/dist/styles/components/panel.css +77 -77
  43. package/dist/styles/components/query-state.css +88 -88
  44. package/dist/styles/components/radio.css +271 -271
  45. package/dist/styles/components/radio.tokens.css +26 -26
  46. package/dist/styles/components/search.css +34 -34
  47. package/dist/styles/components/select.css +326 -326
  48. package/dist/styles/components/select.tokens.css +44 -44
  49. package/dist/styles/components/skeleton.css +60 -60
  50. package/dist/styles/components/skeleton.tokens.css +27 -27
  51. package/dist/styles/components/steps.css +205 -205
  52. package/dist/styles/components/steps.tokens.css +44 -44
  53. package/dist/styles/components/switch.css +165 -165
  54. package/dist/styles/components/switch.tokens.css +26 -26
  55. package/dist/styles/components/tabbar.css +235 -235
  56. package/dist/styles/components/tabbar.tokens.css +30 -30
  57. package/dist/styles/components/table.css +504 -504
  58. package/dist/styles/components/table.tokens.css +44 -44
  59. package/dist/styles/components/tag.css +127 -127
  60. package/dist/styles/components/tag.tokens.css +24 -24
  61. package/dist/styles/components/toast.css +185 -185
  62. package/dist/styles/components/toast.tokens.css +26 -26
  63. package/dist/styles/components/tooltip.css +89 -89
  64. package/dist/styles/components/tooltip.tokens.css +25 -25
  65. package/dist/styles/components/tree.css +173 -173
  66. package/dist/styles/components/upload.css +151 -151
  67. package/dist/styles/components/upload.tokens.css +27 -27
  68. package/dist/styles/index.css +153 -153
  69. package/dist/styles/operations/collapse.css +84 -84
  70. package/dist/styles/operations/popup.css +193 -193
  71. package/dist/styles/operations/tabs.css +82 -73
  72. package/package.json +62 -62
@@ -1,244 +1,244 @@
1
- /**
2
- * ListView(卡片网格列表:容器自适应列数 + 骨架卡 + 三态)。
3
- *
4
- * 依据:卡片本体沿用 card.css(Card);本文件只管网格容器、骨架卡与卡片项几何。
5
- */
6
-
7
- /* ===== ListView(卡片网格列表:容器自适应列数 + 骨架卡 + 三态)=====
8
- 列数由**容器宽度**决定(auto-fill),不跟视口断点:窄栏自动减列。
9
- `min(var(--mh-list-view-min), 100%)` 是必需的一层保护 —— 只写固定下限时,
10
- 容器比下限还窄会溢出(列宽不会缩到容器以内)。 */
11
-
12
- .mh-list-view {
13
- --mh-list-view-min: var(--ui-grid-column-min);
14
- --mh-list-view-gap: var(--ui-space-5);
15
- --mh-list-view-card-min-height: 144px;
16
- display: grid;
17
- grid-template-columns: repeat(auto-fill, minmax(min(var(--mh-list-view-min), 100%), 1fr));
18
- gap: var(--mh-list-view-gap);
19
- align-items: stretch;
20
- }
21
-
22
- /* 骨架卡:与卡片同尺寸(最小高 + 圆角),避免加载完成时高度跳动 */
23
-
24
- .mh-list-view__skeleton {
25
- min-height: var(--mh-list-view-card-min-height);
26
- border-radius: var(--ui-radius-md);
27
- background: var(--ui-base-200);
28
- animation: mh-list-view-pulse 1.4s ease-in-out infinite;
29
- }
30
-
31
- @keyframes mh-list-view-pulse {
32
- 0%,
33
- 100% {
34
- opacity: 1;
35
- }
36
- 50% {
37
- opacity: 0.55;
38
- }
39
- }
40
-
41
- /* 列表卡片项:最小高对齐(原型 min-h-36),同排卡片等高、尾部一行对齐 */
42
-
43
- .mh-list-view__card {
44
- min-height: var(--mh-list-view-card-min-height);
45
- }
46
-
47
- /* 头部:图标 + 标题块 + 状态胶囊(原型 flex items-start) */
48
-
49
- .mh-list-view__card-head {
50
- display: flex;
51
- align-items: flex-start;
52
- gap: var(--ui-space-3);
53
- }
54
-
55
- /* 图标容器 36×36(原型 h-9 w-9),圆角取控件档 6(原型 rounded-md) */
56
-
57
- .mh-list-view__card-icon {
58
- flex: none;
59
- width: 36px;
60
- height: 36px;
61
- overflow: hidden;
62
- border-radius: var(--ui-radius-control);
63
- }
64
-
65
- .mh-list-view__card-icon-img {
66
- display: block;
67
- width: 100%;
68
- height: 100%;
69
- object-fit: cover;
70
- }
71
-
72
- .mh-list-view__card-title-block {
73
- display: flex;
74
- flex: 1;
75
- flex-direction: column;
76
- min-width: 0;
77
- }
78
-
79
- /* 标题 16/600(原型 text-base font-semibold leading-6,与令牌档一致) */
80
-
81
- .mh-list-view__card-title {
82
- overflow: hidden;
83
- font-size: var(--ui-font-heading);
84
- font-weight: var(--ui-weight-semibold);
85
- line-height: var(--ui-line-heading);
86
- color: var(--ui-base-content);
87
- text-overflow: ellipsis;
88
- white-space: nowrap;
89
- }
90
-
91
- .mh-list-view__card-subtitle {
92
- font-size: var(--ui-font-caption);
93
- line-height: var(--ui-line-caption);
94
- color: var(--ui-base-content-muted);
95
- }
96
-
97
- /* 状态胶囊:全圆角 + 弱底同色字(原型 rounded-full px-2.5 text-xs leading-5) */
98
-
99
- .mh-list-view__card-status {
100
- --mh-status-fg: var(--ui-primary);
101
- --mh-status-bg: var(--ui-primary-weak);
102
- display: inline-flex;
103
- flex: none;
104
- align-items: center;
105
- gap: var(--ui-space-1);
106
- margin-left: auto;
107
- padding: 0 10px;
108
- border-radius: var(--ui-radius-full);
109
- font-size: var(--ui-font-caption);
110
- line-height: var(--ui-line-caption);
111
- white-space: nowrap;
112
- color: var(--mh-status-fg);
113
- background: var(--mh-status-bg);
114
- }
115
-
116
- .mh-list-view__card-status--primary {
117
- --mh-status-fg: var(--ui-primary);
118
- --mh-status-bg: var(--ui-primary-weak);
119
- }
120
-
121
- .mh-list-view__card-status--success {
122
- --mh-status-fg: var(--ui-success-strong);
123
- --mh-status-bg: var(--ui-success-weak);
124
- }
125
-
126
- .mh-list-view__card-status--warning {
127
- --mh-status-fg: var(--ui-warning-strong);
128
- --mh-status-bg: var(--ui-warning-weak);
129
- }
130
-
131
- .mh-list-view__card-status--error {
132
- --mh-status-fg: var(--ui-error);
133
- --mh-status-bg: var(--ui-error-weak);
134
- }
135
-
136
- .mh-list-view__card-status--neutral {
137
- --mh-status-fg: var(--ui-base-content-muted);
138
- --mh-status-bg: var(--ui-base-200);
139
- }
140
-
141
- .mh-list-view__card-status-dot {
142
- width: 6px;
143
- height: 6px;
144
- flex: none;
145
- border-radius: var(--ui-radius-full);
146
- background: var(--mh-status-fg);
147
- }
148
-
149
- /* 描述:两行截断(原型 line-clamp-2 text-xs text-muted-foreground) */
150
-
151
- .mh-list-view__card-desc {
152
- display: -webkit-box;
153
- margin: 0;
154
- overflow: hidden;
155
- -webkit-box-orient: vertical;
156
- -webkit-line-clamp: 2;
157
- line-clamp: 2;
158
- font-size: var(--ui-font-caption);
159
- line-height: var(--ui-line-caption);
160
- color: var(--ui-base-content-muted);
161
- }
162
-
163
- /* 尾部:左「自定义内容 + 标签组」、右「统计 + 操作位」;贴卡片底部(原型 mt-auto) */
164
-
165
- .mh-list-view__card-foot {
166
- display: flex;
167
- align-items: center;
168
- gap: var(--ui-space-2);
169
- margin-top: auto;
170
- }
171
-
172
- .mh-list-view__card-foot-main {
173
- display: flex;
174
- align-items: center;
175
- gap: var(--ui-space-2);
176
- min-width: 0;
177
- }
178
-
179
- .mh-list-view__card-foot-side {
180
- display: flex;
181
- flex: none;
182
- align-items: center;
183
- gap: var(--ui-space-1);
184
- margin-left: auto;
185
- }
186
-
187
- .mh-list-view__card-tags {
188
- display: flex;
189
- align-items: center;
190
- gap: var(--ui-space-2);
191
- min-width: 0;
192
- }
193
-
194
- /* 标签片:主色弱底 + 主色字 + 小圆角(原型 rounded bg-primary/10 px-2 leading-5 font-medium) */
195
-
196
- .mh-list-view__card-tag {
197
- flex: none;
198
- padding: 0 var(--ui-space-2);
199
- border-radius: var(--ui-radius-sm);
200
- font-size: var(--ui-font-caption);
201
- font-weight: var(--ui-weight-medium);
202
- line-height: var(--ui-line-caption);
203
- color: var(--ui-primary);
204
- background: var(--ui-primary-weak);
205
- }
206
-
207
- .mh-list-view__card-extra {
208
- display: inline-flex;
209
- align-items: center;
210
- gap: var(--ui-space-1);
211
- font-size: var(--ui-font-caption);
212
- line-height: var(--ui-line-caption);
213
- color: var(--ui-base-content-muted);
214
- }
215
-
216
- /* 操作位:默认隐藏,卡片悬浮(或卡内获得焦点)时显形 —— 键盘 Tab 进来同样可见。
217
- 触屏没有 hover 能力,故 hover 缺失时恒显形,避免操作不可达。 */
218
-
219
- .mh-list-view__card-actions {
220
- display: inline-flex;
221
- align-items: center;
222
- gap: var(--ui-space-1);
223
- opacity: 0;
224
- transition: opacity 0.15s ease;
225
- }
226
-
227
- .mh-list-view__card:hover .mh-list-view__card-actions {
228
- opacity: 1;
229
- }
230
-
231
- .mh-list-view__card:focus-within .mh-list-view__card-actions {
232
- opacity: 1;
233
- }
234
-
235
- @media (hover: none) {
236
- .mh-list-view__card-actions {
237
- opacity: 1;
238
- }
239
- }
240
-
241
- /* ===== 固定列数档(`columns > 0`):不再按容器宽度自适应 ===== */
242
- .mh-list-view--fixed {
243
- grid-template-columns: repeat(var(--mh-list-view-columns, 1), minmax(0, 1fr));
244
- }
1
+ /**
2
+ * ListView(卡片网格列表:容器自适应列数 + 骨架卡 + 三态)。
3
+ *
4
+ * 依据:卡片本体沿用 card.css(Card);本文件只管网格容器、骨架卡与卡片项几何。
5
+ */
6
+
7
+ /* ===== ListView(卡片网格列表:容器自适应列数 + 骨架卡 + 三态)=====
8
+ 列数由**容器宽度**决定(auto-fill),不跟视口断点:窄栏自动减列。
9
+ `min(var(--mh-list-view-min), 100%)` 是必需的一层保护 —— 只写固定下限时,
10
+ 容器比下限还窄会溢出(列宽不会缩到容器以内)。 */
11
+
12
+ .mh-list-view {
13
+ --mh-list-view-min: var(--ui-grid-column-min);
14
+ --mh-list-view-gap: var(--ui-space-5);
15
+ --mh-list-view-card-min-height: 144px;
16
+ display: grid;
17
+ grid-template-columns: repeat(auto-fill, minmax(min(var(--mh-list-view-min), 100%), 1fr));
18
+ gap: var(--mh-list-view-gap);
19
+ align-items: stretch;
20
+ }
21
+
22
+ /* 骨架卡:与卡片同尺寸(最小高 + 圆角),避免加载完成时高度跳动 */
23
+
24
+ .mh-list-view__skeleton {
25
+ min-height: var(--mh-list-view-card-min-height);
26
+ border-radius: var(--ui-radius-md);
27
+ background: var(--ui-base-200);
28
+ animation: mh-list-view-pulse 1.4s ease-in-out infinite;
29
+ }
30
+
31
+ @keyframes mh-list-view-pulse {
32
+ 0%,
33
+ 100% {
34
+ opacity: 1;
35
+ }
36
+ 50% {
37
+ opacity: 0.55;
38
+ }
39
+ }
40
+
41
+ /* 列表卡片项:最小高对齐(原型 min-h-36),同排卡片等高、尾部一行对齐 */
42
+
43
+ .mh-list-view__card {
44
+ min-height: var(--mh-list-view-card-min-height);
45
+ }
46
+
47
+ /* 头部:图标 + 标题块 + 状态胶囊(原型 flex items-start) */
48
+
49
+ .mh-list-view__card-head {
50
+ display: flex;
51
+ align-items: flex-start;
52
+ gap: var(--ui-space-3);
53
+ }
54
+
55
+ /* 图标容器 36×36(原型 h-9 w-9),圆角取控件档 6(原型 rounded-md) */
56
+
57
+ .mh-list-view__card-icon {
58
+ flex: none;
59
+ width: 36px;
60
+ height: 36px;
61
+ overflow: hidden;
62
+ border-radius: var(--ui-radius-control);
63
+ }
64
+
65
+ .mh-list-view__card-icon-img {
66
+ display: block;
67
+ width: 100%;
68
+ height: 100%;
69
+ object-fit: cover;
70
+ }
71
+
72
+ .mh-list-view__card-title-block {
73
+ display: flex;
74
+ flex: 1;
75
+ flex-direction: column;
76
+ min-width: 0;
77
+ }
78
+
79
+ /* 标题 16/600(原型 text-base font-semibold leading-6,与令牌档一致) */
80
+
81
+ .mh-list-view__card-title {
82
+ overflow: hidden;
83
+ font-size: var(--ui-font-heading);
84
+ font-weight: var(--ui-weight-semibold);
85
+ line-height: var(--ui-line-heading);
86
+ color: var(--ui-base-content);
87
+ text-overflow: ellipsis;
88
+ white-space: nowrap;
89
+ }
90
+
91
+ .mh-list-view__card-subtitle {
92
+ font-size: var(--ui-font-caption);
93
+ line-height: var(--ui-line-caption);
94
+ color: var(--ui-base-content-muted);
95
+ }
96
+
97
+ /* 状态胶囊:全圆角 + 弱底同色字(原型 rounded-full px-2.5 text-xs leading-5) */
98
+
99
+ .mh-list-view__card-status {
100
+ --mh-status-fg: var(--ui-primary);
101
+ --mh-status-bg: var(--ui-primary-weak);
102
+ display: inline-flex;
103
+ flex: none;
104
+ align-items: center;
105
+ gap: var(--ui-space-1);
106
+ margin-left: auto;
107
+ padding: 0 10px;
108
+ border-radius: var(--ui-radius-full);
109
+ font-size: var(--ui-font-caption);
110
+ line-height: var(--ui-line-caption);
111
+ white-space: nowrap;
112
+ color: var(--mh-status-fg);
113
+ background: var(--mh-status-bg);
114
+ }
115
+
116
+ .mh-list-view__card-status--primary {
117
+ --mh-status-fg: var(--ui-primary);
118
+ --mh-status-bg: var(--ui-primary-weak);
119
+ }
120
+
121
+ .mh-list-view__card-status--success {
122
+ --mh-status-fg: var(--ui-success-strong);
123
+ --mh-status-bg: var(--ui-success-weak);
124
+ }
125
+
126
+ .mh-list-view__card-status--warning {
127
+ --mh-status-fg: var(--ui-warning-strong);
128
+ --mh-status-bg: var(--ui-warning-weak);
129
+ }
130
+
131
+ .mh-list-view__card-status--error {
132
+ --mh-status-fg: var(--ui-error);
133
+ --mh-status-bg: var(--ui-error-weak);
134
+ }
135
+
136
+ .mh-list-view__card-status--neutral {
137
+ --mh-status-fg: var(--ui-base-content-muted);
138
+ --mh-status-bg: var(--ui-base-200);
139
+ }
140
+
141
+ .mh-list-view__card-status-dot {
142
+ width: 6px;
143
+ height: 6px;
144
+ flex: none;
145
+ border-radius: var(--ui-radius-full);
146
+ background: var(--mh-status-fg);
147
+ }
148
+
149
+ /* 描述:两行截断(原型 line-clamp-2 text-xs text-muted-foreground) */
150
+
151
+ .mh-list-view__card-desc {
152
+ display: -webkit-box;
153
+ margin: 0;
154
+ overflow: hidden;
155
+ -webkit-box-orient: vertical;
156
+ -webkit-line-clamp: 2;
157
+ line-clamp: 2;
158
+ font-size: var(--ui-font-caption);
159
+ line-height: var(--ui-line-caption);
160
+ color: var(--ui-base-content-muted);
161
+ }
162
+
163
+ /* 尾部:左「自定义内容 + 标签组」、右「统计 + 操作位」;贴卡片底部(原型 mt-auto) */
164
+
165
+ .mh-list-view__card-foot {
166
+ display: flex;
167
+ align-items: center;
168
+ gap: var(--ui-space-2);
169
+ margin-top: auto;
170
+ }
171
+
172
+ .mh-list-view__card-foot-main {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: var(--ui-space-2);
176
+ min-width: 0;
177
+ }
178
+
179
+ .mh-list-view__card-foot-side {
180
+ display: flex;
181
+ flex: none;
182
+ align-items: center;
183
+ gap: var(--ui-space-1);
184
+ margin-left: auto;
185
+ }
186
+
187
+ .mh-list-view__card-tags {
188
+ display: flex;
189
+ align-items: center;
190
+ gap: var(--ui-space-2);
191
+ min-width: 0;
192
+ }
193
+
194
+ /* 标签片:主色弱底 + 主色字 + 小圆角(原型 rounded bg-primary/10 px-2 leading-5 font-medium) */
195
+
196
+ .mh-list-view__card-tag {
197
+ flex: none;
198
+ padding: 0 var(--ui-space-2);
199
+ border-radius: var(--ui-radius-sm);
200
+ font-size: var(--ui-font-caption);
201
+ font-weight: var(--ui-weight-medium);
202
+ line-height: var(--ui-line-caption);
203
+ color: var(--ui-primary);
204
+ background: var(--ui-primary-weak);
205
+ }
206
+
207
+ .mh-list-view__card-extra {
208
+ display: inline-flex;
209
+ align-items: center;
210
+ gap: var(--ui-space-1);
211
+ font-size: var(--ui-font-caption);
212
+ line-height: var(--ui-line-caption);
213
+ color: var(--ui-base-content-muted);
214
+ }
215
+
216
+ /* 操作位:默认隐藏,卡片悬浮(或卡内获得焦点)时显形 —— 键盘 Tab 进来同样可见。
217
+ 触屏没有 hover 能力,故 hover 缺失时恒显形,避免操作不可达。 */
218
+
219
+ .mh-list-view__card-actions {
220
+ display: inline-flex;
221
+ align-items: center;
222
+ gap: var(--ui-space-1);
223
+ opacity: 0;
224
+ transition: opacity 0.15s ease;
225
+ }
226
+
227
+ .mh-list-view__card:hover .mh-list-view__card-actions {
228
+ opacity: 1;
229
+ }
230
+
231
+ .mh-list-view__card:focus-within .mh-list-view__card-actions {
232
+ opacity: 1;
233
+ }
234
+
235
+ @media (hover: none) {
236
+ .mh-list-view__card-actions {
237
+ opacity: 1;
238
+ }
239
+ }
240
+
241
+ /* ===== 固定列数档(`columns > 0`):不再按容器宽度自适应 ===== */
242
+ .mh-list-view--fixed {
243
+ grid-template-columns: repeat(var(--mh-list-view-columns, 1), minmax(0, 1fr));
244
+ }
@@ -1,76 +1,76 @@
1
- /**
2
- * Loading —— 加载态面(转圈 + 可选文案;行内 / 区域遮罩 / 全屏遮罩三形态)。
3
- *
4
- * 出处:设计稿的「正在忙」态没有独立组件,各页自绘了五花八门的遮罩与转圈
5
- * (`::after` 画环、文字符号 `...`、gif 图各有)。本件收的是**三件事**:
6
- * 转圈字形、遮罩底色、覆盖范围 —— 三者都是「改一处要全会跟着变」的口径。
7
- *
8
- * 字形归 `@manohub/icon`(`loading`),本面只负责**转**与**在哪转**:
9
- * 动画名加 `mh-` 前缀(与 toast 的 `mh-toast-spin` 同理:动画名是全局标识,防撞名)。
10
- *
11
- * 尺寸按**全局图标档**派生(`calc()` 加减,与 button.css 同款):
12
- * 改全局图标档时三档一起缩放,不会出现「转圈比旁边图标大一圈」。
13
- *
14
- * 遮罩底色由主题底色派生(`color-mix`,**不新造色值**):换主题跟着变。
15
- */
16
- .mh-loading {
17
- display: inline-flex;
18
- align-items: center;
19
- justify-content: center;
20
- gap: var(--ui-loading-gap);
21
- color: var(--ui-loading-text-color);
22
- font-size: var(--ui-font-body);
23
- line-height: var(--ui-line-body);
24
- }
25
-
26
- /* 尺寸档(按全局图标档派生,档距用 calc 表达) */
27
- .mh-loading--sm {
28
- --ui-loading-spinner-size: calc(var(--ui-font-icon) - 4px);
29
- }
30
- .mh-loading--lg {
31
- --ui-loading-spinner-size: calc(var(--ui-font-icon) + 8px);
32
- }
33
-
34
- .mh-loading__spinner {
35
- flex: none;
36
- width: var(--ui-loading-spinner-size);
37
- height: var(--ui-loading-spinner-size);
38
- /* 转圈是**提示进行中**,取主色:与语义四色(成功/警告/错误)不混 |
39
- 独立 `rotate` 属性(不碰 transform):与全库动画令牌同款约束 */
40
- color: var(--ui-primary);
41
- animation: mh-loading-spin 0.8s linear infinite;
42
- }
43
- @keyframes mh-loading-spin {
44
- to {
45
- rotate: 360deg;
46
- }
47
- }
48
- /* 降级:减弱动效时放慢而不是全停 —— 完全静止的转圈会被读成「卡住了」 */
49
- @media (prefers-reduced-motion: reduce) {
50
- .mh-loading__spinner {
51
- animation-duration: 2.4s;
52
- }
53
- }
54
-
55
- .mh-loading__text {
56
- min-width: 0;
57
- }
58
-
59
- /* ===== 区域遮罩:铺满**最近的定位祖先**(宿主需自带 position: relative)===== */
60
- .mh-loading--area {
61
- position: absolute;
62
- inset: 0;
63
- z-index: 10;
64
- background: var(--ui-loading-mask);
65
- /* 遮罩要拦住交互:光标与吞点击都是「正在忙」的表达 */
66
- cursor: wait;
67
- }
68
-
69
- /* ===== 全屏遮罩:铺满视口(层级夹在 toast 堆叠 1080 与模态 top layer 之间)===== */
70
- .mh-loading--screen {
71
- position: fixed;
72
- inset: 0;
73
- z-index: 1090;
74
- background: var(--ui-loading-mask);
75
- cursor: wait;
76
- }
1
+ /**
2
+ * Loading —— 加载态面(转圈 + 可选文案;行内 / 区域遮罩 / 全屏遮罩三形态)。
3
+ *
4
+ * 出处:设计稿的「正在忙」态没有独立组件,各页自绘了五花八门的遮罩与转圈
5
+ * (`::after` 画环、文字符号 `...`、gif 图各有)。本件收的是**三件事**:
6
+ * 转圈字形、遮罩底色、覆盖范围 —— 三者都是「改一处要全会跟着变」的口径。
7
+ *
8
+ * 字形归 `@manohub/icon`(`loading`),本面只负责**转**与**在哪转**:
9
+ * 动画名加 `mh-` 前缀(与 toast 的 `mh-toast-spin` 同理:动画名是全局标识,防撞名)。
10
+ *
11
+ * 尺寸按**全局图标档**派生(`calc()` 加减,与 button.css 同款):
12
+ * 改全局图标档时三档一起缩放,不会出现「转圈比旁边图标大一圈」。
13
+ *
14
+ * 遮罩底色由主题底色派生(`color-mix`,**不新造色值**):换主题跟着变。
15
+ */
16
+ .mh-loading {
17
+ display: inline-flex;
18
+ align-items: center;
19
+ justify-content: center;
20
+ gap: var(--ui-loading-gap);
21
+ color: var(--ui-loading-text-color);
22
+ font-size: var(--ui-font-body);
23
+ line-height: var(--ui-line-body);
24
+ }
25
+
26
+ /* 尺寸档(按全局图标档派生,档距用 calc 表达) */
27
+ .mh-loading--sm {
28
+ --ui-loading-spinner-size: calc(var(--ui-font-icon) - 4px);
29
+ }
30
+ .mh-loading--lg {
31
+ --ui-loading-spinner-size: calc(var(--ui-font-icon) + 8px);
32
+ }
33
+
34
+ .mh-loading__spinner {
35
+ flex: none;
36
+ width: var(--ui-loading-spinner-size);
37
+ height: var(--ui-loading-spinner-size);
38
+ /* 转圈是**提示进行中**,取主色:与语义四色(成功/警告/错误)不混 |
39
+ 独立 `rotate` 属性(不碰 transform):与全库动画令牌同款约束 */
40
+ color: var(--ui-primary);
41
+ animation: mh-loading-spin 0.8s linear infinite;
42
+ }
43
+ @keyframes mh-loading-spin {
44
+ to {
45
+ rotate: 360deg;
46
+ }
47
+ }
48
+ /* 降级:减弱动效时放慢而不是全停 —— 完全静止的转圈会被读成「卡住了」 */
49
+ @media (prefers-reduced-motion: reduce) {
50
+ .mh-loading__spinner {
51
+ animation-duration: 2.4s;
52
+ }
53
+ }
54
+
55
+ .mh-loading__text {
56
+ min-width: 0;
57
+ }
58
+
59
+ /* ===== 区域遮罩:铺满**最近的定位祖先**(宿主需自带 position: relative)===== */
60
+ .mh-loading--area {
61
+ position: absolute;
62
+ inset: 0;
63
+ z-index: 10;
64
+ background: var(--ui-loading-mask);
65
+ /* 遮罩要拦住交互:光标与吞点击都是「正在忙」的表达 */
66
+ cursor: wait;
67
+ }
68
+
69
+ /* ===== 全屏遮罩:铺满视口(层级夹在 toast 堆叠 1080 与模态 top layer 之间)===== */
70
+ .mh-loading--screen {
71
+ position: fixed;
72
+ inset: 0;
73
+ z-index: 1090;
74
+ background: var(--ui-loading-mask);
75
+ cursor: wait;
76
+ }