@manohub/ui 0.6.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 (169) hide show
  1. package/README.md +141 -0
  2. package/dist/components/avatar/index.d.ts +283 -0
  3. package/dist/components/avatar/index.js +167 -0
  4. package/dist/components/badge/index.d.ts +132 -0
  5. package/dist/components/badge/index.js +99 -0
  6. package/dist/components/button/index.d.ts +578 -0
  7. package/dist/components/button/index.js +191 -0
  8. package/dist/components/capsule/index.d.ts +161 -0
  9. package/dist/components/capsule/index.js +101 -0
  10. package/dist/components/card/index.d.ts +456 -0
  11. package/dist/components/card/index.js +231 -0
  12. package/dist/components/checkbox/index.d.ts +331 -0
  13. package/dist/components/checkbox/index.js +165 -0
  14. package/dist/components/code/index.d.ts +134 -0
  15. package/dist/components/code/index.js +117 -0
  16. package/dist/components/code-editor/index.d.ts +163 -0
  17. package/dist/components/code-editor/index.js +98 -0
  18. package/dist/components/collapse/index.d.ts +125 -0
  19. package/dist/components/collapse/index.js +95 -0
  20. package/dist/components/control-size.d.ts +8 -0
  21. package/dist/components/dialog/index.d.ts +224 -0
  22. package/dist/components/dialog/index.js +194 -0
  23. package/dist/components/divider/index.d.ts +64 -0
  24. package/dist/components/divider/index.js +62 -0
  25. package/dist/components/drawer/index.d.ts +226 -0
  26. package/dist/components/drawer/index.js +190 -0
  27. package/dist/components/filter/index.d.ts +391 -0
  28. package/dist/components/filter/index.js +203 -0
  29. package/dist/components/form/index.d.ts +704 -0
  30. package/dist/components/form/index.js +329 -0
  31. package/dist/components/input/index.d.ts +980 -0
  32. package/dist/components/input/index.js +334 -0
  33. package/dist/components/layout/index.d.ts +162 -0
  34. package/dist/components/layout/index.js +100 -0
  35. package/dist/components/list-view/index.d.ts +563 -0
  36. package/dist/components/list-view/index.js +221 -0
  37. package/dist/components/loading/index.d.ts +77 -0
  38. package/dist/components/loading/index.js +40 -0
  39. package/dist/components/nav/index.d.ts +293 -0
  40. package/dist/components/nav/index.js +164 -0
  41. package/dist/components/notice/index.d.ts +137 -0
  42. package/dist/components/notice/index.js +101 -0
  43. package/dist/components/notification/index.d.ts +118 -0
  44. package/dist/components/notification/index.js +99 -0
  45. package/dist/components/page/index.d.ts +276 -0
  46. package/dist/components/page/index.js +351 -0
  47. package/dist/components/page/split-resize.d.ts +42 -0
  48. package/dist/components/page/split-resize.js +36 -0
  49. package/dist/components/pagination/index.d.ts +171 -0
  50. package/dist/components/pagination/index.js +226 -0
  51. package/dist/components/panel/index.d.ts +401 -0
  52. package/dist/components/panel/index.js +193 -0
  53. package/dist/components/part-padding.d.ts +27 -0
  54. package/dist/components/part-padding.js +23 -0
  55. package/dist/components/query-state/index.d.ts +207 -0
  56. package/dist/components/query-state/index.js +181 -0
  57. package/dist/components/radio/index.d.ts +473 -0
  58. package/dist/components/radio/index.js +250 -0
  59. package/dist/components/search/index.d.ts +167 -0
  60. package/dist/components/search/index.js +105 -0
  61. package/dist/components/select/index.d.ts +252 -0
  62. package/dist/components/select/index.js +281 -0
  63. package/dist/components/skeleton/index.d.ts +88 -0
  64. package/dist/components/skeleton/index.js +56 -0
  65. package/dist/components/steps/index.d.ts +199 -0
  66. package/dist/components/steps/index.js +117 -0
  67. package/dist/components/switch/index.d.ts +150 -0
  68. package/dist/components/switch/index.js +103 -0
  69. package/dist/components/table/index.d.ts +351 -0
  70. package/dist/components/table/index.js +286 -0
  71. package/dist/components/tabs/index.d.ts +179 -0
  72. package/dist/components/tabs/index.js +153 -0
  73. package/dist/components/tabset/index.d.ts +105 -0
  74. package/dist/components/tabset/index.js +68 -0
  75. package/dist/components/tag/index.d.ts +203 -0
  76. package/dist/components/tag/index.js +144 -0
  77. package/dist/components/toast/index.d.ts +271 -0
  78. package/dist/components/toast/index.js +116 -0
  79. package/dist/components/tooltip/index.d.ts +126 -0
  80. package/dist/components/tooltip/index.js +97 -0
  81. package/dist/components/tree/index.d.ts +317 -0
  82. package/dist/components/tree/index.js +251 -0
  83. package/dist/components/upload/index.d.ts +384 -0
  84. package/dist/components/upload/index.js +172 -0
  85. package/dist/index.d.ts +63 -0
  86. package/dist/index.js +102 -0
  87. package/dist/services/base.d.ts +21 -0
  88. package/dist/services/base.js +42 -0
  89. package/dist/services/dialog.d.ts +41 -0
  90. package/dist/services/dialog.js +83 -0
  91. package/dist/services/index.d.ts +12 -0
  92. package/dist/services/loading.d.ts +21 -0
  93. package/dist/services/loading.js +41 -0
  94. package/dist/services/toast.d.ts +40 -0
  95. package/dist/services/toast.js +74 -0
  96. package/dist/styles/components/avatar.css +128 -0
  97. package/dist/styles/components/avatar.tokens.css +24 -0
  98. package/dist/styles/components/badge.css +237 -0
  99. package/dist/styles/components/button.css +454 -0
  100. package/dist/styles/components/button.tokens.css +56 -0
  101. package/dist/styles/components/capsule.css +120 -0
  102. package/dist/styles/components/capsule.tokens.css +27 -0
  103. package/dist/styles/components/card.css +192 -0
  104. package/dist/styles/components/checkbox.css +145 -0
  105. package/dist/styles/components/checkbox.tokens.css +26 -0
  106. package/dist/styles/components/code-editor.css +91 -0
  107. package/dist/styles/components/code-editor.tokens.css +24 -0
  108. package/dist/styles/components/code.css +153 -0
  109. package/dist/styles/components/code.tokens.css +29 -0
  110. package/dist/styles/components/collapse.css +62 -0
  111. package/dist/styles/components/collapse.tokens.css +20 -0
  112. package/dist/styles/components/dialog.css +106 -0
  113. package/dist/styles/components/dialog.tokens.css +24 -0
  114. package/dist/styles/components/divider.css +71 -0
  115. package/dist/styles/components/divider.tokens.css +21 -0
  116. package/dist/styles/components/drawer.css +143 -0
  117. package/dist/styles/components/drawer.tokens.css +22 -0
  118. package/dist/styles/components/filter.css +41 -0
  119. package/dist/styles/components/filter.tokens.css +14 -0
  120. package/dist/styles/components/form.css +220 -0
  121. package/dist/styles/components/form.tokens.css +15 -0
  122. package/dist/styles/components/input.css +445 -0
  123. package/dist/styles/components/input.tokens.css +41 -0
  124. package/dist/styles/components/layout.css +198 -0
  125. package/dist/styles/components/list-view.css +244 -0
  126. package/dist/styles/components/loading.css +76 -0
  127. package/dist/styles/components/loading.tokens.css +23 -0
  128. package/dist/styles/components/nav.css +48 -0
  129. package/dist/styles/components/notice.css +153 -0
  130. package/dist/styles/components/notice.tokens.css +17 -0
  131. package/dist/styles/components/notification.css +159 -0
  132. package/dist/styles/components/notification.tokens.css +37 -0
  133. package/dist/styles/components/page.css +473 -0
  134. package/dist/styles/components/pagination.css +297 -0
  135. package/dist/styles/components/pagination.tokens.css +32 -0
  136. package/dist/styles/components/panel.css +77 -0
  137. package/dist/styles/components/query-state.css +88 -0
  138. package/dist/styles/components/radio.css +271 -0
  139. package/dist/styles/components/radio.tokens.css +26 -0
  140. package/dist/styles/components/search.css +30 -0
  141. package/dist/styles/components/select.css +242 -0
  142. package/dist/styles/components/select.tokens.css +33 -0
  143. package/dist/styles/components/skeleton.css +60 -0
  144. package/dist/styles/components/skeleton.tokens.css +27 -0
  145. package/dist/styles/components/steps.css +157 -0
  146. package/dist/styles/components/steps.tokens.css +42 -0
  147. package/dist/styles/components/switch.css +165 -0
  148. package/dist/styles/components/switch.tokens.css +26 -0
  149. package/dist/styles/components/table.css +439 -0
  150. package/dist/styles/components/table.tokens.css +41 -0
  151. package/dist/styles/components/tabs.css +234 -0
  152. package/dist/styles/components/tabs.tokens.css +30 -0
  153. package/dist/styles/components/tag.css +200 -0
  154. package/dist/styles/components/tag.tokens.css +30 -0
  155. package/dist/styles/components/toast.css +150 -0
  156. package/dist/styles/components/toast.tokens.css +26 -0
  157. package/dist/styles/components/tooltip.css +89 -0
  158. package/dist/styles/components/tooltip.tokens.css +25 -0
  159. package/dist/styles/components/tree.css +139 -0
  160. package/dist/styles/components/tree.tokens.css +20 -0
  161. package/dist/styles/components/upload.css +150 -0
  162. package/dist/styles/components/upload.tokens.css +27 -0
  163. package/dist/styles/index.css +149 -0
  164. package/dist/styles/operations/collapse.css +84 -0
  165. package/dist/styles/operations/popup.css +189 -0
  166. package/dist/styles/operations/tabset.css +57 -0
  167. package/dist/utils/state-illustration.d.ts +31 -0
  168. package/dist/utils/state-illustration.js +156 -0
  169. package/package.json +62 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Tabs —— 页签条(下划线指示条 + 禁用 + 「更多」页签)。
