@manohub/ui 0.6.1 → 0.7.1

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 (69) hide show
  1. package/README.md +12 -4
  2. package/dist/components/button/index.d.ts +8 -8
  3. package/dist/components/capsule/index.d.ts +13 -9
  4. package/dist/components/capsule/index.js +1 -1
  5. package/dist/components/card/index.js +7 -4
  6. package/dist/components/checkbox/index.js +1 -0
  7. package/dist/components/dialog/index.d.ts +58 -6
  8. package/dist/components/dialog/index.js +45 -8
  9. package/dist/components/drawer/index.d.ts +18 -6
  10. package/dist/components/drawer/index.js +11 -5
  11. package/dist/components/form/index.d.ts +115 -17
  12. package/dist/components/form/index.js +39 -9
  13. package/dist/components/input/index.d.ts +4 -4
  14. package/dist/components/input/index.js +1 -1
  15. package/dist/components/layout/index.d.ts +43 -1
  16. package/dist/components/layout/index.js +22 -2
  17. package/dist/components/notice/index.d.ts +24 -11
  18. package/dist/components/notice/index.js +11 -5
  19. package/dist/components/notification/index.d.ts +2 -2
  20. package/dist/components/page/index.js +4 -4
  21. package/dist/components/panel/index.js +4 -4
  22. package/dist/components/part-padding.d.ts +9 -6
  23. package/dist/components/part-padding.js +2 -1
  24. package/dist/components/radio/index.d.ts +1 -1
  25. package/dist/components/radio/index.js +1 -0
  26. package/dist/components/search/index.d.ts +26 -6
  27. package/dist/components/search/index.js +22 -4
  28. package/dist/components/steps/index.d.ts +232 -6
  29. package/dist/components/steps/index.js +84 -26
  30. package/dist/components/switch/index.d.ts +29 -5
  31. package/dist/components/switch/index.js +8 -2
  32. package/dist/components/tabbar/index.d.ts +184 -0
  33. package/dist/components/tabbar/index.js +161 -0
  34. package/dist/components/table/index.d.ts +74 -8
  35. package/dist/components/table/index.js +69 -16
  36. package/dist/components/tabs/index.d.ts +145 -125
  37. package/dist/components/tabs/index.js +93 -117
  38. package/dist/components/tag/index.d.ts +2 -2
  39. package/dist/components/text/index.d.ts +120 -0
  40. package/dist/components/text/index.js +55 -0
  41. package/dist/components/toast/index.d.ts +8 -8
  42. package/dist/components/toast/index.js +11 -2
  43. package/dist/components/upload/index.d.ts +30 -0
  44. package/dist/components/upload/index.js +7 -1
  45. package/dist/index.d.ts +6 -5
  46. package/dist/index.js +6 -3
  47. package/dist/services/dialog.d.ts +20 -5
  48. package/dist/services/dialog.js +8 -1
  49. package/dist/styles/components/capsule.css +4 -4
  50. package/dist/styles/components/dialog.css +40 -1
  51. package/dist/styles/components/form.css +206 -26
  52. package/dist/styles/components/input.css +29 -2
  53. package/dist/styles/components/layout.css +2 -0
  54. package/dist/styles/components/select.css +11 -0
  55. package/dist/styles/components/steps.css +48 -0
  56. package/dist/styles/components/{tabs.css → tabbar.css} +66 -65
  57. package/dist/styles/components/tabbar.tokens.css +30 -0
  58. package/dist/styles/components/table.css +50 -1
  59. package/dist/styles/components/table.tokens.css +3 -0
  60. package/dist/styles/components/text.css +101 -0
  61. package/dist/styles/components/toast.css +12 -6
  62. package/dist/styles/index.css +8 -4
  63. package/dist/styles/operations/tabs.css +73 -0
  64. package/dist/styles/reset.css +205 -0
  65. package/package.json +2 -2
  66. package/dist/components/tabset/index.d.ts +0 -105
  67. package/dist/components/tabset/index.js +0 -68
  68. package/dist/styles/components/tabs.tokens.css +0 -30
  69. package/dist/styles/operations/tabset.css +0 -57
@@ -131,6 +131,17 @@
131
131
  width: 100%;
132
132
  height: var(--ui-select-option-height);
133
133
  padding: 0 var(--ui-select-padding-x);
