@manohub/ui 0.10.5 → 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.
- package/README.md +155 -155
- package/dist/components/form/index.js +8 -1
- package/dist/styles/components/avatar.css +131 -131
- package/dist/styles/components/avatar.tokens.css +24 -24
- package/dist/styles/components/badge.css +266 -266
- package/dist/styles/components/badge.tokens.css +24 -24
- package/dist/styles/components/button.css +460 -460
- package/dist/styles/components/capsule.css +128 -128
- package/dist/styles/components/capsule.tokens.css +27 -27
- package/dist/styles/components/card.css +198 -198
- package/dist/styles/components/checkbox.css +145 -145
- package/dist/styles/components/checkbox.tokens.css +26 -26
- package/dist/styles/components/code-block.css +216 -216
- package/dist/styles/components/code-block.tokens.css +40 -40
- package/dist/styles/components/collapse.css +62 -62
- package/dist/styles/components/collapse.tokens.css +20 -20
- package/dist/styles/components/dialog.css +158 -158
- package/dist/styles/components/dialog.tokens.css +24 -24
- package/dist/styles/components/divider.css +75 -75
- package/dist/styles/components/divider.tokens.css +22 -22
- package/dist/styles/components/drawer.css +143 -143
- package/dist/styles/components/drawer.tokens.css +22 -22
- package/dist/styles/components/filter.css +29 -29
- package/dist/styles/components/form.css +442 -425
- package/dist/styles/components/form.tokens.css +15 -15
- package/dist/styles/components/input.css +538 -538
- package/dist/styles/components/input.tokens.css +43 -43
- package/dist/styles/components/layout.css +200 -200
- package/dist/styles/components/list-view.css +244 -244
- package/dist/styles/components/loading.css +76 -76
- package/dist/styles/components/loading.tokens.css +23 -23
- package/dist/styles/components/nav.css +48 -48
- package/dist/styles/components/notice.css +153 -153
- package/dist/styles/components/notice.tokens.css +17 -17
- package/dist/styles/components/notification.css +159 -159
- package/dist/styles/components/notification.tokens.css +37 -37
- package/dist/styles/components/page.css +473 -473
- package/dist/styles/components/pagination.css +303 -303
- package/dist/styles/components/pagination.tokens.css +32 -32
- package/dist/styles/components/panel.css +77 -77
- package/dist/styles/components/query-state.css +88 -88
- package/dist/styles/components/radio.css +271 -271
- package/dist/styles/components/radio.tokens.css +26 -26
- package/dist/styles/components/search.css +34 -34
- package/dist/styles/components/select.css +326 -326
- package/dist/styles/components/select.tokens.css +44 -44
- package/dist/styles/components/skeleton.css +60 -60
- package/dist/styles/components/skeleton.tokens.css +27 -27
- package/dist/styles/components/steps.css +205 -205
- package/dist/styles/components/steps.tokens.css +44 -44
- package/dist/styles/components/switch.css +165 -165
- package/dist/styles/components/switch.tokens.css +26 -26
- package/dist/styles/components/tabbar.css +235 -235
- package/dist/styles/components/tabbar.tokens.css +30 -30
- package/dist/styles/components/table.css +504 -504
- package/dist/styles/components/table.tokens.css +44 -44
- package/dist/styles/components/tag.css +127 -127
- package/dist/styles/components/tag.tokens.css +24 -24
- package/dist/styles/components/toast.css +185 -185
- package/dist/styles/components/toast.tokens.css +26 -26
- package/dist/styles/components/tooltip.css +89 -89
- package/dist/styles/components/tooltip.tokens.css +25 -25
- package/dist/styles/components/tree.css +173 -173
- package/dist/styles/components/upload.css +151 -151
- package/dist/styles/components/upload.tokens.css +27 -27
- package/dist/styles/index.css +153 -153
- package/dist/styles/operations/collapse.css +84 -84
- package/dist/styles/operations/popup.css +193 -193
- package/dist/styles/operations/tabs.css +82 -82
- package/package.json +62 -62
|
@@ -1,504 +1,504 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Table —— 表格(表头/行/单元格类型 + 行态四档 + 固定表头与列 + 批量栏与合计行)。
|
|
3
|
-
*
|
|
4
|
-
* 出处(**两套来源在关键几何上一致**,故此处没有取舍余地):
|
|
5
|
-
* - `@aihub/theme` 的 `src/components/table.css`:表头 **34** / 行 **30** / 字号 13 / 勾选列 40 /
|
|
6
|
-
* 省略号 150 / 拖拽线 3×40 / 合计行 40;
|
|
7
|
-
* - 设计稿《MH后台-0911》:表头 **34**(`0:3962` 1160×34)/ 行 **30**(`0:3956`–`0:3961` 919×30,
|
|
8
|
-
* 节距 31 = 30 + 1px 线)/ 表头底 `#f1f2f5`(= `--ui-base-200`)/ 行线 `#e6e6e6`
|
|
9
|
-
* (每行 `DROP_SHADOW(0,1,b0,#e6e6e6)`)/ 外框 `#e6e6e6 @1` / 选中行底 `#dbe9ff`
|
|
10
|
-
* (= `--ui-primary-subtle`)。
|
|
11
|
-
*
|
|
12
|
-
* ⚠️ 改前这里写的是 44 / 46 —— 与上面两套来源**都不符**,是历史遗留值(文件头注释一直写着 34/30,
|
|
13
|
-
* 是代码没跟上),本轮已归位。
|
|
14
|
-
*
|
|
15
|
-
* **单元格左右内距保持 16(`--ui-space-4`)**:设计稿里可量的只有「勾选框距表左 20」这一处,
|
|
16
|
-
* 而它量的是**内容盒**、不是单元格盒(勾选列 40 宽 + 居中时内容盒落在 13 处),无法唯一反推内距,
|
|
17
|
-
* 故不作推测性改动。勾选列宽 `40` 也不动,理由同此。
|
|
18
|
-
*
|
|
19
|
-
* 行态:表头底 `--ui-base-200` + 字 `--ui-base-content-muted` + 中粗 / 外框 1px `--ui-base-300` /
|
|
20
|
-
* 斑马与禁用 `--ui-base-200` / 滑过 `--ui-primary-weak` / 选中 `--ui-primary-subtle`(**只底色**)。
|
|
21
|
-
*
|
|
22
|
-
* 四条必须照做的**结构**决定(做错就与规范不是一回事):
|
|
23
|
-
*
|
|
24
|
-
* 1. **边框模型**:默认是**外框**(画在 `.mh-table` 上)+ 表头下分割线 + 每行底线(末行去线),
|
|
25
|
-
* 故 `border-collapse: separate` + `border-spacing: 0` —— 圆角只有在 separate 下才渲染得出来;
|
|
26
|
-
* `--borderless` 才切回 `collapse` 并去掉外框。
|
|
27
|
-
* **三条线之外的边一律显式清零**(`border: 0` 写在 `th` / `td` / `tr` 上,不是冗余):特异性只在
|
|
28
|
-
* **同一个属性**上分胜负,宿主给单元格或行下的整圈边框(典型是 markdown 正文的
|
|
29
|
-
* `.vp-doc th, .vp-doc td { border: 1px solid }`、`.vp-doc tr { border-top: ... }`)不会被本件
|
|
30
|
-
* "没写的边"顶掉,结果就是与表外框叠成 2px、行交界处叠成 2px、还多出列分隔线。
|
|
31
|
-
* 2. **斑马纹是显式类**(`.is-striped`)而非 `:nth-child(even)`:表里可以插分组行,`nth-child` 会整表错位
|
|
32
|
-
* —— 这是规范里唯一允许"用类代替结构选择器"的豁免。
|
|
33
|
-
* 3. **行选中由行内的选择控件驱动**(`tr:has(.mh-table__col-check input:checked)`):这样零 JS 也能选中;
|
|
34
|
-
* 组件态给 `[data-state='selected']`,静态档给 `.is-selected` —— 三源等价。
|
|
35
|
-
* 勾选列复用 `Checkbox` **组件**(不在表格里手写原生 input):该件内部才是真实 `<input type="checkbox">`,
|
|
36
|
-
* 故 `:has(...)` 这条路径照旧成立;`Checkbox` 的框体带 `data-state`(checked / indeterminate),
|
|
37
|
-
* 半选与选中都走它自己的样式数据,表格这边不再画方块。
|
|
38
|
-
* **选择器必须限定在勾选列内**(`.mh-table__col-check`,勾选列单元格自带的类):不限列时,
|
|
39
|
-
* 功能列里任何「内部本来就是 checkbox」的件都会命中 —— `Switch` 的内部正是 `<input type="checkbox">`,
|
|
40
|
-
* 于是「启用」这类**功能值**会把整行点亮。功能值与行选择语义不同,视觉必须分开(否则一张表里
|
|
41
|
-
* 开关一开就整行变色,且用户无从判断那到底表示什么)。
|
|
42
|
-
* 4. **固定列必须自带底**(`background: var(--ui-base-100)`):它是 sticky 的,不遮挡就会被滚过的单元格透出。
|
|
43
|
-
*
|
|
44
|
-
* **不做**:排序与列宽拖拽的**算法**(规范只给了 `↕` 字形与 3×40 拖拽线这两处视觉),也不做空态/加载态
|
|
45
|
-
* (规范表格里没有这两个样张 —— 三态归 `QueryState`)。
|
|
46
|
-
*/
|
|
47
|
-
.mh-table-wrapper {
|
|
48
|
-
overflow: auto;
|
|
49
|
-
}
|
|
50
|
-
/* `--fill` 档把外框从表移交给包裹层(表自己不再画框,改由包裹层画满高框) */
|
|
51
|
-
.mh-table-wrapper:has(> .mh-table--fill) {
|
|
52
|
-
border: 1px solid var(--ui-table-border);
|
|
53
|
-
border-radius: var(--ui-table-radius);
|
|
54
|
-
}
|
|
55
|
-
.mh-table-scroll {
|
|
56
|
-
max-height: var(--ui-table-scroll-height); /* 规范样张 132(实际用按需覆盖) */
|
|
57
|
-
overflow: auto;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/* 几何只挂在 `<table>` 上:令牌在同名 `.tokens.css`(锚 `[data-manohub-ui]`),几何若跟着挂会给包裹层加边框与圆角 */
|
|
61
|
-
.mh-table {
|
|
62
|
-
width: 100%;
|
|
63
|
-
border: 1px solid var(--ui-table-border);
|
|
64
|
-
border-collapse: separate; /* 圆角需要 separate(见文件头第 1 条) */
|
|
65
|
-
border-spacing: 0;
|
|
66
|
-
border-radius: var(--ui-table-radius);
|
|
67
|
-
font-size: var(--ui-table-font-size);
|
|
68
|
-
color: var(--ui-table-text);
|
|
69
|
-
background: var(--ui-base-100);
|
|
70
|
-
}
|
|
71
|
-
/* 无框档:去外框并切回 collapse(不再需要圆角) */
|
|
72
|
-
.mh-table--borderless {
|
|
73
|
-
border: none;
|
|
74
|
-
border-collapse: collapse;
|
|
75
|
-
border-radius: 0;
|
|
76
|
-
}
|
|
77
|
-
/* 满高档:外框交包裹层,去掉自己的圆角(否则内外两层圆角会露缝) */
|
|
78
|
-
.mh-table--fill {
|
|
79
|
-
border: none;
|
|
80
|
-
border-radius: 0;
|
|
81
|
-
}
|
|
82
|
-
/* 紧凑档(`size="sm"`):三档 30 / 38 / 46 里的最小档,嵌在卡片 / 面板里的表格用它 */
|
|
83
|
-
.mh-table--xs {
|
|
84
|
-
--ui-table-head-height: 30px;
|
|
85
|
-
--ui-table-row-height: 30px;
|
|
86
|
-
}
|
|
87
|
-
/* 窄屏下的最小宽(触发横向滚动,而不是把列压扁) */
|
|
88
|
-
.mh-table--wide {
|
|
89
|
-
min-width: 620px;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/* ===== 固定布局档(`layout="fixed"`)=====
|
|
93
|
-
* 列宽由 `<colgroup>` 下发(与档位无关),本档只把布局算法换成 `fixed`:
|
|
94
|
-
* 列宽从此**受声明约束、不再被内容撑破** ⇒ 长文本不会把表格撑得比容器还宽,
|
|
95
|
-
* 于是「百分比 / 数字权重」可以「吃满容器 + 严格按比例」。
|
|
96
|
-
*
|
|
97
|
-
* 调用方要知道的:表体**默认不换行**(nowrap + 省略号,见下条);要换行的列显式标 `wrap: true`。 */
|
|
98
|
-
.mh-table--fixed {
|
|
99
|
-
table-layout: fixed;
|
|
100
|
-
}
|
|
101
|
-
/* `fixed` 档表体默认**不换行**(nowrap + 省略号)。两条依据:
|
|
102
|
-
* ① 列宽已被 `<colgroup>` 钉死,换行救不回内容,只会把行高顶高(`td` 的 `height` 只是**下限**);
|
|
103
|
-
* ② 换行必然伴随**从字符间断字** —— 实测序号列窄到装不下两位数时,旧的 `overflow-wrap: anywhere`
|
|
104
|
-
* 把 `10` 拆成 `1` / `0` 两行,行高 30 → **49**。
|
|
105
|
-
* 于是「换行」改成**列级主动选择**:`TableColumn.wrap: true`(见 `.mh-table__cell-wrap`)。
|
|
106
|
-
* ⚠️ **只在本档翻默认**:`auto` 档的列宽由内容计算,td 默认 nowrap 会让长文本列不再靠换行收敛、
|
|
107
|
-
* 表格更容易撑破容器 —— 与本档「表头裁切只加在 fixed」同一条判据(见上一条注释)。 */
|
|
108
|
-
.mh-table--fixed tbody td {
|
|
109
|
-
overflow: hidden;
|
|
110
|
-
text-overflow: ellipsis;
|
|
111
|
-
white-space: nowrap;
|
|
112
|
-
}
|
|
113
|
-
/* 前导列(勾选 / 展开)在 auto 下靠内容把 40px 的「建议宽」撑出去;fixed 下是硬宽,
|
|
114
|
-
而 `thead th` / `tbody td` 的标准左右内距各 16px ⇒ 可用内容只有 40 − 32 = 8px,
|
|
115
|
-
装不下 16px 的勾选框(实测该列溢出 19px,还会被上面的 `overflow: hidden` 裁掉)。
|
|
116
|
-
故本档把前导列的内距清零,靠既有的 `text-align: center` 居中。 */
|
|
117
|
-
.mh-table--fixed .mh-table__col-check,
|
|
118
|
-
.mh-table--fixed .mh-table__col-expand {
|
|
119
|
-
padding: 0;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/* ===== 表头 =====
|
|
123
|
-
* `border: 0` **不是冗余**:本件只画「表外框 + 表头分割线 + 每行底线」三条,其余边必须显式清零。
|
|
124
|
-
* 特异性和平局只发生在**同一个属性**上 —— 本件只声明 `border-bottom` 时,宿主给单元格下的整圈边框
|
|
125
|
-
* (典型:markdown 正文的 `.vp-doc th, .vp-doc td { border: 1px solid }`)不会被任何组件声明顶掉,
|
|
126
|
-
* 于是单元格四边各来一条:与表外框叠成 2px、每行交界处上一行底线 + 本行顶线叠成 2px,还凭空多出列分隔线。
|
|
127
|
-
* 这三条不是「装饰」而是边框模型的一部分,故与 `border-bottom` 写在同一规则里(0-1-2 压过 `.vp-doc th` 0-1-1)。 */
|
|
128
|
-
.mh-table thead th {
|
|
129
|
-
height: var(--ui-table-head-height);
|
|
130
|
-
padding: 0 var(--ui-table-padding-x);
|
|
131
|
-
border: 0;
|
|
132
|
-
border-bottom: 1px solid var(--ui-table-border);
|
|
133
|
-
background: var(--ui-table-head-bg);
|
|
134
|
-
color: var(--ui-table-head-text);
|
|
135
|
-
font-weight: var(--ui-weight-medium);
|
|
136
|
-
text-align: left;
|
|
137
|
-
white-space: nowrap;
|
|
138
|
-
}
|
|
139
|
-
.mh-table thead th:hover,
|
|
140
|
-
.mh-table thead th.is-hover {
|
|
141
|
-
background: var(--ui-table-head-bg-hover);
|
|
142
|
-
}
|
|
143
|
-
/* 固定档下表头也要裁切:列宽已被 colgroup 钉死,长表头文字会**溢出到相邻列**
|
|
144
|
-
(实测溢出 97px),必须靠这两条收住。`white-space: nowrap` 上面已有。
|
|
145
|
-
⚠️ 只在本档加 —— auto 档下表头参与列宽计算,加裁切会改动老页面的列宽分配。 */
|
|
146
|
-
.mh-table--fixed thead th {
|
|
147
|
-
overflow: hidden;
|
|
148
|
-
text-overflow: ellipsis;
|
|
149
|
-
}
|
|
150
|
-
/* 多级表头的组头:下边线不加(组头跨列,加线会切断视觉分组) */
|
|
151
|
-
.mh-table thead th.mh-table__th-group {
|
|
152
|
-
border-bottom: 1px solid var(--ui-table-head-divider);
|
|
153
|
-
text-align: center;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/* ===== 行 =====
|
|
157
|
-
* 行自身不画线(行线在单元格底边上):同样显式清零,挡住宿主给 `tr` 加的顶线(会与本件行底线叠成双线)。 */
|
|
158
|
-
.mh-table thead tr,
|
|
159
|
-
.mh-table tbody tr {
|
|
160
|
-
border: 0;
|
|
161
|
-
}
|
|
162
|
-
/* 单元格的边框模型:**全清零 + 只留底线**(理由同表头处:宿主给 `th` / `td` 下的整圈边框只靠
|
|
163
|
-
* 特异性挡不住未声明的三边,会让行线与表外框全部叠成双线)。 */
|
|
164
|
-
.mh-table tbody td {
|
|
165
|
-
height: var(--ui-table-row-height);
|
|
166
|
-
padding: var(--ui-space-1) var(--ui-table-padding-x);
|
|
167
|
-
border: 0;
|
|
168
|
-
border-bottom: 1px solid var(--ui-table-border);
|
|
169
|
-
line-height: var(--ui-table-line-height);
|
|
170
|
-
vertical-align: middle;
|
|
171
|
-
}
|
|
172
|
-
.mh-table tbody tr:last-child td {
|
|
173
|
-
border-bottom: none;
|
|
174
|
-
}
|
|
175
|
-
/* 行态顺序即优先级:斑马 → 滑过 → 选中 → 禁用(禁用压住一切,故放最后) */
|
|
176
|
-
.mh-table tbody tr.is-striped td {
|
|
177
|
-
background: var(--ui-table-row-alt);
|
|
178
|
-
}
|
|
179
|
-
.mh-table tbody tr:hover td,
|
|
180
|
-
.mh-table tbody tr.is-hover td {
|
|
181
|
-
background: var(--ui-table-row-hover);
|
|
182
|
-
}
|
|
183
|
-
/* 选中态**只有底色**:规范样张里那条 2px 主色下沿(Au01)已去掉 ——
|
|
184
|
-
行线只由单元格底边提供,选中行不再额外压一条线(`box-shadow: inset 0 -2px` 会盖住底边线,
|
|
185
|
-
看起来像"两行线叠在一起")。要恢复下沿就加回 inset 阴影 + 对应令牌。
|
|
186
|
-
第三条路径限定在勾选列内(见文件头第 3 条):不限列会被功能列的 Switch 命中。 */
|
|
187
|
-
.mh-table tbody tr.is-selected td,
|
|
188
|
-
.mh-table tbody tr[data-state='selected'] td,
|
|
189
|
-
.mh-table tbody tr:has(.mh-table__col-check input:checked) td {
|
|
190
|
-
background: var(--ui-table-row-selected);
|
|
191
|
-
}
|
|
192
|
-
.mh-table tbody tr.is-disabled td,
|
|
193
|
-
.mh-table tbody tr[aria-disabled='true'] td {
|
|
194
|
-
background: var(--ui-table-row-disabled);
|
|
195
|
-
color: var(--ui-base-content-subtle);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/* 分组行:整行一条、不可选、字重中粗 */
|
|
199
|
-
.mh-table tbody tr.mh-table__group-row td {
|
|
200
|
-
height: var(--ui-table-row-height);
|
|
201
|
-
background: var(--ui-table-head-bg);
|
|
202
|
-
color: var(--ui-table-head-text);
|
|
203
|
-
font-weight: var(--ui-weight-medium);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/* 树行:子行首列缩进(与树的缩进同一口径) */
|
|
207
|
-
.mh-table tbody tr.mh-table__row--child td:first-child {
|
|
208
|
-
padding-left: var(--ui-table-tree-indent);
|
|
209
|
-
}
|
|
210
|
-
.mh-table__tree-caret {
|
|
211
|
-
display: inline-flex;
|
|
212
|
-
width: var(--ui-font-icon); /* 常规图标档(改前无声明、掉到 `<svg>` 默认 16) */
|
|
213
|
-
height: var(--ui-font-icon);
|
|
214
|
-
margin-right: var(--ui-space-1);
|
|
215
|
-
color: var(--ui-base-content-subtle);
|
|
216
|
-
transition: transform 0.15s ease;
|
|
217
|
-
}
|
|
218
|
-
.mh-table__tree-caret--open {
|
|
219
|
-
transform: rotate(-90deg);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/* ===== 列 ===== */
|
|
223
|
-
/* 勾选列:只负责「多宽 + 居中」——`Checkbox` 组件是 inline-flex,靠格子的 text-align 居中;
|
|
224
|
-
方块尺寸 / 圆角 / 三态配色全归 `checkbox.css`(表格不再给这一列任何选中态样式) */
|
|
225
|
-
.mh-table__col-check {
|
|
226
|
-
width: var(--ui-table-col-check);
|
|
227
|
-
text-align: center;
|
|
228
|
-
}
|
|
229
|
-
.mh-table__col-actions {
|
|
230
|
-
text-align: right;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/* ⚠️ **表头要把对齐重声明一遍**:上面这几条与 `.mh-table__cell-center` / `.mh-table__cell-amount`
|
|
234
|
-
* 都只有 **0-1-0**,而 `.mh-table thead th { text-align: left }` 是 **0-1-1** ⇒ 表头被强拉成左对齐、
|
|
235
|
-
* 与表体不齐:勾选框应居中却贴左(实测表头左留白 0 / 右留白 26,与表体错位 13px)、
|
|
236
|
-
* 右对齐列的标题应靠右却被拉到左边。
|
|
237
|
-
* 只用补 `text-align` —— `thead th` 没声明过其它会被这些类覆盖的属性(宽度/内距不冲突)。
|
|
238
|
-
* 写法沿用 `th.mh-table__th-group`(组头居中)那条既有先例。 */
|
|
239
|
-
.mh-table thead th.mh-table__col-check,
|
|
240
|
-
.mh-table thead th.mh-table__cell-center {
|
|
241
|
-
text-align: center;
|
|
242
|
-
}
|
|
243
|
-
.mh-table thead th.mh-table__col-actions {
|
|
244
|
-
text-align: right;
|
|
245
|
-
}
|
|
246
|
-
/* `--sticky-col`:首列钉住(必须自带底,见文件头第 4 条) */
|
|
247
|
-
.mh-table--sticky-col thead th:first-child,
|
|
248
|
-
.mh-table--sticky-col tbody td:first-child {
|
|
249
|
-
position: sticky;
|
|
250
|
-
left: 0;
|
|
251
|
-
z-index: 1;
|
|
252
|
-
background: var(--ui-base-100);
|
|
253
|
-
}
|
|
254
|
-
.mh-table--sticky-col thead th:first-child {
|
|
255
|
-
z-index: 2; /* 表头既钉顶又钉左,压住表头其余列 */
|
|
256
|
-
background: var(--ui-table-head-bg);
|
|
257
|
-
}
|
|
258
|
-
/* `--sticky-head`:表头钉顶。
|
|
259
|
-
* ⚠️ 选择器必须带 `tr`(0-1-3):文件后段「拖拽线的定位上下文」那条
|
|
260
|
-
* `.mh-table thead th { position: relative }` 是 **0-1-2**,与不写 `tr` 的写法**同特异性且在后**
|
|
261
|
-
* ⇒ 会把 `position: sticky` 覆盖掉,`stickyHead` 静默失效(0.6.0 起就存在,0.9.0 复核仍在)。
|
|
262
|
-
* `sticky` 同样是定位元素,照样给表头里的拖拽线当包含块,故加 `tr` 不损失原能力。 */
|
|
263
|
-
.mh-table--sticky-head thead tr th {
|
|
264
|
-
position: sticky;
|
|
265
|
-
top: 0;
|
|
266
|
-
z-index: 1;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/* ===== 单元格类型 ===== */
|
|
270
|
-
.mh-table__cell-center {
|
|
271
|
-
text-align: center;
|
|
272
|
-
}
|
|
273
|
-
.mh-table__cell-amount {
|
|
274
|
-
text-align: right;
|
|
275
|
-
font-variant-numeric: tabular-nums; /* 金额对齐靠等宽数字,不靠右对齐就够 */
|
|
276
|
-
}
|
|
277
|
-
.mh-table__cell-link {
|
|
278
|
-
color: var(--ui-table-link);
|
|
279
|
-
text-decoration: none;
|
|
280
|
-
cursor: pointer;
|
|
281
|
-
}
|
|
282
|
-
.mh-table__cell-link:hover {
|
|
283
|
-
text-decoration: underline;
|
|
284
|
-
}
|
|
285
|
-
/* 列级**放开换行**(列定义里 `wrap: true` 时下发,只作用于表体 `td`;表头始终 nowrap)。
|
|
286
|
-
* 缺省不换行在面文件的 `.mh-table--fixed tbody td` 里 —— 本档才翻默认,故这里同时把
|
|
287
|
-
* 「换行三件套」与 `overflow-wrap` 兜底一并给回:换来的是「长文本列自己决定换行」。
|
|
288
|
-
* ⚠️ 选择器必须带 `td`(0-1-3):`.mh-table--fixed tbody td` 是 **0-1-2**,
|
|
289
|
-
* 单个类(0-1-0)压不过它(同 §表头对齐那条的先例)。 */
|
|
290
|
-
.mh-table tbody td.mh-table__cell-wrap {
|
|
291
|
-
white-space: normal;
|
|
292
|
-
overflow: visible;
|
|
293
|
-
text-overflow: clip;
|
|
294
|
-
overflow-wrap: anywhere;
|
|
295
|
-
}
|
|
296
|
-
.mh-table__cell-icon {
|
|
297
|
-
display: inline-flex;
|
|
298
|
-
align-items: center;
|
|
299
|
-
margin-right: var(--ui-space-1);
|
|
300
|
-
color: var(--ui-base-content-muted);
|
|
301
|
-
}
|
|
302
|
-
.mh-table__cell-main {
|
|
303
|
-
display: block;
|
|
304
|
-
}
|
|
305
|
-
.mh-table__cell-sub {
|
|
306
|
-
display: block;
|
|
307
|
-
color: var(--ui-base-content-muted);
|
|
308
|
-
}
|
|
309
|
-
/* 必填列的表头加星号(只在表头,不在单元格) */
|
|
310
|
-
.mh-table th.mh-table__cell-required::before {
|
|
311
|
-
content: '*';
|
|
312
|
-
margin-right: var(--ui-space-1);
|
|
313
|
-
color: var(--ui-error);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/* 状态点(语义四档) */
|
|
317
|
-
.mh-table__status-dot {
|
|
318
|
-
display: inline-block;
|
|
319
|
-
width: var(--ui-table-status-dot);
|
|
320
|
-
height: var(--ui-table-status-dot);
|
|
321
|
-
margin-right: var(--ui-space-1);
|
|
322
|
-
border-radius: var(--ui-radius-full);
|
|
323
|
-
background: var(--ui-base-400);
|
|
324
|
-
vertical-align: middle;
|
|
325
|
-
}
|
|
326
|
-
.mh-table__status-dot--info {
|
|
327
|
-
background: var(--ui-info);
|
|
328
|
-
}
|
|
329
|
-
.mh-table__status-dot--success {
|
|
330
|
-
background: var(--ui-success);
|
|
331
|
-
}
|
|
332
|
-
.mh-table__status-dot--warning {
|
|
333
|
-
background: var(--ui-warning);
|
|
334
|
-
}
|
|
335
|
-
.mh-table__status-dot--error {
|
|
336
|
-
background: var(--ui-error);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/* ===== 表头操作:排序按钮与列宽拖拽线 ===== */
|
|
340
|
-
.mh-table__sort {
|
|
341
|
-
display: inline-flex;
|
|
342
|
-
align-items: center;
|
|
343
|
-
gap: 2px;
|
|
344
|
-
margin-left: var(--ui-space-1);
|
|
345
|
-
padding: 0;
|
|
346
|
-
border: none;
|
|
347
|
-
background: transparent;
|
|
348
|
-
color: var(--ui-base-content-subtle);
|
|
349
|
-
cursor: pointer;
|
|
350
|
-
}
|
|
351
|
-
.mh-table__sort--active {
|
|
352
|
-
color: var(--ui-primary);
|
|
353
|
-
}
|
|
354
|
-
/* 槽位尺寸:常规图标一律取全局图标档(**不写 `.mh-table__sort-icon`** —— 那是只作朝向锚点的结构类,
|
|
355
|
-
面上为排序指示写规则会被契约拦下,见下方注释) */
|
|
356
|
-
.mh-table__sort > svg {
|
|
357
|
-
width: var(--ui-font-icon);
|
|
358
|
-
height: var(--ui-font-icon);
|
|
359
|
-
}
|
|
360
|
-
/* 排序朝向:**方位在字形里**(升序 `chevron-up` / 降序与未排序 `chevron-down`,未排走浅色、已排随
|
|
361
|
-
`.mh-table__sort--active` 主色)—— 本层零 `transform`,不走"把别的图标旋转 90° 冒充上下"的老路
|
|
362
|
-
(包内硬约束)。`mh-table__sort-icon` 与 `--asc` / `--desc` 只作**状态锚点**(消费方与用例按它们定位
|
|
363
|
-
当前朝向),面上无声明,登记在测试契约的结构锚点台账里。 */
|
|
364
|
-
.mh-table__drag-line {
|
|
365
|
-
position: absolute;
|
|
366
|
-
top: 50%;
|
|
367
|
-
right: 0;
|
|
368
|
-
width: var(--ui-table-drag-line-width);
|
|
369
|
-
height: var(--ui-table-drag-line-height);
|
|
370
|
-
background: var(--ui-table-drag-line);
|
|
371
|
-
transform: translateY(-50%);
|
|
372
|
-
cursor: col-resize;
|
|
373
|
-
}
|
|
374
|
-
/* 拖拽线要定在表头单元格右缘,故表头格需要定位上下文 */
|
|
375
|
-
.mh-table thead th {
|
|
376
|
-
position: relative;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/* ===== 批量栏(选中若干行后出现在表格上方) ===== */
|
|
380
|
-
.mh-table__batch {
|
|
381
|
-
display: flex;
|
|
382
|
-
align-items: center;
|
|
383
|
-
gap: var(--ui-space-2);
|
|
384
|
-
height: var(--ui-table-batch-height);
|
|
385
|
-
padding: 0 var(--ui-table-padding-x);
|
|
386
|
-
background: var(--ui-table-head-bg);
|
|
387
|
-
color: var(--ui-table-head-text);
|
|
388
|
-
}
|
|
389
|
-
.mh-table__batch-count {
|
|
390
|
-
margin-left: auto;
|
|
391
|
-
color: var(--ui-primary);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/* ===== 合计行(当页合计) ===== */
|
|
395
|
-
.mh-table__summary {
|
|
396
|
-
display: flex;
|
|
397
|
-
align-items: center;
|
|
398
|
-
gap: var(--ui-space-4);
|
|
399
|
-
height: var(--ui-table-summary-height);
|
|
400
|
-
padding: 0 var(--ui-table-padding-x);
|
|
401
|
-
border-radius: var(--ui-table-radius);
|
|
402
|
-
background: var(--ui-warning-weak); /* 规范 Au07 暖底渐变,本仓取警示弱底 */
|
|
403
|
-
}
|
|
404
|
-
.mh-table__summary-label {
|
|
405
|
-
color: var(--ui-table-head-text);
|
|
406
|
-
}
|
|
407
|
-
.mh-table__summary-value {
|
|
408
|
-
font-size: var(--ui-font-body);
|
|
409
|
-
font-weight: var(--ui-weight-medium);
|
|
410
|
-
color: var(--ui-warning); /* 规范 #ff6c29 */
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/* ===== 尺寸档:大号(详情页 / 展示型表格)—— 三档 30 / 38 / 46 里的最大档 ===== */
|
|
414
|
-
.mh-table--lg {
|
|
415
|
-
--ui-table-head-height: 46px;
|
|
416
|
-
--ui-table-row-height: 46px;
|
|
417
|
-
--ui-table-padding-x: var(--ui-space-6);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/* ===== 加载态 =====
|
|
421
|
-
* 盖一层浅罩而不是换骨架行:行高不塌,表格不会在加载前后跳动(跳动比没骨架更刺眼)。 */
|
|
422
|
-
.mh-table-wrapper {
|
|
423
|
-
position: relative;
|
|
424
|
-
}
|
|
425
|
-
.mh-table__loading {
|
|
426
|
-
position: absolute;
|
|
427
|
-
inset: 0;
|
|
428
|
-
display: flex;
|
|
429
|
-
align-items: flex-start;
|
|
430
|
-
justify-content: center;
|
|
431
|
-
padding-top: 80px;
|
|
432
|
-
background: var(--ui-mask-light);
|
|
433
|
-
}
|
|
434
|
-
.mh-table__spinner {
|
|
435
|
-
width: 24px;
|
|
436
|
-
height: 24px;
|
|
437
|
-
border: 2px solid var(--ui-primary);
|
|
438
|
-
border-top-color: transparent;
|
|
439
|
-
border-radius: var(--ui-radius-full);
|
|
440
|
-
animation: mh-table-spin 0.8s linear infinite;
|
|
441
|
-
}
|
|
442
|
-
@keyframes mh-table-spin {
|
|
443
|
-
to {
|
|
444
|
-
transform: rotate(360deg);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/* ===== 空态(表格内的空数据行;要插画与操作按钮就用 empty 插槽) ===== */
|
|
449
|
-
.mh-table__empty {
|
|
450
|
-
height: 120px;
|
|
451
|
-
text-align: center;
|
|
452
|
-
color: var(--ui-base-content-muted);
|
|
453
|
-
}
|
|
454
|
-
.mh-table__empty-row:hover td {
|
|
455
|
-
background: transparent;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/* ===== 可点行(onRow 给了 onClick 才挂) ===== */
|
|
459
|
-
.mh-table tbody tr.is-clickable {
|
|
460
|
-
cursor: pointer;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
/* ===== 展开行 ===== */
|
|
464
|
-
.mh-table__col-expand {
|
|
465
|
-
width: 40px;
|
|
466
|
-
text-align: center;
|
|
467
|
-
}
|
|
468
|
-
.mh-table__expand {
|
|
469
|
-
display: inline-flex;
|
|
470
|
-
align-items: center;
|
|
471
|
-
justify-content: center;
|
|
472
|
-
width: 20px;
|
|
473
|
-
height: 20px;
|
|
474
|
-
padding: 0;
|
|
475
|
-
border: none;
|
|
476
|
-
border-radius: var(--ui-radius-sm);
|
|
477
|
-
background: transparent;
|
|
478
|
-
color: var(--ui-base-content-muted);
|
|
479
|
-
cursor: pointer;
|
|
480
|
-
}
|
|
481
|
-
.mh-table__expand:hover {
|
|
482
|
-
background: var(--ui-base-200);
|
|
483
|
-
color: var(--ui-base-content);
|
|
484
|
-
}
|
|
485
|
-
/* 展开时箭头转 180 度:同一个下箭头字形,不另画一个上箭头 */
|
|
486
|
-
.mh-table__expand-icon {
|
|
487
|
-
width: var(--ui-font-icon); /* 常规图标档 */
|
|
488
|
-
height: var(--ui-font-icon);
|
|
489
|
-
transition: transform 0.15s ease;
|
|
490
|
-
}
|
|
491
|
-
.mh-table__expand[aria-expanded='true'] .mh-table__expand-icon {
|
|
492
|
-
transform: rotate(180deg);
|
|
493
|
-
}
|
|
494
|
-
.mh-table__expand-row > td {
|
|
495
|
-
padding: var(--ui-space-4) var(--ui-table-padding-x);
|
|
496
|
-
background: var(--ui-base-200);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
/* ===== 分页条(贴在表格下方、右对齐;分页件自身的面归 pagination.css) ===== */
|
|
500
|
-
.mh-table__pagination {
|
|
501
|
-
display: flex;
|
|
502
|
-
justify-content: flex-end;
|
|
503
|
-
padding: var(--ui-space-4) 0 0;
|
|
504
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Table —— 表格(表头/行/单元格类型 + 行态四档 + 固定表头与列 + 批量栏与合计行)。
|
|
3
|
+
*
|
|
4
|
+
* 出处(**两套来源在关键几何上一致**,故此处没有取舍余地):
|
|
5
|
+
* - `@aihub/theme` 的 `src/components/table.css`:表头 **34** / 行 **30** / 字号 13 / 勾选列 40 /
|
|
6
|
+
* 省略号 150 / 拖拽线 3×40 / 合计行 40;
|
|
7
|
+
* - 设计稿《MH后台-0911》:表头 **34**(`0:3962` 1160×34)/ 行 **30**(`0:3956`–`0:3961` 919×30,
|
|
8
|
+
* 节距 31 = 30 + 1px 线)/ 表头底 `#f1f2f5`(= `--ui-base-200`)/ 行线 `#e6e6e6`
|
|
9
|
+
* (每行 `DROP_SHADOW(0,1,b0,#e6e6e6)`)/ 外框 `#e6e6e6 @1` / 选中行底 `#dbe9ff`
|
|
10
|
+
* (= `--ui-primary-subtle`)。
|
|
11
|
+
*
|
|
12
|
+
* ⚠️ 改前这里写的是 44 / 46 —— 与上面两套来源**都不符**,是历史遗留值(文件头注释一直写着 34/30,
|
|
13
|
+
* 是代码没跟上),本轮已归位。
|
|
14
|
+
*
|
|
15
|
+
* **单元格左右内距保持 16(`--ui-space-4`)**:设计稿里可量的只有「勾选框距表左 20」这一处,
|
|
16
|
+
* 而它量的是**内容盒**、不是单元格盒(勾选列 40 宽 + 居中时内容盒落在 13 处),无法唯一反推内距,
|
|
17
|
+
* 故不作推测性改动。勾选列宽 `40` 也不动,理由同此。
|
|
18
|
+
*
|
|
19
|
+
* 行态:表头底 `--ui-base-200` + 字 `--ui-base-content-muted` + 中粗 / 外框 1px `--ui-base-300` /
|
|
20
|
+
* 斑马与禁用 `--ui-base-200` / 滑过 `--ui-primary-weak` / 选中 `--ui-primary-subtle`(**只底色**)。
|
|
21
|
+
*
|
|
22
|
+
* 四条必须照做的**结构**决定(做错就与规范不是一回事):
|
|
23
|
+
*
|
|
24
|
+
* 1. **边框模型**:默认是**外框**(画在 `.mh-table` 上)+ 表头下分割线 + 每行底线(末行去线),
|
|
25
|
+
* 故 `border-collapse: separate` + `border-spacing: 0` —— 圆角只有在 separate 下才渲染得出来;
|
|
26
|
+
* `--borderless` 才切回 `collapse` 并去掉外框。
|
|
27
|
+
* **三条线之外的边一律显式清零**(`border: 0` 写在 `th` / `td` / `tr` 上,不是冗余):特异性只在
|
|
28
|
+
* **同一个属性**上分胜负,宿主给单元格或行下的整圈边框(典型是 markdown 正文的
|
|
29
|
+
* `.vp-doc th, .vp-doc td { border: 1px solid }`、`.vp-doc tr { border-top: ... }`)不会被本件
|
|
30
|
+
* "没写的边"顶掉,结果就是与表外框叠成 2px、行交界处叠成 2px、还多出列分隔线。
|
|
31
|
+
* 2. **斑马纹是显式类**(`.is-striped`)而非 `:nth-child(even)`:表里可以插分组行,`nth-child` 会整表错位
|
|
32
|
+
* —— 这是规范里唯一允许"用类代替结构选择器"的豁免。
|
|
33
|
+
* 3. **行选中由行内的选择控件驱动**(`tr:has(.mh-table__col-check input:checked)`):这样零 JS 也能选中;
|
|
34
|
+
* 组件态给 `[data-state='selected']`,静态档给 `.is-selected` —— 三源等价。
|
|
35
|
+
* 勾选列复用 `Checkbox` **组件**(不在表格里手写原生 input):该件内部才是真实 `<input type="checkbox">`,
|
|
36
|
+
* 故 `:has(...)` 这条路径照旧成立;`Checkbox` 的框体带 `data-state`(checked / indeterminate),
|
|
37
|
+
* 半选与选中都走它自己的样式数据,表格这边不再画方块。
|
|
38
|
+
* **选择器必须限定在勾选列内**(`.mh-table__col-check`,勾选列单元格自带的类):不限列时,
|
|
39
|
+
* 功能列里任何「内部本来就是 checkbox」的件都会命中 —— `Switch` 的内部正是 `<input type="checkbox">`,
|
|
40
|
+
* 于是「启用」这类**功能值**会把整行点亮。功能值与行选择语义不同,视觉必须分开(否则一张表里
|
|
41
|
+
* 开关一开就整行变色,且用户无从判断那到底表示什么)。
|
|
42
|
+
* 4. **固定列必须自带底**(`background: var(--ui-base-100)`):它是 sticky 的,不遮挡就会被滚过的单元格透出。
|
|
43
|
+
*
|
|
44
|
+
* **不做**:排序与列宽拖拽的**算法**(规范只给了 `↕` 字形与 3×40 拖拽线这两处视觉),也不做空态/加载态
|
|
45
|
+
* (规范表格里没有这两个样张 —— 三态归 `QueryState`)。
|
|
46
|
+
*/
|
|
47
|
+
.mh-table-wrapper {
|
|
48
|
+
overflow: auto;
|
|
49
|
+
}
|
|
50
|
+
/* `--fill` 档把外框从表移交给包裹层(表自己不再画框,改由包裹层画满高框) */
|
|
51
|
+
.mh-table-wrapper:has(> .mh-table--fill) {
|
|
52
|
+
border: 1px solid var(--ui-table-border);
|
|
53
|
+
border-radius: var(--ui-table-radius);
|
|
54
|
+
}
|
|
55
|
+
.mh-table-scroll {
|
|
56
|
+
max-height: var(--ui-table-scroll-height); /* 规范样张 132(实际用按需覆盖) */
|
|
57
|
+
overflow: auto;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* 几何只挂在 `<table>` 上:令牌在同名 `.tokens.css`(锚 `[data-manohub-ui]`),几何若跟着挂会给包裹层加边框与圆角 */
|
|
61
|
+
.mh-table {
|
|
62
|
+
width: 100%;
|
|
63
|
+
border: 1px solid var(--ui-table-border);
|
|
64
|
+
border-collapse: separate; /* 圆角需要 separate(见文件头第 1 条) */
|
|
65
|
+
border-spacing: 0;
|
|
66
|
+
border-radius: var(--ui-table-radius);
|
|
67
|
+
font-size: var(--ui-table-font-size);
|
|
68
|
+
color: var(--ui-table-text);
|
|
69
|
+
background: var(--ui-base-100);
|
|
70
|
+
}
|
|
71
|
+
/* 无框档:去外框并切回 collapse(不再需要圆角) */
|
|
72
|
+
.mh-table--borderless {
|
|
73
|
+
border: none;
|
|
74
|
+
border-collapse: collapse;
|
|
75
|
+
border-radius: 0;
|
|
76
|
+
}
|
|
77
|
+
/* 满高档:外框交包裹层,去掉自己的圆角(否则内外两层圆角会露缝) */
|
|
78
|
+
.mh-table--fill {
|
|
79
|
+
border: none;
|
|
80
|
+
border-radius: 0;
|
|
81
|
+
}
|
|
82
|
+
/* 紧凑档(`size="sm"`):三档 30 / 38 / 46 里的最小档,嵌在卡片 / 面板里的表格用它 */
|
|
83
|
+
.mh-table--xs {
|
|
84
|
+
--ui-table-head-height: 30px;
|
|
85
|
+
--ui-table-row-height: 30px;
|
|
86
|
+
}
|
|
87
|
+
/* 窄屏下的最小宽(触发横向滚动,而不是把列压扁) */
|
|
88
|
+
.mh-table--wide {
|
|
89
|
+
min-width: 620px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ===== 固定布局档(`layout="fixed"`)=====
|
|
93
|
+
* 列宽由 `<colgroup>` 下发(与档位无关),本档只把布局算法换成 `fixed`:
|
|
94
|
+
* 列宽从此**受声明约束、不再被内容撑破** ⇒ 长文本不会把表格撑得比容器还宽,
|
|
95
|
+
* 于是「百分比 / 数字权重」可以「吃满容器 + 严格按比例」。
|
|
96
|
+
*
|
|
97
|
+
* 调用方要知道的:表体**默认不换行**(nowrap + 省略号,见下条);要换行的列显式标 `wrap: true`。 */
|
|
98
|
+
.mh-table--fixed {
|
|
99
|
+
table-layout: fixed;
|
|
100
|
+
}
|
|
101
|
+
/* `fixed` 档表体默认**不换行**(nowrap + 省略号)。两条依据:
|
|
102
|
+
* ① 列宽已被 `<colgroup>` 钉死,换行救不回内容,只会把行高顶高(`td` 的 `height` 只是**下限**);
|
|
103
|
+
* ② 换行必然伴随**从字符间断字** —— 实测序号列窄到装不下两位数时,旧的 `overflow-wrap: anywhere`
|
|
104
|
+
* 把 `10` 拆成 `1` / `0` 两行,行高 30 → **49**。
|
|
105
|
+
* 于是「换行」改成**列级主动选择**:`TableColumn.wrap: true`(见 `.mh-table__cell-wrap`)。
|
|
106
|
+
* ⚠️ **只在本档翻默认**:`auto` 档的列宽由内容计算,td 默认 nowrap 会让长文本列不再靠换行收敛、
|
|
107
|
+
* 表格更容易撑破容器 —— 与本档「表头裁切只加在 fixed」同一条判据(见上一条注释)。 */
|
|
108
|
+
.mh-table--fixed tbody td {
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
text-overflow: ellipsis;
|
|
111
|
+
white-space: nowrap;
|
|
112
|
+
}
|
|
113
|
+
/* 前导列(勾选 / 展开)在 auto 下靠内容把 40px 的「建议宽」撑出去;fixed 下是硬宽,
|
|
114
|
+
而 `thead th` / `tbody td` 的标准左右内距各 16px ⇒ 可用内容只有 40 − 32 = 8px,
|
|
115
|
+
装不下 16px 的勾选框(实测该列溢出 19px,还会被上面的 `overflow: hidden` 裁掉)。
|
|
116
|
+
故本档把前导列的内距清零,靠既有的 `text-align: center` 居中。 */
|
|
117
|
+
.mh-table--fixed .mh-table__col-check,
|
|
118
|
+
.mh-table--fixed .mh-table__col-expand {
|
|
119
|
+
padding: 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* ===== 表头 =====
|
|
123
|
+
* `border: 0` **不是冗余**:本件只画「表外框 + 表头分割线 + 每行底线」三条,其余边必须显式清零。
|
|
124
|
+
* 特异性和平局只发生在**同一个属性**上 —— 本件只声明 `border-bottom` 时,宿主给单元格下的整圈边框
|
|
125
|
+
* (典型:markdown 正文的 `.vp-doc th, .vp-doc td { border: 1px solid }`)不会被任何组件声明顶掉,
|
|
126
|
+
* 于是单元格四边各来一条:与表外框叠成 2px、每行交界处上一行底线 + 本行顶线叠成 2px,还凭空多出列分隔线。
|
|
127
|
+
* 这三条不是「装饰」而是边框模型的一部分,故与 `border-bottom` 写在同一规则里(0-1-2 压过 `.vp-doc th` 0-1-1)。 */
|
|
128
|
+
.mh-table thead th {
|
|
129
|
+
height: var(--ui-table-head-height);
|
|
130
|
+
padding: 0 var(--ui-table-padding-x);
|
|
131
|
+
border: 0;
|
|
132
|
+
border-bottom: 1px solid var(--ui-table-border);
|
|
133
|
+
background: var(--ui-table-head-bg);
|
|
134
|
+
color: var(--ui-table-head-text);
|
|
135
|
+
font-weight: var(--ui-weight-medium);
|
|
136
|
+
text-align: left;
|
|
137
|
+
white-space: nowrap;
|
|
138
|
+
}
|
|
139
|
+
.mh-table thead th:hover,
|
|
140
|
+
.mh-table thead th.is-hover {
|
|
141
|
+
background: var(--ui-table-head-bg-hover);
|
|
142
|
+
}
|
|
143
|
+
/* 固定档下表头也要裁切:列宽已被 colgroup 钉死,长表头文字会**溢出到相邻列**
|
|
144
|
+
(实测溢出 97px),必须靠这两条收住。`white-space: nowrap` 上面已有。
|
|
145
|
+
⚠️ 只在本档加 —— auto 档下表头参与列宽计算,加裁切会改动老页面的列宽分配。 */
|
|
146
|
+
.mh-table--fixed thead th {
|
|
147
|
+
overflow: hidden;
|
|
148
|
+
text-overflow: ellipsis;
|
|
149
|
+
}
|
|
150
|
+
/* 多级表头的组头:下边线不加(组头跨列,加线会切断视觉分组) */
|
|
151
|
+
.mh-table thead th.mh-table__th-group {
|
|
152
|
+
border-bottom: 1px solid var(--ui-table-head-divider);
|
|
153
|
+
text-align: center;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* ===== 行 =====
|
|
157
|
+
* 行自身不画线(行线在单元格底边上):同样显式清零,挡住宿主给 `tr` 加的顶线(会与本件行底线叠成双线)。 */
|
|
158
|
+
.mh-table thead tr,
|
|
159
|
+
.mh-table tbody tr {
|
|
160
|
+
border: 0;
|
|
161
|
+
}
|
|
162
|
+
/* 单元格的边框模型:**全清零 + 只留底线**(理由同表头处:宿主给 `th` / `td` 下的整圈边框只靠
|
|
163
|
+
* 特异性挡不住未声明的三边,会让行线与表外框全部叠成双线)。 */
|
|
164
|
+
.mh-table tbody td {
|
|
165
|
+
height: var(--ui-table-row-height);
|
|
166
|
+
padding: var(--ui-space-1) var(--ui-table-padding-x);
|
|
167
|
+
border: 0;
|
|
168
|
+
border-bottom: 1px solid var(--ui-table-border);
|
|
169
|
+
line-height: var(--ui-table-line-height);
|
|
170
|
+
vertical-align: middle;
|
|
171
|
+
}
|
|
172
|
+
.mh-table tbody tr:last-child td {
|
|
173
|
+
border-bottom: none;
|
|
174
|
+
}
|
|
175
|
+
/* 行态顺序即优先级:斑马 → 滑过 → 选中 → 禁用(禁用压住一切,故放最后) */
|
|
176
|
+
.mh-table tbody tr.is-striped td {
|
|
177
|
+
background: var(--ui-table-row-alt);
|
|
178
|
+
}
|
|
179
|
+
.mh-table tbody tr:hover td,
|
|
180
|
+
.mh-table tbody tr.is-hover td {
|
|
181
|
+
background: var(--ui-table-row-hover);
|
|
182
|
+
}
|
|
183
|
+
/* 选中态**只有底色**:规范样张里那条 2px 主色下沿(Au01)已去掉 ——
|
|
184
|
+
行线只由单元格底边提供,选中行不再额外压一条线(`box-shadow: inset 0 -2px` 会盖住底边线,
|
|
185
|
+
看起来像"两行线叠在一起")。要恢复下沿就加回 inset 阴影 + 对应令牌。
|
|
186
|
+
第三条路径限定在勾选列内(见文件头第 3 条):不限列会被功能列的 Switch 命中。 */
|
|
187
|
+
.mh-table tbody tr.is-selected td,
|
|
188
|
+
.mh-table tbody tr[data-state='selected'] td,
|
|
189
|
+
.mh-table tbody tr:has(.mh-table__col-check input:checked) td {
|
|
190
|
+
background: var(--ui-table-row-selected);
|
|
191
|
+
}
|
|
192
|
+
.mh-table tbody tr.is-disabled td,
|
|
193
|
+
.mh-table tbody tr[aria-disabled='true'] td {
|
|
194
|
+
background: var(--ui-table-row-disabled);
|
|
195
|
+
color: var(--ui-base-content-subtle);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* 分组行:整行一条、不可选、字重中粗 */
|
|
199
|
+
.mh-table tbody tr.mh-table__group-row td {
|
|
200
|
+
height: var(--ui-table-row-height);
|
|
201
|
+
background: var(--ui-table-head-bg);
|
|
202
|
+
color: var(--ui-table-head-text);
|
|
203
|
+
font-weight: var(--ui-weight-medium);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* 树行:子行首列缩进(与树的缩进同一口径) */
|
|
207
|
+
.mh-table tbody tr.mh-table__row--child td:first-child {
|
|
208
|
+
padding-left: var(--ui-table-tree-indent);
|
|
209
|
+
}
|
|
210
|
+
.mh-table__tree-caret {
|
|
211
|
+
display: inline-flex;
|
|
212
|
+
width: var(--ui-font-icon); /* 常规图标档(改前无声明、掉到 `<svg>` 默认 16) */
|
|
213
|
+
height: var(--ui-font-icon);
|
|
214
|
+
margin-right: var(--ui-space-1);
|
|
215
|
+
color: var(--ui-base-content-subtle);
|
|
216
|
+
transition: transform 0.15s ease;
|
|
217
|
+
}
|
|
218
|
+
.mh-table__tree-caret--open {
|
|
219
|
+
transform: rotate(-90deg);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* ===== 列 ===== */
|
|
223
|
+
/* 勾选列:只负责「多宽 + 居中」——`Checkbox` 组件是 inline-flex,靠格子的 text-align 居中;
|
|
224
|
+
方块尺寸 / 圆角 / 三态配色全归 `checkbox.css`(表格不再给这一列任何选中态样式) */
|
|
225
|
+
.mh-table__col-check {
|
|
226
|
+
width: var(--ui-table-col-check);
|
|
227
|
+
text-align: center;
|
|
228
|
+
}
|
|
229
|
+
.mh-table__col-actions {
|
|
230
|
+
text-align: right;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* ⚠️ **表头要把对齐重声明一遍**:上面这几条与 `.mh-table__cell-center` / `.mh-table__cell-amount`
|
|
234
|
+
* 都只有 **0-1-0**,而 `.mh-table thead th { text-align: left }` 是 **0-1-1** ⇒ 表头被强拉成左对齐、
|
|
235
|
+
* 与表体不齐:勾选框应居中却贴左(实测表头左留白 0 / 右留白 26,与表体错位 13px)、
|
|
236
|
+
* 右对齐列的标题应靠右却被拉到左边。
|
|
237
|
+
* 只用补 `text-align` —— `thead th` 没声明过其它会被这些类覆盖的属性(宽度/内距不冲突)。
|
|
238
|
+
* 写法沿用 `th.mh-table__th-group`(组头居中)那条既有先例。 */
|
|
239
|
+
.mh-table thead th.mh-table__col-check,
|
|
240
|
+
.mh-table thead th.mh-table__cell-center {
|
|
241
|
+
text-align: center;
|
|
242
|
+
}
|
|
243
|
+
.mh-table thead th.mh-table__col-actions {
|
|
244
|
+
text-align: right;
|
|
245
|
+
}
|
|
246
|
+
/* `--sticky-col`:首列钉住(必须自带底,见文件头第 4 条) */
|
|
247
|
+
.mh-table--sticky-col thead th:first-child,
|
|
248
|
+
.mh-table--sticky-col tbody td:first-child {
|
|
249
|
+
position: sticky;
|
|
250
|
+
left: 0;
|
|
251
|
+
z-index: 1;
|
|
252
|
+
background: var(--ui-base-100);
|
|
253
|
+
}
|
|
254
|
+
.mh-table--sticky-col thead th:first-child {
|
|
255
|
+
z-index: 2; /* 表头既钉顶又钉左,压住表头其余列 */
|
|
256
|
+
background: var(--ui-table-head-bg);
|
|
257
|
+
}
|
|
258
|
+
/* `--sticky-head`:表头钉顶。
|
|
259
|
+
* ⚠️ 选择器必须带 `tr`(0-1-3):文件后段「拖拽线的定位上下文」那条
|
|
260
|
+
* `.mh-table thead th { position: relative }` 是 **0-1-2**,与不写 `tr` 的写法**同特异性且在后**
|
|
261
|
+
* ⇒ 会把 `position: sticky` 覆盖掉,`stickyHead` 静默失效(0.6.0 起就存在,0.9.0 复核仍在)。
|
|
262
|
+
* `sticky` 同样是定位元素,照样给表头里的拖拽线当包含块,故加 `tr` 不损失原能力。 */
|
|
263
|
+
.mh-table--sticky-head thead tr th {
|
|
264
|
+
position: sticky;
|
|
265
|
+
top: 0;
|
|
266
|
+
z-index: 1;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* ===== 单元格类型 ===== */
|
|
270
|
+
.mh-table__cell-center {
|
|
271
|
+
text-align: center;
|
|
272
|
+
}
|
|
273
|
+
.mh-table__cell-amount {
|
|
274
|
+
text-align: right;
|
|
275
|
+
font-variant-numeric: tabular-nums; /* 金额对齐靠等宽数字,不靠右对齐就够 */
|
|
276
|
+
}
|
|
277
|
+
.mh-table__cell-link {
|
|
278
|
+
color: var(--ui-table-link);
|
|
279
|
+
text-decoration: none;
|
|
280
|
+
cursor: pointer;
|
|
281
|
+
}
|
|
282
|
+
.mh-table__cell-link:hover {
|
|
283
|
+
text-decoration: underline;
|
|
284
|
+
}
|
|
285
|
+
/* 列级**放开换行**(列定义里 `wrap: true` 时下发,只作用于表体 `td`;表头始终 nowrap)。
|
|
286
|
+
* 缺省不换行在面文件的 `.mh-table--fixed tbody td` 里 —— 本档才翻默认,故这里同时把
|
|
287
|
+
* 「换行三件套」与 `overflow-wrap` 兜底一并给回:换来的是「长文本列自己决定换行」。
|
|
288
|
+
* ⚠️ 选择器必须带 `td`(0-1-3):`.mh-table--fixed tbody td` 是 **0-1-2**,
|
|
289
|
+
* 单个类(0-1-0)压不过它(同 §表头对齐那条的先例)。 */
|
|
290
|
+
.mh-table tbody td.mh-table__cell-wrap {
|
|
291
|
+
white-space: normal;
|
|
292
|
+
overflow: visible;
|
|
293
|
+
text-overflow: clip;
|
|
294
|
+
overflow-wrap: anywhere;
|
|
295
|
+
}
|
|
296
|
+
.mh-table__cell-icon {
|
|
297
|
+
display: inline-flex;
|
|
298
|
+
align-items: center;
|
|
299
|
+
margin-right: var(--ui-space-1);
|
|
300
|
+
color: var(--ui-base-content-muted);
|
|
301
|
+
}
|
|
302
|
+
.mh-table__cell-main {
|
|
303
|
+
display: block;
|
|
304
|
+
}
|
|
305
|
+
.mh-table__cell-sub {
|
|
306
|
+
display: block;
|
|
307
|
+
color: var(--ui-base-content-muted);
|
|
308
|
+
}
|
|
309
|
+
/* 必填列的表头加星号(只在表头,不在单元格) */
|
|
310
|
+
.mh-table th.mh-table__cell-required::before {
|
|
311
|
+
content: '*';
|
|
312
|
+
margin-right: var(--ui-space-1);
|
|
313
|
+
color: var(--ui-error);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/* 状态点(语义四档) */
|
|
317
|
+
.mh-table__status-dot {
|
|
318
|
+
display: inline-block;
|
|
319
|
+
width: var(--ui-table-status-dot);
|
|
320
|
+
height: var(--ui-table-status-dot);
|
|
321
|
+
margin-right: var(--ui-space-1);
|
|
322
|
+
border-radius: var(--ui-radius-full);
|
|
323
|
+
background: var(--ui-base-400);
|
|
324
|
+
vertical-align: middle;
|
|
325
|
+
}
|
|
326
|
+
.mh-table__status-dot--info {
|
|
327
|
+
background: var(--ui-info);
|
|
328
|
+
}
|
|
329
|
+
.mh-table__status-dot--success {
|
|
330
|
+
background: var(--ui-success);
|
|
331
|
+
}
|
|
332
|
+
.mh-table__status-dot--warning {
|
|
333
|
+
background: var(--ui-warning);
|
|
334
|
+
}
|
|
335
|
+
.mh-table__status-dot--error {
|
|
336
|
+
background: var(--ui-error);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* ===== 表头操作:排序按钮与列宽拖拽线 ===== */
|
|
340
|
+
.mh-table__sort {
|
|
341
|
+
display: inline-flex;
|
|
342
|
+
align-items: center;
|
|
343
|
+
gap: 2px;
|
|
344
|
+
margin-left: var(--ui-space-1);
|
|
345
|
+
padding: 0;
|
|
346
|
+
border: none;
|
|
347
|
+
background: transparent;
|
|
348
|
+
color: var(--ui-base-content-subtle);
|
|
349
|
+
cursor: pointer;
|
|
350
|
+
}
|
|
351
|
+
.mh-table__sort--active {
|
|
352
|
+
color: var(--ui-primary);
|
|
353
|
+
}
|
|
354
|
+
/* 槽位尺寸:常规图标一律取全局图标档(**不写 `.mh-table__sort-icon`** —— 那是只作朝向锚点的结构类,
|
|
355
|
+
面上为排序指示写规则会被契约拦下,见下方注释) */
|
|
356
|
+
.mh-table__sort > svg {
|
|
357
|
+
width: var(--ui-font-icon);
|
|
358
|
+
height: var(--ui-font-icon);
|
|
359
|
+
}
|
|
360
|
+
/* 排序朝向:**方位在字形里**(升序 `chevron-up` / 降序与未排序 `chevron-down`,未排走浅色、已排随
|
|
361
|
+
`.mh-table__sort--active` 主色)—— 本层零 `transform`,不走"把别的图标旋转 90° 冒充上下"的老路
|
|
362
|
+
(包内硬约束)。`mh-table__sort-icon` 与 `--asc` / `--desc` 只作**状态锚点**(消费方与用例按它们定位
|
|
363
|
+
当前朝向),面上无声明,登记在测试契约的结构锚点台账里。 */
|
|
364
|
+
.mh-table__drag-line {
|
|
365
|
+
position: absolute;
|
|
366
|
+
top: 50%;
|
|
367
|
+
right: 0;
|
|
368
|
+
width: var(--ui-table-drag-line-width);
|
|
369
|
+
height: var(--ui-table-drag-line-height);
|
|
370
|
+
background: var(--ui-table-drag-line);
|
|
371
|
+
transform: translateY(-50%);
|
|
372
|
+
cursor: col-resize;
|
|
373
|
+
}
|
|
374
|
+
/* 拖拽线要定在表头单元格右缘,故表头格需要定位上下文 */
|
|
375
|
+
.mh-table thead th {
|
|
376
|
+
position: relative;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* ===== 批量栏(选中若干行后出现在表格上方) ===== */
|
|
380
|
+
.mh-table__batch {
|
|
381
|
+
display: flex;
|
|
382
|
+
align-items: center;
|
|
383
|
+
gap: var(--ui-space-2);
|
|
384
|
+
height: var(--ui-table-batch-height);
|
|
385
|
+
padding: 0 var(--ui-table-padding-x);
|
|
386
|
+
background: var(--ui-table-head-bg);
|
|
387
|
+
color: var(--ui-table-head-text);
|
|
388
|
+
}
|
|
389
|
+
.mh-table__batch-count {
|
|
390
|
+
margin-left: auto;
|
|
391
|
+
color: var(--ui-primary);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* ===== 合计行(当页合计) ===== */
|
|
395
|
+
.mh-table__summary {
|
|
396
|
+
display: flex;
|
|
397
|
+
align-items: center;
|
|
398
|
+
gap: var(--ui-space-4);
|
|
399
|
+
height: var(--ui-table-summary-height);
|
|
400
|
+
padding: 0 var(--ui-table-padding-x);
|
|
401
|
+
border-radius: var(--ui-table-radius);
|
|
402
|
+
background: var(--ui-warning-weak); /* 规范 Au07 暖底渐变,本仓取警示弱底 */
|
|
403
|
+
}
|
|
404
|
+
.mh-table__summary-label {
|
|
405
|
+
color: var(--ui-table-head-text);
|
|
406
|
+
}
|
|
407
|
+
.mh-table__summary-value {
|
|
408
|
+
font-size: var(--ui-font-body);
|
|
409
|
+
font-weight: var(--ui-weight-medium);
|
|
410
|
+
color: var(--ui-warning); /* 规范 #ff6c29 */
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* ===== 尺寸档:大号(详情页 / 展示型表格)—— 三档 30 / 38 / 46 里的最大档 ===== */
|
|
414
|
+
.mh-table--lg {
|
|
415
|
+
--ui-table-head-height: 46px;
|
|
416
|
+
--ui-table-row-height: 46px;
|
|
417
|
+
--ui-table-padding-x: var(--ui-space-6);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* ===== 加载态 =====
|
|
421
|
+
* 盖一层浅罩而不是换骨架行:行高不塌,表格不会在加载前后跳动(跳动比没骨架更刺眼)。 */
|
|
422
|
+
.mh-table-wrapper {
|
|
423
|
+
position: relative;
|
|
424
|
+
}
|
|
425
|
+
.mh-table__loading {
|
|
426
|
+
position: absolute;
|
|
427
|
+
inset: 0;
|
|
428
|
+
display: flex;
|
|
429
|
+
align-items: flex-start;
|
|
430
|
+
justify-content: center;
|
|
431
|
+
padding-top: 80px;
|
|
432
|
+
background: var(--ui-mask-light);
|
|
433
|
+
}
|
|
434
|
+
.mh-table__spinner {
|
|
435
|
+
width: 24px;
|
|
436
|
+
height: 24px;
|
|
437
|
+
border: 2px solid var(--ui-primary);
|
|
438
|
+
border-top-color: transparent;
|
|
439
|
+
border-radius: var(--ui-radius-full);
|
|
440
|
+
animation: mh-table-spin 0.8s linear infinite;
|
|
441
|
+
}
|
|
442
|
+
@keyframes mh-table-spin {
|
|
443
|
+
to {
|
|
444
|
+
transform: rotate(360deg);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/* ===== 空态(表格内的空数据行;要插画与操作按钮就用 empty 插槽) ===== */
|
|
449
|
+
.mh-table__empty {
|
|
450
|
+
height: 120px;
|
|
451
|
+
text-align: center;
|
|
452
|
+
color: var(--ui-base-content-muted);
|
|
453
|
+
}
|
|
454
|
+
.mh-table__empty-row:hover td {
|
|
455
|
+
background: transparent;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/* ===== 可点行(onRow 给了 onClick 才挂) ===== */
|
|
459
|
+
.mh-table tbody tr.is-clickable {
|
|
460
|
+
cursor: pointer;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/* ===== 展开行 ===== */
|
|
464
|
+
.mh-table__col-expand {
|
|
465
|
+
width: 40px;
|
|
466
|
+
text-align: center;
|
|
467
|
+
}
|
|
468
|
+
.mh-table__expand {
|
|
469
|
+
display: inline-flex;
|
|
470
|
+
align-items: center;
|
|
471
|
+
justify-content: center;
|
|
472
|
+
width: 20px;
|
|
473
|
+
height: 20px;
|
|
474
|
+
padding: 0;
|
|
475
|
+
border: none;
|
|
476
|
+
border-radius: var(--ui-radius-sm);
|
|
477
|
+
background: transparent;
|
|
478
|
+
color: var(--ui-base-content-muted);
|
|
479
|
+
cursor: pointer;
|
|
480
|
+
}
|
|
481
|
+
.mh-table__expand:hover {
|
|
482
|
+
background: var(--ui-base-200);
|
|
483
|
+
color: var(--ui-base-content);
|
|
484
|
+
}
|
|
485
|
+
/* 展开时箭头转 180 度:同一个下箭头字形,不另画一个上箭头 */
|
|
486
|
+
.mh-table__expand-icon {
|
|
487
|
+
width: var(--ui-font-icon); /* 常规图标档 */
|
|
488
|
+
height: var(--ui-font-icon);
|
|
489
|
+
transition: transform 0.15s ease;
|
|
490
|
+
}
|
|
491
|
+
.mh-table__expand[aria-expanded='true'] .mh-table__expand-icon {
|
|
492
|
+
transform: rotate(180deg);
|
|
493
|
+
}
|
|
494
|
+
.mh-table__expand-row > td {
|
|
495
|
+
padding: var(--ui-space-4) var(--ui-table-padding-x);
|
|
496
|
+
background: var(--ui-base-200);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/* ===== 分页条(贴在表格下方、右对齐;分页件自身的面归 pagination.css) ===== */
|
|
500
|
+
.mh-table__pagination {
|
|
501
|
+
display: flex;
|
|
502
|
+
justify-content: flex-end;
|
|
503
|
+
padding: var(--ui-space-4) 0 0;
|
|
504
|
+
}
|