@xihan-ui/styles 1.0.0-alpha.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +2177 -0
  2. package/README.md +1 -1
  3. package/css/accordion.css +80 -6
  4. package/css/alert.css +43 -14
  5. package/css/anchor.css +8 -8
  6. package/css/avatar-group.css +7 -3
  7. package/css/avatar.css +9 -3
  8. package/css/back-top.css +22 -1
  9. package/css/badge.css +104 -32
  10. package/css/breadcrumb.css +25 -5
  11. package/css/button-group.css +18 -13
  12. package/css/button.css +48 -11
  13. package/css/calendar.css +150 -7
  14. package/css/card.css +20 -11
  15. package/css/carousel.css +36 -5
  16. package/css/cascader.css +211 -124
  17. package/css/checkbox-group.css +72 -22
  18. package/css/checkbox.css +70 -13
  19. package/css/clipboard.css +2 -1
  20. package/css/code-block.css +12 -7
  21. package/css/collapsible.css +49 -3
  22. package/css/color-picker.css +132 -46
  23. package/css/combobox.css +132 -60
  24. package/css/composer.css +5 -3
  25. package/css/context-menu.css +113 -74
  26. package/css/date-field.css +93 -16
  27. package/css/date-picker.css +293 -72
  28. package/css/descriptions.css +11 -5
  29. package/css/dialog.css +47 -14
  30. package/css/download-trigger.css +76 -0
  31. package/css/drawer.css +57 -16
  32. package/css/dynamic-input.css +75 -17
  33. package/css/editable.css +12 -10
  34. package/css/ellipsis.css +7 -1
  35. package/css/empty-state.css +22 -12
  36. package/css/field.css +16 -6
  37. package/css/fieldset.css +69 -0
  38. package/css/file-upload.css +46 -8
  39. package/css/flex.css +13 -7
  40. package/css/float-button.css +23 -1
  41. package/css/floating-panel.css +316 -0
  42. package/css/form.css +4 -4
  43. package/css/grid.css +11 -5
  44. package/css/heatmap.css +411 -0
  45. package/css/highlight.css +2 -2
  46. package/css/hotkeys.css +90 -0
  47. package/css/hover-card.css +43 -45
  48. package/css/image-cropper.css +233 -0
  49. package/css/image-viewer.css +155 -17
  50. package/css/image.css +2 -2
  51. package/css/infinite-scroll.css +1 -1
  52. package/css/json-viewer.css +274 -0
  53. package/css/layout.css +19 -15
  54. package/css/list.css +22 -13
  55. package/css/listbox.css +24 -6
  56. package/css/loading-bar.css +12 -5
  57. package/css/log.css +7 -3
  58. package/css/marquee.css +9 -0
  59. package/css/masonry.css +63 -0
  60. package/css/mention.css +100 -36
  61. package/css/menu.css +127 -50
  62. package/css/menubar.css +155 -61
  63. package/css/navigation-menu.css +56 -31
  64. package/css/notification.css +377 -0
  65. package/css/number-animation.css +3 -3
  66. package/css/number-field.css +182 -19
  67. package/css/overlay-arrow.css +51 -0
  68. package/css/page-header.css +12 -5
  69. package/css/pagination.css +171 -14
  70. package/css/password-input.css +356 -0
  71. package/css/pin-input.css +15 -12
  72. package/css/popconfirm.css +55 -12
  73. package/css/popover.css +73 -45
  74. package/css/popselect.css +207 -57
  75. package/css/progress.css +54 -8
  76. package/css/qr-code.css +1 -1
  77. package/css/radio-group.css +27 -10
  78. package/css/rating.css +4 -4
  79. package/css/reset.css +17 -0
  80. package/css/result.css +21 -11
  81. package/css/scroll-area.css +61 -89
  82. package/css/scrollbar.css +170 -0
  83. package/css/segmented.css +215 -0
  84. package/css/select.css +298 -131
  85. package/css/separator.css +2 -2
  86. package/css/side-nav.css +127 -24
  87. package/css/signature-pad.css +144 -0
  88. package/css/skeleton.css +7 -1
  89. package/css/slider.css +14 -12
  90. package/css/space.css +117 -0
  91. package/css/spinner.css +22 -10
  92. package/css/statistic.css +9 -9
  93. package/css/steps.css +29 -12
  94. package/css/switch.css +57 -8
  95. package/css/table.css +146 -44
  96. package/css/tabs.css +13 -5
  97. package/css/tag.css +179 -0
  98. package/css/tags-input.css +80 -42
  99. package/css/text-field.css +151 -38
  100. package/css/thread.css +11 -3
  101. package/css/time-field.css +99 -18
  102. package/css/time-picker.css +261 -71
  103. package/css/timeline.css +15 -15
  104. package/css/timer.css +119 -0
  105. package/css/toast.css +129 -55
  106. package/css/toggle-group.css +30 -4
  107. package/css/toggle.css +12 -6
  108. package/css/tone.css +57 -22
  109. package/css/toolbar.css +1 -1
  110. package/css/tooltip.css +40 -31
  111. package/css/tour.css +112 -61
  112. package/css/transfer.css +98 -21
  113. package/css/tree-select.css +215 -89
  114. package/css/tree.css +131 -5
  115. package/css/typography.css +5 -5
  116. package/css/undefined.css +12 -1
  117. package/css/virtualizer.css +3 -1
  118. package/css/watermark.css +1 -2
  119. package/index.css +18 -1
  120. package/index.unlayered.css +10356 -3255
  121. package/package.json +20 -4
  122. package/css/toaster.css +0 -74
