@manohub/ui 0.10.5 → 1.0.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.
- package/README.md +155 -155
- package/dist/components/form/index.js +8 -1
- package/dist/components/input/bordered.d.ts +15 -0
- package/dist/components/input/bordered.js +8 -0
- package/dist/components/input/index.d.ts +82 -31
- package/dist/components/input/index.js +16 -6
- package/dist/components/input/number-input.d.ts +239 -0
- package/dist/components/input/number-input.js +240 -0
- package/dist/components/select/index.d.ts +19 -0
- package/dist/components/select/index.js +10 -0
- package/dist/components/select/select-tree.d.ts +11 -0
- package/dist/components/select/select-tree.js +6 -0
- package/dist/components/select/select-trigger.d.ts +17 -0
- package/dist/components/select/select-trigger.js +9 -0
- package/dist/components/table/index.d.ts +85 -10
- package/dist/components/table/index.js +38 -9
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -0
- 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 +456 -425
- package/dist/styles/components/form.tokens.css +19 -15
- package/dist/styles/components/input.css +659 -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 +510 -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,326 +1,326 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Select —— 选择器族(单选触发器 + 多选标签 + 选项面板 + 搜索行 + 日期格)。
|
|
3
|
-
*
|
|
4
|
-
* 出处:`@aihub/theme` 的 `playground/components/select.css` 与 `src/components/select.css`
|
|
5
|
-
* (触发器同输入框、选项行高 30、内距 8;面板内距 4 + 选项 30;多选标签复用标签族形态;
|
|
6
|
-
* 日期格 26 方形,选中主色实底、区间 Ne10)。
|
|
7
|
-
*
|
|
8
|
-
* **触发器的框不在本件**:触发器 = 输入框的「触发器形态」(TSX 里是 `<Input as="button">`),
|
|
9
|
-
* 框 / 内距 / 边 / 圆角 / 底 / 字 / hover / 聚焦 / 禁用 / 校验色与**清除位**、**右侧图标位**
|
|
10
|
-
* 全部归输入面与它的表壳(`.mh-input` + `.mh-input__wrap`)。本件只给选择器自己的排版
|
|
11
|
-
* (`display` / `gap` / `width` / `text-align` / `overflow` 与值 / 标签),另通过挂在**表壳**上的
|
|
12
|
-
* `.mh-select-host` 微调两处壳内节奏(间距回到 4px、箭头收敛回 12px)。
|
|
13
|
-
* **禁写:本件不得再画框**(画了就又开一份会与输入面漂移的规格 —— 这正是本次收敛掉的东西)。
|
|
14
|
-
*
|
|
15
|
-
* **面板开合与定位不在本件**:面板是操作层的组合 —— 消费方/组件在面板根并列挂
|
|
16
|
-
* `class="mh-popup mh-select__panel mh-popup--anchored"`(`data-side` / `data-align` 定位档、
|
|
17
|
-
* Esc、点外部关闭、顶层渲染全在 `styles/operations/popup.css`)。本件只给**面**
|
|
18
|
-
* (底 / 圆角 / 内距 / 阴影 / 选项行)。
|
|
19
|
-
*
|
|
20
|
-
* **面板宽度跟触发器走**:规范把触发器与面板都钉在 300px,本仓触发器是**流式宽度**
|
|
21
|
-
* (与 input 同一结论),故面板用 `anchor-size(width)` 取锚点宽。触发器进表壳后,
|
|
22
|
-
* `popovertarget` 的**隐式锚**只有壳内那个控件那么宽,故这里走**显式锚档**:
|
|
23
|
-
* 表壳挂 `.mh-popup-anchor`(`anchor-name`)、面板挂 `.mh-popup--anchored`(`position-anchor`),
|
|
24
|
-
* 锚点即整件;非锚定场景回落到 240px 兜底值。
|
|
25
|
-
*
|
|
26
|
-
* **面板有高度上限**:`--ui-select-panel-max-height`(默认 320px)钉在面板根上,超出即内容区
|
|
27
|
-
* (`.mh-select__body`)滚动、搜索行常驻 —— 列表与树两形态共用这一份,形态里不许各写限高。
|
|
28
|
-
*
|
|
29
|
-
* **一处有色差异**:规范的选中行是灰底(Ne10),本仓的「选中」统一走**主色浅底**
|
|
30
|
-
* `--ui-primary-subtle`(与列表 / 树的选中态同一语义槽位),否则悬停(Ne11)与选中(Ne10)两档灰
|
|
31
|
-
* 在本仓有限的灰阶里挤成同色、看不出选中。
|
|
32
|
-
*
|
|
33
|
-
* 选项选中态**三源等价**:原生 `:has(input:checked)`(零 JS 单选路径)/ 组件下发
|
|
34
|
-
* `[data-state='selected']` / 静态档 `.is-selected`。
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/* ===== 触发器:只留选择器自己的排版(框与状态全归输入面) ===== */
|
|
38
|
-
.mh-select {
|
|
39
|
-
display: inline-flex;
|
|
40
|
-
align-items: center;
|
|
41
|
-
gap: var(--ui-space-1);
|
|
42
|
-
width: 100%;
|
|
43
|
-
text-align: left;
|
|
44
|
-
cursor: pointer;
|
|
45
|
-
overflow: hidden;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/* 表壳上的本件修饰(TSX 把 `mh-select-host` 挂在**表壳**上:`class` 落壳是输入面的既有契约)。 */
|
|
49
|
-
/* ① 壳内间距:输入框的附加位节奏是 8px,选择器自己的是 4px(值 / 标签与清除位、箭头之间) */
|
|
50
|
-
.mh-select-host {
|
|
51
|
-
gap: var(--ui-space-1);
|
|
52
|
-
}
|
|
53
|
-
/* ② 箭头尺寸:`.mh-input__suffix > svg`(0-1-1)会把槽内图标统一成 16px,而本件箭头是 12px
|
|
54
|
-
—— 这里以 0-2-0 收敛回来。注意不能在 select.css 里直写 `.mh-input__suffix`:
|
|
55
|
-
面文件的类名必须与文件词根同根(机械护栏),故走自己的壳修饰类。 */
|
|
56
|
-
.mh-select-host .mh-select__caret {
|
|
57
|
-
width: var(--ui-select-icon-size);
|
|
58
|
-
height: var(--ui-select-icon-size);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/* ===== 尺寸档:框的尺寸归输入面,本类只承载选择器自有部位的对档微调 ===== */
|
|
62
|
-
/* 框高 / 字号由 `<Input size>` 下发的 `mh-input--sm` / `--lg` 承担(含表壳的换高)。
|
|
63
|
-
两处口径要认(都是输入面既有事实,不是本件选择):
|
|
64
|
-
① **左右内距不随档位变**:带壳时内距归表壳(`--ui-input-padding-x` = 12px 恒定),
|
|
65
|
-
`--ui-input-padding-x-sm/-lg` 只对**裸控件**生效 —— 输入框自己的 sm / lg 实测也是 12px;
|
|
66
|
-
② `mh-select--*` 只跟「选择器自己的东西」有关 —— 当前只有标签:小号控件 24px 高,
|
|
67
|
-
24px 的标签会顶满整件、失去呼吸位,故收 4px。 */
|
|
68
|
-
.mh-select--sm .mh-select__chip {
|
|
69
|
-
height: calc(var(--ui-select-chip-height) - 4px);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/* 值区:有值时的单选那一行(占满剩余宽、超出省略)。
|
|
73
|
-
⚠️ **无值态不在这里** —— 占位由输入面渲染(`.mh-input__placeholder`,色与截断同档):
|
|
74
|
-
2026-09-29 收敛,此前本文件还有一个 `--placeholder` 修饰类专门给占位上灰字。 */
|
|
75
|
-
.mh-select__value {
|
|
76
|
-
flex: 1;
|
|
77
|
-
min-width: 0;
|
|
78
|
-
overflow: hidden;
|
|
79
|
-
text-overflow: ellipsis;
|
|
80
|
-
white-space: nowrap;
|
|
81
|
-
}
|
|
82
|
-
/* 下拉箭头:渲染在输入面的**右侧图标位**(`.mh-input__suffix`,表壳的子元素)里 ——
|
|
83
|
-
位置由表壳的 flex 排布给(控件 `flex: 1 1 auto` 自然把附加位挤到右端),故不再需要 `margin-left: auto`。
|
|
84
|
-
字形由 @manohub/icon 给;展开转向由 popup.css 的 `.mh-popup-caret` 承担(含触发器进表壳后的兄弟档);
|
|
85
|
-
尺寸的 12px 在下面 `mh-select-host` 一节按特异性收敛(槽内 svg 会被输入面统一成 16px)。 */
|
|
86
|
-
.mh-select__caret {
|
|
87
|
-
flex: none;
|
|
88
|
-
color: var(--ui-base-content-muted); /* Te07 */
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/* ===== 多选:标签 + 收纳(单行不换行,超出由组件算「其他 n 项」) =====
|
|
92
|
-
清除位不在本件:它是输入面的内建件(`.mh-input__clear`,圆点实底 + 反白叉号),
|
|
93
|
-
由 `<Input clearable>` 渲染在**表壳**里 —— 与值 / 标签同一行的右端。 */
|
|
94
|
-
.mh-select--multiple {
|
|
95
|
-
flex-wrap: nowrap;
|
|
96
|
-
}
|
|
97
|
-
.mh-select__chip {
|
|
98
|
-
display: inline-flex;
|
|
99
|
-
align-items: center;
|
|
100
|
-
flex: none;
|
|
101
|
-
height: var(--ui-select-chip-height);
|
|
102
|
-
padding: 0 var(--ui-space-2);
|
|
103
|
-
border-radius: var(--ui-radius-full);
|
|
104
|
-
background: var(--ui-base-200); /* Ne11 轻量片底 */
|
|
105
|
-
font-size: var(--ui-select-font-size);
|
|
106
|
-
color: var(--ui-base-content);
|
|
107
|
-
}
|
|
108
|
-
.mh-select__chip--fold {
|
|
109
|
-
background: var(--ui-base-200);
|
|
110
|
-
color: var(--ui-base-content-muted);
|
|
111
|
-
}
|
|
112
|
-
/* ===== 面板皮肤(与操作层并列组合:`class="mh-popup mh-select__panel mh-popup--anchored"`) =====
|
|
113
|
-
**面板是列容器 + 限高**:搜索行常驻(不滚),下一条的 `.mh-select__body` 承担滚动 ——
|
|
114
|
-
列表与树两形态因此共用同一份「长内容不撑破面板」的规格。
|
|
115
|
-
(历史症状:限高原先只写在树体 `.mh-select__tree` 上,而列表形态的选项是面板的**直接子节点**,
|
|
116
|
-
面板会被一路撑高;实测 60 条选项的面板高 2212px、视口只有 925px。) */
|
|
117
|
-
.mh-select__panel {
|
|
118
|
-
/* 锚 = `.mh-popup-anchor`(挂在表壳上)→ 面板与**整件**同宽;非锚定场景回落 240 */
|
|
119
|
-
width: anchor-size(width, 240px);
|
|
120
|
-
/* 列容器:搜索行 `flex: none` + 内容区 `flex: 1 / min-height: 0`。
|
|
121
|
-
⚠️ 加 `display: flex` 会以作者源压过 UA 给**收起态**定的 `display: none`,收起态靠操作层
|
|
122
|
-
`operations/popup.css` 里那条 `:is()` 兜底(把收起的浮层重新钉成 `display: none`,
|
|
123
|
-
特异性 0-3-0、高于本行)—— **那条兜底不能删**(与 `dialog.css` 同一处坑)。 */
|
|
124
|
-
display: flex;
|
|
125
|
-
flex-direction: column;
|
|
126
|
-
/* 限高(**含搜索行**):超出即内容区滚动。面板仍贴锚点,只是不再无限长 */
|
|
127
|
-
max-height: var(--ui-select-panel-max-height);
|
|
128
|
-
/* UA 给 `[popover]` 的是 `overflow: auto`,必须归零:内容区已是滚动容器,
|
|
129
|
-
留一层就会与它叠成两条滚动条(同一个面板上实测会同时出现)。 */
|
|
130
|
-
overflow: hidden;
|
|
131
|
-
padding: var(--ui-space-1) 0;
|
|
132
|
-
border-radius: var(--ui-select-radius);
|
|
133
|
-
background: var(--ui-base-100);
|
|
134
|
-
/* 锚定浮层的投影走 `--ui-shadow-popover`(**不是** elevated):两枚令牌按「锚定浮层 vs 居中浮层」
|
|
135
|
-
分工,default 主题给前者填的是设计实测值(`0:4025` 的 `0 4px 20px rgba(0,14,51,.10)`),
|
|
136
|
-
farris 主题给的是规范的 `--mh-shadow-lg:14dp 下拉/弹出层` —— 语义与两套来源都对得上。 */
|
|
137
|
-
box-shadow: var(--ui-shadow-popover);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/* 内容区:**面板里唯一的滚动容器**(列表体的选项行 / 树体的树都装在它里面),
|
|
141
|
-
同时是**两形态共用的一处内距** —— 内容贴面板左右边各留一个最小呼吸位
|
|
142
|
-
(行仍是满宽,只有内容缩进;选项行的内距与树行的缩进各由自己承担)。
|
|
143
|
-
内距为什么在这儿而不是各形态自己一层:见下方「树体壳已退场」一节的实测症状。
|
|
144
|
-
`min-height: 0` 是这一档生效的前提:列容器里弹性项的可收缩下限默认取内容高,
|
|
145
|
-
不给它,内容就永远压不下去、上面的限高形同虚设(与 `panel.css` 的 `.mh-panel__body` 同款)。 */
|
|
146
|
-
.mh-select__body {
|
|
147
|
-
flex: 1;
|
|
148
|
-
min-height: 0;
|
|
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);
|
|
154
|
-
}
|
|
155
|
-
|
|
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 拿满宽)。 */
|
|
165
|
-
.mh-select__option {
|
|
166
|
-
position: relative;
|
|
167
|
-
display: flex;
|
|
168
|
-
align-items: center;
|
|
169
|
-
height: var(--ui-select-option-height);
|
|
170
|
-
padding: 0 var(--ui-select-padding-x);
|
|
171
|
-
border-radius: var(--ui-radius-control);
|
|
172
|
-
font-size: var(--ui-select-font-size);
|
|
173
|
-
color: var(--ui-base-content);
|
|
174
|
-
cursor: pointer;
|
|
175
|
-
}
|
|
176
|
-
/* 零 JS 单选路径的隐身开关(真实 radio 负责键盘与可访问性,高亮画在行上) */
|
|
177
|
-
.mh-select__option > input {
|
|
178
|
-
position: absolute;
|
|
179
|
-
width: 1px;
|
|
180
|
-
height: 1px;
|
|
181
|
-
margin: -1px;
|
|
182
|
-
padding: 0;
|
|
183
|
-
border: 0;
|
|
184
|
-
overflow: hidden;
|
|
185
|
-
white-space: nowrap;
|
|
186
|
-
clip-path: inset(50%);
|
|
187
|
-
appearance: none;
|
|
188
|
-
pointer-events: none;
|
|
189
|
-
}
|
|
190
|
-
/* 行态三档与树行逐条对应(滑过 / 按下 / 选中):
|
|
191
|
-
① 滑过 = 键盘高亮(`data-active`,见 `select-list.tsx` 的高亮模型)= 主色浅底;
|
|
192
|
-
② 按下 = 选中底(与树行的 `:active` 同款);
|
|
193
|
-
③ 选中 = 选中底 + 主色字。 */
|
|
194
|
-
.mh-select__option:hover,
|
|
195
|
-
.mh-select__option.is-hover,
|
|
196
|
-
.mh-select__option[data-active='true'] {
|
|
197
|
-
background: var(--ui-select-option-hover);
|
|
198
|
-
}
|
|
199
|
-
.mh-select__option:active {
|
|
200
|
-
background: var(--ui-select-option-selected);
|
|
201
|
-
}
|
|
202
|
-
/* 零 JS 静态档的键盘可达:行内含原生 radio / checkbox 时,焦点在它身上即给行描边
|
|
203
|
-
(组件路径的选项**不可聚焦**,键盘高亮走上面的 `data-active`)。 */
|
|
204
|
-
.mh-select__option:has(input:focus-visible) {
|
|
205
|
-
outline: 2px solid var(--ui-primary);
|
|
206
|
-
outline-offset: -2px;
|
|
207
|
-
}
|
|
208
|
-
/* 选中:三源等价(原生 / 组件 / 静态档) */
|
|
209
|
-
.mh-select__option.is-selected,
|
|
210
|
-
.mh-select__option[data-state='selected'],
|
|
211
|
-
.mh-select__option:has(input:checked) {
|
|
212
|
-
background: var(--ui-select-option-selected);
|
|
213
|
-
color: var(--ui-primary);
|
|
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
|
-
}
|
|
237
|
-
.mh-select__option.is-disabled,
|
|
238
|
-
.mh-select__option[data-disabled='true'],
|
|
239
|
-
.mh-select__option:has(input:disabled) {
|
|
240
|
-
color: var(--ui-base-content-subtle);
|
|
241
|
-
cursor: not-allowed;
|
|
242
|
-
}
|
|
243
|
-
.mh-select__option--hint {
|
|
244
|
-
color: var(--ui-base-content-muted);
|
|
245
|
-
}
|
|
246
|
-
.mh-select__option--empty {
|
|
247
|
-
color: var(--ui-base-content-muted);
|
|
248
|
-
}
|
|
249
|
-
/* 「创建 xxx」行:搜索词无命中时出现 —— 它是 `.mh-select__option` 上的**修饰类**
|
|
250
|
-
(两件同写:`class="mh-select__option mh-select__add"`),行的几何与三态全沿用基类,
|
|
251
|
-
这里只改字色为「可创建」的主色。 */
|
|
252
|
-
.mh-select__add {
|
|
253
|
-
color: var(--ui-primary);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/* ===== 选项分组(组标题不可点,只做分区;组间距靠分隔线给) ===== */
|
|
257
|
-
.mh-select__group + .mh-select__group,
|
|
258
|
-
.mh-select__group + .mh-select__option {
|
|
259
|
-
border-top: 1px solid var(--ui-base-200);
|
|
260
|
-
}
|
|
261
|
-
.mh-select__group-label {
|
|
262
|
-
display: block;
|
|
263
|
-
padding: var(--ui-space-1) var(--ui-select-padding-x);
|
|
264
|
-
font-size: var(--ui-select-font-size);
|
|
265
|
-
color: var(--ui-base-content-muted);
|
|
266
|
-
cursor: default;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/* 搜索行(**消费方显式 `searchable` 时才由组件渲染**,件不按选项条数自动决断)。
|
|
270
|
-
`flex: none`:它是面板的**常驻**行 —— 面板限高时收缩与滚动都归内容区,
|
|
271
|
-
少了它,搜索行会被一起压扁(列容器里它默认是可收缩的)。 */
|
|
272
|
-
.mh-select__search {
|
|
273
|
-
flex: none;
|
|
274
|
-
padding: var(--ui-space-2) var(--ui-space-2) var(--ui-space-1);
|
|
275
|
-
}
|
|
276
|
-
|
|
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 面。 */
|
|
285
|
-
|
|
286
|
-
/* 命中高亮(搜索命中的那段文字,由组件的 `renderLabel` 落进 `.mh-tree__label` 槽)。
|
|
287
|
-
底色取主色浅底档(与选中 / 滑过同一套语义槽位);字色 `inherit` —— 高亮只负责「标出位置」,
|
|
288
|
-
不引入第二套强调色,否则同一行里会同时出现三种主色深浅。 */
|
|
289
|
-
.mh-select__hit {
|
|
290
|
-
border-radius: var(--ui-radius-xs);
|
|
291
|
-
background: var(--ui-primary-weak);
|
|
292
|
-
color: inherit;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/* ===== 日期格(DatePicker 复用本族面板;选中主色实底、区间浅底) ===== */
|
|
296
|
-
.mh-select__date {
|
|
297
|
-
display: inline-flex;
|
|
298
|
-
align-items: center;
|
|
299
|
-
justify-content: center;
|
|
300
|
-
width: var(--ui-select-height);
|
|
301
|
-
height: var(--ui-select-height);
|
|
302
|
-
border: none;
|
|
303
|
-
border-radius: var(--ui-radius-control);
|
|
304
|
-
background: transparent;
|
|
305
|
-
font-family: inherit;
|
|
306
|
-
font-size: var(--ui-select-font-size);
|
|
307
|
-
color: var(--ui-base-content);
|
|
308
|
-
cursor: pointer;
|
|
309
|
-
}
|
|
310
|
-
.mh-select__date:hover,
|
|
311
|
-
.mh-select__date.is-hover {
|
|
312
|
-
background: var(--ui-select-option-hover);
|
|
313
|
-
}
|
|
314
|
-
.mh-select__date.is-selected,
|
|
315
|
-
.mh-select__date[data-state='selected'] {
|
|
316
|
-
background: var(--ui-primary);
|
|
317
|
-
color: var(--ui-primary-content);
|
|
318
|
-
}
|
|
319
|
-
.mh-select__date.is-range {
|
|
320
|
-
background: var(--ui-primary-weak);
|
|
321
|
-
}
|
|
322
|
-
.mh-select__date.is-disabled,
|
|
323
|
-
.mh-select__date:disabled {
|
|
324
|
-
color: var(--ui-base-content-subtle);
|
|
325
|
-
cursor: not-allowed;
|
|
326
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Select —— 选择器族(单选触发器 + 多选标签 + 选项面板 + 搜索行 + 日期格)。
|
|
3
|
+
*
|
|
4
|
+
* 出处:`@aihub/theme` 的 `playground/components/select.css` 与 `src/components/select.css`
|
|
5
|
+
* (触发器同输入框、选项行高 30、内距 8;面板内距 4 + 选项 30;多选标签复用标签族形态;
|
|
6
|
+
* 日期格 26 方形,选中主色实底、区间 Ne10)。
|
|
7
|
+
*
|
|
8
|
+
* **触发器的框不在本件**:触发器 = 输入框的「触发器形态」(TSX 里是 `<Input as="button">`),
|
|
9
|
+
* 框 / 内距 / 边 / 圆角 / 底 / 字 / hover / 聚焦 / 禁用 / 校验色与**清除位**、**右侧图标位**
|
|
10
|
+
* 全部归输入面与它的表壳(`.mh-input` + `.mh-input__wrap`)。本件只给选择器自己的排版
|
|
11
|
+
* (`display` / `gap` / `width` / `text-align` / `overflow` 与值 / 标签),另通过挂在**表壳**上的
|
|
12
|
+
* `.mh-select-host` 微调两处壳内节奏(间距回到 4px、箭头收敛回 12px)。
|
|
13
|
+
* **禁写:本件不得再画框**(画了就又开一份会与输入面漂移的规格 —— 这正是本次收敛掉的东西)。
|
|
14
|
+
*
|
|
15
|
+
* **面板开合与定位不在本件**:面板是操作层的组合 —— 消费方/组件在面板根并列挂
|
|
16
|
+
* `class="mh-popup mh-select__panel mh-popup--anchored"`(`data-side` / `data-align` 定位档、
|
|
17
|
+
* Esc、点外部关闭、顶层渲染全在 `styles/operations/popup.css`)。本件只给**面**
|
|
18
|
+
* (底 / 圆角 / 内距 / 阴影 / 选项行)。
|
|
19
|
+
*
|
|
20
|
+
* **面板宽度跟触发器走**:规范把触发器与面板都钉在 300px,本仓触发器是**流式宽度**
|
|
21
|
+
* (与 input 同一结论),故面板用 `anchor-size(width)` 取锚点宽。触发器进表壳后,
|
|
22
|
+
* `popovertarget` 的**隐式锚**只有壳内那个控件那么宽,故这里走**显式锚档**:
|
|
23
|
+
* 表壳挂 `.mh-popup-anchor`(`anchor-name`)、面板挂 `.mh-popup--anchored`(`position-anchor`),
|
|
24
|
+
* 锚点即整件;非锚定场景回落到 240px 兜底值。
|
|
25
|
+
*
|
|
26
|
+
* **面板有高度上限**:`--ui-select-panel-max-height`(默认 320px)钉在面板根上,超出即内容区
|
|
27
|
+
* (`.mh-select__body`)滚动、搜索行常驻 —— 列表与树两形态共用这一份,形态里不许各写限高。
|
|
28
|
+
*
|
|
29
|
+
* **一处有色差异**:规范的选中行是灰底(Ne10),本仓的「选中」统一走**主色浅底**
|
|
30
|
+
* `--ui-primary-subtle`(与列表 / 树的选中态同一语义槽位),否则悬停(Ne11)与选中(Ne10)两档灰
|
|
31
|
+
* 在本仓有限的灰阶里挤成同色、看不出选中。
|
|
32
|
+
*
|
|
33
|
+
* 选项选中态**三源等价**:原生 `:has(input:checked)`(零 JS 单选路径)/ 组件下发
|
|
34
|
+
* `[data-state='selected']` / 静态档 `.is-selected`。
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/* ===== 触发器:只留选择器自己的排版(框与状态全归输入面) ===== */
|
|
38
|
+
.mh-select {
|
|
39
|
+
display: inline-flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: var(--ui-space-1);
|
|
42
|
+
width: 100%;
|
|
43
|
+
text-align: left;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
overflow: hidden;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* 表壳上的本件修饰(TSX 把 `mh-select-host` 挂在**表壳**上:`class` 落壳是输入面的既有契约)。 */
|
|
49
|
+
/* ① 壳内间距:输入框的附加位节奏是 8px,选择器自己的是 4px(值 / 标签与清除位、箭头之间) */
|
|
50
|
+
.mh-select-host {
|
|
51
|
+
gap: var(--ui-space-1);
|
|
52
|
+
}
|
|
53
|
+
/* ② 箭头尺寸:`.mh-input__suffix > svg`(0-1-1)会把槽内图标统一成 16px,而本件箭头是 12px
|
|
54
|
+
—— 这里以 0-2-0 收敛回来。注意不能在 select.css 里直写 `.mh-input__suffix`:
|
|
55
|
+
面文件的类名必须与文件词根同根(机械护栏),故走自己的壳修饰类。 */
|
|
56
|
+
.mh-select-host .mh-select__caret {
|
|
57
|
+
width: var(--ui-select-icon-size);
|
|
58
|
+
height: var(--ui-select-icon-size);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* ===== 尺寸档:框的尺寸归输入面,本类只承载选择器自有部位的对档微调 ===== */
|
|
62
|
+
/* 框高 / 字号由 `<Input size>` 下发的 `mh-input--sm` / `--lg` 承担(含表壳的换高)。
|
|
63
|
+
两处口径要认(都是输入面既有事实,不是本件选择):
|
|
64
|
+
① **左右内距不随档位变**:带壳时内距归表壳(`--ui-input-padding-x` = 12px 恒定),
|
|
65
|
+
`--ui-input-padding-x-sm/-lg` 只对**裸控件**生效 —— 输入框自己的 sm / lg 实测也是 12px;
|
|
66
|
+
② `mh-select--*` 只跟「选择器自己的东西」有关 —— 当前只有标签:小号控件 24px 高,
|
|
67
|
+
24px 的标签会顶满整件、失去呼吸位,故收 4px。 */
|
|
68
|
+
.mh-select--sm .mh-select__chip {
|
|
69
|
+
height: calc(var(--ui-select-chip-height) - 4px);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* 值区:有值时的单选那一行(占满剩余宽、超出省略)。
|
|
73
|
+
⚠️ **无值态不在这里** —— 占位由输入面渲染(`.mh-input__placeholder`,色与截断同档):
|
|
74
|
+
2026-09-29 收敛,此前本文件还有一个 `--placeholder` 修饰类专门给占位上灰字。 */
|
|
75
|
+
.mh-select__value {
|
|
76
|
+
flex: 1;
|
|
77
|
+
min-width: 0;
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
text-overflow: ellipsis;
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
}
|
|
82
|
+
/* 下拉箭头:渲染在输入面的**右侧图标位**(`.mh-input__suffix`,表壳的子元素)里 ——
|
|
83
|
+
位置由表壳的 flex 排布给(控件 `flex: 1 1 auto` 自然把附加位挤到右端),故不再需要 `margin-left: auto`。
|
|
84
|
+
字形由 @manohub/icon 给;展开转向由 popup.css 的 `.mh-popup-caret` 承担(含触发器进表壳后的兄弟档);
|
|
85
|
+
尺寸的 12px 在下面 `mh-select-host` 一节按特异性收敛(槽内 svg 会被输入面统一成 16px)。 */
|
|
86
|
+
.mh-select__caret {
|
|
87
|
+
flex: none;
|
|
88
|
+
color: var(--ui-base-content-muted); /* Te07 */
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* ===== 多选:标签 + 收纳(单行不换行,超出由组件算「其他 n 项」) =====
|
|
92
|
+
清除位不在本件:它是输入面的内建件(`.mh-input__clear`,圆点实底 + 反白叉号),
|
|
93
|
+
由 `<Input clearable>` 渲染在**表壳**里 —— 与值 / 标签同一行的右端。 */
|
|
94
|
+
.mh-select--multiple {
|
|
95
|
+
flex-wrap: nowrap;
|
|
96
|
+
}
|
|
97
|
+
.mh-select__chip {
|
|
98
|
+
display: inline-flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
flex: none;
|
|
101
|
+
height: var(--ui-select-chip-height);
|
|
102
|
+
padding: 0 var(--ui-space-2);
|
|
103
|
+
border-radius: var(--ui-radius-full);
|
|
104
|
+
background: var(--ui-base-200); /* Ne11 轻量片底 */
|
|
105
|
+
font-size: var(--ui-select-font-size);
|
|
106
|
+
color: var(--ui-base-content);
|
|
107
|
+
}
|
|
108
|
+
.mh-select__chip--fold {
|
|
109
|
+
background: var(--ui-base-200);
|
|
110
|
+
color: var(--ui-base-content-muted);
|
|
111
|
+
}
|
|
112
|
+
/* ===== 面板皮肤(与操作层并列组合:`class="mh-popup mh-select__panel mh-popup--anchored"`) =====
|
|
113
|
+
**面板是列容器 + 限高**:搜索行常驻(不滚),下一条的 `.mh-select__body` 承担滚动 ——
|
|
114
|
+
列表与树两形态因此共用同一份「长内容不撑破面板」的规格。
|
|
115
|
+
(历史症状:限高原先只写在树体 `.mh-select__tree` 上,而列表形态的选项是面板的**直接子节点**,
|
|
116
|
+
面板会被一路撑高;实测 60 条选项的面板高 2212px、视口只有 925px。) */
|
|
117
|
+
.mh-select__panel {
|
|
118
|
+
/* 锚 = `.mh-popup-anchor`(挂在表壳上)→ 面板与**整件**同宽;非锚定场景回落 240 */
|
|
119
|
+
width: anchor-size(width, 240px);
|
|
120
|
+
/* 列容器:搜索行 `flex: none` + 内容区 `flex: 1 / min-height: 0`。
|
|
121
|
+
⚠️ 加 `display: flex` 会以作者源压过 UA 给**收起态**定的 `display: none`,收起态靠操作层
|
|
122
|
+
`operations/popup.css` 里那条 `:is()` 兜底(把收起的浮层重新钉成 `display: none`,
|
|
123
|
+
特异性 0-3-0、高于本行)—— **那条兜底不能删**(与 `dialog.css` 同一处坑)。 */
|
|
124
|
+
display: flex;
|
|
125
|
+
flex-direction: column;
|
|
126
|
+
/* 限高(**含搜索行**):超出即内容区滚动。面板仍贴锚点,只是不再无限长 */
|
|
127
|
+
max-height: var(--ui-select-panel-max-height);
|
|
128
|
+
/* UA 给 `[popover]` 的是 `overflow: auto`,必须归零:内容区已是滚动容器,
|
|
129
|
+
留一层就会与它叠成两条滚动条(同一个面板上实测会同时出现)。 */
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
padding: var(--ui-space-1) 0;
|
|
132
|
+
border-radius: var(--ui-select-radius);
|
|
133
|
+
background: var(--ui-base-100);
|
|
134
|
+
/* 锚定浮层的投影走 `--ui-shadow-popover`(**不是** elevated):两枚令牌按「锚定浮层 vs 居中浮层」
|
|
135
|
+
分工,default 主题给前者填的是设计实测值(`0:4025` 的 `0 4px 20px rgba(0,14,51,.10)`),
|
|
136
|
+
farris 主题给的是规范的 `--mh-shadow-lg:14dp 下拉/弹出层` —— 语义与两套来源都对得上。 */
|
|
137
|
+
box-shadow: var(--ui-shadow-popover);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* 内容区:**面板里唯一的滚动容器**(列表体的选项行 / 树体的树都装在它里面),
|
|
141
|
+
同时是**两形态共用的一处内距** —— 内容贴面板左右边各留一个最小呼吸位
|
|
142
|
+
(行仍是满宽,只有内容缩进;选项行的内距与树行的缩进各由自己承担)。
|
|
143
|
+
内距为什么在这儿而不是各形态自己一层:见下方「树体壳已退场」一节的实测症状。
|
|
144
|
+
`min-height: 0` 是这一档生效的前提:列容器里弹性项的可收缩下限默认取内容高,
|
|
145
|
+
不给它,内容就永远压不下去、上面的限高形同虚设(与 `panel.css` 的 `.mh-panel__body` 同款)。 */
|
|
146
|
+
.mh-select__body {
|
|
147
|
+
flex: 1;
|
|
148
|
+
min-height: 0;
|
|
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);
|
|
154
|
+
}
|
|
155
|
+
|
|
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 拿满宽)。 */
|
|
165
|
+
.mh-select__option {
|
|
166
|
+
position: relative;
|
|
167
|
+
display: flex;
|
|
168
|
+
align-items: center;
|
|
169
|
+
height: var(--ui-select-option-height);
|
|
170
|
+
padding: 0 var(--ui-select-padding-x);
|
|
171
|
+
border-radius: var(--ui-radius-control);
|
|
172
|
+
font-size: var(--ui-select-font-size);
|
|
173
|
+
color: var(--ui-base-content);
|
|
174
|
+
cursor: pointer;
|
|
175
|
+
}
|
|
176
|
+
/* 零 JS 单选路径的隐身开关(真实 radio 负责键盘与可访问性,高亮画在行上) */
|
|
177
|
+
.mh-select__option > input {
|
|
178
|
+
position: absolute;
|
|
179
|
+
width: 1px;
|
|
180
|
+
height: 1px;
|
|
181
|
+
margin: -1px;
|
|
182
|
+
padding: 0;
|
|
183
|
+
border: 0;
|
|
184
|
+
overflow: hidden;
|
|
185
|
+
white-space: nowrap;
|
|
186
|
+
clip-path: inset(50%);
|
|
187
|
+
appearance: none;
|
|
188
|
+
pointer-events: none;
|
|
189
|
+
}
|
|
190
|
+
/* 行态三档与树行逐条对应(滑过 / 按下 / 选中):
|
|
191
|
+
① 滑过 = 键盘高亮(`data-active`,见 `select-list.tsx` 的高亮模型)= 主色浅底;
|
|
192
|
+
② 按下 = 选中底(与树行的 `:active` 同款);
|
|
193
|
+
③ 选中 = 选中底 + 主色字。 */
|
|
194
|
+
.mh-select__option:hover,
|
|
195
|
+
.mh-select__option.is-hover,
|
|
196
|
+
.mh-select__option[data-active='true'] {
|
|
197
|
+
background: var(--ui-select-option-hover);
|
|
198
|
+
}
|
|
199
|
+
.mh-select__option:active {
|
|
200
|
+
background: var(--ui-select-option-selected);
|
|
201
|
+
}
|
|
202
|
+
/* 零 JS 静态档的键盘可达:行内含原生 radio / checkbox 时,焦点在它身上即给行描边
|
|
203
|
+
(组件路径的选项**不可聚焦**,键盘高亮走上面的 `data-active`)。 */
|
|
204
|
+
.mh-select__option:has(input:focus-visible) {
|
|
205
|
+
outline: 2px solid var(--ui-primary);
|
|
206
|
+
outline-offset: -2px;
|
|
207
|
+
}
|
|
208
|
+
/* 选中:三源等价(原生 / 组件 / 静态档) */
|
|
209
|
+
.mh-select__option.is-selected,
|
|
210
|
+
.mh-select__option[data-state='selected'],
|
|
211
|
+
.mh-select__option:has(input:checked) {
|
|
212
|
+
background: var(--ui-select-option-selected);
|
|
213
|
+
color: var(--ui-primary);
|
|
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
|
+
}
|
|
237
|
+
.mh-select__option.is-disabled,
|
|
238
|
+
.mh-select__option[data-disabled='true'],
|
|
239
|
+
.mh-select__option:has(input:disabled) {
|
|
240
|
+
color: var(--ui-base-content-subtle);
|
|
241
|
+
cursor: not-allowed;
|
|
242
|
+
}
|
|
243
|
+
.mh-select__option--hint {
|
|
244
|
+
color: var(--ui-base-content-muted);
|
|
245
|
+
}
|
|
246
|
+
.mh-select__option--empty {
|
|
247
|
+
color: var(--ui-base-content-muted);
|
|
248
|
+
}
|
|
249
|
+
/* 「创建 xxx」行:搜索词无命中时出现 —— 它是 `.mh-select__option` 上的**修饰类**
|
|
250
|
+
(两件同写:`class="mh-select__option mh-select__add"`),行的几何与三态全沿用基类,
|
|
251
|
+
这里只改字色为「可创建」的主色。 */
|
|
252
|
+
.mh-select__add {
|
|
253
|
+
color: var(--ui-primary);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* ===== 选项分组(组标题不可点,只做分区;组间距靠分隔线给) ===== */
|
|
257
|
+
.mh-select__group + .mh-select__group,
|
|
258
|
+
.mh-select__group + .mh-select__option {
|
|
259
|
+
border-top: 1px solid var(--ui-base-200);
|
|
260
|
+
}
|
|
261
|
+
.mh-select__group-label {
|
|
262
|
+
display: block;
|
|
263
|
+
padding: var(--ui-space-1) var(--ui-select-padding-x);
|
|
264
|
+
font-size: var(--ui-select-font-size);
|
|
265
|
+
color: var(--ui-base-content-muted);
|
|
266
|
+
cursor: default;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* 搜索行(**消费方显式 `searchable` 时才由组件渲染**,件不按选项条数自动决断)。
|
|
270
|
+
`flex: none`:它是面板的**常驻**行 —— 面板限高时收缩与滚动都归内容区,
|
|
271
|
+
少了它,搜索行会被一起压扁(列容器里它默认是可收缩的)。 */
|
|
272
|
+
.mh-select__search {
|
|
273
|
+
flex: none;
|
|
274
|
+
padding: var(--ui-space-2) var(--ui-space-2) var(--ui-space-1);
|
|
275
|
+
}
|
|
276
|
+
|
|
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 面。 */
|
|
285
|
+
|
|
286
|
+
/* 命中高亮(搜索命中的那段文字,由组件的 `renderLabel` 落进 `.mh-tree__label` 槽)。
|
|
287
|
+
底色取主色浅底档(与选中 / 滑过同一套语义槽位);字色 `inherit` —— 高亮只负责「标出位置」,
|
|
288
|
+
不引入第二套强调色,否则同一行里会同时出现三种主色深浅。 */
|
|
289
|
+
.mh-select__hit {
|
|
290
|
+
border-radius: var(--ui-radius-xs);
|
|
291
|
+
background: var(--ui-primary-weak);
|
|
292
|
+
color: inherit;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* ===== 日期格(DatePicker 复用本族面板;选中主色实底、区间浅底) ===== */
|
|
296
|
+
.mh-select__date {
|
|
297
|
+
display: inline-flex;
|
|
298
|
+
align-items: center;
|
|
299
|
+
justify-content: center;
|
|
300
|
+
width: var(--ui-select-height);
|
|
301
|
+
height: var(--ui-select-height);
|
|
302
|
+
border: none;
|
|
303
|
+
border-radius: var(--ui-radius-control);
|
|
304
|
+
background: transparent;
|
|
305
|
+
font-family: inherit;
|
|
306
|
+
font-size: var(--ui-select-font-size);
|
|
307
|
+
color: var(--ui-base-content);
|
|
308
|
+
cursor: pointer;
|
|
309
|
+
}
|
|
310
|
+
.mh-select__date:hover,
|
|
311
|
+
.mh-select__date.is-hover {
|
|
312
|
+
background: var(--ui-select-option-hover);
|
|
313
|
+
}
|
|
314
|
+
.mh-select__date.is-selected,
|
|
315
|
+
.mh-select__date[data-state='selected'] {
|
|
316
|
+
background: var(--ui-primary);
|
|
317
|
+
color: var(--ui-primary-content);
|
|
318
|
+
}
|
|
319
|
+
.mh-select__date.is-range {
|
|
320
|
+
background: var(--ui-primary-weak);
|
|
321
|
+
}
|
|
322
|
+
.mh-select__date.is-disabled,
|
|
323
|
+
.mh-select__date:disabled {
|
|
324
|
+
color: var(--ui-base-content-subtle);
|
|
325
|
+
cursor: not-allowed;
|
|
326
|
+
}
|