@manohub/ui 0.10.1 → 0.10.3
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 +1 -1
- package/dist/components/badge/index.d.ts +46 -1
- package/dist/components/badge/index.js +42 -9
- package/dist/components/card/index.d.ts +1 -1
- package/dist/components/drawer/index.d.ts +1 -1
- package/dist/components/form/index.d.ts +50 -1
- package/dist/components/form/index.js +20 -2
- package/dist/components/input/index.js +1 -0
- package/dist/components/nav/index.d.ts +27 -0
- package/dist/components/nav/index.js +12 -0
- package/dist/components/notice/index.d.ts +1 -1
- package/dist/components/notification/index.d.ts +2 -2
- package/dist/components/select/index.d.ts +9 -0
- package/dist/components/select/index.js +57 -12
- package/dist/components/select/select-list.d.ts +42 -8
- package/dist/components/select/select-list.js +36 -11
- package/dist/components/select/select-panel.d.ts +36 -8
- package/dist/components/select/select-panel.js +18 -4
- package/dist/components/select/select-shared.d.ts +51 -10
- package/dist/components/select/select-shared.js +12 -2
- package/dist/components/select/select-tree.d.ts +25 -3
- package/dist/components/select/select-tree.js +17 -6
- package/dist/components/select/select-trigger.d.ts +21 -0
- package/dist/components/select/select-trigger.js +15 -1
- package/dist/components/tag/index.d.ts +32 -153
- package/dist/components/tag/index.js +102 -101
- package/dist/components/text/index.d.ts +1 -1
- package/dist/components/tooltip/index.d.ts +1 -1
- package/dist/components/tree/index.d.ts +65 -0
- package/dist/components/tree/index.js +29 -2
- package/dist/index.d.ts +1 -1
- package/dist/styles/components/avatar.css +2 -2
- package/dist/styles/components/badge.css +31 -4
- package/dist/styles/components/badge.tokens.css +24 -0
- package/dist/styles/components/button.css +7 -6
- package/dist/styles/components/button.tokens.css +5 -2
- package/dist/styles/components/dialog.css +13 -0
- package/dist/styles/components/divider.css +8 -4
- package/dist/styles/components/divider.tokens.css +2 -1
- package/dist/styles/components/form.css +51 -0
- package/dist/styles/components/notification.css +1 -1
- package/dist/styles/components/select.css +62 -39
- package/dist/styles/components/select.tokens.css +16 -9
- package/dist/styles/components/tag.css +77 -154
- package/dist/styles/components/tag.tokens.css +13 -19
- package/dist/styles/components/tree.css +37 -3
- package/dist/styles/components/tree.tokens.css +4 -3
- package/dist/styles/components/upload.tokens.css +1 -1
- package/dist/styles/index.css +2 -1
- package/dist/styles/operations/popup.css +5 -1
- package/package.json +2 -2
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
.mh-avatar--icon {
|
|
65
65
|
color: var(--ui-base-100);
|
|
66
66
|
}
|
|
67
|
-
/* 占位:虚线框 +
|
|
67
|
+
/* 占位:虚线框 + 说明字(虚线线色取线型档,口径「实线 base-300 / 虚线 base-400」) */
|
|
68
68
|
.mh-avatar--placeholder {
|
|
69
|
-
border: 1px dashed var(--ui-
|
|
69
|
+
border: 1px dashed var(--ui-line-dashed);
|
|
70
70
|
background: var(--ui-base-100);
|
|
71
71
|
color: var(--ui-base-content-subtle);
|
|
72
72
|
font-size: var(--ui-font-caption);
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
box-sizing: border-box;
|
|
21
21
|
border: 1px solid transparent;
|
|
22
22
|
font-size: var(--ui-font-caption);
|
|
23
|
+
/* `as="button"`(可点形态,`Tag` 的「新增」用)时根是 `<button>`:UA 会把字形换成 Arial、
|
|
24
|
+
文字居中、并给 padding/border/background —— 后三样本件已自带(`.mh-badge` 的框与各档内距),
|
|
25
|
+
只有字族漏在外面,这里补上(对 `<span>` 根无副作用:span 本就继承)。 */
|
|
26
|
+
font-family: inherit;
|
|
23
27
|
line-height: 1;
|
|
24
28
|
white-space: nowrap;
|
|
25
29
|
color: var(--mh-badge-fg);
|
|
@@ -28,16 +32,19 @@
|
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
/* 尺寸档的圆角吃**体量档**(`xs` / `sm`),不吃容器档 `md` —— 容器档一改(卡片圆角调整)
|
|
31
|
-
徽标会跟着变,那是两件无关的事。20 档有设计实证(表格内标签 r3),24 档无实证、按体量就近升一档。
|
|
35
|
+
徽标会跟着变,那是两件无关的事。20 档有设计实证(表格内标签 r3),24 档无实证、按体量就近升一档。
|
|
36
|
+
高度取**标记体量档**(全局令牌 `--ui-mark-height-sm/md`):与 `Tag` 的 20 / 24、`Select` 多选
|
|
37
|
+
标签片的 24 同源 —— 这三处以前各写一份字面量,改一次档要改三处(2026-09-30 收敛)。
|
|
38
|
+
`Tag` 的基础圆角同日也归到这两档(改前它走控件档 6px):两族在 20 / 24 上同高同角。 */
|
|
32
39
|
.mh-badge--sm {
|
|
33
|
-
height:
|
|
40
|
+
height: var(--ui-mark-height-sm);
|
|
34
41
|
padding: 0 6px;
|
|
35
42
|
min-width: 36px;
|
|
36
43
|
border-radius: var(--ui-radius-xs);
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
.mh-badge--md {
|
|
40
|
-
height:
|
|
47
|
+
height: var(--ui-mark-height-md);
|
|
41
48
|
padding: 0 8px;
|
|
42
49
|
border-radius: var(--ui-radius-sm);
|
|
43
50
|
}
|
|
@@ -96,8 +103,13 @@
|
|
|
96
103
|
--mh-badge-fg: var(--ui-base-content-muted);
|
|
97
104
|
}
|
|
98
105
|
|
|
106
|
+
/* ⚠️ 主色软底取**浅底档** `--ui-primary-weak`(同一槽位的其他消费者:`Tag` 默认底、表壳滑过底、
|
|
107
|
+
聚焦环);**不取** `--ui-primary-subtle` —— 那是**选中态底**(树行 / 表格行 / 卡片选中 / 单选卡),
|
|
108
|
+
两档在 default 主题里差一整档(#EFF5FF → #DBE9FF),取错会让徽标比同排的标签深一档,
|
|
109
|
+
而徽标表达的是「标记」不是「选中」(2026-09-30 收敛,槽位口径见
|
|
110
|
+
`@manohub/theme` 的 `default/colors.css` 品牌槽位两条注释)。 */
|
|
99
111
|
.mh-badge--soft.mh-badge--primary {
|
|
100
|
-
--mh-badge-bg: var(--ui-primary-
|
|
112
|
+
--mh-badge-bg: var(--ui-primary-weak);
|
|
101
113
|
}
|
|
102
114
|
|
|
103
115
|
/* 描边:浅底 + 同色描边;default 退化为白底 + 中性描边 + 正文色(状态胶囊) */
|
|
@@ -132,11 +144,23 @@
|
|
|
132
144
|
--mh-badge-fg: var(--ui-error);
|
|
133
145
|
}
|
|
134
146
|
|
|
147
|
+
/* ===== 前置点 / 状态点:**光学对齐**(下移 1px)=====
|
|
148
|
+
两族的圆点都被 flex 居中在**盒中心**(实测偏心 0px),但**文字的墨迹中心在盒中心之下**:
|
|
149
|
+
中文(`带点(填充)`)约 +0.5px、纯小写(`sm` / `md`)约 +2px、状态点那族(14px)约 +1px
|
|
150
|
+
—— 于是盒居中读起来是「点偏高」(2026-09-30 用户反馈,文档站 3× 放大逐档比对确认)。
|
|
151
|
+
下移 1px 是这几种串的**折中**:中文偏下 0.5px、纯小写偏上 1px。
|
|
152
|
+
没有再细分的办法 —— 小写字母的墨迹中心本就低于盒中心,任何单一常数都盖不住两种极端。
|
|
153
|
+
位移走 `top`(绘制层):不参与 flex 布局,点仍被盒居中,只是看起来对着字。
|
|
154
|
+
⚠️ 位移取值在**值区**(`badge.tokens.css` 的 `--ui-badge-dot-shift`):本件有两个互不嵌套的
|
|
155
|
+
根类(`.mh-badge` / `.mh-badge--status`),声明在任一**根类**上都到不了另一个根。 */
|
|
156
|
+
|
|
135
157
|
.mh-badge__dot {
|
|
136
158
|
width: 8px;
|
|
137
159
|
height: 8px;
|
|
138
160
|
flex: none;
|
|
139
161
|
border-radius: var(--ui-radius-full);
|
|
162
|
+
position: relative;
|
|
163
|
+
top: var(--ui-badge-dot-shift);
|
|
140
164
|
}
|
|
141
165
|
|
|
142
166
|
.mh-badge--dot-filled .mh-badge__dot {
|
|
@@ -226,6 +250,9 @@
|
|
|
226
250
|
height: 8px;
|
|
227
251
|
border-radius: var(--ui-radius-full);
|
|
228
252
|
background: var(--mh-badge-dot);
|
|
253
|
+
/* 与前置点同一句光学对齐(位移取值见 `__dot` 一节的注释;令牌在 badge.tokens.css) */
|
|
254
|
+
position: relative;
|
|
255
|
+
top: var(--ui-badge-dot-shift);
|
|
229
256
|
}
|
|
230
257
|
|
|
231
258
|
/* `processing`(映射到 primary)加点呼吸:静态点读不出「正在进行」 */
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* badge —— 单件令牌(**基础值**)。
|
|
3
|
+
*
|
|
4
|
+
* 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
|
|
5
|
+
*
|
|
6
|
+
* ## 抽出说明
|
|
7
|
+
* 本文件从面文件里抽出(原先混写在 `badge.css` 顶部):这些是**基础值**,锚在
|
|
8
|
+
* `[data-manohub-ui]` —— 跨包唯一作用域锚,由入口层无条件写在应用容器上,因此**任何落在
|
|
9
|
+
* 容器里的分件都取得到值**,不再依赖「声明在某个组件根类上」这条脆弱假设
|
|
10
|
+
* (历史症状:跨件消费的 `--ui-*-group-*` 取不到值、组内间距变 0)。
|
|
11
|
+
*
|
|
12
|
+
* 本件为什么需要本文件:`Badge` 有**两个互不嵌套的根类** —— `.mh-badge`(内容徽标 / 数字角标)
|
|
13
|
+
* 与 `.mh-badge--status`(状态点 + 文字,它不带 `.mh-badge`)。前置点与状态点共用同一枚
|
|
14
|
+
* 光学对齐位移,声明在任何**根类**上都到不了另一个根(自定义属性只向下继承),故按本仓口径
|
|
15
|
+
* 落到容器锚上。
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里 —— 它们靠「同一元素上两个
|
|
18
|
+
* 选择器改写同一个令牌」生效,搬到本文件会让档位失效。
|
|
19
|
+
* ⚠️ 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
|
|
20
|
+
*/
|
|
21
|
+
[data-manohub-ui] {
|
|
22
|
+
/* 前置点 / 状态点的**光学对齐**位移(数字见面文件 `__dot` 一节:盒居中读起来偏高)。 */
|
|
23
|
+
--ui-badge-dot-shift: 1px;
|
|
24
|
+
}
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
transition-timing-function: ease;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
/* 危险色修饰:换槽位即可,六型与各自 hover / active 一并跟随
|
|
53
|
+
/* 危险色修饰:换槽位即可,六型与各自 hover / active 一并跟随
|
|
54
|
+
(`--ui-button-accent-soft` 随无消费者的孤令牌一并撤除,2026-09-30) */
|
|
54
55
|
.mh-button--danger {
|
|
55
56
|
--ui-button-accent: var(--ui-error);
|
|
56
57
|
--ui-button-accent-hover: color-mix(in srgb, var(--ui-error) 88%, black);
|
|
57
58
|
--ui-button-accent-content: var(--ui-error-content);
|
|
58
|
-
--ui-button-accent-soft: var(--ui-error-weak);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/* 键盘焦点环:画在按钮自身(与 radio / tag 同一句) */
|
|
@@ -166,12 +166,13 @@
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/* ===== 虚线:区域内添加内容 =====
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
169
|
+
* 虚线取 `--ui-line-dashed`(= `base-400`,比实线深一档):同样粗细下虚线的墨迹只有实线的一半,
|
|
170
|
+
* 取实线色(`base-300`)会明显偏浅、整条框看着发虚。
|
|
171
|
+
* 这条口径 2026-09-30 一天内翻过一次:早些时候按「线框色只留一套」把虚线也收敛到 `base-300`,
|
|
172
|
+
* 当日晚按实机观感反转 —— 定稿见 `@manohub/theme` 的 `default/colors.css` 头「三条口径」第 2 条。 */
|
|
172
173
|
.mh-button--dashed {
|
|
173
174
|
background: var(--ui-base-100);
|
|
174
|
-
border: 1px dashed var(--ui-
|
|
175
|
+
border: 1px dashed var(--ui-line-dashed);
|
|
175
176
|
color: var(--ui-button-accent);
|
|
176
177
|
}
|
|
177
178
|
.mh-button--dashed:hover,
|
|
@@ -48,9 +48,12 @@
|
|
|
48
48
|
等效「主色 65% 透明叠在页面上」,但**只作用于底** —— 字与环保持纯色(见「加载」节)。
|
|
49
49
|
嫌淡嫌深都改这一处,不必去动任何一条色彩规则。 */
|
|
50
50
|
--ui-button-loading-mix: 65%;
|
|
51
|
-
/*
|
|
51
|
+
/* 色彩槽位:危险色只换这三个变量(设计见文件头;`danger` 档在 button.css 里成组覆盖)。
|
|
52
|
+
⚠️ `--ui-button-accent-soft` 已撤除(2026-09-30):本件**没有 soft 型**,这枚令牌从声明起就
|
|
53
|
+
无人读取,而它取的槽位还是「选中态底」`--ui-primary-subtle`(危险色那半区取的却是浅底档
|
|
54
|
+
`-weak`)—— 无消费者不预置令牌;要浅底档时按档位惯例新开型,别复活它(负向锁见
|
|
55
|
+
`__tests__/contract-style-form.spec.ts` 的 Button 一组)。 */
|
|
52
56
|
--ui-button-accent: var(--ui-primary);
|
|
53
57
|
--ui-button-accent-hover: var(--ui-primary-hover);
|
|
54
58
|
--ui-button-accent-content: var(--ui-primary-content);
|
|
55
|
-
--ui-button-accent-soft: var(--ui-primary-subtle); /* 危险的浅底(次级实心档) */
|
|
56
59
|
}
|
|
@@ -25,6 +25,19 @@
|
|
|
25
25
|
(特异性 0-3-0,高于本行)—— **那条兜底不能删**。 */
|
|
26
26
|
display: flex;
|
|
27
27
|
flex-direction: column;
|
|
28
|
+
/**
|
|
29
|
+
* **`margin: auto` 必须写**(靠 `inset: 0` + `margin: auto` 居中)。
|
|
30
|
+
*
|
|
31
|
+
* 不能依赖 UA 那条 `dialog { margin: auto }`:作者源无条件压过 UA 源(与特异性无关),
|
|
32
|
+
* 而**几乎每个宿主的 reset 都有 `* { margin: 0 }`**(Tailwind preflight / 本仓 ui reset 都会发下),
|
|
33
|
+
* 一旦命中就把 UA 的 `auto` 归零 ⇒ 弹窗**贴上贴左**(`inset: 0` + 无 margin 的必然结果)。
|
|
34
|
+
* 2026-09-30 实测:在 `apps/skill`(还带 Tailwind)里 `getComputedStyle` 读到 `margin: 0px`、
|
|
35
|
+
* `rect = (0, 0)`;显式补 `auto` 后立刻回到 `(432, 43)` 的精确居中。
|
|
36
|
+
*
|
|
37
|
+
* 与 `Drawer` 那条 `margin: 0` 是**同一件事的两面**:那边要贴侧、必须把 `auto` 归零,
|
|
38
|
+
* 这边要居中、必须把 `auto` 写实 —— 两边都**不能交给 UA**。`Toast` 同(它也显式归零)。
|
|
39
|
+
*/
|
|
40
|
+
margin: auto;
|
|
28
41
|
width: var(--ui-dialog-width);
|
|
29
42
|
max-width: var(--ui-dialog-width);
|
|
30
43
|
padding: 0; /* UA 给 <dialog> 的内距一律归零:内距由页头 / 内容 / 底栏各自拥有 */
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* 出处:设计稿《MH后台-0911》内容区**用了 44 处** 1px 分隔线,取值统一:
|
|
5
5
|
* - 水平:`0:2128 > 标题区 > 直线 2` = 1200×1(筛选区与页头带之间);
|
|
6
6
|
* - 垂直:`0:3920 > 直线 2备份` = 1×708(树栏与主栏之间);
|
|
7
|
-
* - 色:`#e6e6e6` = `--ui-base-300`(与页头下边线、表格线、卡片描边同源 ——
|
|
7
|
+
* - 色:`#e6e6e6` = `--ui-base-300`(与页头下边线、表格线、卡片描边同源 —— 实线只有这一条「线」色)。
|
|
8
|
+
* 虚线档另按**线型档**走 `--ui-line-dashed`(= `base-400`,见 `@manohub/theme` 的 `default/colors.css`
|
|
9
|
+
* 头「三条口径」第 2 条):同样粗细下虚线的墨迹只有实线的一半,取实线色会整条发虚。
|
|
8
10
|
*
|
|
9
11
|
* **为什么单独成件**:这条线在业务里被自绘了 44 次(`border-bottom: 1px solid #e6e6e6` 一类),
|
|
10
12
|
* 于是「线色改一处漏一处」必然发生。收进一件后,改线色/改粗细只需要动本文件。
|
|
@@ -25,8 +27,10 @@
|
|
|
25
27
|
width: 100%;
|
|
26
28
|
border-top: 1px solid var(--ui-divider-line);
|
|
27
29
|
}
|
|
30
|
+
/* 虚线档**连同线色一起换**:只写 `border-top-style: dashed` 会让虚线仍吃实线色 `base-300`,
|
|
31
|
+
同一个分隔位上线型不同、深浅也不同(2026-09-30 实测发现 —— 当时只改了「带中段文字」那条路径)。 */
|
|
28
32
|
.mh-divider--horizontal.mh-divider--dashed {
|
|
29
|
-
border-top
|
|
33
|
+
border-top: 1px dashed var(--ui-line-dashed);
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
/* 带中段文字:整条改成 flex 行,线由两根 `.mh-divider__line` 承担(左固定 24px、右吃剩余) */
|
|
@@ -51,7 +55,7 @@
|
|
|
51
55
|
}
|
|
52
56
|
.mh-divider--dashed .mh-divider__line {
|
|
53
57
|
height: 0;
|
|
54
|
-
border-top: 1px dashed var(--ui-
|
|
58
|
+
border-top: 1px dashed var(--ui-line-dashed);
|
|
55
59
|
}
|
|
56
60
|
.mh-divider__label {
|
|
57
61
|
flex: 0 0 auto;
|
|
@@ -67,5 +71,5 @@
|
|
|
67
71
|
vertical-align: middle;
|
|
68
72
|
}
|
|
69
73
|
.mh-divider--vertical.mh-divider--dashed {
|
|
70
|
-
border-left
|
|
74
|
+
border-left: 1px dashed var(--ui-line-dashed);
|
|
71
75
|
}
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
[data-manohub-ui] {
|
|
17
17
|
/* 单件令牌 */
|
|
18
|
-
--ui-divider-line: var(--ui-base-300);
|
|
18
|
+
--ui-divider-line: var(--ui-base-300); /* **实线**档的线色(与卡片描边、表格线同源)——
|
|
19
|
+
虚线档不用它:虚线走线型档 `--ui-line-dashed`(`base-400`),在面文件的修饰符块里直接取 */
|
|
19
20
|
--ui-divider-label-gap: var(--ui-space-3); /* 中段文字与两侧线的距离 12 */
|
|
20
21
|
--ui-divider-label-color: var(--ui-base-content-subtle);
|
|
21
22
|
}
|
|
@@ -155,6 +155,57 @@
|
|
|
155
155
|
color: var(--ui-required-mark);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
/* ===== label 提示位(`Form.Item` 的 `tip`)=====
|
|
159
|
+
* 图标与气泡都**不新造** —— 图标取 `@manohub/icon` 的 `help`(带圈问号),气泡复用 `Tooltip` 的面
|
|
160
|
+
* (`.mh-tooltip`)与操作层 `popup.css` 的 hover 档;本件只声明**提示位在 label 行里怎么排**。
|
|
161
|
+
*
|
|
162
|
+
* 宿主位(Tooltip 落在 label 里的那个 span)有两件事必做,少一件就有肉眼可见的偏移:
|
|
163
|
+
* ① `flex: 0 0 auto` —— label 文本过长时走省略号,图标不被挤压;
|
|
164
|
+
* ② 行高归 1 —— 图标比一行文字矮(图标档对 20px 行盒),留在 label 的行盒里会按基线排,
|
|
165
|
+
* 中线与 label 文字错开(本仓对这类 1~6px 偏移有实测前科,见 `.mh-form-item__control` 那段)。
|
|
166
|
+
* 气泡本身是固定定位(操作层 hover 档),不参与本行排布,故宿主宽度恒等于图标宽度。 */
|
|
167
|
+
|
|
168
|
+
.mh-form-item__tip {
|
|
169
|
+
display: inline-flex;
|
|
170
|
+
align-items: center;
|
|
171
|
+
flex: 0 0 auto;
|
|
172
|
+
line-height: 1;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* 触发器(问号按钮):`reset` 不代消费方归零控件外观,故边 / 底 / 内距三项自备。
|
|
176
|
+
颜色取次要色 —— label 旁是**辅助**信息,不与字段名抢层级;悬停 / 聚焦升到正文色。 */
|
|
177
|
+
|
|
178
|
+
.mh-form-item__tip-btn {
|
|
179
|
+
display: inline-flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
justify-content: center;
|
|
182
|
+
padding: 0;
|
|
183
|
+
border: none;
|
|
184
|
+
background: transparent;
|
|
185
|
+
color: var(--ui-base-content-muted);
|
|
186
|
+
cursor: help;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.mh-form-item__tip-btn:hover,
|
|
190
|
+
.mh-form-item__tip-btn:focus-visible {
|
|
191
|
+
color: var(--ui-base-content);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* 键盘可达:气泡显形靠操作层的宿主 `:focus-within` 档,这里只管**焦点可见**(主色环)。 */
|
|
195
|
+
|
|
196
|
+
.mh-form-item__tip-btn:focus-visible {
|
|
197
|
+
outline: 2px solid var(--ui-primary);
|
|
198
|
+
outline-offset: 2px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* 图标尺寸:常规图标一律取全局图标档。`<Icon>` 的宽高是**属性**,面层能覆盖;
|
|
202
|
+
不写就会静默落到组件默认的 16(口径见 `contract-icon-direction.spec.ts`)。 */
|
|
203
|
+
|
|
204
|
+
.mh-form-item__tip-btn > svg {
|
|
205
|
+
width: var(--ui-font-icon);
|
|
206
|
+
height: var(--ui-font-icon);
|
|
207
|
+
}
|
|
208
|
+
|
|
158
209
|
/* label 对齐:基类默认右对齐(贴控件列,`labelAlign` 缺省档);
|
|
159
210
|
`labelAlign="left"` 时挂这个修饰类改成左对齐 —— 只给「非默认值」挂类,避免两段声明争胜出顺序。
|
|
160
211
|
位置必须在基类规则之后:`.mh-form-item__label {` 是它的子串,测试取规则体时按首次出现命中。 */
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* **左边线用绝对定位伪元素画,不用 `border-left` + `border-image`**:后者会吃掉圆角(规范踩过这个坑)。
|
|
16
16
|
* 语义八档的线色是规范 04 档**渐变**,色板编号写在令牌注释里;底色复用本仓语义弱底令牌(一处定义)。
|
|
17
17
|
*
|
|
18
|
-
*
|
|
18
|
+
* **标签位与操作位不重复实现**:标签用标记族(只读走 `.mh-badge`,要可关闭走 `.mh-tag`),
|
|
19
19
|
* 操作用按钮族(`.mh-button--sm`)—— 本件只给它们的容器与间距。
|
|
20
20
|
*/
|
|
21
21
|
.mh-notification {
|
|
@@ -137,37 +137,38 @@
|
|
|
137
137
|
box-shadow: var(--ui-shadow-popover);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
/* 内容区:**面板里唯一的滚动容器**(列表体的选项行 /
|
|
140
|
+
/* 内容区:**面板里唯一的滚动容器**(列表体的选项行 / 树体的树都装在它里面),
|
|
141
|
+
同时是**两形态共用的一处内距** —— 内容贴面板左右边各留一个最小呼吸位
|
|
142
|
+
(行仍是满宽,只有内容缩进;选项行的内距与树行的缩进各由自己承担)。
|
|
143
|
+
内距为什么在这儿而不是各形态自己一层:见下方「树体壳已退场」一节的实测症状。
|
|
141
144
|
`min-height: 0` 是这一档生效的前提:列容器里弹性项的可收缩下限默认取内容高,
|
|
142
145
|
不给它,内容就永远压不下去、上面的限高形同虚设(与 `panel.css` 的 `.mh-panel__body` 同款)。 */
|
|
143
146
|
.mh-select__body {
|
|
144
147
|
flex: 1;
|
|
145
148
|
min-height: 0;
|
|
146
149
|
overflow-y: auto;
|
|
150
|
+
/* 左右与下各一个最小呼吸位(上不写:面板根已有 4px 上内距)。
|
|
151
|
+
底部这一档落在**滚动容器**上:现代引擎已把滚动器的 padding-bottom 计入可滚动区
|
|
152
|
+
(实测 60 条选项 scrollHeight = 2160 + 4),故滚到底时最后一行不会贴着面板下边。 */
|
|
153
|
+
padding: 0 var(--ui-space-1) var(--ui-space-1);
|
|
147
154
|
}
|
|
148
155
|
|
|
149
|
-
/* 选项行:滑过 / 选中 / 禁用 / 提示 / 空态
|
|
156
|
+
/* 选项行:滑过 / 键盘高亮 / 选中 / 禁用 / 提示 / 空态
|
|
157
|
+
**行的几何与行态与树行同源**(`mh-tree__row`,2026-09-30 由使用方拍板对齐):行高 / 圆角 /
|
|
158
|
+
基础内距 / 字号 / 滑过与选中底色逐项同值 —— 同一个面板里,列表与树两形态不再各是一套行。
|
|
159
|
+
行元素是 `div[role='option']`、**不是 button**(见 `select-list.tsx`):listbox 的选项不是交互控件,
|
|
160
|
+
键盘改由「触发器持焦 + `aria-activedescendant` 指向高亮行」表达。
|
|
161
|
+
随之退场的两条补丁(都是为 `<button>` 而写的):
|
|
162
|
+
① 按钮 UA 四件套重置(`border` / `background` / `font-family` / `text-align`)—— div 本就没有 UA 外观;
|
|
163
|
+
② `width: 100%` —— 那是按钮的 `width: auto` 解析成「包裹内容宽」才要补的,div 是块级、本就满宽
|
|
164
|
+
(hint / empty 两个 span 靠下面的 display 拿满宽)。 */
|
|
150
165
|
.mh-select__option {
|
|
151
166
|
position: relative;
|
|
152
167
|
display: flex;
|
|
153
168
|
align-items: center;
|
|
154
|
-
/* **必须显式给宽**:选项是 `<button>`,而按钮的 `width: auto` 解析成「包裹内容宽」
|
|
155
|
-
(表单控件不参与块级拉伸),不给就会缩成文字那么宽 ——
|
|
156
|
-
滑过 / 选中的底色只剩一小条,聚焦环也贴着文字。`.mh-select__add` 同理。 */
|
|
157
|
-
width: 100%;
|
|
158
169
|
height: var(--ui-select-option-height);
|
|
159
170
|
padding: 0 var(--ui-select-padding-x);
|
|
160
|
-
|
|
161
|
-
(`border: 2px outset` / `background: ButtonFace` / `font-family: Arial` / `text-align: center`)。
|
|
162
|
-
reset 层(`styles/reset.css`)虽然也清零了前三条,但组件面**不得依赖它** ——
|
|
163
|
-
本仓的 0.6.x 就漏了这四条,表现为选项行呈原生按钮外观(灰底 + 立体边框 + 居中 Arial),
|
|
164
|
-
而同一面板里的 `.mh-select__add` 写齐了 ⇒ 一个面板里两种外观。
|
|
165
|
-
`text-align` 是 reset 层**没有**的一项(它不属于「元素基线」,属于「列表行」语义),故此处必写。
|
|
166
|
-
色彩 / 字族这些**值**仍然归令牌,这四条只是把 UA 的默认值归零。 */
|
|
167
|
-
border: none;
|
|
168
|
-
background: transparent;
|
|
169
|
-
font-family: inherit;
|
|
170
|
-
text-align: left;
|
|
171
|
+
border-radius: var(--ui-radius-control);
|
|
171
172
|
font-size: var(--ui-select-font-size);
|
|
172
173
|
color: var(--ui-base-content);
|
|
173
174
|
cursor: pointer;
|
|
@@ -186,10 +187,20 @@
|
|
|
186
187
|
appearance: none;
|
|
187
188
|
pointer-events: none;
|
|
188
189
|
}
|
|
190
|
+
/* 行态三档与树行逐条对应(滑过 / 按下 / 选中):
|
|
191
|
+
① 滑过 = 键盘高亮(`data-active`,见 `select-list.tsx` 的高亮模型)= 主色浅底;
|
|
192
|
+
② 按下 = 选中底(与树行的 `:active` 同款);
|
|
193
|
+
③ 选中 = 选中底 + 主色字。 */
|
|
189
194
|
.mh-select__option:hover,
|
|
190
|
-
.mh-select__option.is-hover
|
|
195
|
+
.mh-select__option.is-hover,
|
|
196
|
+
.mh-select__option[data-active='true'] {
|
|
191
197
|
background: var(--ui-select-option-hover);
|
|
192
198
|
}
|
|
199
|
+
.mh-select__option:active {
|
|
200
|
+
background: var(--ui-select-option-selected);
|
|
201
|
+
}
|
|
202
|
+
/* 零 JS 静态档的键盘可达:行内含原生 radio / checkbox 时,焦点在它身上即给行描边
|
|
203
|
+
(组件路径的选项**不可聚焦**,键盘高亮走上面的 `data-active`)。 */
|
|
193
204
|
.mh-select__option:has(input:focus-visible) {
|
|
194
205
|
outline: 2px solid var(--ui-primary);
|
|
195
206
|
outline-offset: -2px;
|
|
@@ -201,6 +212,28 @@
|
|
|
201
212
|
background: var(--ui-select-option-selected);
|
|
202
213
|
color: var(--ui-primary);
|
|
203
214
|
}
|
|
215
|
+
/* 相连的选中行:缝上的圆角**融合抵消**(多选连续勾选时最扎眼 —— 两个 6px 圆角各自让出的
|
|
216
|
+
凹口拼成一个「蝴蝶结」,看着像渲染坏了)。
|
|
217
|
+
做法:给自己选中、**下一行也选中**的那一行补一条同色补片,向上下各延伸一个圆角位 ——
|
|
218
|
+
它同时盖住上行让出的下半凹口与下行让出的上半凹口,两块底因此连成一片。
|
|
219
|
+
只认「下一行」这一个方向(CSS 只有向后的兄弟组合子):**单向就够**,补片本来横跨两行。
|
|
220
|
+
补片不吃事件(`pointer-events: none`)—— 它压在下一行顶上 6px,若可点会把点击算到上一行头上。
|
|
221
|
+
⚠️ 零 JS 那一路的下家条件写成 `+ .mh-select__option input:checked`(兄弟组合子后再接后代),
|
|
222
|
+
**不是** `+ .mh-select__option:has(input:checked)`:`:has()` **不许嵌套**,写了整条规则会被
|
|
223
|
+
解析器丢掉(浏览器里静默失效 —— 实测踩过,`contract-class-surface` 有机械护栏)。 */
|
|
224
|
+
.mh-select__option.is-selected:has(+ .mh-select__option.is-selected)::after,
|
|
225
|
+
.mh-select__option[data-state='selected']:has(+ .mh-select__option[data-state='selected'])::after,
|
|
226
|
+
.mh-select__option:has(input:checked):has(+ .mh-select__option input:checked)::after {
|
|
227
|
+
content: '';
|
|
228
|
+
position: absolute;
|
|
229
|
+
left: 0;
|
|
230
|
+
right: 0;
|
|
231
|
+
bottom: calc(-1 * var(--ui-radius-control));
|
|
232
|
+
height: calc(2 * var(--ui-radius-control));
|
|
233
|
+
/* 取本行**算出来**的底色(选中底随主题与状态变,写死色值就对不上了) */
|
|
234
|
+
background-color: inherit;
|
|
235
|
+
pointer-events: none;
|
|
236
|
+
}
|
|
204
237
|
.mh-select__option.is-disabled,
|
|
205
238
|
.mh-select__option[data-disabled='true'],
|
|
206
239
|
.mh-select__option:has(input:disabled) {
|
|
@@ -213,18 +246,11 @@
|
|
|
213
246
|
.mh-select__option--empty {
|
|
214
247
|
color: var(--ui-base-content-muted);
|
|
215
248
|
}
|
|
216
|
-
/* 「创建 xxx
|
|
249
|
+
/* 「创建 xxx」行:搜索词无命中时出现 —— 它是 `.mh-select__option` 上的**修饰类**
|
|
250
|
+
(两件同写:`class="mh-select__option mh-select__add"`),行的几何与三态全沿用基类,
|
|
251
|
+
这里只改字色为「可创建」的主色。 */
|
|
217
252
|
.mh-select__add {
|
|
218
|
-
width: 100%;
|
|
219
|
-
border: none;
|
|
220
|
-
background: transparent;
|
|
221
253
|
color: var(--ui-primary);
|
|
222
|
-
font-family: inherit;
|
|
223
|
-
text-align: left;
|
|
224
|
-
}
|
|
225
|
-
.mh-select__add:hover,
|
|
226
|
-
.mh-select__add.is-hover {
|
|
227
|
-
background: var(--ui-select-option-hover);
|
|
228
254
|
}
|
|
229
255
|
|
|
230
256
|
/* ===== 选项分组(组标题不可点,只做分区;组间距靠分隔线给) ===== */
|
|
@@ -248,17 +274,14 @@
|
|
|
248
274
|
padding: var(--ui-space-2) var(--ui-space-2) var(--ui-space-1);
|
|
249
275
|
}
|
|
250
276
|
|
|
251
|
-
/* =====
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
/* 行底满宽、只有内容缩进(缩进公式在 tree 面),故左右各留一个最小呼吸位 */
|
|
260
|
-
padding: 0 var(--ui-space-1) var(--ui-space-1);
|
|
261
|
-
}
|
|
277
|
+
/* ===== 树体壳已退场(2026-09-30)=====
|
|
278
|
+
原先这里有一个 `.mh-select__tree`:面板里的树包在它里面拿内距(左右 4 / 下 4),
|
|
279
|
+
而列表形态的选项是面板的**直接子节点**、一路贴到面板边缘 —— 同一个面板里两形态的内距不一样
|
|
280
|
+
(浏览器实测:面板 240 时树行 232、选项行 240)。
|
|
281
|
+
内距现归**共用的内容区**(上一节 `.mh-select__body`):一处规格、两形态同数;
|
|
282
|
+
树体壳的唯一职责既然已经上移,壳本身一并退场 —— 留一层不承载任何规则的包裹只是噪音。
|
|
283
|
+
边界不变:**面板皮肤归本文件**,**树的行态归 tree 面**(`.mh-tree__*` 那一族,本文件一行都不碰
|
|
284
|
+
—— 跨族类名须先登记跨面豁免,这里不走那条路),行高 / 缩进 / 滑过与选中底色全沿用 tree 面。 */
|
|
262
285
|
|
|
263
286
|
/* 命中高亮(搜索命中的那段文字,由组件的 `renderLabel` 落进 `.mh-tree__label` 槽)。
|
|
264
287
|
底色取主色浅底档(与选中 / 滑过同一套语义槽位);字色 `inherit` —— 高亮只负责「标出位置」,
|
|
@@ -20,18 +20,25 @@
|
|
|
20
20
|
(实测:chrome 里量到 16px 才发现的);
|
|
21
21
|
- 面板 `.mh-select__panel`:挂在 `.mh-popup-host` 下、与触发器**兄弟**(不在 `.mh-select`
|
|
22
22
|
子树里)—— 否则圆角、行高、字号、选中底全失效。 */
|
|
23
|
-
/* 单件令牌
|
|
23
|
+
/* 单件令牌
|
|
24
|
+
## 选项行与树行同源(2026-09-30 由使用方拍板对齐)
|
|
25
|
+
面板里的选项行与 `mh-tree__row`(`SelectTree` 的面板内容)现在是**同一套行**:
|
|
26
|
+
下面的行高 / 基础内距 / 字号 / 滑过底四项都取树行那份值(选中底两处本来就同源),
|
|
27
|
+
故面板里列表形态与树形态不会再长成两套行。改树行的行几何 = 选项行一起动(有意)。
|
|
28
|
+
⚠️ 与全局 `--ui-row-height`(36,Skeleton / Collapse 头行在用)**不是一档**:
|
|
29
|
+
对齐目标是树行(34),不是全库行高 —— 别再按「行高就该 36」改回来。 */
|
|
24
30
|
--ui-select-height: var(--ui-control-height-md); /* 标准档 32(日期格与面板内部用;触发器的框高归输入面) */
|
|
25
|
-
--ui-select-padding-x: var(--ui-space-
|
|
31
|
+
--ui-select-padding-x: var(--ui-space-2); /* 8 = 树行的基础内距(缩进之外的左右呼吸位) */
|
|
26
32
|
--ui-select-radius: var(--ui-radius-md); /* 8:设计 `0:4025` 下拉面板 r8(原注释写 8 但取的是控件档 6) */
|
|
27
|
-
--ui-select-font-size: var(--ui-font-
|
|
28
|
-
--ui-select-option-height:
|
|
29
|
-
--ui-select-option-hover: var(--ui-
|
|
30
|
-
--ui-select-option-selected: var(--ui-primary-subtle); /*
|
|
31
|
-
--ui-select-chip-height:
|
|
33
|
+
--ui-select-font-size: var(--ui-font-caption); /* 13 = 树行字号(不是触发器的 14) */
|
|
34
|
+
--ui-select-option-height: var(--ui-tree-row-height); /* 34 = 树行高(同源引用,两处不会各自漂) */
|
|
35
|
+
--ui-select-option-hover: var(--ui-primary-weak); /* 滑过 / 键盘高亮:与树行的滑过同档(**不再是中性灰**) */
|
|
36
|
+
--ui-select-option-selected: var(--ui-primary-subtle); /* 选中底:与树行的选中同档 */
|
|
37
|
+
--ui-select-chip-height: var(--ui-mark-height-md); /* 多选标签(规范复用标签族 24 档)⇒ 标记体量档,与徽标 / 标签同源 */
|
|
32
38
|
--ui-select-icon-size: var(--ui-font-icon); /* 下拉箭头:常规图标档 */
|
|
33
39
|
/* 面板限高(**列表与树两形态共用**):面板整体(含搜索行)不超此高,超出即内容区滚动。
|
|
34
|
-
320px ≈ 8
|
|
35
|
-
|
|
40
|
+
320px ≈ 8 行(行高 34 + 面板上下内距 8)—— 列表与树两形态的节距现在是同一个数
|
|
41
|
+
(树行 2026-09-30 起也去掉了行距),有无搜索行会差一行上下。
|
|
42
|
+
要改高度改这枚令牌,不要在业务侧压 max-height。 */
|
|
36
43
|
--ui-select-panel-max-height: 320px;
|
|
37
44
|
}
|