134
+ /* **按钮重置四条,必须自带**:本行是 `<button role="option">`,而按钮自带 UA 外观
135
+ (`border: 2px outset` / `background: ButtonFace` / `font-family: Arial` / `text-align: center`)。
136
+ reset 层(`styles/reset.css`)虽然也清零了前三条,但组件面**不得依赖它** ——
137
+ 本仓的 0.6.x 就漏了这四条,表现为选项行呈原生按钮外观(灰底 + 立体边框 + 居中 Arial),
138
+ 而同一面板里的 `.mh-select__add` 写齐了 ⇒ 一个面板里两种外观。
139
+ `text-align` 是 reset 层**没有**的一项(它不属于「元素基线」,属于「列表行」语义),故此处必写。
140
+ 色彩 / 字族这些**值**仍然归令牌,这四条只是把 UA 的默认值归零。 */
141
+ border: none;
142
+ background: transparent;
143
+ font-family: inherit;
144
+ text-align: left;
134
145
  font-size: var(--ui-select-font-size);
135
146
  color: var(--ui-base-content);
136
147
  cursor: pointer;
@@ -13,6 +13,8 @@
13
13
  *
14
14
  * 连线用**独立空元素**(`.mh-steps__connector`)而不是 `.mh-steps__step + ::after`:折角箭头要撑开弹性余量,
15
15
  * 且 N 个节点配 N-1 条线,独立元素才能让两端节点各自保持自己的标题宽度。
16
+ *
17
+ * 可点档(`clickable`)下步元素是**原生 `<button>`** —— 归零、焦点环、禁用态见文件中间那节。
16
18
  */
17
19
 
18
20
  /* 几何只挂在 node 档根件上:令牌在同名 `.tokens.css`(锚 `[data-manohub-ui]`),几何若跟着挂会给 bar / 进度条多套一层 flex */
@@ -132,6 +134,52 @@
132
134
  filter: drop-shadow(0 4px 5px color-mix(in srgb, var(--ui-primary) 30%, transparent));
133
135
  }
134
136
 
137
+ /* ===== 可点档与禁用态(`clickable`)=====
138
+ 可点档把步元素换成**原生 `<button>`**(键盘 Tab/Enter、`:focus-visible`、`disabled` 都交浏览器),
139
+ 于是这里只剩两件事:把 UA 默认外观归零、给禁用与焦点一份视觉。 */
140
+
141
+ /* 归零。**用 `:where()` 把本档特异性压到 0**:它只该清掉 UA 的 button 默认外观,
142
+ 件自己的几何 / 字号 / 配色(上面 `.mh-steps__seg` 那几条)必须原样生效。
143
+ 若用普通类选择器(0-1-0),这里的 `padding: 0` 会与 `.mh-steps__seg` 的
144
+ `padding-left`(让开燕尾尖)打平、靠源序决胜 —— `:where()` 让那条稳赢,也省得以后
145
+ 调文件顺序就把段条弄坏。 */
146
+ :where(.mh-steps__step--clickable, .mh-steps__seg--clickable) {
147
+ appearance: none;
148
+ border: 0;
149
+ padding: 0;
150
+ margin: 0;
151
+ background: none;
152
+ font: inherit;
153
+ color: inherit;
154
+ text-align: inherit;
155
+ cursor: pointer;
156
+ }
157
+
158
+ /* 键盘焦点环(与 button / radio / tag 同一句)。
159
+ 外扩 2px 而不是按钮那套 `-2px`:步元素没内距,内缩会把环画在节点圆与标题上 */
160
+ .mh-steps__step--clickable:focus-visible,
161
+ .mh-steps__seg--clickable:focus-visible {
162
+ outline: 2px solid var(--ui-primary);
163
+ outline-offset: 2px;
164
+ border-radius: var(--ui-radius-sm);
165
+ }
166
+
167
+ /* 禁用态:原生 `disabled` 已经挡住了点击与键盘序列,这里只补视觉。
168
+ 节点 / 段底**不动** —— 它的「已完成 / 当前」状态语义仍然成立,禁用只表示
169
+ 「这一步现在不能跳」,不是「这一步不存在」。
170
+ 段条另排 `:not(--active)`:当前段本来是主色底 + 反白字,把它的字色降成 subtle 会读不清;
171
+ 而且「当前段」本来也不该被画成禁用。 */
172
+ .mh-steps__step--disabled,
173
+ .mh-steps__seg--disabled {
174
+ cursor: not-allowed;
175
+ }
176
+ .mh-steps__step--disabled .mh-steps__title {
177
+ color: var(--ui-base-content-subtle);
178
+ }
179
+ .mh-steps__seg--disabled:not(.mh-steps__seg--active) {
180
+ color: var(--ui-base-content-subtle);
181
+ }
182
+
135
183
  /* ===== 进度条(规范只有令牌、无标记示例;与对话框的进程条共用) ===== */
