@xihan-ui/styles 1.0.0 → 2.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/CHANGELOG.md +5146 -6
- package/README.md +22 -2
- package/component-tokens.d.ts +4212 -0
- package/component-tokens.js +2 -0
- package/components.tokens.json +80116 -0
- package/css/accordion.css +131 -75
- package/css/affix.css +16 -1
- package/css/alert.css +114 -67
- package/css/anchor.css +99 -27
- package/css/approval.css +461 -0
- package/css/avatar-group.css +14 -6
- package/css/avatar.css +33 -9
- package/css/back-top.css +103 -48
- package/css/badge.css +42 -14
- package/css/bar-code.css +62 -0
- package/css/breadcrumb.css +40 -21
- package/css/button-group.css +146 -24
- package/css/button.css +116 -99
- package/css/calendar-picker.css +448 -0
- package/css/calendar-range-picker.css +517 -0
- package/css/card.css +54 -77
- package/css/carousel.css +412 -68
- package/css/cascader.css +429 -246
- package/css/checkbox-group.css +225 -77
- package/css/checkbox.css +174 -37
- package/css/clipboard.css +266 -47
- package/css/code-view.css +279 -0
- package/css/collapsible.css +108 -63
- package/css/color-field.css +158 -0
- package/css/color-picker.css +172 -184
- package/css/color-slider.css +274 -0
- package/css/color-swatch-picker.css +243 -0
- package/css/color-swatch.css +35 -0
- package/css/combobox.css +267 -273
- package/css/command.css +399 -0
- package/css/context-menu.css +183 -108
- package/css/date-field.css +94 -121
- package/css/date-picker.css +486 -249
- package/css/date-range-picker.css +559 -0
- package/css/description.css +51 -0
- package/css/descriptions.css +133 -87
- package/css/dialog.css +247 -68
- package/css/diff-view.css +428 -0
- package/css/download-trigger.css +155 -46
- package/css/drawer.css +194 -111
- package/css/editable.css +172 -152
- package/css/empty-state.css +80 -11
- package/css/field-array.css +190 -0
- package/css/field.css +84 -31
- package/css/fieldset.css +51 -18
- package/css/file-upload.css +134 -36
- package/css/flex.css +20 -1
- package/css/float-button.css +238 -57
- package/css/floating-panel.css +173 -92
- package/css/focus.css +46 -0
- package/css/forced-colors.css +93 -0
- package/css/form.css +254 -77
- package/css/gradient-text.css +34 -10
- package/css/grid.css +516 -5
- package/css/heatmap.css +87 -29
- package/css/highlight.css +20 -5
- package/css/hover-card.css +97 -47
- package/css/icon-wrapper.css +15 -3
- package/css/icon.css +74 -8
- package/css/image-cropper.css +143 -29
- package/css/image-viewer.css +150 -89
- package/css/image.css +30 -1
- package/css/infinite-scroll.css +51 -1
- package/css/input-group.css +277 -0
- package/css/json-viewer.css +102 -45
- package/css/kbd.css +72 -0
- package/css/label.css +78 -0
- package/css/layers.css +5 -0
- package/css/layout.css +175 -31
- package/css/list.css +24 -3
- package/css/listbox.css +208 -67
- package/css/loading-bar.css +52 -3
- package/css/log.css +144 -9
- package/css/markdown-stream.css +149 -0
- package/css/marquee.css +27 -1
- package/css/masonry.css +7 -0
- package/css/matrix-code.css +67 -0
- package/css/mention.css +234 -152
- package/css/menu.css +180 -83
- package/css/menubar.css +204 -136
- package/css/message-feed.css +197 -0
- package/css/navigation-menu.css +144 -90
- package/css/notification.css +178 -100
- package/css/number-animation.css +7 -0
- package/css/number-field.css +120 -277
- package/css/overlay-arrow.css +12 -7
- package/css/page-header.css +99 -14
- package/css/pagination.css +175 -135
- package/css/password-input.css +222 -219
- package/css/pin-input.css +101 -67
- package/css/pointer.css +36 -0
- package/css/popconfirm.css +185 -94
- package/css/popover.css +121 -77
- package/css/progress.css +60 -12
- package/css/prompt-input.css +224 -0
- package/css/question-flow.css +513 -0
- package/css/radio-group.css +147 -30
- package/css/rating.css +193 -43
- package/css/reasoning.css +336 -0
- package/css/reset.css +84 -6
- package/css/resizable.css +237 -0
- package/css/scroll-area.css +68 -7
- package/css/scrollbar.css +47 -13
- package/css/segmented.css +94 -29
- package/css/select.css +288 -274
- package/css/separator.css +101 -1
- package/css/side-nav.css +133 -75
- package/css/signature-pad.css +74 -54
- package/css/skeleton.css +84 -11
- package/css/slider.css +132 -39
- package/css/sortable.css +198 -0
- package/css/spinner.css +126 -12
- package/css/splitter.css +29 -8
- package/css/statistic.css +55 -0
- package/css/steps.css +206 -72
- package/css/switch.css +268 -36
- package/css/table.css +695 -118
- package/css/tabs.css +604 -42
- package/css/tag-group.css +219 -0
- package/css/tag.css +118 -28
- package/css/tags-input.css +156 -274
- package/css/text-field.css +101 -249
- package/css/time-field.css +100 -128
- package/css/time-picker.css +323 -252
- package/css/time-range-picker.css +719 -0
- package/css/timeline.css +202 -68
- package/css/timer.css +56 -52
- package/css/timestamp.css +34 -0
- package/css/toast.css +373 -144
- package/css/toggle-group.css +309 -76
- package/css/toggle.css +116 -85
- package/css/tone.css +47 -0
- package/css/tool-call.css +421 -0
- package/css/toolbar.css +181 -33
- package/css/tooltip.css +107 -36
- package/css/tour.css +183 -152
- package/css/transfer.css +351 -138
- package/css/tree-select.css +323 -216
- package/css/tree.css +294 -62
- package/css/truncate.css +65 -0
- package/css/typography.css +228 -5
- package/css/undefined.css +10 -1
- package/css/virtualizer.css +9 -10
- package/css/visually-hidden.css +7 -0
- package/css/watermark.css +7 -0
- package/family/action-control.css +487 -0
- package/family/collection-item.css +721 -0
- package/family/field-chrome.css +298 -0
- package/family/motion.css +166 -0
- package/family/swatch.css +59 -0
- package/index.css +41705 -126
- package/index.unlayered.css +33692 -17339
- package/package.json +51 -17
- package/css/calendar.css +0 -367
- package/css/code-block.css +0 -91
- package/css/composer.css +0 -134
- package/css/countdown.css +0 -26
- package/css/dynamic-input.css +0 -220
- package/css/ellipsis.css +0 -52
- package/css/hotkeys.css +0 -90
- package/css/popselect.css +0 -391
- package/css/qr-code.css +0 -55
- package/css/result.css +0 -119
- package/css/space.css +0 -117
- package/css/thread.css +0 -120
- package/css/time.css +0 -25
package/css/combobox.css
CHANGED
|
@@ -1,29 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from {
|
|
6
|
-
opacity: 0;
|
|
7
|
-
scale: var(--xh-motion-scale-enter);
|
|
8
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2021-Present XiHanFun and contributors.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE in the project root for license information.
|
|
4
|
+
*/
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
@keyframes xh-pop-out {
|
|
16
|
-
from {
|
|
17
|
-
opacity: 1;
|
|
18
|
-
scale: 1;
|
|
19
|
-
}
|
|
6
|
+
/* Combobox 独立皮肤同时传递引入字段视觉盒、字段内动作与浮层集合行;full bundle 递归去重。 */
|
|
7
|
+
@import '../family/field-chrome.css';
|
|
8
|
+
@import '../family/action-control.css';
|
|
9
|
+
@import '../family/collection-item.css';
|
|
20
10
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
scale: var(--xh-motion-scale-enter);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
11
|
+
/* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
|
|
12
|
+
@import '../family/motion.css';
|
|
27
13
|
|
|
28
14
|
@layer xihan.components {
|
|
29
15
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
@@ -36,12 +22,25 @@
|
|
|
36
22
|
/* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,内容层继承它限高;
|
|
37
23
|
引擎没算(尚未落位 / 无引擎)时不额外限高 */
|
|
38
24
|
--xh-_combobox-available-h: 100vh;
|
|
25
|
+
/* 落定那一侧的可用宽度,同样由定位引擎经内联自定义属性写进来,行内轴据此夹取;
|
|
26
|
+
引擎没算(尚未落位 / 无引擎 / 贴边归零)时退到视口宽 */
|
|
27
|
+
--xh-_combobox-available-w: 100vw;
|
|
28
|
+
/* 输入框实测宽度,由定位引擎经内联自定义属性写进来,内容层拿它当最小宽的下界;
|
|
29
|
+
引擎没算(尚未落位 / 无引擎)时为 0,max 取静态档,等于不抬宽 */
|
|
30
|
+
--xh-_combobox-anchor-w: 0px;
|
|
31
|
+
/* 每层使用自身落位方向,不继承外层弹窗留下的方向。 */
|
|
32
|
+
--xh-_overlay-enter-up: 0;
|
|
33
|
+
--xh-_overlay-enter-down: 0;
|
|
34
|
+
--xh-_overlay-enter-left: 0;
|
|
35
|
+
--xh-_overlay-enter-right: 0;
|
|
39
36
|
|
|
40
37
|
/* 候选列表的自绘条浮在内容之上:轨道不上底色,实色轨道会在列表右缘糊一条竖灰带 */
|
|
41
38
|
--xh-scrollbar-track-bg: transparent;
|
|
42
39
|
|
|
43
40
|
position: fixed;
|
|
44
|
-
|
|
41
|
+
/* listbox 与同级 status 占同一个格:content 始终是唯一表面,状态文字叠在它上面。 */
|
|
42
|
+
display: grid;
|
|
43
|
+
z-index: var(--xh-combobox-layer, var(--xh-_layer, var(--xh-layer-popover)));
|
|
45
44
|
/* 空壳不吃指针,交互只发生在 content 与 empty 上 */
|
|
46
45
|
pointer-events: none;
|
|
47
46
|
}
|
|
@@ -51,37 +50,58 @@
|
|
|
51
50
|
visibility: hidden;
|
|
52
51
|
}
|
|
53
52
|
|
|
53
|
+
/* 作者显式收起整层时让位;连接层自己的退场只操作 content,不会命中这条。 */
|
|
54
|
+
[data-scope='combobox'][data-part='positioner'][hidden] {
|
|
55
|
+
display: none;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* placement 与位移同为物理方向,不随书写方向翻转。 */
|
|
59
|
+
[data-scope='combobox'][data-part='positioner'][data-placement^='top'] {
|
|
60
|
+
--xh-_overlay-enter-down: 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
[data-scope='combobox'][data-part='positioner'][data-placement^='bottom'] {
|
|
64
|
+
--xh-_overlay-enter-up: 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
[data-scope='combobox'][data-part='positioner'][data-placement^='left'] {
|
|
68
|
+
--xh-_overlay-enter-right: 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[data-scope='combobox'][data-part='positioner'][data-placement^='right'] {
|
|
72
|
+
--xh-_overlay-enter-left: 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
54
75
|
/* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
|
|
55
76
|
[data-scope='combobox']:is([data-part='root'], [data-part='positioner']) {
|
|
56
|
-
/*
|
|
57
|
-
|
|
77
|
+
/* 尺寸档只换这几个私有槽,输入行与候选都从这两处继承它们,
|
|
78
|
+
换档不必给每个部件各写一条选择器;形态三档由家族按 control 上的 data-variant 生成,皮肤不再声明 */
|
|
58
79
|
--xh-_combobox-h: var(--xh-control-h-md);
|
|
59
80
|
--xh-_combobox-px: var(--xh-control-px-md);
|
|
60
81
|
--xh-_combobox-item-py: var(--xh-list-option-py-md);
|
|
61
82
|
--xh-_combobox-item-px: var(--xh-control-px-md);
|
|
62
83
|
--xh-_combobox-gap: var(--xh-control-gap-md);
|
|
63
84
|
--xh-_combobox-font-size: var(--xh-control-font-md);
|
|
64
|
-
--xh-_combobox-label-font-size: var(--xh-control-font-md);
|
|
65
85
|
|
|
66
|
-
/* 作者塞进指示符槽的图标跟着控件的尺寸档走;它自己写了 size
|
|
86
|
+
/* 作者塞进指示符槽的图标跟着控件的尺寸档走;它自己写了 size 时仍以作者的为准。
|
|
87
|
+
浮层条目里自绘的状态字形(勾选标记所在的标记盒与盒里的勾)不读这支:它们是指示符,走
|
|
88
|
+
--xh-control-indicator-* 一族——标记盒在自己身上把 --xh-icon-size 改接到盒的尺(§6.5) */
|
|
67
89
|
--xh-icon-size: var(--xh-combobox-icon-size, var(--xh-glyph-size-md));
|
|
68
90
|
|
|
69
|
-
/*
|
|
70
|
-
--xh-_combobox-control-bg: var(--xh-bg-canvas);
|
|
71
|
-
--xh-_combobox-control-border: var(--xh-border-control);
|
|
72
|
-
--xh-_combobox-control-border-hover: var(--xh-border-control-hover);
|
|
73
|
-
|
|
74
|
-
/* 聚焦环恒用固定环色;强调色随语气走,只落在勾选标记与选中文字上,正文文字色不动。
|
|
75
|
-
没写 data-tone 时 --xh-_tone 没被声明,两处都退回原来的取值 */
|
|
76
|
-
--xh-_combobox-ring: var(--xh-ring-focus);
|
|
91
|
+
/* 语气只落在勾选标记上,单选与多选正文使用同一颜色。 */
|
|
77
92
|
--xh-_combobox-accent: var(--xh-_tone, var(--xh-fg-brand));
|
|
78
|
-
--xh-_combobox-item-selected-fg: var(--xh-_tone-fg, var(--xh-fg-brand-strong));
|
|
79
93
|
}
|
|
80
94
|
|
|
81
95
|
[data-scope='combobox'][data-part='root'] {
|
|
82
96
|
display: inline-flex;
|
|
83
97
|
flex-direction: column;
|
|
84
98
|
gap: var(--xh-combobox-gap, var(--xh-space-1));
|
|
99
|
+
|
|
100
|
+
/* 不传尺寸时一律这么宽,宽度不随内容走;父容器给不出这么宽时整件跟着收,地板同步让步,不越出父容器。
|
|
101
|
+
地板不高过缺省宽:使用者把缺省宽钉到底线以下时不必再放开底线 */
|
|
102
|
+
inline-size: var(--xh-combobox-control-w, var(--xh-control-w));
|
|
103
|
+
min-inline-size: min(var(--xh-combobox-control-w, var(--xh-control-w)), var(--xh-combobox-control-min-w, var(--xh-control-min-w)), 100%);
|
|
104
|
+
max-inline-size: 100%;
|
|
85
105
|
}
|
|
86
106
|
|
|
87
107
|
/* 只要声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
|
|
@@ -98,7 +118,6 @@
|
|
|
98
118
|
--xh-_combobox-item-px: var(--xh-control-px-sm);
|
|
99
119
|
--xh-_combobox-gap: var(--xh-control-gap-sm);
|
|
100
120
|
--xh-_combobox-font-size: var(--xh-control-font-sm);
|
|
101
|
-
--xh-_combobox-label-font-size: var(--xh-control-font-sm);
|
|
102
121
|
|
|
103
122
|
--xh-icon-size: var(--xh-combobox-icon-size, var(--xh-glyph-size-sm));
|
|
104
123
|
}
|
|
@@ -110,178 +129,110 @@
|
|
|
110
129
|
--xh-_combobox-item-px: var(--xh-control-px-lg);
|
|
111
130
|
--xh-_combobox-gap: var(--xh-control-gap-lg);
|
|
112
131
|
--xh-_combobox-font-size: var(--xh-control-font-lg);
|
|
113
|
-
--xh-_combobox-label-font-size: var(--xh-control-font-lg);
|
|
114
132
|
|
|
115
133
|
--xh-icon-size: var(--xh-combobox-icon-size, var(--xh-glyph-size-lg));
|
|
116
134
|
}
|
|
117
135
|
|
|
118
|
-
/* —— 形态 —— */
|
|
119
|
-
/* 输入类不做 solid:实心底压着可编辑的文字,读起来像块不可点的色板。
|
|
120
|
-
形态只决定描边与底色怎么用,用哪族颜色由 data-tone 决定 */
|
|
121
|
-
[data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-variant='outline'] {
|
|
122
|
-
--xh-_combobox-control-bg: var(--xh-bg-canvas);
|
|
123
|
-
--xh-_combobox-control-border: var(--xh-border-control);
|
|
124
|
-
--xh-_combobox-control-border-hover: var(--xh-border-control-hover);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/* 填充式:底色顶替描边,悬停时才浮出一道淡边 */
|
|
128
|
-
[data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-variant='subtle'] {
|
|
129
|
-
--xh-_combobox-control-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
|
|
130
|
-
--xh-_combobox-control-border: transparent;
|
|
131
|
-
--xh-_combobox-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* 无框:底与常态描边透明,悬停与聚焦浮出描边 */
|
|
135
|
-
[data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-variant='ghost'] {
|
|
136
|
-
--xh-_combobox-control-bg: transparent;
|
|
137
|
-
--xh-_combobox-control-border: transparent;
|
|
138
|
-
--xh-_combobox-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
136
|
[data-scope='combobox'][data-part='label'] {
|
|
142
137
|
color: var(--xh-combobox-label-fg, var(--xh-fg-default));
|
|
143
|
-
font-size: var(--xh-combobox-label-font-size, var(--xh-
|
|
138
|
+
font-size: var(--xh-combobox-label-font-size, var(--xh-text-label-size));
|
|
144
139
|
font-weight: var(--xh-combobox-label-font-weight, var(--xh-text-label-weight));
|
|
145
140
|
line-height: var(--xh-leading-none);
|
|
146
141
|
}
|
|
147
142
|
|
|
148
143
|
[data-scope='combobox'][data-part='label'][data-disabled] {
|
|
149
|
-
color: var(--xh-fg-subtle);
|
|
144
|
+
color: var(--xh-combobox-label-fg-disabled, var(--xh-fg-subtle));
|
|
150
145
|
}
|
|
151
146
|
|
|
152
147
|
/* 画成一个框的是 control 而不是 input:输入框、展开按钮、清空按钮三者要看起来是一体的,
|
|
153
|
-
|
|
148
|
+
边框长在里面任何一个身上都会把另外两个割在框外。描边、底色、圆角、聚焦环、五态与悬停由
|
|
149
|
+
Field Chrome 家族画在 control 上,多行宿主的排版由家族按 input 上的布局值切换;
|
|
150
|
+
组件只映射既有公开槽(shadow 缺省 none:字段静息描边式、无影) */
|
|
154
151
|
[data-scope='combobox'][data-part='control'] {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
gap: var(--xh-combobox-control-gap, var(--xh-_combobox-gap));
|
|
158
|
-
min-inline-size: var(--xh-combobox-control-min-w, var(--xh-control-min-w));
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
152
|
+
--xh-field-control-height: var(--xh-combobox-control-h, var(--xh-_combobox-h));
|
|
153
|
+
--xh-field-control-padding-inline: var(--xh-combobox-control-px, var(--xh-_combobox-px));
|
|
154
|
+
--xh-field-control-gap: var(--xh-combobox-control-gap, var(--xh-_combobox-gap));
|
|
155
|
+
--xh-field-control-min-inline-size: var(--xh-combobox-control-min-w, var(--xh-control-min-w));
|
|
156
|
+
--xh-field-control-radius: var(--xh-combobox-control-radius, var(--xh-shape-control));
|
|
157
|
+
--xh-field-bg-rest: var(--xh-combobox-control-bg, var(--xh-_field-variant-bg-rest));
|
|
158
|
+
--xh-field-bg-hover: var(--xh-combobox-control-bg-hover, var(--xh-_field-variant-bg-hover));
|
|
159
|
+
--xh-field-bg-read-only: var(--xh-combobox-control-bg-readonly, var(--xh-_field-variant-bg-read-only));
|
|
160
|
+
--xh-field-bg-disabled: var(--xh-combobox-control-bg-disabled, var(--xh-_field-variant-bg-disabled));
|
|
161
|
+
--xh-field-fg-rest: var(--xh-combobox-control-fg, var(--xh-fg-default));
|
|
162
|
+
--xh-field-border-rest: var(--xh-combobox-control-border, var(--xh-_field-variant-border-rest));
|
|
163
|
+
--xh-field-border-hover: var(--xh-combobox-control-border-hover, var(--xh-_field-variant-border-hover));
|
|
164
|
+
--xh-field-border-focus: var(--xh-combobox-control-border-focus, var(--xh-_field-variant-border-focus));
|
|
165
|
+
--xh-field-border-invalid: var(--xh-combobox-control-border-invalid, var(--xh-_field-variant-border-invalid));
|
|
166
|
+
--xh-field-ring-focus: var(--xh-ring-focus);
|
|
167
|
+
--xh-field-ring-invalid: var(--xh-ring-invalid);
|
|
168
|
+
--xh-field-shadow-rest: var(--xh-combobox-control-shadow, none);
|
|
169
|
+
/* 家族 chrome 会重写 --xh-icon-size,使用者图标槽必须经桥接槽下发才能在盒内生效 */
|
|
170
|
+
--xh-field-glyph-size: var(--xh-combobox-icon-size, var(--xh-_field-size-glyph-size));
|
|
166
171
|
}
|
|
167
172
|
|
|
168
173
|
[data-scope='combobox'][data-part='control'][hidden] {
|
|
169
174
|
display: none;
|
|
170
175
|
}
|
|
171
176
|
|
|
172
|
-
/* hover 只在中性态换描边:invalid 正拿边框颜色说事,被 hover 盖掉那条信息就没了 */
|
|
173
|
-
[data-scope='combobox'][data-part='control']:hover:not([data-disabled], [data-invalid]) {
|
|
174
|
-
border-color: var(--xh-combobox-control-border-hover, var(--xh-_combobox-control-border-hover));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/* 焦点环画在 control 上而不是 input 上:视觉上的「框」是 control,
|
|
178
|
-
环若长在里面那个透明的 input 身上,就会缩在文字区里、与框错开一圈。
|
|
179
|
-
input 是这里唯一可聚焦的常规节点,:focus-within 与它的 :focus-visible 等价 */
|
|
180
|
-
[data-scope='combobox'][data-part='control']:focus-within:not([data-disabled]) {
|
|
181
|
-
border-color: var(--xh-combobox-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
|
|
182
|
-
outline: var(--xh-ring-width) solid var(--xh-_combobox-ring);
|
|
183
|
-
outline-offset: var(--xh-ring-offset);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
[data-scope='combobox'][data-part='control'][data-invalid] {
|
|
187
|
-
border-color: var(--xh-combobox-control-border-invalid, var(--xh-border-invalid));
|
|
188
|
-
|
|
189
|
-
/* 校验失败时环也跟着变红:两圈等宽相邻却一红一蓝,读的人不知道哪个才是当前状态 */
|
|
190
|
-
--xh-_combobox-ring: var(--xh-ring-invalid);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/* 只读仍可聚焦、可复制,所以不置灰,只把底色压下去表示"改不动" */
|
|
194
|
-
[data-scope='combobox'][data-part='control'][data-readonly] {
|
|
195
|
-
background: var(--xh-combobox-control-bg-readonly, var(--xh-bg-subtle));
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
[data-scope='combobox'][data-part='control'][data-disabled] {
|
|
199
|
-
background: var(--xh-combobox-control-bg-disabled, var(--xh-bg-subtle));
|
|
200
|
-
color: var(--xh-fg-disabled);
|
|
201
|
-
cursor: not-allowed;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
177
|
/* input 是单体表单控件,禁用走原生 disabled(候选那边一律 aria-disabled)。
|
|
205
|
-
它自己不画框也不画环,两者都归 control
|
|
178
|
+
它自己不画框也不画环,两者都归 control;边框 / 底 / 内距的重置、占位色与自动填充回铺由家族按
|
|
179
|
+
data-xh-field-input 给(含撑满剩余宽度的 flex:1),多行宿主的 block-size:auto 与只许纵向拉伸同由家族的 textarea 布局给 */
|
|
206
180
|
[data-scope='combobox'][data-part='input'] {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
background: transparent;
|
|
213
|
-
color: inherit;
|
|
214
|
-
/* 表单控件不继承页面字体,只给字号会让输入框用 UA 默认字族,与周围文本对不上 */
|
|
215
|
-
font-family: inherit;
|
|
216
|
-
font-size: var(--xh-combobox-input-font-size, var(--xh-_combobox-font-size));
|
|
217
|
-
line-height: var(--xh-leading-normal);
|
|
181
|
+
--xh-field-input-fg: var(--xh-combobox-input-fg, var(--xh-combobox-control-fg, var(--xh-fg-default)));
|
|
182
|
+
--xh-field-input-font-size: var(--xh-combobox-input-font-size, var(--xh-_combobox-font-size));
|
|
183
|
+
--xh-field-placeholder-fg: var(--xh-combobox-placeholder-fg, var(--xh-fg-subtle));
|
|
184
|
+
--xh-field-autofill-bg: var(--xh-combobox-input-autofill-bg, var(--xh-bg-canvas));
|
|
185
|
+
--xh-field-autofill-fg: var(--xh-combobox-input-autofill-fg, var(--xh-fg-default));
|
|
218
186
|
}
|
|
219
187
|
|
|
220
188
|
[data-scope='combobox'][data-part='input'][hidden] {
|
|
221
189
|
display: none;
|
|
222
190
|
}
|
|
223
191
|
|
|
224
|
-
/*
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
align-items: start;
|
|
228
|
-
block-size: auto;
|
|
229
|
-
padding-block: var(--xh-combobox-input-py, var(--xh-field-py));
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
[data-scope='combobox'][data-part='input'][data-multiline] {
|
|
233
|
-
block-size: auto;
|
|
234
|
-
/* 只许纵向拉伸:横向拉宽会把浮层与输入行的对齐拽歪 */
|
|
235
|
-
resize: vertical;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
[data-scope='combobox'][data-part='input']::placeholder {
|
|
239
|
-
color: var(--xh-combobox-placeholder-fg, var(--xh-fg-subtle));
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/* 焦点环已由 control 的 :focus-within 画好,这里再画一圈会套成两层 */
|
|
243
|
-
[data-scope='combobox'][data-part='input']:focus-visible {
|
|
244
|
-
outline: none;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
[data-scope='combobox'][data-part='input']:disabled {
|
|
248
|
-
color: var(--xh-fg-disabled);
|
|
249
|
-
cursor: not-allowed;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/* 两个按钮同一副长相:贴在框内右侧的小方钮,不占宽度也不撑高 control */
|
|
192
|
+
/* 两个按钮同一副长相:贴在框内末端的小方钮,不占宽度也不撑高 control。正方视觉盒、inset 圆角、
|
|
193
|
+
悬停 100 / 按下 200 与 0.97 按压、粗指针热区、禁用面与 :focus-visible 关环(盒的 :focus-within
|
|
194
|
+
已画了一圈)全由 Action Control 的 field-inset ghost 档给,组件只映射既有覆盖槽 */
|
|
253
195
|
[data-scope='combobox'][data-part='trigger'],
|
|
254
196
|
[data-scope='combobox'][data-part='clear-trigger'] {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
197
|
+
--xh-action-visual-size: var(--xh-combobox-action-size, var(--xh-_action-profile-visual-size));
|
|
198
|
+
--xh-action-min-inline-size: var(--xh-combobox-action-size, var(--xh-_action-profile-visual-size));
|
|
199
|
+
--xh-action-radius: var(--xh-combobox-action-radius, var(--xh-shape-inset));
|
|
200
|
+
/* 底色阶梯由 ghost 档给(透明 → 100 → 200),使用者槽只作覆盖入口 */
|
|
201
|
+
--xh-action-bg-rest: var(--xh-combobox-action-bg, var(--xh-_action-variant-bg-rest));
|
|
202
|
+
--xh-action-bg-hover: var(--xh-combobox-action-bg-hover, var(--xh-_action-variant-bg-hover));
|
|
203
|
+
--xh-action-bg-pressed: var(--xh-combobox-action-bg-active, var(--xh-_action-variant-bg-pressed));
|
|
204
|
+
--xh-action-fg-rest: var(--xh-combobox-action-fg, var(--xh-fg-muted));
|
|
205
|
+
--xh-action-fg-hover: var(--xh-combobox-action-fg-hover, var(--xh-fg-default));
|
|
206
|
+
--xh-action-border-rest: transparent;
|
|
207
|
+
--xh-action-highlight-rest: transparent;
|
|
208
|
+
--xh-action-shadow-rest: none;
|
|
209
|
+
--xh-action-shadow-hover: none;
|
|
210
|
+
--xh-action-shadow-pressed: none;
|
|
211
|
+
--xh-action-font-size: var(--xh-combobox-action-font-size, var(--xh-text-secondary-size));
|
|
212
|
+
/* 配方尚未把 profile 字形档灌进 --xh-icon-size,钮内字形先按 field-inset 档逐钮取值 */
|
|
213
|
+
--xh-icon-size: var(--xh-_action-profile-glyph-size);
|
|
214
|
+
|
|
215
|
+
border-width: 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* 没值时连接层给的是 hidden 属性;家族那条 display 会把 UA 规则盖掉 */
|
|
275
219
|
[data-scope='combobox'][data-part='trigger'][hidden],
|
|
276
220
|
[data-scope='combobox'][data-part='clear-trigger'][hidden] {
|
|
277
221
|
display: none;
|
|
278
222
|
}
|
|
279
223
|
|
|
224
|
+
/* 有值时清空钮顶上来,展开钮让位:两颗并排堆着用户分不清点哪个,换来换去还会让盒的宽度跳一下。
|
|
225
|
+
判据是盒里此刻有一颗没收起的清空钮——没写清空钮的结构里展开钮照常留着;
|
|
226
|
+
输入框仍是展开的入口(打字、方向键、openOnClick) */
|
|
227
|
+
[data-scope='combobox'][data-part='control']:has([data-part='clear-trigger']:not([hidden])) [data-part='trigger'] {
|
|
228
|
+
display: none;
|
|
229
|
+
}
|
|
230
|
+
|
|
280
231
|
/* 展开时箭头翻个面,指向与列表的去向一致。转的是字形或作者塞的图形,不转按钮本体:
|
|
281
|
-
|
|
232
|
+
按钮自带悬停底色,整个按钮转会带着底色一起转;家族按压缩放的是整钮,不影响这里的转向 */
|
|
282
233
|
[data-scope='combobox'][data-part='trigger']:empty::before,
|
|
283
234
|
[data-scope='combobox'][data-part='trigger'] > * {
|
|
284
|
-
transition: rotate var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
235
|
+
transition: rotate var(--xh-motion-duration-micro) var(--xh-motion-ease-enter-strong);
|
|
285
236
|
}
|
|
286
237
|
|
|
287
238
|
/* 没写内容就由皮肤画箭头;作者往部件里塞了自己的图形,这条规则即不命中 */
|
|
@@ -308,53 +259,56 @@
|
|
|
308
259
|
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
309
260
|
}
|
|
310
261
|
|
|
262
|
+
/* 打开中与悬停同档:展开钮不另上底,方向由箭头转向承担 */
|
|
311
263
|
[data-scope='combobox'][data-part='trigger'][data-state='open']:empty::before,
|
|
312
264
|
[data-scope='combobox'][data-part='trigger'][data-state='open'] > * {
|
|
313
265
|
rotate: 180deg;
|
|
314
266
|
}
|
|
315
267
|
|
|
316
|
-
[data-scope='combobox'][data-part='trigger']:hover:not(:disabled),
|
|
317
|
-
[data-scope='combobox'][data-part='clear-trigger']:hover:not(:disabled) {
|
|
318
|
-
background: var(--xh-combobox-action-bg-hover, var(--xh-bg-subtle-hover));
|
|
319
|
-
color: var(--xh-combobox-action-fg-hover, var(--xh-fg-default));
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
[data-scope='combobox'][data-part='trigger']:active:not(:disabled),
|
|
323
|
-
[data-scope='combobox'][data-part='clear-trigger']:active:not(:disabled) {
|
|
324
|
-
background: var(--xh-combobox-action-bg-active, var(--xh-bg-subtle-active));
|
|
325
|
-
scale: var(--xh-motion-scale-press);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/* 两个按钮都在盒里,盒的 :focus-within 已经画了一圈;这里再画一圈就是框里套框 */
|
|
329
|
-
[data-scope='combobox'][data-part='trigger']:focus-visible,
|
|
330
|
-
[data-scope='combobox'][data-part='clear-trigger']:focus-visible {
|
|
331
|
-
outline: none;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
[data-scope='combobox'][data-part='trigger']:disabled {
|
|
335
|
-
background: var(--xh-combobox-action-bg, transparent);
|
|
336
|
-
color: var(--xh-fg-disabled);
|
|
337
|
-
cursor: not-allowed;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
268
|
[data-scope='combobox'][data-part='content'] {
|
|
269
|
+
position: relative;
|
|
341
270
|
display: flex;
|
|
342
271
|
flex-direction: column;
|
|
343
272
|
gap: var(--xh-combobox-content-gap, var(--xh-list-option-gap));
|
|
344
|
-
|
|
345
|
-
|
|
273
|
+
grid-area: 1 / 1;
|
|
274
|
+
/* 下界跟着输入框走,面板不窄于它;可用宽度的夹取写在这一侧:
|
|
275
|
+
min-inline-size 恒压过 max-inline-size,锚点比可用区还宽时只夹 max 等于没夹 */
|
|
276
|
+
min-inline-size: min(
|
|
277
|
+
max(var(--xh-combobox-content-min-w, var(--xh-overlay-min-w)), var(--xh-_combobox-anchor-w)),
|
|
278
|
+
var(--xh-_combobox-available-w)
|
|
279
|
+
);
|
|
280
|
+
/* 静态档与落位后的可用宽度取小:窄视口下面板伸出去,最右侧的内容就点不到了 */
|
|
281
|
+
max-inline-size: min(var(--xh-combobox-content-max-w, var(--xh-overlay-max-w)), var(--xh-_combobox-available-w));
|
|
282
|
+
/* 空列表也保留完整状态面的高度;empty/loading 先隐藏时,Presence 退场不会塌成细边条。 */
|
|
283
|
+
min-block-size: var(--xh-combobox-content-min-h, var(--xh-_combobox-h));
|
|
346
284
|
max-block-size: min(var(--xh-combobox-content-max-h, var(--xh-overlay-max-h)), var(--xh-_combobox-available-h));
|
|
347
285
|
padding-block: var(--xh-combobox-content-py, var(--xh-space-1));
|
|
348
286
|
padding-inline: var(--xh-combobox-content-px, var(--xh-space-1));
|
|
349
|
-
border: var(--xh-stroke-thin) solid var(--xh-combobox-content-border, var(--xh-border
|
|
350
|
-
border-radius: var(--xh-combobox-content-radius, var(--xh-shape-
|
|
351
|
-
background: var(--xh-combobox-content-bg, var(--xh-bg
|
|
352
|
-
color: var(--xh-combobox-content-fg, var(--xh-fg
|
|
353
|
-
box-shadow: var(--xh-combobox-content-shadow, var(--xh-
|
|
287
|
+
border: var(--xh-stroke-thin) solid var(--xh-combobox-content-border, var(--xh-material-frosted-border));
|
|
288
|
+
border-radius: var(--xh-combobox-content-radius, var(--xh-shape-overlay));
|
|
289
|
+
background: var(--xh-combobox-content-bg, var(--xh-material-frosted-bg));
|
|
290
|
+
color: var(--xh-combobox-content-fg, var(--xh-material-frosted-fg));
|
|
291
|
+
box-shadow: var(--xh-combobox-content-shadow, var(--xh-material-frosted-shadow));
|
|
292
|
+
-webkit-backdrop-filter: var(--xh-combobox-content-backdrop, var(--xh-material-frosted-backdrop));
|
|
293
|
+
backdrop-filter: var(--xh-combobox-content-backdrop, var(--xh-material-frosted-backdrop));
|
|
354
294
|
overflow-y: auto;
|
|
295
|
+
/* 浮层滚动面:滚到头不把页面一起带走 */
|
|
296
|
+
overscroll-behavior: contain;
|
|
355
297
|
pointer-events: auto;
|
|
356
298
|
}
|
|
357
299
|
|
|
300
|
+
/* 顶光只沿表面上边缘绘制,不参与列表布局、不拦截候选交互。 */
|
|
301
|
+
[data-scope='combobox'][data-part='content']::before {
|
|
302
|
+
content: '';
|
|
303
|
+
position: absolute;
|
|
304
|
+
inset-block-start: 0;
|
|
305
|
+
inset-inline: 0;
|
|
306
|
+
block-size: var(--xh-stroke-thin);
|
|
307
|
+
border-radius: inherit;
|
|
308
|
+
background: var(--xh-combobox-content-highlight, var(--xh-material-frosted-highlight));
|
|
309
|
+
pointer-events: none;
|
|
310
|
+
}
|
|
311
|
+
|
|
358
312
|
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
|
|
359
313
|
收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
|
|
360
314
|
[hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
|
|
@@ -368,96 +322,97 @@
|
|
|
368
322
|
}
|
|
369
323
|
|
|
370
324
|
[data-scope='combobox'][data-part='content'][data-state='open'] {
|
|
371
|
-
animation: xh-
|
|
325
|
+
animation: xh-overlay-slide-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
|
|
326
|
+
/* 只在开着的这一档挂:合成层随 data-state 一起收走,收起后不再占着 */
|
|
327
|
+
will-change: opacity, translate;
|
|
372
328
|
}
|
|
373
329
|
|
|
374
330
|
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
|
|
375
331
|
免得动画结束到真收起之间闪一下原样 */
|
|
376
332
|
[data-scope='combobox'][data-part='content'][data-state='closed'] {
|
|
377
|
-
animation: xh-
|
|
333
|
+
animation: xh-overlay-slide-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
378
334
|
}
|
|
379
335
|
|
|
380
|
-
[data-scope='combobox'][data-part='
|
|
336
|
+
[data-scope='combobox'][data-part='group'] {
|
|
381
337
|
display: flex;
|
|
382
338
|
flex-direction: column;
|
|
383
|
-
gap: var(--xh-combobox-
|
|
339
|
+
gap: var(--xh-combobox-group-gap, var(--xh-list-option-gap));
|
|
384
340
|
}
|
|
385
341
|
|
|
386
|
-
[data-scope='combobox'][data-part='
|
|
342
|
+
[data-scope='combobox'][data-part='group'][hidden] {
|
|
387
343
|
display: none;
|
|
388
344
|
}
|
|
389
345
|
|
|
390
346
|
/* 组间留白只加在后继分组上:首组顶上已经有 content 的内边距,再加一层会显得头重 */
|
|
391
|
-
[data-scope='combobox'][data-part='
|
|
392
|
-
margin-block-start: var(--xh-combobox-group-
|
|
347
|
+
[data-scope='combobox'][data-part='group'] + [data-scope='combobox'][data-part='group'] {
|
|
348
|
+
margin-block-start: var(--xh-combobox-group-spacing, var(--xh-space-1_5));
|
|
393
349
|
}
|
|
394
350
|
|
|
395
351
|
/* 分组标题不是候选、进不了导航,画成小号次要文字,内缩与候选对齐(同一个 padding-inline) */
|
|
396
|
-
[data-scope='combobox'][data-part='
|
|
352
|
+
[data-scope='combobox'][data-part='group-label'] {
|
|
397
353
|
display: block;
|
|
398
354
|
padding-block: var(--xh-combobox-group-label-py, var(--xh-space-1));
|
|
399
355
|
padding-inline: var(--xh-combobox-group-label-px, var(--xh-control-px-md));
|
|
400
|
-
color: var(--xh-combobox-group-label-fg, var(--xh-fg-
|
|
356
|
+
color: var(--xh-combobox-group-label-fg, var(--xh-material-frosted-fg-muted));
|
|
401
357
|
font-size: var(--xh-combobox-group-label-font-size, var(--xh-text-caption-size));
|
|
402
358
|
font-weight: var(--xh-combobox-group-label-font-weight, var(--xh-font-weight-medium));
|
|
403
359
|
line-height: var(--xh-leading-none);
|
|
404
360
|
user-select: none;
|
|
405
361
|
}
|
|
406
362
|
|
|
407
|
-
[data-scope='combobox'][data-part='
|
|
363
|
+
[data-scope='combobox'][data-part='group-label'][hidden] {
|
|
408
364
|
display: none;
|
|
409
365
|
}
|
|
410
366
|
|
|
367
|
+
/* 候选行:网格、尺寸档、悬停 / 高亮 100、按下 200、禁用面与选中标记由 Collection Item 家族按 overlay
|
|
368
|
+
语境给(选中 = 透明底 + 行尾对号,正文保持 rest 色与常规字重),公开 Combobox 槽只映射到家族合同 */
|
|
411
369
|
[data-scope='combobox'][data-part='item'] {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
gap: var(--xh-combobox-item-gap, var(--xh-_combobox-gap));
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
370
|
+
--xh-collection-block-padding: var(--xh-combobox-item-py, var(--xh-_combobox-item-py));
|
|
371
|
+
--xh-collection-inline-padding: var(--xh-combobox-item-px, var(--xh-_combobox-item-px));
|
|
372
|
+
--xh-collection-gap: var(--xh-combobox-item-gap, var(--xh-_combobox-gap));
|
|
373
|
+
--xh-collection-font-size: var(--xh-combobox-item-font-size, var(--xh-_combobox-font-size));
|
|
374
|
+
--xh-collection-radius: var(--xh-combobox-item-radius, var(--xh-shape-control));
|
|
375
|
+
--xh-collection-fg-rest: var(--xh-combobox-item-fg, var(--xh-material-frosted-fg));
|
|
376
|
+
--xh-collection-fg-hover: var(--xh-combobox-item-fg, var(--xh-material-frosted-fg));
|
|
377
|
+
--xh-collection-fg-keyboard-highlight: var(--xh-combobox-item-fg, var(--xh-material-frosted-fg));
|
|
378
|
+
--xh-collection-fg-selected: var(--xh-combobox-item-fg-selected, var(--xh-combobox-item-fg, var(--xh-material-frosted-fg)));
|
|
379
|
+
--xh-collection-fg-selected-highlight: var(--xh-combobox-item-fg-selected, var(--xh-combobox-item-fg, var(--xh-material-frosted-fg)));
|
|
380
|
+
--xh-collection-fg-selected-hover: var(--xh-combobox-item-fg-selected, var(--xh-combobox-item-fg, var(--xh-material-frosted-fg)));
|
|
381
|
+
--xh-collection-fg-selected-pressed: var(--xh-combobox-item-fg-selected, var(--xh-combobox-item-fg, var(--xh-material-frosted-fg)));
|
|
382
|
+
--xh-collection-fg-pressed: var(--xh-combobox-item-fg, var(--xh-material-frosted-fg));
|
|
383
|
+
--xh-collection-font-weight-selected: var(--xh-combobox-item-font-weight-selected, var(--xh-font-weight-regular));
|
|
384
|
+
--xh-collection-font-weight-selected-highlight: var(--xh-combobox-item-font-weight-selected, var(--xh-font-weight-regular));
|
|
385
|
+
--xh-collection-font-weight-selected-hover: var(--xh-combobox-item-font-weight-selected, var(--xh-font-weight-regular));
|
|
386
|
+
--xh-collection-font-weight-selected-pressed: var(--xh-combobox-item-font-weight-selected, var(--xh-font-weight-regular));
|
|
387
|
+
--xh-collection-bg-hover: var(--xh-combobox-item-bg-hover, var(--xh-bg-subtle));
|
|
388
|
+
--xh-collection-bg-keyboard-highlight: var(--xh-combobox-item-bg-hover, var(--xh-bg-subtle));
|
|
389
|
+
--xh-collection-bg-selected-highlight: var(--xh-combobox-item-bg-hover, var(--xh-bg-subtle));
|
|
390
|
+
--xh-collection-bg-selected-hover: var(--xh-combobox-item-bg-hover, var(--xh-bg-subtle));
|
|
391
|
+
--xh-collection-bg-pressed: var(--xh-combobox-item-bg-pressed, var(--xh-bg-subtle-hover));
|
|
392
|
+
--xh-collection-bg-selected-pressed: var(--xh-combobox-item-bg-pressed, var(--xh-bg-subtle-hover));
|
|
393
|
+
/* data-highlighted 同时覆盖指针与键盘路径;焦点恒在输入框,候选不接环 */
|
|
394
|
+
--xh-collection-outline-keyboard-highlight: transparent;
|
|
395
|
+
--xh-collection-outline-selected-highlight: transparent;
|
|
396
|
+
--xh-collection-indicator-fg-rest: var(--xh-combobox-item-check-fg, var(--xh-combobox-item-indicator-fg, var(--xh-_combobox-accent)));
|
|
397
|
+
--xh-collection-indicator-fg-checked: var(--xh-combobox-item-check-fg, var(--xh-combobox-item-indicator-fg, var(--xh-_combobox-accent)));
|
|
398
|
+
--xh-collection-indicator-fg-selected: var(--xh-combobox-item-check-fg, var(--xh-combobox-item-indicator-fg, var(--xh-_combobox-accent)));
|
|
399
|
+
--xh-collection-indicator-fg-selected-hover: var(--xh-combobox-item-check-fg, var(--xh-combobox-item-indicator-fg, var(--xh-_combobox-accent)));
|
|
400
|
+
--xh-collection-indicator-fg-selected-highlight: var(--xh-combobox-item-check-fg, var(--xh-combobox-item-indicator-fg, var(--xh-_combobox-accent)));
|
|
401
|
+
--xh-collection-indicator-fg-selected-pressed: var(--xh-combobox-item-check-fg, var(--xh-combobox-item-indicator-fg, var(--xh-_combobox-accent)));
|
|
402
|
+
|
|
420
403
|
/* 行高留出文字的上下伸展空间,行内那层 overflow:hidden 才不会把字削掉 */
|
|
421
404
|
line-height: var(--xh-combobox-item-leading, var(--xh-leading-normal));
|
|
422
405
|
white-space: nowrap;
|
|
423
|
-
cursor: pointer;
|
|
424
406
|
user-select: none;
|
|
425
|
-
transition:
|
|
426
|
-
background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
427
|
-
color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
428
407
|
}
|
|
429
408
|
|
|
430
|
-
/*
|
|
409
|
+
/* 候选按需收起(作者自己藏掉某几条)时要让位,家族给了 display 就得补这条 */
|
|
431
410
|
[data-scope='combobox'][data-part='item'][hidden] {
|
|
432
411
|
display: none;
|
|
433
412
|
}
|
|
434
413
|
|
|
435
|
-
/*
|
|
436
|
-
两套底色各画各的会出现"鼠标停在 A 上、回车提交的却是 B" */
|
|
437
|
-
[data-scope='combobox'][data-part='item'][data-highlighted]:not([data-disabled]) {
|
|
438
|
-
background: var(--xh-combobox-item-bg-hover, var(--xh-bg-subtle));
|
|
439
|
-
/* 焦点恒在输入框,高亮条目自带内收环;列表是滚动容器,环画在外沿会被裁掉 */
|
|
440
|
-
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
441
|
-
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/* 选中只换文字色与字重,配合行尾的 ✓ 标记;底色整条通道留给高亮,
|
|
445
|
-
两者因此能同时看见 */
|
|
446
|
-
[data-scope='combobox'][data-part='item'][data-state='checked'] {
|
|
447
|
-
color: var(--xh-combobox-item-fg-selected, var(--xh-_combobox-item-selected-fg));
|
|
448
|
-
font-weight: var(--xh-combobox-item-font-weight-selected, var(--xh-font-weight-medium));
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
/* 禁用走 aria-disabled 而非原生 disabled(原生 disabled 不派 click,禁用守卫就走不到),
|
|
452
|
-
所以只能靠 data-disabled 表达,写 :disabled 永远不命中 */
|
|
453
|
-
[data-scope='combobox'][data-part='item'][data-disabled] {
|
|
454
|
-
color: var(--xh-fg-disabled);
|
|
455
|
-
cursor: not-allowed;
|
|
456
|
-
}
|
|
457
|
-
|
|
414
|
+
/* 正文落在家族网格的 text 列;网格项默认最小尺寸是内容尺寸,不归零则长文本把行撑破、省略号轮不上 */
|
|
458
415
|
[data-scope='combobox'][data-part='item-text'] {
|
|
459
|
-
flex: 1;
|
|
460
|
-
/* 弹性项默认 min-width: auto 不肯收缩到内容以下,省略号因此永不生效 */
|
|
461
416
|
min-inline-size: 0;
|
|
462
417
|
overflow: hidden;
|
|
463
418
|
white-space: nowrap;
|
|
@@ -468,22 +423,27 @@
|
|
|
468
423
|
display: none;
|
|
469
424
|
}
|
|
470
425
|
|
|
471
|
-
/*
|
|
426
|
+
/* 勾选标记落在家族网格的 indicator 列,只在选中项上显形(家族按 aria-selected / data-state=checked 给);
|
|
427
|
+
未选中时占位不塌,切换选中不引起行宽抖动。
|
|
428
|
+
盒与盒里的勾是指示符(§6.5):盒按指示符档取尺,并在自己身上把 --xh-icon-size 改接到盒的尺,皮肤画的
|
|
429
|
+
兜底勾与作者塞进盒里的 XhIcon 读同一把尺、与盒同边长(勾选标记不是勾选格,不取 × 0.75,与 Select /
|
|
430
|
+
Listbox / Menu 族同口径);不读 root / positioner 按档下发的 --xh-icon-size——那支只管作者放进条目里的
|
|
431
|
+
图标,按图标档取的 20px 比 16 / 14 的指示符档大一圈 */
|
|
472
432
|
[data-scope='combobox'][data-part='item-indicator'] {
|
|
433
|
+
--xh-icon-size: var(--xh-combobox-item-indicator-size, var(--xh-control-indicator-size));
|
|
434
|
+
|
|
473
435
|
display: inline-flex;
|
|
474
|
-
flex: none;
|
|
475
436
|
align-items: center;
|
|
476
437
|
justify-content: center;
|
|
477
438
|
inline-size: var(--xh-combobox-item-indicator-size, var(--xh-control-indicator-size));
|
|
478
|
-
|
|
479
|
-
visibility: hidden;
|
|
439
|
+
block-size: var(--xh-combobox-item-indicator-size, var(--xh-control-indicator-size));
|
|
480
440
|
}
|
|
481
441
|
|
|
482
442
|
[data-scope='combobox'][data-part='item-indicator'][hidden] {
|
|
483
443
|
display: none;
|
|
484
444
|
}
|
|
485
445
|
|
|
486
|
-
/*
|
|
446
|
+
/* 同上:没写内容就由皮肤画勾。尺寸读标记盒自己改接过的 --xh-icon-size:与盒同边长,随指示符档换档 */
|
|
487
447
|
[data-scope='combobox'][data-part='item-indicator']:empty::before {
|
|
488
448
|
content: '';
|
|
489
449
|
display: inline-block;
|
|
@@ -495,33 +455,67 @@
|
|
|
495
455
|
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
496
456
|
}
|
|
497
457
|
|
|
498
|
-
|
|
499
|
-
visibility: visible;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
[data-scope='combobox'][data-part='item-indicator'][data-disabled] {
|
|
503
|
-
color: var(--xh-fg-disabled);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
/* 空态提示是列表之外的一句状态播报(role=status),不进 role=listbox。
|
|
507
|
-
它与 content 是兄弟,因此要自带浮层的那身皮,否则会光秃秃地飘在页面上 */
|
|
458
|
+
/* 空态提示保持为 listbox 的同级 role=status;它只承载文字,表面由同格 content 统一绘制。 */
|
|
508
459
|
[data-scope='combobox'][data-part='empty'] {
|
|
509
|
-
|
|
460
|
+
/* 与带滤镜的 content 同属定位绘制层,按 DOM 顺序将状态文字画在表面之上。 */
|
|
461
|
+
position: relative;
|
|
462
|
+
display: flex;
|
|
463
|
+
align-items: center;
|
|
464
|
+
justify-content: center;
|
|
465
|
+
grid-area: 1 / 1;
|
|
510
466
|
padding-block: var(--xh-combobox-empty-py, var(--xh-space-3));
|
|
511
467
|
padding-inline: var(--xh-combobox-empty-px, var(--xh-control-px-md));
|
|
512
|
-
|
|
513
|
-
border-radius: var(--xh-combobox-empty-radius, var(--xh-shape-surface));
|
|
514
|
-
background: var(--xh-combobox-empty-bg, var(--xh-bg-surface));
|
|
515
|
-
color: var(--xh-combobox-empty-fg, var(--xh-fg-subtle));
|
|
468
|
+
color: var(--xh-combobox-empty-fg, var(--xh-material-frosted-fg-muted));
|
|
516
469
|
font-size: var(--xh-combobox-empty-font-size, var(--xh-_combobox-font-size));
|
|
517
470
|
line-height: var(--xh-leading-none);
|
|
518
|
-
box-shadow: var(--xh-combobox-empty-shadow, var(--xh-elevation-floating));
|
|
519
471
|
text-align: center;
|
|
520
|
-
pointer-events:
|
|
472
|
+
pointer-events: none;
|
|
521
473
|
}
|
|
522
474
|
|
|
523
475
|
/* 漏了这条,候选一有结果空态提示就永远撤不下去(上面那条 display 盖掉了 UA 的 [hidden] 规则) */
|
|
524
476
|
[data-scope='combobox'][data-part='empty'][hidden] {
|
|
525
477
|
display: none;
|
|
526
478
|
}
|
|
479
|
+
|
|
480
|
+
/* 在途占位与空态占同一个表面、两者不同屏;同样只承载状态文字。 */
|
|
481
|
+
[data-scope='combobox'][data-part='loading'] {
|
|
482
|
+
position: relative;
|
|
483
|
+
display: flex;
|
|
484
|
+
align-items: center;
|
|
485
|
+
justify-content: center;
|
|
486
|
+
grid-area: 1 / 1;
|
|
487
|
+
padding-block: var(--xh-combobox-loading-py, var(--xh-space-3));
|
|
488
|
+
padding-inline: var(--xh-combobox-loading-px, var(--xh-control-px-md));
|
|
489
|
+
color: var(--xh-combobox-loading-fg, var(--xh-material-frosted-fg-muted));
|
|
490
|
+
font-size: var(--xh-combobox-loading-font-size, var(--xh-_combobox-font-size));
|
|
491
|
+
line-height: var(--xh-leading-none);
|
|
492
|
+
text-align: center;
|
|
493
|
+
pointer-events: none;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
[data-scope='combobox'][data-part='loading'][hidden] {
|
|
497
|
+
display: none;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/* 自动结构没收到状态文案时,空 status 不生成盒;打开着的空 listbox 也不画无意义表面。
|
|
501
|
+
closed 不命中:有文案的空态刚关闭时,content 仍要作为 Presence 宿主完成退场。 */
|
|
502
|
+
[data-scope='combobox'][data-part='empty']:empty,
|
|
503
|
+
[data-scope='combobox'][data-part='loading']:empty {
|
|
504
|
+
display: none;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
[data-scope='combobox'][data-part='positioner']:not(:has(
|
|
508
|
+
> [data-scope='combobox'][data-part='empty']:not([hidden]):not(:empty),
|
|
509
|
+
> [data-scope='combobox'][data-part='loading']:not([hidden]):not(:empty)
|
|
510
|
+
)) > [data-scope='combobox'][data-part='content'][data-state='open']:empty {
|
|
511
|
+
visibility: hidden;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
@media print {
|
|
515
|
+
/* 打印:定位层与遮罩是交互期才存在的东西,落到纸上只会盖住底下的正文。
|
|
516
|
+
收起写在这份皮肤里而不是 reset:reset 层排在组件层之前,组件层里任何一条 display 都压得住它。 */
|
|
517
|
+
[data-scope='combobox'][data-part='positioner'] {
|
|
518
|
+
display: none;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
527
521
|
}
|