package/css/combobox.css CHANGED
@@ -1,13 +1,26 @@
1
1
  @layer xihan.motion {
2
2
  /* 动画名的查找只认「文档里有没有这个名字」:引用别处文件里的名字,那份文件不一定在场,
3
3
  动画会静默地整个不跑。每份皮肤都能单独引入,所以它用到的关键帧都写在自己身上。 */
4
- @keyframes xh-fade-in {
4
+ @keyframes xh-pop-in {
5
5
  from {
6
6
  opacity: 0;
7
+ scale: var(--xh-motion-scale-enter);
7
8
  }
8
9
 
9
10
  to {
10
11
  opacity: 1;
12
+ scale: 1;
13
+ }
14
+ }
15
+ @keyframes xh-pop-out {
16
+ from {
17
+ opacity: 1;
18
+ scale: 1;
19
+ }
20
+
21
+ to {
22
+ opacity: 0;
23
+ scale: var(--xh-motion-scale-enter);
11
24
  }
12
25
  }
13
26
  }
@@ -18,14 +31,40 @@
18
31
  --xh-combobox-skin: 1;
19
32
  }
20
33
 
21
- [data-scope='combobox'][data-part='root'] {
22
- /* 尺寸档只换这五个私有槽,输入行、标题与候选都从 root 继承它们,
23
- 换档不必给每个部件各写一条选择器。浮层在 positioner 里、也是 root 的后代,一并继承 */
34
+ /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
35
+ [data-scope='combobox'][data-part='positioner'] {
36
+ /* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,内容层继承它限高;
37
+ 引擎没算(尚未落位 / 无引擎)时不额外限高 */
38
+ --xh-_combobox-available-h: 100vh;
39
+
40
+ /* 候选列表的自绘条浮在内容之上:轨道不上底色,实色轨道会在列表右缘糊一条竖灰带 */
41
+ --xh-scrollbar-track-bg: transparent;
42
+
43
+ position: fixed;
44
+ z-index: var(--xh-combobox-layer, var(--xh-layer-popover));
45
+ /* 空壳不吃指针,交互只发生在 content 与 empty 上 */
46
+ pointer-events: none;
47
+ }
48
+
49
+ /* 锚点被滚出可视区:整个浮层随之收起 */
50
+ [data-scope='combobox'][data-part='positioner'][data-hidden] {
51
+ visibility: hidden;
52
+ }
53
+
54
+ /* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
55
+ [data-scope='combobox']:is([data-part='root'], [data-part='positioner']) {
56
+ /* 尺寸档只换这五个私有槽,输入行、标题与候选都从这两处继承它们,
57
+ 换档不必给每个部件各写一条选择器 */
24
58
  --xh-_combobox-h: var(--xh-control-h-md);
25
59
  --xh-_combobox-px: var(--xh-control-px-md);
60
+ --xh-_combobox-item-py: var(--xh-list-option-py-md);
61
+ --xh-_combobox-item-px: var(--xh-control-px-md);
26
62
  --xh-_combobox-gap: var(--xh-control-gap-md);
27
- --xh-_combobox-font-size: var(--xh-text-body-size);
28
- --xh-_combobox-label-font-size: var(--xh-text-label-size);
63
+ --xh-_combobox-font-size: var(--xh-control-font-md);
64
+ --xh-_combobox-label-font-size: var(--xh-control-font-md);
65
+
66
+ /* 作者塞进指示符槽的图标跟着控件的尺寸档走;它自己写了 size 时仍以作者的为准 */
67
+ --xh-icon-size: var(--xh-combobox-icon-size, var(--xh-glyph-size-md));
29
68
 
30
69
  /* 形态档只换这三个槽:缺省即 outline(描边 + 画布底) */
31
70
  --xh-_combobox-control-bg: var(--xh-bg-canvas);
@@ -35,12 +74,14 @@
35
74
  /* 聚焦环恒用固定环色;强调色随语气走,只落在勾选标记与选中文字上,正文文字色不动。
36
75
  没写 data-tone 时 --xh-_tone 没被声明,两处都退回原来的取值 */
37
76
  --xh-_combobox-ring: var(--xh-ring-focus);
38
- --xh-_combobox-accent: var(--xh-_tone, var(--xh-bg-brand));
77
+ --xh-_combobox-accent: var(--xh-_tone, var(--xh-fg-brand));
39
78
  --xh-_combobox-item-selected-fg: var(--xh-_tone-fg, var(--xh-fg-brand-strong));
79
+ }
40
80
 