136
184
  .mh-steps__progress {
137
185
  height: var(--ui-steps-progress-height);
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Tabs —— 页签条(下划线指示条 + 禁用 + 「更多」页签)。
2
+ * TabBar —— 页签条(下划线指示条 + 禁用 + 「更多」页签)。
3
3
  *
4
- * 出处:`@aihub/theme` 的 `playground/components/tabs.css` 与 `src/components/tabs.css`
4
+ * 出处:`@aihub/theme` 的 `playground/components/tabbar.css` 与 `src/components/tabbar.css`
5
5
  * (区高 26 / 项间距 30 / 字号 14 / 指示条高 3、距文字 3、两端与文字同宽 / 未选字 `#446a9f` /
6
6
  * 滑过 `#529dff` / 选中 `#4e94ff` / 禁用 Te07)。
7
7
  *
@@ -17,38 +17,39 @@
17
17
  * **三源等价**(本仓通例):原生 `:checked +` / 组件下发 `[data-state='active']` / 静态档 `.is-selected`
18
18
  * 指向同一份声明 —— 原生态给零 JS 用法(原生 radio 互斥 + ← → 换页签),组件态给受控值。
19
19
  */
20
- .mh-tabs {
20
+ .mh-tabbar {
21
21
  display: flex;
22
22
  align-items: flex-end;
23
- gap: var(--ui-tabs-gap);
24
- height: var(--ui-tabs-height);
23
+ gap: var(--ui-tabbar-gap);
24
+ height: var(--ui-tabbar-height);
25
+ flex-shrink: 0;
25
26
  }
26
27
 
27
- .mh-tabs__tab {
28
+ .mh-tabbar__tab {
28
29
  position: relative;
29
30
  display: inline-flex;
30
31
  align-items: flex-end;
31
32
  height: 100%;
32
- padding: 0 0 calc(var(--ui-tabs-indicator-gap) + var(--ui-tabs-indicator-height));
33
+ padding: 0 0 calc(var(--ui-tabbar-indicator-gap) + var(--ui-tabbar-indicator-height));
33
34
  border: none;
34
35
  background: transparent;
35
36
  font-family: inherit;
36
- font-size: var(--ui-tabs-font-size);
37
+ font-size: var(--ui-tabbar-font-size);
37
38
  line-height: var(--ui-line-body);
38
- color: var(--ui-tabs-text);
39
+ color: var(--ui-tabbar-text);
39
40
  cursor: pointer;
40
41
  white-space: nowrap;
41
42
  }
42
43
  /* 指示条:常驻、与文字同宽(不内缩),靠 opacity + scale 过渡出"滑动感" */
43
- .mh-tabs__tab::after {
44
+ .mh-tabbar__tab::after {
44
45
  content: '';
45
46
  position: absolute;
46
47
  right: 0;
47
48
  bottom: 0;
48
49
  left: 0;
49
- height: var(--ui-tabs-indicator-height);
50
- border-radius: var(--ui-tabs-indicator-radius);
51
- background: var(--ui-tabs-indicator);
50
+ height: var(--ui-tabbar-indicator-height);
51
+ border-radius: var(--ui-tabbar-indicator-radius);
52
+ background: var(--ui-tabbar-indicator);
52
53
  opacity: 0;
53
54
  scale: 0.75;
54
55
  transition-property: opacity, scale;
@@ -56,49 +57,49 @@
56
57
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
57
58
  }
58
59
 
59
- .mh-tabs__tab:hover {
60
- color: var(--ui-tabs-text-hover);
60
+ .mh-tabbar__tab:hover {
61
+ color: var(--ui-tabbar-text-hover);
61
62
  }
62
- .mh-tabs__tab:active {
63
- color: var(--ui-tabs-text-active);
63
+ .mh-tabbar__tab:active {
64
+ color: var(--ui-tabbar-text-active);
64
65
  }
65
66
 
66
67
  /* 选中(三源等价):字转主色 + 中粗,指示条亮起 */
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);
68
+ .mh-tabbar__tab.is-selected,
69
+ .mh-tabbar__tab[data-state='active'],
70
+ .mh-tabbar > input:checked + .mh-tabbar__tab {
71
+ color: var(--ui-tabbar-text-active);
71
72
  font-weight: var(--ui-weight-medium);
72
73
  }
73
- .mh-tabs__tab.is-selected::after,
74
- .mh-tabs__tab[data-state='active']::after,
75
- .mh-tabs > input:checked + .mh-tabs__tab::after {
74
+ .mh-tabbar__tab.is-selected::after,
75
+ .mh-tabbar__tab[data-state='active']::after,
76
+ .mh-tabbar > input:checked + .mh-tabbar__tab::after {
76
77
  opacity: 1;
77
78
  scale: 1;
78
79
  }
79
80
 
80
81
  /* 禁用(三源等价):字转弱、不可点 */
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);
82
+ .mh-tabbar__tab.is-disabled,
83
+ .mh-tabbar__tab:disabled,
84
+ .mh-tabbar > input:disabled + .mh-tabbar__tab {
85
+ color: var(--ui-tabbar-text-disabled);
85
86
  cursor: not-allowed;
86
87
  }
87
- .mh-tabs__tab.is-disabled::after,
88
- .mh-tabs__tab:disabled::after,
89
- .mh-tabs > input:disabled + .mh-tabs__tab::after {
88
+ .mh-tabbar__tab.is-disabled::after,
89
+ .mh-tabbar__tab:disabled::after,
90
+ .mh-tabbar > input:disabled + .mh-tabbar__tab::after {
90
91
  opacity: 0;
91
92
  }
92
93
 
93
94
  /* 「更多」页签:文字 + 转向箭头(字形来自 `@manohub/icon`,本层只排布) */
94
- .mh-tabs__tab--more {
95
+ .mh-tabbar__tab--more {
95
96
  display: inline-flex;
96
97
  align-items: center;
97
98
  gap: var(--ui-space-1);
98
99
  }
99
100
 
100
101
  /* 原生路径的隐身开关:可聚焦但不可见(焦点环画在可见的项上) */
101
- .mh-tabs > input {
102
+ .mh-tabbar > input {
102
103
  position: absolute;
103
104
  width: 1px;
104
105
  height: 1px;
@@ -113,40 +114,40 @@
113
114
  }
114
115
 
115
116
  /* 键盘焦点环(两条路径各一处,不重叠) */
116
- .mh-tabs__tab:focus-visible,
117
- .mh-tabs > input:focus-visible + .mh-tabs__tab {
117
+ .mh-tabbar__tab:focus-visible,
118
+ .mh-tabbar > input:focus-visible + .mh-tabbar__tab {
118
119
  outline: 2px solid var(--ui-primary);
119
120
  outline-offset: -2px;
120
121
  }
121
122
 
122
123
  /* ===== 居中档:页签少、要撑满整行时用 ===== */
123
- .mh-tabs--centered {
124
+ .mh-tabbar--centered {
124
125
  justify-content: center;
125
126
  }
126
127
 
127
128
  /* ===== 尺寸档(只覆盖令牌) ===== */
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);
129
+ .mh-tabbar--sm {
130
+ --ui-tabbar-height: var(--ui-control-height-sm);
131
+ --ui-tabbar-font-size: var(--ui-font-caption);
132
+ --ui-tabbar-gap: var(--ui-space-6);
132
133
  }
133
- .mh-tabs--lg {
134
- --ui-tabs-height: var(--ui-control-height-lg);
135
- --ui-tabs-font-size: var(--ui-font-heading);
134
+ .mh-tabbar--lg {
135
+ --ui-tabbar-height: var(--ui-control-height-lg);
136
+ --ui-tabbar-font-size: var(--ui-font-heading);
136
137
  }
137
138
 
138
139
  /* ===== 选项卡形态(type="card") =====
139
140
  * 与内容区连成一体:页签有边框与浅底,选中项转白底 + 顶部主色条;
140
141
  * 底边刻意不画 —— 让内容区自己的上边框接上(面板的 bordered 档就是为此)。 */
141
- .mh-tabs--card {
142
+ .mh-tabbar--card {
142
143
  align-items: flex-end;
143
144
  gap: var(--ui-space-1);
144
145
  height: auto;
145
146
  }
146
- .mh-tabs--card .mh-tabs__tab {
147
+ .mh-tabbar--card .mh-tabbar__tab {
147
148
  align-items: center;
148
- height: var(--ui-tabs-height);
149
- padding: 0 var(--ui-tabs-card-padding-x);
149
+ height: var(--ui-tabbar-height);
150
+ padding: 0 var(--ui-tabbar-card-padding-x);
150
151
  border: 1px solid var(--ui-base-300);
151
152
  border-bottom: none;
152
153
  border-radius: var(--ui-radius-control) var(--ui-radius-control) 0 0;
@@ -154,28 +155,28 @@
154
155
  color: var(--ui-base-content-muted);
155
156
  }
156
157
  /* 卡片档不画指示条:选中由底色与顶边表达(两套选中语汇叠在一起会互相打架) */
157
- .mh-tabs--card .mh-tabs__tab::after {
158
+ .mh-tabbar--card .mh-tabbar__tab::after {
158
159
  content: none;
159
160
  }
160
- .mh-tabs--card .mh-tabs__tab:hover {
161
+ .mh-tabbar--card .mh-tabbar__tab:hover {
161
162
  color: var(--ui-primary);
162
163
  }
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 {
164
+ .mh-tabbar--card .mh-tabbar__tab.is-selected,
165
+ .mh-tabbar--card .mh-tabbar__tab[data-state='active'],
166
+ .mh-tabbar--card > input:checked + .mh-tabbar__tab {
166
167
  background: var(--ui-base-100);
167
168
  color: var(--ui-primary);
168
169
  box-shadow: inset 0 2px 0 var(--ui-primary);
169
170
  }
170
- .mh-tabs--card .mh-tabs__tab.is-disabled {
171
+ .mh-tabbar--card .mh-tabbar__tab.is-disabled {
171
172
  background: var(--ui-base-200);
172
- color: var(--ui-tabs-text-disabled);
173
+ color: var(--ui-tabbar-text-disabled);
173
174
  }
174
175
 
175
176
  /* ===== 关闭位 =====
176
177
  * 页签自己是 `<button>`,所以关闭位用 `<span role="button">`(按钮里嵌按钮是非法 HTML);
177
178
  * 线上档的文字是「贴底」的,故关闭位要自己把底部内距补回来才与文字同一水平线。 */
178
- .mh-tabs__close {
179
+ .mh-tabbar__close {
179
180
  display: inline-flex;
180
181
  align-items: center;
181
182
  justify-content: center;
@@ -183,7 +184,7 @@
183
184
  flex: none;
184
185
  width: 16px;
185
186
  height: 16px;
186
- margin-bottom: calc(var(--ui-tabs-indicator-gap) + var(--ui-tabs-indicator-height));
187
+ margin-bottom: calc(var(--ui-tabbar-indicator-gap) + var(--ui-tabbar-indicator-height));
187
188
  margin-left: var(--ui-space-1);
188
189
  border-radius: var(--ui-radius-full);
189
190
  color: inherit;
@@ -191,26 +192,26 @@
191
192
  opacity: 0.5;
192
193
  transition: opacity 0.15s ease, background-color 0.15s ease;
193
194
  }
194
- .mh-tabs--card .mh-tabs__close {
195
+ .mh-tabbar--card .mh-tabbar__close {
195
196
  margin-bottom: 0;
196
197
  }
197
- .mh-tabs__close > svg {
198
+ .mh-tabbar__close > svg {
198
199
  width: 12px;
199
200
  height: 12px;
200
201
  }
201
- .mh-tabs__close:hover {
202
+ .mh-tabbar__close:hover {
202
203
  opacity: 1;
203
204
  background: rgb(0 0 0 / 0.08);
204
205
  }
205
206
 
206
207
  /* ===== 新增位 ===== */
207
- .mh-tabs__add {
208
+ .mh-tabbar__add {
208
209
  display: inline-flex;
209
210
  align-items: center;
210
211
  justify-content: center;
211
212
  flex: none;
212
- width: var(--ui-tabs-height);
213
- height: var(--ui-tabs-height);
213
+ width: var(--ui-tabbar-height);
214
+ height: var(--ui-tabbar-height);
214
215
  padding: 0;
215
216
  border: none;
216
217
  border-radius: var(--ui-radius-control);
@@ -219,16 +220,16 @@
219
220
  cursor: pointer;
220
221
  transition: background-color 0.15s ease, color 0.15s ease;
221
222
  }
222
- .mh-tabs__add > svg {
223
+ .mh-tabbar__add > svg {
223
224
  width: var(--ui-font-icon); /* 常规图标档 */
224
225
  height: var(--ui-font-icon);
225
226
  }
226
227
  /* 「更多」的折叠箭头:改前无声明、掉到 `<svg>` 默认 16 —— 与新增位同取常规图标档 */
227
- .mh-tabs__tab--more > svg {
228
+ .mh-tabbar__tab--more > svg {
228
229
  width: var(--ui-font-icon);
229
230
  height: var(--ui-font-icon);
230
231
  }
231
- .mh-tabs__add:hover {
232
+ .mh-tabbar__add:hover {
232
233
  background: var(--ui-base-200);
233
234
  color: var(--ui-primary);
234
235
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * tabs —— 单件令牌(**基础值**)。
3
+ *
4
+ * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
+ *
6
+ * ## 抽出说明
7
+ * 本文件从面文件里抽出(原先混写在 `tabbar.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-tabbar-height: var(--ui-control-height-md); /* 标准控件高 32 */
19
+ --ui-tabbar-gap: 30px; /* 项间距(规范实测) */
20
+ --ui-tabbar-font-size: var(--ui-font-body);
21
+ --ui-tabbar-text: var(--ui-base-content); /* 规范未选档 #446a9f(偏蓝的正文色),本仓取正文色 */
22
+ --ui-tabbar-text-hover: var(--ui-primary-hover); /* 规范 #529dff */
23
+ --ui-tabbar-text-active: var(--ui-primary); /* 规范 #4e94ff */
24
+ --ui-tabbar-text-disabled: var(--ui-base-content-subtle); /* 规范 Te07 */
25
+ --ui-tabbar-indicator: var(--ui-primary);
26
+ --ui-tabbar-indicator-gap: 3px; /* 指示条与文字的留白 */
27
+ --ui-tabbar-indicator-height: 3px;
28
+ --ui-tabbar-indicator-radius: var(--ui-radius-full);
29
+ --ui-tabbar-card-padding-x: var(--ui-space-4);
30
+ }
@@ -89,6 +89,29 @@
89
89
  min-width: 620px;
90
90
  }
91
91
 
92
+ /* ===== 固定布局档(`layout="fixed"`)=====
93
+ * 列宽由 `<colgroup>` 下发(与档位无关),本档只把布局算法换成 `fixed`:
94
+ * 列宽从此**受声明约束、不再被内容撑破** ⇒ 长文本不会把表格撑得比容器还宽,
95
+ * 于是「百分比 / 数字权重」可以「吃满容器 + 严格按比例」。
96
+ *
97
+ * 代价(调用方要知道):长文本列必须显式 `ellipsis: true`,否则会**换行**(行高变高,见下条)。 */
98
+ .mh-table--fixed {
99
+ table-layout: fixed;
100
+ }
101
+ /* 换行兜底:fixed 已保证「不撑破容器」,这条只防**无空格长串**(如 500 字符的 token)
102
+ 溢出单元格、视觉上压到相邻列。`anywhere` 而不是 `break-word`:后者不参与最小内容宽计算。 */
103
+ .mh-table--fixed tbody td {
104
+ overflow-wrap: anywhere;
105
+ }
106
+ /* 前导列(勾选 / 展开)在 auto 下靠内容把 40px 的「建议宽」撑出去;fixed 下是硬宽,
107
+ 而 `thead th` / `tbody td` 的标准左右内距各 16px ⇒ 可用内容只有 40 − 32 = 8px,
108
+ 装不下 16px 的勾选框(实测该列溢出 19px,还会被上面的 `overflow: hidden` 裁掉)。
109
+ 故本档把前导列的内距清零,靠既有的 `text-align: center` 居中。 */
110
+ .mh-table--fixed .mh-table__col-check,
111
+ .mh-table--fixed .mh-table__col-expand {
112
+ padding: 0;
113
+ }
114
+
92
115
  /* ===== 表头 =====
93
116
  * `border: 0` **不是冗余**:本件只画「表外框 + 表头分割线 + 每行底线」三条,其余边必须显式清零。
94
117
  * 特异性和平局只发生在**同一个属性**上 —— 本件只声明 `border-bottom` 时,宿主给单元格下的整圈边框
@@ -110,6 +133,13 @@
110
133
  .mh-table thead th.is-hover {
111
134
  background: var(--ui-table-head-bg-hover);
112
135
  }
136
+ /* 固定档下表头也要裁切:列宽已被 colgroup 钉死,长表头文字会**溢出到相邻列**
137
+ (实测溢出 97px),必须靠这两条收住。`white-space: nowrap` 上面已有。
138
+ ⚠️ 只在本档加 —— auto 档下表头参与列宽计算,加裁切会改动老页面的列宽分配。 */
139
+ .mh-table--fixed thead th {
140
+ overflow: hidden;
141
+ text-overflow: ellipsis;
142
+ }
113
143
  /* 多级表头的组头:下边线不加(组头跨列,加线会切断视觉分组) */
114
144
  .mh-table thead th.mh-table__th-group {
115
145
  border-bottom: 1px solid var(--ui-table-head-divider);
@@ -192,6 +222,20 @@
192
222
  .mh-table__col-actions {
193
223
  text-align: right;
194
224
  }
225
+
226
+ /* ⚠️ **表头要把对齐重声明一遍**:上面这几条与 `.mh-table__cell-center` / `.mh-table__cell-amount`
227
+ * 都只有 **0-1-0**,而 `.mh-table thead th { text-align: left }` 是 **0-1-1** ⇒ 表头被强拉成左对齐、
228
+ * 与表体不齐:勾选框应居中却贴左(实测表头左留白 0 / 右留白 26,与表体错位 13px)、
229
+ * 右对齐列的标题应靠右却被拉到左边。
230
+ * 只用补 `text-align` —— `thead th` 没声明过其它会被这些类覆盖的属性(宽度/内距不冲突)。
231
+ * 写法沿用 `th.mh-table__th-group`(组头居中)那条既有先例。 */
232
+ .mh-table thead th.mh-table__col-check,
233
+ .mh-table thead th.mh-table__cell-center {
234
+ text-align: center;
235
+ }
236
+ .mh-table thead th.mh-table__col-actions {
237
+ text-align: right;
238
+ }
195
239
  /* `--sticky-col`:首列钉住(必须自带底,见文件头第 4 条) */
196
240
  .mh-table--sticky-col thead th:first-child,
197
241
  .mh-table--sticky-col tbody td:first-child {
@@ -227,12 +271,17 @@
227
271
  .mh-table__cell-link:hover {
228
272
  text-decoration: underline;
229
273
  }
274
+ /* 长文本省略(列定义里 `ellipsis: true` 时下发)。
275
+ * 基础三件套与档位无关;`max-width` **只在 auto 档兜底**:
276
+ * fixed 档的列宽已由 `<colgroup>` 钉死,再来一条 150px 的 max-width 会把宽列又压回 150(自相矛盾)。 */
230
277
  .mh-table__cell-ellipsis {
231
- max-width: var(--ui-table-ellipsis);
232
278
  overflow: hidden;
233
279
  text-overflow: ellipsis;
234
280
  white-space: nowrap;
235
281
  }
282
+ .mh-table:not(.mh-table--fixed) .mh-table__cell-ellipsis {
283
+ max-width: var(--ui-table-ellipsis);
284
+ }
236
285
  .mh-table__cell-icon {
237
286
  display: inline-flex;
238
287
  align-items: center;
@@ -29,6 +29,9 @@
29
29
  --ui-table-link: var(--ui-primary);
30
30
  --ui-table-padding-x: var(--ui-space-4); /* 单元格左右内距 16 */
31
31
  --ui-table-col-check: 40px;
32
+ /* 长文本列的兜底上限 —— **只在 `layout="auto"` 下生效**(`.mh-table:not(.mh-table--fixed)`
33
+ 作用域内)。`layout="fixed"` 下列宽由 `<colgroup>` 钉死,本令牌不参与,
34
+ 否则「宽列」会被它压回 150px 而自相矛盾。要按列给宽请用 `TableColumn.width`。 */
32
35
  --ui-table-ellipsis: 150px;
33
36
  --ui-table-drag-line: var(--ui-primary);
34
37
  --ui-table-drag-line-width: 3px;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Text —— 文本排版(字号 / 行高 / 字重 / 语义色 / 等宽 / 截断)。
3
+ *
4
+ * 本文件是 `@manohub/theme` 那套 `--ui-font-*` / `--ui-line-*` / `--ui-weight-*` 档位令牌的
5
+ * **第一个消费者**:在此之前它们只有定义、没有件,于是「卡片里的文字层级」在应用侧无合规落点
6
+ * (契约 L1-5 禁 `font-*` / `color`),每个应用都要留一条定版例外登记。
7
+ *
8
+ * ## 取色口径
9
+ *
10
+ * 与 `Notice` / `Dialog` 的语义档同一张表:`success` / `warning` 取 `-strong` 档
11
+ * (直接用 500 档主色在浅底上对比度不足,属可读性缺陷)。
12
+ *
13
+ * ## 为什么 tone 走内部变量
14
+ *
15
+ * `--mh-text-tone-color` 是**内部状态变量**(`--mh-` 命名空间),由修饰符类赋值、由根类消费 ——
16
+ * 这样「一条规则管颜色」而不是七条各写一次 `color`。默认值取 `inherit`,
17
+ * 故**不传 tone 的文字也不会被强行染色**(`tone` 缺省档是 `default`,与正文色一致)。
18
+ *
19
+ * ## 截断
20
+ *
21
+ * `--truncate`(单行)与 `--clamp`(N 行)都要 `min-width: 0` 才能在被 flex 拉伸的子项里生效
22
+ * (flex 子项的 `min-width` 默认是 `auto`,不给就会把容器撑开而不是省略)。
23
+ * N 行的行数经 `--mh-text-lines` 下发(`-webkit-line-clamp` 只吃值,不能由类名表达行数)。
24
+ */
25
+
26
+ .mh-text {
27
+ color: var(--mh-text-tone-color, inherit);
28
+ }
29
+
30
+ /* ===== 字号档(每档配一枚行高令牌,两者成对出现才不会出现「字号变了行距没变」) ===== */
31
+ .mh-text--caption {
32
+ font-size: var(--ui-font-caption);
33
+ line-height: var(--ui-line-caption);
34
+ }
35
+ .mh-text--body {
36
+ font-size: var(--ui-font-body);
37
+ line-height: var(--ui-line-body);
38
+ }
39
+ .mh-text--heading {
40
+ font-size: var(--ui-font-heading);
41
+ line-height: var(--ui-line-heading);
42
+ }
43
+ .mh-text--title {
44
+ font-size: var(--ui-font-title);
45
+ line-height: var(--ui-line-title);
46
+ }
47
+
48
+ /* ===== 字重档(缺省不给,即继承上下文) ===== */
49
+ .mh-text--regular {
50
+ font-weight: var(--ui-weight-regular);
51
+ }
52
+ .mh-text--medium {
53
+ font-weight: var(--ui-weight-medium);
54
+ }
55
+ .mh-text--semibold {
56
+ font-weight: var(--ui-weight-semibold);
57
+ }
58
+
59
+ /* ===== 语义色档 ===== */
60
+ .mh-text--default {
61
+ --mh-text-tone-color: var(--ui-base-content);
62
+ }
63
+ .mh-text--muted {
64
+ --mh-text-tone-color: var(--ui-base-content-muted);
65
+ }
66
+ .mh-text--subtle {
67
+ --mh-text-tone-color: var(--ui-base-content-subtle);
68
+ }
69
+ .mh-text--primary {
70
+ --mh-text-tone-color: var(--ui-primary);
71
+ }
72
+ .mh-text--success {
73
+ --mh-text-tone-color: var(--ui-success-strong);
74
+ }
75
+ .mh-text--warning {
76
+ --mh-text-tone-color: var(--ui-warning-strong);
77
+ }
78
+ .mh-text--error {
79
+ --mh-text-tone-color: var(--ui-error);
80
+ }
81
+
82
+ /* ===== 等宽族(代码 / 路径 / ID;字号跟随所在档,不另开一档) ===== */
83
+ .mh-text--mono {
84
+ font-family: var(--ui-font-mono);
85
+ }
86
+
87
+ /* ===== 截断 ===== */
88
+ .mh-text--truncate {
89
+ display: block;
90
+ min-width: 0;
91
+ overflow: hidden;
92
+ text-overflow: ellipsis;
93
+ white-space: nowrap;
94
+ }
95
+ .mh-text--clamp {
96
+ display: -webkit-box;
97
+ -webkit-box-orient: vertical;
98
+ -webkit-line-clamp: var(--mh-text-lines, 2);
99
+ min-width: 0;
100
+ overflow: hidden;
101
+ }
@@ -42,7 +42,7 @@
42
42
  width: 360px;
43
43
  }
44
44
 
45
- /* 图标:圆形色底 + 白色字形(18×18) */
45
+ /* ===== 图标:圆形色底 + 白色字形(18×18) ===== */
46
46
  .mh-toast__icon {
47
47
  display: flex;
48
48
  align-items: center;
@@ -55,22 +55,28 @@
55
55
  font-size: var(--ui-font-caption);
56
56
  line-height: 1;
57
57
  }
58
- .mh-toast__icon--info {
58
+
59
+ /* ===== 语义档:色落在**根修饰符**上,由它再作用到图标 =====
60
+ * 本包 tone 维度的统一落点是 `.mh-<件>--<tone>`(`Badge` / `Dialog` / `Notice` / `Notification`
61
+ * / `Tag` / `Text` 同款)。本件此前写成 `.mh-toast__icon--<tone>`,是唯一一个落子元素修饰符的 ——
62
+ * 消费方按直觉拼 `.mh-toast--success` 会落空。现改为「根挂 tone、面里用后代选择器取到图标」,
63
+ * **视觉一字未变**(圆形色底仍然只在图标上)。 */
64
+ .mh-toast--info .mh-toast__icon {
59
65
  background: var(--ui-info);
60
66
  }
61
- .mh-toast__icon--success {
67
+ .mh-toast--success .mh-toast__icon {
62
68
  background: var(--ui-success);
63
69
  }
64
- .mh-toast__icon--warning {
70
+ .mh-toast--warning .mh-toast__icon {
65
71
  background: var(--ui-warning);
66
72
  }
67
- .mh-toast__icon--error {
73
+ .mh-toast--error .mh-toast__icon {
68
74
  background: var(--ui-error);
69
75
  }
70
76
  /* loading 档:透明底 + 主色字形 + 匀速转圈。
71
77
  规范此处是「2px 描边 + 上边缺口」的自画法,本仓改用意形(图标包的 `loading`)——
72
78
  硬约束是「图标一律来自图标包、不用文字符号或自画形状冒充」,视觉等价(都是转圈环)。 */
73
- .mh-toast__icon--loading {
79
+ .mh-toast--loading .mh-toast__icon {
74
80
  background: transparent;
75
81
  color: var(--ui-primary);
76
82
  animation: mh-toast-spin 0.8s linear infinite;