3
+ *
4
+ * 出处:`@aihub/theme` 的 `playground/components/tabs.css` 与 `src/components/tabs.css`
5
+ * (区高 26 / 项间距 30 / 字号 14 / 指示条高 3、距文字 3、两端与文字同宽 / 未选字 `#446a9f` /
6
+ * 滑过 `#529dff` / 选中 `#4e94ff` / 禁用 Te07)。
7
+ *
8
+ * 三条必须照做的几何(做错一眼就歪):
9
+ *
10
+ * 1. **不画轨线**:规范明确警告 —— 页签区没有底边框,选中只由指示条表达;加轨线会扣走区高 1px。
11
+ * 「像不像页签」全靠那道 3px 指示条,不靠一条横线。
12
+ * 2. **指示条是每个项自己的伪元素**(`::after`),不是一条共享滑块:所有项的指示条常驻,未选 `opacity:0; scale:.75`,
13
+ * 选中转 `opacity:1; scale:1` —— "滑过去"的观感来自这两个属性的过渡(`display` 直切补间不了)。
14
+ * 3. **文字贴底**:项高 26 = 文字框 20 + 留白 3 + 指示条 3,故 `align-items:flex-end` +
15
+ * `padding-bottom = indicator-gap + indicator-height`。少了这段内距,指示条会压在字上。
16
+ *
17
+ * **三源等价**(本仓通例):原生 `:checked +` / 组件下发 `[data-state='active']` / 静态档 `.is-selected`
18
+ * 指向同一份声明 —— 原生态给零 JS 用法(原生 radio 互斥 + ← → 换页签),组件态给受控值。
19
+ */
20
+ .mh-tabs {
21
+ display: flex;
22
+ align-items: flex-end;
23
+ gap: var(--ui-tabs-gap);
24
+ height: var(--ui-tabs-height);
25
+ }
26
+
27
+ .mh-tabs__tab {
28
+ position: relative;
29
+ display: inline-flex;
30
+ align-items: flex-end;
31
+ height: 100%;
32
+ padding: 0 0 calc(var(--ui-tabs-indicator-gap) + var(--ui-tabs-indicator-height));
33
+ border: none;
34
+ background: transparent;
35
+ font-family: inherit;
36
+ font-size: var(--ui-tabs-font-size);
37
+ line-height: var(--ui-line-body);
38
+ color: var(--ui-tabs-text);
39
+ cursor: pointer;
40
+ white-space: nowrap;
41
+ }
42
+ /* 指示条:常驻、与文字同宽(不内缩),靠 opacity + scale 过渡出"滑动感" */
43
+ .mh-tabs__tab::after {
44
+ content: '';
45
+ position: absolute;
46
+ right: 0;
47
+ bottom: 0;
48
+ left: 0;
49
+ height: var(--ui-tabs-indicator-height);
50
+ border-radius: var(--ui-tabs-indicator-radius);
51
+ background: var(--ui-tabs-indicator);
52
+ opacity: 0;
53
+ scale: 0.75;
54
+ transition-property: opacity, scale;
55
+ transition-duration: 0.15s;
56
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
57
+ }
58
+
59
+ .mh-tabs__tab:hover {
60
+ color: var(--ui-tabs-text-hover);
61
+ }
62
+ .mh-tabs__tab:active {
63
+ color: var(--ui-tabs-text-active);
64
+ }
65
+
66
+ /* 选中(三源等价):字转主色 + 中粗,指示条亮起 */
67
+ .mh-tabs__tab.is-selected,
68
+ .mh-tabs__tab[data-state='active'],
69
+ .mh-tabs > input:checked + .mh-tabs__tab {
70
+ color: var(--ui-tabs-text-active);
71
+ font-weight: var(--ui-weight-medium);
72
+ }
73
+ .mh-tabs__tab.is-selected::after,
74
+ .mh-tabs__tab[data-state='active']::after,
75
+ .mh-tabs > input:checked + .mh-tabs__tab::after {
76
+ opacity: 1;
77
+ scale: 1;
78
+ }
79
+
80
+ /* 禁用(三源等价):字转弱、不可点 */
81
+ .mh-tabs__tab.is-disabled,
82
+ .mh-tabs__tab:disabled,
83
+ .mh-tabs > input:disabled + .mh-tabs__tab {
84
+ color: var(--ui-tabs-text-disabled);
85
+ cursor: not-allowed;
86
+ }
87
+ .mh-tabs__tab.is-disabled::after,
88
+ .mh-tabs__tab:disabled::after,
89
+ .mh-tabs > input:disabled + .mh-tabs__tab::after {
90
+ opacity: 0;
91
+ }
92
+
93
+ /* 「更多」页签:文字 + 转向箭头(字形来自 `@manohub/icon`,本层只排布) */
94
+ .mh-tabs__tab--more {
95
+ display: inline-flex;
96
+ align-items: center;
97
+ gap: var(--ui-space-1);
98
+ }
99
+
100
+ /* 原生路径的隐身开关:可聚焦但不可见(焦点环画在可见的项上) */
101
+ .mh-tabs > input {
102
+ position: absolute;
103
+ width: 1px;
104
+ height: 1px;
105
+ margin: -1px;
106
+ padding: 0;
107
+ border: 0;
108
+ overflow: hidden;
109
+ white-space: nowrap;
110
+ clip-path: inset(50%);
111
+ appearance: none;
112
+ pointer-events: none;
113
+ }
114
+
115
+ /* 键盘焦点环(两条路径各一处,不重叠) */
116
+ .mh-tabs__tab:focus-visible,
117
+ .mh-tabs > input:focus-visible + .mh-tabs__tab {
118
+ outline: 2px solid var(--ui-primary);
119
+ outline-offset: -2px;
120
+ }
121
+
122
+ /* ===== 居中档:页签少、要撑满整行时用 ===== */
123
+ .mh-tabs--centered {
124
+ justify-content: center;
125
+ }
126
+
127
+ /* ===== 尺寸档(只覆盖令牌) ===== */
128
+ .mh-tabs--sm {
129
+ --ui-tabs-height: var(--ui-control-height-sm);
130
+ --ui-tabs-font-size: var(--ui-font-caption);
131
+ --ui-tabs-gap: var(--ui-space-6);
132
+ }
133
+ .mh-tabs--lg {
134
+ --ui-tabs-height: var(--ui-control-height-lg);
135
+ --ui-tabs-font-size: var(--ui-font-heading);
136
+ }
137
+
138
+ /* ===== 选项卡形态(type="card") =====
139
+ * 与内容区连成一体:页签有边框与浅底,选中项转白底 + 顶部主色条;
140
+ * 底边刻意不画 —— 让内容区自己的上边框接上(面板的 bordered 档就是为此)。 */
141
+ .mh-tabs--card {
142
+ align-items: flex-end;
143
+ gap: var(--ui-space-1);
144
+ height: auto;
145
+ }
146
+ .mh-tabs--card .mh-tabs__tab {
147
+ align-items: center;
148
+ height: var(--ui-tabs-height);
149
+ padding: 0 var(--ui-tabs-card-padding-x);
150
+ border: 1px solid var(--ui-base-300);
151
+ border-bottom: none;
152
+ border-radius: var(--ui-radius-control) var(--ui-radius-control) 0 0;
153
+ background: var(--ui-base-200);
154
+ color: var(--ui-base-content-muted);
155
+ }
156
+ /* 卡片档不画指示条:选中由底色与顶边表达(两套选中语汇叠在一起会互相打架) */
157
+ .mh-tabs--card .mh-tabs__tab::after {
158
+ content: none;
159
+ }
160
+ .mh-tabs--card .mh-tabs__tab:hover {
161
+ color: var(--ui-primary);
162
+ }
163
+ .mh-tabs--card .mh-tabs__tab.is-selected,
164
+ .mh-tabs--card .mh-tabs__tab[data-state='active'],
165
+ .mh-tabs--card > input:checked + .mh-tabs__tab {
166
+ background: var(--ui-base-100);
167
+ color: var(--ui-primary);
168
+ box-shadow: inset 0 2px 0 var(--ui-primary);
169
+ }
170
+ .mh-tabs--card .mh-tabs__tab.is-disabled {
171
+ background: var(--ui-base-200);
172
+ color: var(--ui-tabs-text-disabled);
173
+ }
174
+
175
+ /* ===== 关闭位 =====
176
+ * 页签自己是 `<button>`,所以关闭位用 `<span role="button">`(按钮里嵌按钮是非法 HTML);
177
+ * 线上档的文字是「贴底」的,故关闭位要自己把底部内距补回来才与文字同一水平线。 */
178
+ .mh-tabs__close {
179
+ display: inline-flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ align-self: center;
183
+ flex: none;
184
+ width: 16px;
185
+ height: 16px;
186
+ margin-bottom: calc(var(--ui-tabs-indicator-gap) + var(--ui-tabs-indicator-height));
187
+ margin-left: var(--ui-space-1);
188
+ border-radius: var(--ui-radius-full);
189
+ color: inherit;
190
+ cursor: pointer;
191
+ opacity: 0.5;
192
+ transition: opacity 0.15s ease, background-color 0.15s ease;
193
+ }
194
+ .mh-tabs--card .mh-tabs__close {
195
+ margin-bottom: 0;
196
+ }
197
+ .mh-tabs__close > svg {
198
+ width: 12px;
199
+ height: 12px;
200
+ }
201
+ .mh-tabs__close:hover {
202
+ opacity: 1;
203
+ background: rgb(0 0 0 / 0.08);
204
+ }
205
+
206
+ /* ===== 新增位 ===== */
207
+ .mh-tabs__add {
208
+ display: inline-flex;
209
+ align-items: center;
210
+ justify-content: center;
211
+ flex: none;
212
+ width: var(--ui-tabs-height);
213
+ height: var(--ui-tabs-height);
214
+ padding: 0;
215
+ border: none;
216
+ border-radius: var(--ui-radius-control);
217
+ background: transparent;
218
+ color: var(--ui-base-content-muted);
219
+ cursor: pointer;
220
+ transition: background-color 0.15s ease, color 0.15s ease;
221
+ }
222
+ .mh-tabs__add > svg {
223
+ width: var(--ui-font-icon); /* 常规图标档 */
224
+ height: var(--ui-font-icon);
225
+ }
226
+ /* 「更多」的折叠箭头:改前无声明、掉到 `<svg>` 默认 16 —— 与新增位同取常规图标档 */
227
+ .mh-tabs__tab--more > svg {
228
+ width: var(--ui-font-icon);
229
+ height: var(--ui-font-icon);
230
+ }
231
+ .mh-tabs__add:hover {
232
+ background: var(--ui-base-200);
233
+ color: var(--ui-primary);
234
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * tabs —— 单件令牌(**基础值**)。
3
+ *
4
+ * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
+ *
6
+ * ## 抽出说明
7
+ * 本文件从面文件里抽出(原先混写在 `tabs.css` 顶部):这些是**基础值**,锚在
8
+ * `[data-manohub-ui]` —— 跨包唯一作用域锚,由入口层无条件写在应用容器上,因此**任何落在
9
+ * 容器里的分件都取得到值**,不再依赖「声明在某个组件根类上」这条脆弱假设
10
+ * (历史症状:跨件消费的 `--ui-*-group-*` 取不到值,组内间距变 0)。
11
+ *
12
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里 —— 它们靠「同一元素上两个
13
+ * 选择器改写同一个令牌」生效,搬到本文件会让档位失效。
14
+ * ⚠️ 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
15
+ */
16
+ [data-manohub-ui] {
17
+ /* 单件令牌 */
18
+ --ui-tabs-height: var(--ui-control-height-md); /* 标准控件高 32 */
19
+ --ui-tabs-gap: 30px; /* 项间距(规范实测) */
20
+ --ui-tabs-font-size: var(--ui-font-body);
21
+ --ui-tabs-text: var(--ui-base-content); /* 规范未选档 #446a9f(偏蓝的正文色),本仓取正文色 */
22
+ --ui-tabs-text-hover: var(--ui-primary-hover); /* 规范 #529dff */
23
+ --ui-tabs-text-active: var(--ui-primary); /* 规范 #4e94ff */
24
+ --ui-tabs-text-disabled: var(--ui-base-content-subtle); /* 规范 Te07 */
25
+ --ui-tabs-indicator: var(--ui-primary);
26
+ --ui-tabs-indicator-gap: 3px; /* 指示条与文字的留白 */
27
+ --ui-tabs-indicator-height: 3px;
28
+ --ui-tabs-indicator-radius: var(--ui-radius-full);
29
+ --ui-tabs-card-padding-x: var(--ui-space-4);
30
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Tag —— 标签(常规 / 状态 / 可选 / 新增 / 轻量筛选片)。
3
+ *
4
+ * 出处:`@aihub/theme` 的 `playground/components/tag.css` 与 `src/components/tag.css`
5
+ * (常规 24 高 / 大号 28;状态档 22 高、小圆角、四色语义;可选档胶囊 + 选中实底主色;
6
+ * 新增档虚线框;筛选项贴片底 + 主色字)。
7
+ *
8
+ * **与 `Badge` 的判据**:`Badge` 是**状态徽标**(固定短、要一眼看出状态色、有圆点/数字档);
9
+ * 本件是**内容标签**(描述性文字、可能可选/可加/可关闭,长度由内容决定)。两者不同族,别互相顶替。
10
+ *
11
+ * **状态档四色**直接用本仓语义令牌(`--ui-{info,success,warning,error}-weak` / 对应主色),
12
+ * 不新造一套色板 —— 与 `Badge` / `Notice` 同一批语义槽位。
13
+ *
14
+ * **高度三档与图标/关闭位尺寸都在本件令牌上**(`--ui-tag-*`):档位只覆盖令牌、不复制几何规则。
15
+ * 自定义色(`color` prop)经组件内联覆盖 `--ui-tag-bg`,故底色的取用点只有一处。
16
+ */
17
+ .mh-tag {
18
+ display: inline-flex;
19
+ align-items: center;
20
+ gap: var(--ui-tag-gap);
21
+ height: var(--ui-tag-height);
22
+ padding: 0 var(--ui-space-3);
23
+ border-radius: var(--ui-radius-control);
24
+ background: var(--ui-tag-bg);
25
+ color: var(--ui-primary);
26
+ font-size: var(--ui-tag-font-size);
27
+ line-height: 1;
28
+ white-space: nowrap;
29
+ }
30
+
31
+ /* ===== 尺寸档 =====
32
+ 20 档是设计稿里**唯一有实证**的标签尺寸(`0:2723` 36×20):小圆角 r3 + 12px 字。
33
+ 左右内距取 8 而不是设计反推的 6:6 不在本包的间距阶(4/8/12/16/20/24)上,
34
+ 为 4px 的总宽差破一档刻度不值当。 */
35
+ .mh-tag--sm {
36
+ height: var(--ui-tag-height-sm);
37
+ padding: 0 var(--ui-space-2);
38
+ border-radius: var(--ui-radius-xs);
39
+ font-size: var(--ui-font-micro);
40
+ }
41
+ .mh-tag--lg {
42
+ height: var(--ui-tag-height-lg);
43
+ }
44
+
45
+ /* ===== 前置图标与关闭位 ===== */
46
+ .mh-tag__icon {
47
+ flex: none;
48
+ width: var(--ui-tag-icon-size);
49
+ height: var(--ui-tag-icon-size);
50
+ }
51
+ .mh-tag__close {
52
+ display: inline-flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ flex: none;
56
+ width: var(--ui-tag-close-size);
57
+ height: var(--ui-tag-close-size);
58
+ margin-right: calc(-1 * var(--ui-space-1));
59
+ padding: 0;
60
+ border: none;
61
+ border-radius: var(--ui-radius-full);
62
+ background: transparent;
63
+ color: inherit;
64
+ cursor: pointer;
65
+ opacity: 0.65;
66
+ transition: opacity 0.15s ease, background-color 0.15s ease;
67
+ }
68
+ .mh-tag__close > svg {
69
+ flex: none;
70
+ width: 12px;
71
+ height: 12px;
72
+ }
73
+ .mh-tag__close:hover {
74
+ opacity: 1;
75
+ background: rgb(0 0 0 / 0.08);
76
+ }
77
+
78
+ /* ===== 描边档(布尔 prop `outline`):设计稿表格内标签的配方 = 浅主色底 + 浅主色边 =====
79
+ 设计实证 `0:2723`:36×20 / 底 `#eaefff` / 边 `#b7caff` / r3 / 字 12 —— 即
80
+ `size="sm"` + `outline` 两档合起来的样子。
81
+ ⚠️ **本条的配方改过**:改前是「透明底 + `1px solid currentColor`」(全色描边)。全色描边在浅底
82
+ 页面上过重,且与 `shape="status"` + `tone` 的观感打架(两者都成了「彩边」);设计给的正是
83
+ 「同色系浅边」。若某个页面确实需要「透明底 + 全色边」那种更硬的轮廓,请提需求另开形态,
84
+ 不要就地改回去。 */
85
+ .mh-tag--outline {
86
+ background: var(--ui-primary-weak);
87
+ border: 1px solid var(--ui-primary-border);
88
+ }
89
+
90
+ /* ===== 状态标签(22 高 / 四色语义)===== */
91
+ .mh-tag--status {
92
+ height: var(--ui-tag-height-status);
93
+ padding: 0 var(--ui-space-2);
94
+ }
95
+ .mh-tag--info {
96
+ background: var(--ui-info-weak);
97
+ color: var(--ui-info);
98
+ }
99
+ .mh-tag--success {
100
+ background: var(--ui-success-weak);
101
+ color: var(--ui-success);
102
+ }
103
+ .mh-tag--warning {
104
+ background: var(--ui-warning-weak);
105
+ color: var(--ui-warning);
106
+ }
107
+ .mh-tag--error {
108
+ background: var(--ui-error-weak);
109
+ color: var(--ui-error);
110
+ }
111
+
112
+ /* ===== 可选标签(胶囊;开关是隐身原生 radio,焦点环画在可见标签上)===== */
113
+ .mh-tag--select {
114
+ position: relative;
115
+ border: none;
116
+ border-radius: var(--ui-radius-full);
117
+ background: var(--ui-primary-weak);
118
+ color: var(--ui-primary);
119
+ cursor: pointer;
120
+ font-family: inherit;
121
+ }
122
+ .mh-tag--select > input {
123
+ position: absolute;
124
+ width: 1px;
125
+ height: 1px;
126
+ margin: -1px;
127
+ padding: 0;
128
+ border: 0;
129
+ overflow: hidden;
130
+ white-space: nowrap;
131
+ clip-path: inset(50%);
132
+ appearance: none;
133
+ pointer-events: none;
134
+ }
135
+ .mh-tag--select:hover {
136
+ background: var(--ui-base-50);
137
+ border: 1px solid var(--ui-base-300);
138
+ }
139
+ .mh-tag--select:has(input:focus-visible) {
140
+ outline: 2px solid var(--ui-primary);
141
+ outline-offset: -2px;
142
+ }
143
+ /* 选中:实底主色白字;三源等价(真实伪类 / 组件下发 / 静态档) */
144
+ .mh-tag--select.is-selected,
145
+ .mh-tag--select[data-state='selected'],
146
+ .mh-tag--select:has(input:checked) {
147
+ background: var(--ui-primary);
148
+ color: var(--ui-primary-content);
149
+ }
150
+ /* 选中态里的关闭位:底是主色,悬停用白蒙层而不是黑蒙层 */
151
+ .mh-tag--select.is-selected .mh-tag__close:hover,
152
+ .mh-tag--select:has(input:checked) .mh-tag__close:hover {
153
+ background: rgb(255 255 255 / 0.24);
154
+ }
155
+ /* 禁用:不可点 + 转弱 */
156
+ .mh-tag--select.is-disabled,
157
+ .mh-tag--select:has(input:disabled) {
158
+ background: var(--ui-base-200);
159
+ color: var(--ui-base-content-subtle);
160
+ cursor: not-allowed;
161
+ }
162
+
163
+ /* ===== 新增档(虚线框 + 加号由 @manohub/icon 的 plus 渲染)===== */
164
+ .mh-tag--add {
165
+ height: var(--ui-tag-height);
166
+ padding: 0 var(--ui-space-2);
167
+ border: 1px dashed var(--ui-base-400);
168
+ border-radius: var(--ui-radius-full);
169
+ background: transparent;
170
+ color: var(--ui-base-content-muted);
171
+ cursor: pointer;
172
+ font-family: inherit;
173
+ font-size: var(--ui-tag-font-size);
174
+ }
175
+ .mh-tag--add:hover {
176
+ border-color: var(--ui-primary-hover);
177
+ color: var(--ui-primary);
178
+ }
179
+ .mh-tag--add:active {
180
+ border-color: var(--ui-primary);
181
+ color: var(--ui-primary);
182
+ }
183
+
184
+ /* ===== 轻量筛选片(浅底 + 主色字)===== */
185
+ .mh-tag--chip {
186
+ height: var(--ui-tag-height-sm);
187
+ padding: 0 var(--ui-space-2);
188
+ border: none;
189
+ border-radius: var(--ui-radius-full);
190
+ background: var(--ui-primary-weak);
191
+ color: var(--ui-primary);
192
+ font-family: inherit;
193
+ font-size: var(--ui-font-caption);
194
+ cursor: pointer;
195
+ }
196
+ .mh-tag--chip[data-state='active'],
197
+ .mh-tag--chip.is-active {
198
+ background: var(--ui-primary);
199
+ color: var(--ui-primary-content);
200
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * tag —— 单件令牌(**基础值**)。
3
+ *
4
+ * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
+ *
6
+ * ## 抽出说明
7
+ * 本文件从面文件里抽出(原先混写在 `tag.css` 顶部):这些是**基础值**,锚在
8
+ * `[data-manohub-ui]` —— 跨包唯一作用域锚,由入口层无条件写在应用容器上,因此**任何落在
9
+ * 容器里的分件都取得到值**,不再依赖「声明在某个组件根类上」这条脆弱假设
10
+ * (历史症状:跨件消费的 `--ui-*-group-*` 取不到值,组内间距变 0)。
11
+ *
12
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里 —— 它们靠「同一元素上两个
13
+ * 选择器改写同一个令牌」生效,搬到本文件会让档位失效。
14
+ * ⚠️ 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
15
+ */
16
+ [data-manohub-ui] {
17
+ /* 单件令牌。
18
+ 软底**只有一档**:改前是 `#e1edff`(24) 与 `#f0faff`(28) 两个字面量,与主题的主色浅底档
19
+ `--ui-primary-weak`(#EFF5FF) 差 ≤ 6/255 —— 三个近值并存的典型症状,本轮并入主题档。
20
+ 设计实证:表格内标签 `0:2723` 底 `#eaefff`。 */
21
+ --ui-tag-bg: var(--ui-primary-weak);
22
+ --ui-tag-height: 24px;
23
+ --ui-tag-height-sm: 20px;
24
+ --ui-tag-height-lg: 28px;
25
+ --ui-tag-height-status: 22px;
26
+ --ui-tag-font-size: var(--ui-font-caption);
27
+ --ui-tag-icon-size: var(--ui-font-icon); /* 常规图标档(本件不再自定数值) */
28
+ --ui-tag-close-size: 14px;
29
+ --ui-tag-gap: var(--ui-space-1);
30
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Toast —— 消息提示(一行提示 + 语义图标 + 可选动作;可堆叠)。
3
+ *
4
+ * 出处:`@aihub/theme` 的 `playground/components/toast.css` 与 `src/components/toast.css`
5
+ * (宽 240 / 最大 560 / 最小高 52 / r8 / 1px 描边 / 内距 10 16 10 24 / 图标 18 圆 / 图标与文字间距 12 /
6
+ * 投影 `0 2 12` 黑 10% / 正文 15;loading 样张 240x93 且图标顶对齐;带动作样张宽 360)。
7
+ *
8
+ * **与规范的一处有意偏差**:loading 那张 240x93 的样张是「多行加载文案」的尺寸,照搬成最小高后,
9
+ * 单行提示会撑出一张上挤下空的空卡 —— 故本档高度回归常态(与其它档同为 52 起,内容多时自然撑高),
10
+ * 只保留图标差异(透明底 + 主色转圈)。
11
+ *
12
+ * 三件事必须与规范一致(容易做错):
13
+ *
14
+ * 1. **图标是「圆形色底 + 白色字形」**,不是一个字形图标 —— 只有 loading 例外(透明底 + 2px 主色描边,
15
+ * **上边留缺口**造成转圈感);
16
+ * 2. **动作按钮靠 `margin-left: auto` 顶到最右**,不是跟在文字后面;
17
+ * 3. **转圈动画的键名归本族**(`mh-toast-spin`):动画名是全局标识,加 `mh-` 前缀避免与页面上别的库撞名。
18
+ *
19
+ * 零 JS 能表达的:全部静态形态 + 转圈。**必须 JS**:自动消失计时、多条的出队、以及把 loading 换成结果态
20
+ * (那三件都在组件层,本面不预设)。
21
+ *
22
+ * 堆叠容器(`.mh-toast-stack`)是随本族给的一层薄皮:定在视口顶部居中、纵向 8 间距 —— 位置与堆叠是
23
+ * 「一族怎么摆」的事,做成类比让每个应用各写一份靠谱。
24
+ */
25
+ .mh-toast {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: var(--ui-toast-gap);
29
+ width: var(--ui-toast-width);
30
+ max-width: var(--ui-toast-width-max);
31
+ min-height: var(--ui-toast-min-height);
32
+ padding: var(--ui-space-3) var(--ui-space-4) var(--ui-space-3) var(--ui-space-6);
33
+ border: 1px solid var(--ui-toast-border);
34
+ border-radius: var(--ui-toast-radius);
35
+ background: var(--ui-base-100);
36
+ box-shadow: var(--ui-shadow-elevated);
37
+ }
38
+
39
+ /* loading:**不另设样张高**(高度与其它档一致,见文件头的「有意偏差」)—— 本档只差图标(转圈) */
40
+ /* 带动作:更宽的样张宽 */
41
+ .mh-toast--action {
42
+ width: 360px;
43
+ }
44
+
45
+ /* 图标:圆形色底 + 白色字形(18×18) */
46
+ .mh-toast__icon {
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ flex: none;
51
+ width: var(--ui-toast-icon-size);
52
+ height: var(--ui-toast-icon-size);
53
+ border-radius: var(--ui-radius-full);
54
+ color: var(--ui-base-100);
55
+ font-size: var(--ui-font-caption);
56
+ line-height: 1;
57
+ }
58
+ .mh-toast__icon--info {
59
+ background: var(--ui-info);
60
+ }
61
+ .mh-toast__icon--success {
62
+ background: var(--ui-success);
63
+ }
64
+ .mh-toast__icon--warning {
65
+ background: var(--ui-warning);
66
+ }
67
+ .mh-toast__icon--error {
68
+ background: var(--ui-error);
69
+ }
70
+ /* loading 档:透明底 + 主色字形 + 匀速转圈。
71
+ 规范此处是「2px 描边 + 上边缺口」的自画法,本仓改用意形(图标包的 `loading`)——
72
+ 硬约束是「图标一律来自图标包、不用文字符号或自画形状冒充」,视觉等价(都是转圈环)。 */
73
+ .mh-toast__icon--loading {
74
+ background: transparent;
75
+ color: var(--ui-primary);
76
+ animation: mh-toast-spin 0.8s linear infinite;
77
+ }
78
+ @keyframes mh-toast-spin {
79
+ to {
80
+ transform: rotate(360deg);
81
+ }
82
+ }
83
+
84
+ .mh-toast__text {
85
+ /* 占满剩余宽度:动作位 / 关闭位都被顶到右端。
86
+ 不写成「每个右侧位各给 margin-left: auto」—— 两个 auto 会平分剩余空间,
87
+ 而本族的常驻提示可能同时带动作与关闭位(那样动作钮会被推到卡片中间)。 */
88
+ flex: 1;
89
+ min-width: 0;
90
+ margin: 0;
91
+ font-size: var(--ui-toast-text-size);
92
+ line-height: var(--ui-line-body);
93
+ color: var(--ui-base-content);
94
+ }
95
+
96
+ /* 动作位:文本按钮样,顶到最右(面归按钮族时可直接用 `.mh-button--text`,本类只给定位与默认字色) */
97
+ .mh-toast__action {
98
+ margin-left: auto;
99
+ padding: 0;
100
+ border: none;
101
+ background: transparent;
102
+ font-family: inherit;
103
+ font-size: var(--ui-font-caption);
104
+ color: var(--ui-primary);
105
+ cursor: pointer;
106
+ }
107
+ .mh-toast__action:focus-visible {
108
+ outline: 2px solid var(--ui-primary);
109
+ outline-offset: 2px;
110
+ }
111
+
112
+ /* ===== 堆叠容器(顶部居中、纵向 8) ===== */
113
+ .mh-toast-stack {
114
+ position: fixed;
115
+ top: var(--ui-space-6);
116
+ left: 50%;
117
+ transform: translateX(-50%);
118
+ z-index: 1080; /* 高于页面内容、低于模态层(原生 <dialog> 的 top layer 不受影响) */
119
+ display: flex;
120
+ flex-direction: column;
121
+ gap: var(--ui-space-2);
122
+ align-items: center;
123
+ pointer-events: none; /* 容器不挡点击;每条自己恢复 */
124
+ }
125
+ .mh-toast-stack > .mh-toast {
126
+ pointer-events: auto;
127
+ }
128
+
129
+ /* ===== 关闭位(`duration=0` 的常驻提示必须给用户一个关掉的入口) =====
130
+ 靠右由 `.mh-toast__text` 的弹性占位实现 —— 本件不写 `margin-left: auto`:
131
+ 与动作位同时存在时两个 auto 会平分剩余空间,反而把动作钮推到卡片中间 */
132
+ .mh-toast__close {
133
+ display: inline-flex;
134
+ align-items: center;
135
+ justify-content: center;
136
+ flex: none;
137
+ padding: 0;
138
+ border: none;
139
+ background: transparent;
140
+ color: inherit;
141
+ cursor: pointer;
142
+ opacity: 0.7;
143
+ transition: opacity 0.15s ease;
144
+ }
145
+ .mh-toast__close:hover {
146
+ opacity: 1;
147
+ }
148
+ .mh-toast__close-icon {
149
+ flex: none;
150
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * toast —— 单件令牌(**基础值**)。
3
+ *
4
+ * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
+ *
6
+ * ## 抽出说明
7
+ * 本文件从面文件里抽出(原先混写在 `toast.css` 顶部):这些是**基础值**,锚在
8
+ * `[data-manohub-ui]` —— 跨包唯一作用域锚,由入口层无条件写在应用容器上,因此**任何落在
9
+ * 容器里的分件都取得到值**,不再依赖「声明在某个组件根类上」这条脆弱假设
10
+ * (历史症状:跨件消费的 `--ui-*-group-*` 取不到值,组内间距变 0)。
11
+ *
12
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里 —— 它们靠「同一元素上两个
13
+ * 选择器改写同一个令牌」生效,搬到本文件会让档位失效。
14
+ * ⚠️ 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
15
+ */
16
+ [data-manohub-ui] {
17
+ /* 单件令牌 */
18
+ --ui-toast-width: 240px;
19
+ --ui-toast-width-max: 560px;
20
+ --ui-toast-min-height: 52px;
21
+ --ui-toast-radius: var(--ui-radius-md); /* 规范 r8 */
22
+ --ui-toast-border: var(--ui-base-300); /* 规范 #d8dce6 */
23
+ --ui-toast-gap: var(--ui-space-3); /* 图标与文字间距 12 */
24
+ --ui-toast-icon-size: 18px;
25
+ --ui-toast-text-size: 15px; /* 规范实测(本仓字阶无 15,按实测值给) */
26
+ }