81
+ [data-scope='combobox'][data-part='root'] {
41
82
  display: inline-flex;
42
83
  flex-direction: column;
43
- gap: var(--xh-combobox-gap, var(--xh-stack-gap-md));
84
+ gap: var(--xh-combobox-gap, var(--xh-space-1));
44
85
  }
45
86
 
46
87
  /* 只要声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
@@ -50,46 +91,55 @@
50
91
 
51
92
  /* —— 尺寸 —— */
52
93
  /* 缺省档写在上面的基础规则里 */
53
- [data-scope='combobox'][data-part='root'][data-size='sm'] {
94
+ [data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
54
95
  --xh-_combobox-h: var(--xh-control-h-sm);
55
96
  --xh-_combobox-px: var(--xh-control-px-sm);
97
+ --xh-_combobox-item-py: var(--xh-list-option-py-sm);
98
+ --xh-_combobox-item-px: var(--xh-control-px-sm);
56
99
  --xh-_combobox-gap: var(--xh-control-gap-sm);
57
- --xh-_combobox-font-size: var(--xh-font-size-sm);
58
- --xh-_combobox-label-font-size: var(--xh-font-size-sm);
100
+ --xh-_combobox-font-size: var(--xh-control-font-sm);
101
+ --xh-_combobox-label-font-size: var(--xh-control-font-sm);
102
+
103
+ --xh-icon-size: var(--xh-combobox-icon-size, var(--xh-glyph-size-sm));
59
104
  }
60
105
 
61
- [data-scope='combobox'][data-part='root'][data-size='lg'] {
106
+ [data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
62
107
  --xh-_combobox-h: var(--xh-control-h-lg);
63
108
  --xh-_combobox-px: var(--xh-control-px-lg);
109
+ --xh-_combobox-item-py: var(--xh-list-option-py-lg);
110
+ --xh-_combobox-item-px: var(--xh-control-px-lg);
64
111
  --xh-_combobox-gap: var(--xh-control-gap-lg);
65
- --xh-_combobox-font-size: var(--xh-font-size-lg);
66
- --xh-_combobox-label-font-size: var(--xh-font-size-lg);
112
+ --xh-_combobox-font-size: var(--xh-control-font-lg);
113
+ --xh-_combobox-label-font-size: var(--xh-control-font-lg);
114
+
115
+ --xh-icon-size: var(--xh-combobox-icon-size, var(--xh-glyph-size-lg));
67
116
  }
68
117
 
69
118
  /* —— 形态 —— */
70
119
  /* 输入类不做 solid:实心底压着可编辑的文字,读起来像块不可点的色板。
71
120
  形态只决定描边与底色怎么用,用哪族颜色由 data-tone 决定 */
72
- [data-scope='combobox'][data-part='root'][data-variant='outline'] {
121
+ [data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-variant='outline'] {
73
122
  --xh-_combobox-control-bg: var(--xh-bg-canvas);
74
123
  --xh-_combobox-control-border: var(--xh-border-control);
75
124
  --xh-_combobox-control-border-hover: var(--xh-border-control-hover);
76
125
  }
77
126
 
78
127
  /* 填充式:底色顶替描边,悬停时才浮出一道淡边 */
79
- [data-scope='combobox'][data-part='root'][data-variant='subtle'] {
128
+ [data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-variant='subtle'] {
80
129
  --xh-_combobox-control-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
81
130
  --xh-_combobox-control-border: transparent;
82
131
  --xh-_combobox-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
83
132
  }
84
133
 
85
- [data-scope='combobox'][data-part='root'][data-variant='ghost'] {
134
+ /* 无框:底与常态描边透明,悬停与聚焦浮出描边 */
135
+ [data-scope='combobox']:is([data-part='root'], [data-part='positioner'])[data-variant='ghost'] {
86
136
  --xh-_combobox-control-bg: transparent;
87
137
  --xh-_combobox-control-border: transparent;
88
138
  --xh-_combobox-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
89
139
  }
90
140
 
91
141
  [data-scope='combobox'][data-part='label'] {
92
- color: var(--xh-combobox-label-fg, var(--xh-fg-muted));
142
+ color: var(--xh-combobox-label-fg, var(--xh-fg-default));
93
143
  font-size: var(--xh-combobox-label-font-size, var(--xh-_combobox-label-font-size));
94
144
  font-weight: var(--xh-combobox-label-font-weight, var(--xh-text-label-weight));
95
145
  line-height: var(--xh-leading-none);
@@ -105,7 +155,7 @@
105
155
  display: inline-flex;
106
156
  align-items: center;
107
157
  gap: var(--xh-combobox-control-gap, var(--xh-_combobox-gap));
108
- min-inline-size: var(--xh-combobox-control-min-w, var(--xh-overlay-min-w));
158
+ min-inline-size: var(--xh-combobox-control-min-w, var(--xh-control-min-w));
109
159
  block-size: var(--xh-combobox-control-h, var(--xh-_combobox-h));
110
160
  padding-inline: var(--xh-combobox-control-px, var(--xh-_combobox-px));
111
161
  border: var(--xh-stroke-thin) solid var(--xh-combobox-control-border, var(--xh-_combobox-control-border));
@@ -127,14 +177,17 @@
127
177
  /* 焦点环画在 control 上而不是 input 上:视觉上的「框」是 control,
128
178
  环若长在里面那个透明的 input 身上,就会缩在文字区里、与框错开一圈。
129
179
  input 是这里唯一可聚焦的常规节点,:focus-within 与它的 :focus-visible 等价 */
130
- [data-scope='combobox'][data-part='control']:focus-within {
131
- border-color: var(--xh-combobox-control-border-focus, var(--xh-_combobox-ring));
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)));
132
182
  outline: var(--xh-ring-width) solid var(--xh-_combobox-ring);
133
183
  outline-offset: var(--xh-ring-offset);
134
184
  }
135
185
 
136
186
  [data-scope='combobox'][data-part='control'][data-invalid] {
137
- border-color: var(--xh-combobox-control-border-invalid, var(--xh-color-danger-500));
187
+ border-color: var(--xh-combobox-control-border-invalid, var(--xh-border-invalid));
188
+
189
+ /* 校验失败时环也跟着变红:两圈等宽相邻却一红一蓝,读的人不知道哪个才是当前状态 */
190
+ --xh-_combobox-ring: var(--xh-ring-invalid);
138
191
  }
139
192
 
140
193
  /* 只读仍可聚焦、可复制,所以不置灰,只把底色压下去表示"改不动" */
@@ -173,7 +226,7 @@
173
226
  [data-scope='combobox'][data-part='control']:has([data-part='input'][data-multiline]) {
174
227
  align-items: start;
175
228
  block-size: auto;
176
- padding-block: var(--xh-field-py);
229
+ padding-block: var(--xh-combobox-input-py, var(--xh-field-py));
177
230
  }
178
231
 
179
232
  [data-scope='combobox'][data-part='input'][data-multiline] {
@@ -211,13 +264,14 @@
211
264
  background: var(--xh-combobox-action-bg, transparent);
212
265
  color: var(--xh-combobox-action-fg, var(--xh-fg-muted));
213
266
  font-family: inherit;
214
- font-size: var(--xh-combobox-action-font-size, var(--xh-font-size-sm));
267
+ font-size: var(--xh-combobox-action-font-size, var(--xh-text-secondary-size));
215
268
  line-height: var(--xh-leading-none);
216
269
  cursor: pointer;
217
270
  user-select: none;
218
- transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
271
+ transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter), scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
219
272
  }
220
273
 
274
+
221
275
  [data-scope='combobox'][data-part='trigger'][hidden],
222
276
  [data-scope='combobox'][data-part='clear-trigger'][hidden] {
223
277
  display: none;
@@ -232,12 +286,26 @@
232
286
 
233
287
  /* 没写内容就由皮肤画箭头;作者往部件里塞了自己的图形,这条规则即不命中 */
234
288
  [data-scope='combobox'][data-part='trigger']:empty::before {
235
- content: '';
289
+ content: '';
290
+ display: inline-block;
291
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
292
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
293
+ vertical-align: var(--xh-glyph-baseline-shift);
294
+ background-color: currentColor;
295
+ -webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
296
+ mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
236
297
  }
237
298
 
238
299
  /* 同上:没写内容就由皮肤画叉 */
239
300
  [data-scope='combobox'][data-part='clear-trigger']:empty::before {
240
- content: '';
301
+ content: '';
302
+ display: inline-block;
303
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
304
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
305
+ vertical-align: var(--xh-glyph-baseline-shift);
306
+ background-color: currentColor;
307
+ -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
308
+ mask: var(--xh-glyph-mark-close) center / contain no-repeat;
241
309
  }
242
310
 
243
311
  [data-scope='combobox'][data-part='trigger'][data-state='open']:empty::before,
@@ -254,57 +322,44 @@
254
322
  [data-scope='combobox'][data-part='trigger']:active:not(:disabled),
255
323
  [data-scope='combobox'][data-part='clear-trigger']:active:not(:disabled) {
256
324
  background: var(--xh-combobox-action-bg-active, var(--xh-bg-subtle-active));
325
+ scale: var(--xh-motion-scale-press);
257
326
  }
258
327
 
259
- /* 两个按钮都退出了 Tab 序列(tabindex=-1),正常操作走不到这里;
260
- 留着是给程序化聚焦兜底,落焦时得看得见 */
328
+ /* 两个按钮都在盒里,盒的 :focus-within 已经画了一圈;这里再画一圈就是框里套框 */
261
329
  [data-scope='combobox'][data-part='trigger']:focus-visible,
262
330
  [data-scope='combobox'][data-part='clear-trigger']:focus-visible {
263
- outline: var(--xh-ring-width) solid var(--xh-_combobox-ring);
264
- outline-offset: var(--xh-ring-offset);
331
+ outline: none;
265
332
  }
266
333
 
267
- [data-scope='combobox'][data-part='trigger']:disabled,
268
- [data-scope='combobox'][data-part='clear-trigger']:disabled {
334
+ [data-scope='combobox'][data-part='trigger']:disabled {
269
335
  background: var(--xh-combobox-action-bg, transparent);
270
336
  color: var(--xh-fg-disabled);
271
337
  cursor: not-allowed;
272
338
  }
273
339
 
274
- /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
275
- [data-scope='combobox'][data-part='positioner'] {
276
- position: fixed;
277
- z-index: var(--xh-layer-popover);
278
- /* 空壳不吃指针,交互只发生在 content 与 empty 上 */
279
- pointer-events: none;
280
- }
281
-
282
- /* 锚点被滚出可视区:整个浮层随之收起 */
283
- [data-scope='combobox'][data-part='positioner'][data-hidden] {
284
- visibility: hidden;
285
- }
286
-
287
340
  [data-scope='combobox'][data-part='content'] {
288
341
  display: flex;
289
342
  flex-direction: column;
343
+ gap: var(--xh-combobox-content-gap, var(--xh-list-option-gap));
290
344
  min-inline-size: var(--xh-combobox-content-min-w, var(--xh-overlay-min-w));
291
- max-inline-size: var(--xh-combobox-content-max-w, 24rem);
292
- max-block-size: var(--xh-combobox-content-max-h, var(--xh-overlay-max-h));
345
+ max-inline-size: var(--xh-combobox-content-max-w, var(--xh-overlay-max-w));
346
+ max-block-size: min(var(--xh-combobox-content-max-h, var(--xh-overlay-max-h)), var(--xh-_combobox-available-h));
293
347
  padding-block: var(--xh-combobox-content-py, var(--xh-space-1));
294
348
  padding-inline: var(--xh-combobox-content-px, var(--xh-space-1));
295
349
  border: var(--xh-stroke-thin) solid var(--xh-combobox-content-border, var(--xh-border-default));
296
350
  border-radius: var(--xh-combobox-content-radius, var(--xh-shape-surface));
297
351
  background: var(--xh-combobox-content-bg, var(--xh-bg-surface));
298
352
  color: var(--xh-combobox-content-fg, var(--xh-fg-default));
299
- box-shadow: var(--xh-combobox-content-shadow, var(--xh-elevation-2));
353
+ box-shadow: var(--xh-combobox-content-shadow, var(--xh-elevation-floating));
300
354
  overflow-y: auto;
301
355
  pointer-events: auto;
302
356
  }
303
357
 
304
- /* display 会盖掉 hidden 属性的 UA 规则,收起态显式让位 */
305
- [data-scope='combobox'][data-part='content'][hidden] {
306
- display: none;
307
- }
358
+ /* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
359
+ 收起态连接层会给 contenthidden,而上面那条 display 正是要盖掉 UA 的
360
+ [hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
361
+ 真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
362
+ 其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
308
363
 
309
364
  /* 列表从不承载焦点(焦点恒在输入框,高亮走 aria-activedescendant),
310
365
  可滚动容器在某些浏览器里会被自动塞进 Tab 序列,落焦时不画环 */
@@ -313,12 +368,19 @@
313
368
  }
314
369
 
315
370
  [data-scope='combobox'][data-part='content'][data-state='open'] {
316
- animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
371
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
372
+ }
373
+
374
+ /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
375
+ 免得动画结束到真收起之间闪一下原样 */
376
+ [data-scope='combobox'][data-part='content'][data-state='closed'] {
377
+ animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
317
378
  }
318
379
 
319
380
  [data-scope='combobox'][data-part='item-group'] {
320
381
  display: flex;
321
382
  flex-direction: column;
383
+ gap: var(--xh-combobox-item-group-gap, var(--xh-list-option-gap));
322
384
  }
323
385
 
324
386
  [data-scope='combobox'][data-part='item-group'][hidden] {
@@ -327,7 +389,7 @@
327
389
 
328
390
  /* 组间留白只加在后继分组上:首组顶上已经有 content 的内边距,再加一层会显得头重 */
329
391
  [data-scope='combobox'][data-part='item-group'] + [data-scope='combobox'][data-part='item-group'] {
330
- margin-block-start: var(--xh-combobox-group-gap, var(--xh-space-2));
392
+ margin-block-start: var(--xh-combobox-group-gap, var(--xh-space-1_5));
331
393
  }
332
394
 
333
395
  /* 分组标题不是候选、进不了导航,画成小号次要文字,内缩与候选对齐(同一个 padding-inline) */
@@ -336,7 +398,7 @@
336
398
  padding-block: var(--xh-combobox-group-label-py, var(--xh-space-1));
337
399
  padding-inline: var(--xh-combobox-group-label-px, var(--xh-control-px-md));
338
400
  color: var(--xh-combobox-group-label-fg, var(--xh-fg-subtle));
339
- font-size: var(--xh-combobox-group-label-font-size, var(--xh-font-size-xs));
401
+ font-size: var(--xh-combobox-group-label-font-size, var(--xh-text-caption-size));
340
402
  font-weight: var(--xh-combobox-group-label-font-weight, var(--xh-font-weight-medium));
341
403
  line-height: var(--xh-leading-none);
342
404
  user-select: none;
@@ -350,8 +412,8 @@
350
412
  display: flex;
351
413
  align-items: center;
352
414
  gap: var(--xh-combobox-item-gap, var(--xh-_combobox-gap));
353
- padding-block: var(--xh-combobox-item-py, var(--xh-space-1_5));
354
- padding-inline: var(--xh-combobox-item-px, var(--xh-control-px-md));
415
+ padding-block: var(--xh-combobox-item-py, var(--xh-_combobox-item-py));
416
+ padding-inline: var(--xh-combobox-item-px, var(--xh-_combobox-item-px));
355
417
  border-radius: var(--xh-combobox-item-radius, var(--xh-shape-control));
356
418
  color: var(--xh-combobox-item-fg, var(--xh-fg-default));
357
419
  font-size: var(--xh-combobox-item-font-size, var(--xh-_combobox-font-size));
@@ -374,6 +436,9 @@
374
436
  两套底色各画各的会出现"鼠标停在 A 上、回车提交的却是 B" */
375
437
  [data-scope='combobox'][data-part='item'][data-highlighted]:not([data-disabled]) {
376
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));
377
442
  }
378
443
 
379
444
  /* 选中只换文字色与字重,配合行尾的 ✓ 标记;底色整条通道留给高亮,
@@ -420,7 +485,14 @@
420
485
 
421
486
  /* 同上:没写内容就由皮肤画勾 */
422
487
  [data-scope='combobox'][data-part='item-indicator']:empty::before {
423
- content: '';
488
+ content: '';
489
+ display: inline-block;
490
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
491
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
492
+ vertical-align: var(--xh-glyph-baseline-shift);
493
+ background-color: currentColor;
494
+ -webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
495
+ mask: var(--xh-glyph-mark-check) center / contain no-repeat;
424
496
  }
425
497
 
426
498
  [data-scope='combobox'][data-part='item-indicator'][data-state='checked'] {
@@ -443,7 +515,7 @@
443
515
  color: var(--xh-combobox-empty-fg, var(--xh-fg-subtle));
444
516
  font-size: var(--xh-combobox-empty-font-size, var(--xh-_combobox-font-size));
445
517
  line-height: var(--xh-leading-none);
446
- box-shadow: var(--xh-combobox-empty-shadow, var(--xh-elevation-2));
518
+ box-shadow: var(--xh-combobox-empty-shadow, var(--xh-elevation-floating));
447
519
  text-align: center;
448
520
  pointer-events: auto;
449
521
  }
package/css/composer.css CHANGED
@@ -12,7 +12,8 @@
12
12
  display: flex;
13
13
  align-items: flex-end;
14
14
  gap: var(--xh-composer-gap, var(--xh-control-gap-md));
15
- padding: var(--xh-composer-p, var(--xh-space-2));
15
+ /* 整框的内衬走控件内边距尺的小档,密度收紧时随之收窄 */
16
+ padding: var(--xh-composer-p, var(--xh-control-px-sm));
16
17
  border: var(--xh-stroke-thin) solid var(--xh-composer-border, var(--xh-border-control));
17
18
  border-radius: var(--xh-composer-radius, var(--xh-shape-surface));
18
19
  background: var(--xh-composer-bg, var(--xh-bg-surface));
@@ -25,14 +26,15 @@
25
26
 
26
27
  /* 焦点环画在整个框上;用 focus-within 使焦点落在发送按钮时同样点亮 */
27
28
  [data-scope='composer'][data-part='root']:focus-within {
29
+ border-color: var(--xh-composer-root-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
28
30
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
29
31
  outline-offset: var(--xh-ring-offset);
30
32
  }
31
33
 
32
- /* 禁用态罩住整框,内部 textarea 与按钮另有原生 disabled 管交互 */
34
+ /* 禁用态只换光标与底色;文字由 textarea 与按钮各自走 fg-disabled,整框不再压 opacity,两者叠起来会压到读不出 */
33
35
  [data-scope='composer'][data-part='root'][data-disabled] {
34
36
  cursor: not-allowed;
35
- opacity: var(--xh-state-disabled-opacity);
37
+ background: var(--xh-composer-bg-disabled, var(--xh-bg-subtle));
36
38
  }
37
39
 
38
40
  /* 无边框透明底,融进 root 的框里;min-inline-size: 0 防止长内容把弹性子项撑出容器 */