@xihan-ui/styles 3.1.0 → 4.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 (290) hide show
  1. package/CHANGELOG.md +470 -0
  2. package/component-tokens.d.ts +230 -60
  3. package/components.tokens.json +5156 -1557
  4. package/css/accordion.css +47 -20
  5. package/css/alert.css +16 -17
  6. package/css/anchor.css +2 -2
  7. package/css/approval.css +41 -17
  8. package/css/avatar-group.css +9 -12
  9. package/css/avatar.css +20 -18
  10. package/css/back-top.css +21 -7
  11. package/css/badge.css +5 -5
  12. package/css/breadcrumb.css +18 -16
  13. package/css/button-group.css +4 -6
  14. package/css/button.css +13 -12
  15. package/css/calendar-picker.css +178 -95
  16. package/css/calendar-range-picker.css +207 -122
  17. package/css/card.css +34 -6
  18. package/css/carousel.css +94 -46
  19. package/css/cartesian-chart.css +11 -11
  20. package/css/cascader.css +51 -39
  21. package/css/checkbox-group.css +9 -6
  22. package/css/checkbox.css +5 -4
  23. package/css/citation.css +9 -4
  24. package/css/clipboard.css +20 -4
  25. package/css/code-view.css +6 -6
  26. package/css/collapsible.css +29 -14
  27. package/css/color-field.css +4 -4
  28. package/css/color-picker.css +77 -23
  29. package/css/color-slider.css +10 -8
  30. package/css/color-swatch-picker.css +14 -9
  31. package/css/combobox.css +26 -14
  32. package/css/command.css +14 -9
  33. package/css/context-menu.css +10 -5
  34. package/css/date-field.css +12 -6
  35. package/css/date-picker.css +178 -109
  36. package/css/date-range-picker.css +199 -130
  37. package/css/description.css +10 -6
  38. package/css/descriptions.css +47 -19
  39. package/css/dialog.css +50 -35
  40. package/css/diff-view.css +8 -8
  41. package/css/drawer.css +75 -21
  42. package/css/editable.css +15 -41
  43. package/css/empty-state.css +21 -3
  44. package/css/field-array.css +5 -2
  45. package/css/field.css +17 -18
  46. package/css/fieldset.css +33 -13
  47. package/css/file-upload.css +66 -33
  48. package/css/float-button.css +60 -35
  49. package/css/floating-panel.css +1 -1
  50. package/css/form.css +30 -16
  51. package/css/graph-chart.css +2 -2
  52. package/css/grid-list.css +1 -1
  53. package/css/highlight.css +5 -5
  54. package/css/hover-card.css +19 -12
  55. package/css/image-viewer.css +77 -27
  56. package/css/image.css +13 -5
  57. package/css/infinite-scroll.css +8 -4
  58. package/css/input-group.css +74 -26
  59. package/css/kbd.css +1 -1
  60. package/css/label.css +27 -11
  61. package/css/layout.css +17 -10
  62. package/css/list.css +13 -9
  63. package/css/listbox.css +12 -7
  64. package/css/loading-bar.css +3 -0
  65. package/css/mention.css +11 -9
  66. package/css/menu.css +10 -5
  67. package/css/menubar.css +13 -8
  68. package/css/message-feed.css +1 -1
  69. package/css/navigation-menu.css +2 -2
  70. package/css/notification.css +132 -49
  71. package/css/number-animation.css +2 -2
  72. package/css/number-field.css +75 -52
  73. package/css/page-header.css +64 -27
  74. package/css/pagination.css +35 -38
  75. package/css/password-input.css +12 -68
  76. package/css/pin-input.css +18 -26
  77. package/css/popconfirm.css +23 -14
  78. package/css/popover.css +18 -12
  79. package/css/progress.css +14 -13
  80. package/css/prompt-input.css +3 -3
  81. package/css/question-flow.css +41 -15
  82. package/css/radar-chart.css +6 -6
  83. package/css/radio-group.css +120 -55
  84. package/css/rating.css +32 -15
  85. package/css/select.css +16 -12
  86. package/css/separator.css +24 -6
  87. package/css/side-nav.css +29 -24
  88. package/css/signature-pad.css +23 -9
  89. package/css/skeleton.css +12 -12
  90. package/css/slider.css +77 -48
  91. package/css/sortable.css +2 -2
  92. package/css/sparkline.css +8 -2
  93. package/css/spinner.css +40 -20
  94. package/css/statistic.css +14 -14
  95. package/css/steps.css +115 -84
  96. package/css/switch.css +9 -7
  97. package/css/table.css +29 -12
  98. package/css/tabs.css +35 -12
  99. package/css/tag-group.css +17 -6
  100. package/css/tag.css +54 -29
  101. package/css/tags-input.css +39 -20
  102. package/css/text-field.css +5 -5
  103. package/css/time-field.css +4 -4
  104. package/css/time-picker.css +150 -64
  105. package/css/time-range-picker.css +91 -62
  106. package/css/timeline.css +37 -20
  107. package/css/timer.css +3 -3
  108. package/css/toggle-group.css +4 -4
  109. package/css/tool-call.css +13 -11
  110. package/css/toolbar.css +6 -5
  111. package/css/tooltip.css +16 -17
  112. package/css/tour.css +14 -7
  113. package/css/transfer.css +22 -16
  114. package/css/tree-select.css +12 -12
  115. package/css/tree.css +26 -25
  116. package/css/typography.css +28 -25
  117. package/dist/css/accordion.css +296 -0
  118. package/dist/css/affix.css +47 -0
  119. package/dist/css/alert.css +246 -0
  120. package/dist/css/anchor.css +252 -0
  121. package/dist/css/approval.css +525 -0
  122. package/dist/css/avatar-group.css +96 -0
  123. package/dist/css/avatar.css +100 -0
  124. package/dist/css/back-top.css +175 -0
  125. package/dist/css/badge.css +205 -0
  126. package/dist/css/bar-code.css +62 -0
  127. package/dist/css/breadcrumb.css +232 -0
  128. package/dist/css/button-group.css +261 -0
  129. package/dist/css/button.css +216 -0
  130. package/dist/css/calendar-picker.css +550 -0
  131. package/dist/css/calendar-range-picker.css +639 -0
  132. package/dist/css/card.css +249 -0
  133. package/dist/css/carousel.css +726 -0
  134. package/dist/css/cartesian-chart.css +830 -0
  135. package/dist/css/cascader.css +973 -0
  136. package/dist/css/checkbox-group.css +361 -0
  137. package/dist/css/checkbox.css +258 -0
  138. package/dist/css/citation.css +475 -0
  139. package/dist/css/clipboard.css +331 -0
  140. package/dist/css/code-view.css +374 -0
  141. package/dist/css/collapsible.css +200 -0
  142. package/dist/css/color-field.css +176 -0
  143. package/dist/css/color-picker.css +649 -0
  144. package/dist/css/color-slider.css +283 -0
  145. package/dist/css/color-swatch-picker.css +250 -0
  146. package/dist/css/color-swatch.css +35 -0
  147. package/dist/css/combobox.css +578 -0
  148. package/dist/css/command.css +404 -0
  149. package/dist/css/context-menu.css +425 -0
  150. package/dist/css/date-field.css +317 -0
  151. package/dist/css/date-picker.css +931 -0
  152. package/dist/css/date-range-picker.css +949 -0
  153. package/dist/css/description.css +71 -0
  154. package/dist/css/descriptions.css +327 -0
  155. package/dist/css/dialog.css +470 -0
  156. package/dist/css/diff-view.css +513 -0
  157. package/dist/css/download-trigger.css +151 -0
  158. package/dist/css/drawer.css +606 -0
  159. package/dist/css/editable.css +269 -0
  160. package/dist/css/empty-state.css +181 -0
  161. package/dist/css/field-array.css +229 -0
  162. package/dist/css/field.css +165 -0
  163. package/dist/css/fieldset.css +122 -0
  164. package/dist/css/file-upload.css +462 -0
  165. package/dist/css/flex.css +441 -0
  166. package/dist/css/float-button.css +579 -0
  167. package/dist/css/floating-panel.css +429 -0
  168. package/dist/css/focus.css +46 -0
  169. package/dist/css/forced-colors.css +93 -0
  170. package/dist/css/form.css +407 -0
  171. package/dist/css/funnel-chart.css +106 -0
  172. package/dist/css/graph-chart.css +205 -0
  173. package/dist/css/grid-list.css +235 -0
  174. package/dist/css/grid.css +1201 -0
  175. package/dist/css/heatmap.css +552 -0
  176. package/dist/css/hierarchy-chart.css +298 -0
  177. package/dist/css/highlight.css +41 -0
  178. package/dist/css/hover-card.css +233 -0
  179. package/dist/css/icon.css +225 -0
  180. package/dist/css/image-cropper.css +373 -0
  181. package/dist/css/image-viewer.css +588 -0
  182. package/dist/css/image.css +106 -0
  183. package/dist/css/infinite-scroll.css +81 -0
  184. package/dist/css/input-group.css +323 -0
  185. package/dist/css/json-viewer.css +379 -0
  186. package/dist/css/kbd.css +72 -0
  187. package/dist/css/label.css +94 -0
  188. package/dist/css/layers.css +7 -0
  189. package/dist/css/layout.css +379 -0
  190. package/dist/css/liquid.css +106 -0
  191. package/dist/css/list.css +156 -0
  192. package/dist/css/listbox.css +395 -0
  193. package/dist/css/loading-bar.css +144 -0
  194. package/dist/css/log.css +306 -0
  195. package/dist/css/markdown-stream.css +149 -0
  196. package/dist/css/marquee.css +378 -0
  197. package/dist/css/masonry.css +70 -0
  198. package/dist/css/matrix-code.css +67 -0
  199. package/dist/css/mention.css +395 -0
  200. package/dist/css/menu.css +369 -0
  201. package/dist/css/menubar.css +461 -0
  202. package/dist/css/message-feed.css +318 -0
  203. package/dist/css/navigation-menu.css +513 -0
  204. package/dist/css/notification.css +865 -0
  205. package/dist/css/number-animation.css +44 -0
  206. package/dist/css/number-field.css +275 -0
  207. package/dist/css/overlay-arrow.css +56 -0
  208. package/dist/css/page-header.css +221 -0
  209. package/dist/css/pagination.css +447 -0
  210. package/dist/css/password-input.css +335 -0
  211. package/dist/css/pie-chart.css +247 -0
  212. package/dist/css/pin-input.css +191 -0
  213. package/dist/css/pointer.css +36 -0
  214. package/dist/css/popconfirm.css +329 -0
  215. package/dist/css/popover.css +285 -0
  216. package/dist/css/progress.css +502 -0
  217. package/dist/css/prompt-input.css +260 -0
  218. package/dist/css/question-flow.css +579 -0
  219. package/dist/css/radar-chart.css +233 -0
  220. package/dist/css/radio-group.css +663 -0
  221. package/dist/css/rating.css +311 -0
  222. package/dist/css/reasoning.css +343 -0
  223. package/dist/css/reset.css +117 -0
  224. package/dist/css/resizable.css +242 -0
  225. package/dist/css/sankey-chart.css +174 -0
  226. package/dist/css/scroll-area.css +240 -0
  227. package/dist/css/scrollbar.css +204 -0
  228. package/dist/css/select.css +616 -0
  229. package/dist/css/separator.css +140 -0
  230. package/dist/css/side-nav.css +481 -0
  231. package/dist/css/signature-pad.css +193 -0
  232. package/dist/css/skeleton.css +161 -0
  233. package/dist/css/slider.css +403 -0
  234. package/dist/css/sortable.css +228 -0
  235. package/dist/css/sparkline.css +170 -0
  236. package/dist/css/spinner.css +256 -0
  237. package/dist/css/splitter.css +159 -0
  238. package/dist/css/statistic.css +137 -0
  239. package/dist/css/steps.css +658 -0
  240. package/dist/css/switch.css +353 -0
  241. package/dist/css/table.css +1162 -0
  242. package/dist/css/tabs.css +967 -0
  243. package/dist/css/tag-group.css +258 -0
  244. package/dist/css/tag.css +335 -0
  245. package/dist/css/tags-input.css +341 -0
  246. package/dist/css/text-field.css +197 -0
  247. package/dist/css/time-field.css +277 -0
  248. package/dist/css/time-picker.css +793 -0
  249. package/dist/css/time-range-picker.css +775 -0
  250. package/dist/css/timeline.css +440 -0
  251. package/dist/css/timer.css +123 -0
  252. package/dist/css/timestamp.css +34 -0
  253. package/dist/css/toggle-group.css +424 -0
  254. package/dist/css/toggle.css +146 -0
  255. package/dist/css/tone.css +189 -0
  256. package/dist/css/tool-call.css +431 -0
  257. package/dist/css/toolbar.css +366 -0
  258. package/dist/css/tooltip.css +217 -0
  259. package/dist/css/tour.css +446 -0
  260. package/dist/css/transfer.css +644 -0
  261. package/dist/css/tree-select.css +878 -0
  262. package/dist/css/tree.css +734 -0
  263. package/dist/css/truncate.css +108 -0
  264. package/dist/css/typography.css +475 -0
  265. package/dist/css/undefined.css +58 -0
  266. package/dist/css/virtualizer.css +166 -0
  267. package/dist/css/visually-hidden.css +20 -0
  268. package/dist/css/watermark.css +82 -0
  269. package/dist/family/action-control.css +493 -0
  270. package/dist/family/chart.css +537 -0
  271. package/dist/family/check-mark.css +94 -0
  272. package/dist/family/choice-card.css +97 -0
  273. package/dist/family/collection-item.css +768 -0
  274. package/dist/family/field-chrome.css +296 -0
  275. package/dist/family/loading-ring.css +102 -0
  276. package/dist/family/material.css +72 -0
  277. package/dist/family/menu-choice.css +56 -0
  278. package/dist/family/motion.css +363 -0
  279. package/dist/family/swatch.css +59 -0
  280. package/dist/family/tag-list.css +65 -0
  281. package/family/action-control.css +33 -36
  282. package/family/chart.css +57 -0
  283. package/family/collection-item.css +12 -8
  284. package/family/field-chrome.css +28 -19
  285. package/family/loading-ring.css +20 -13
  286. package/family/swatch.css +4 -4
  287. package/family/tag-list.css +6 -0
  288. package/index.css +10349 -8756
  289. package/index.unlayered.css +10350 -8758
  290. package/package.json +165 -164
@@ -118,13 +118,16 @@
118
118
  --xh-action-host-bg-pressed: var(--xh-_radio-group-host-bg-pressed);
119
119
 
120
120
  position: relative;
121
- /* row 档铺满容器(inline-size: 100%)会把竖排的命中区拉到整行空白处、横排 wrap 也塌:
122
- 沿用「条目按内容收宽」的既有决定,写法同 checkbox-group 条目 */
123
- inline-size: auto;
124
121
  /* ghost 的 1px 透明边位会把圆圈列相对组标题错开 1px:边归零,几何保持不变 */
125
122
  border-width: 0;
126
123
  }
127
124
 
125
+ /* 条目按内容收宽,盖掉 row 档的 inline-size: 100%(横排时每个条目会独占一行)。
126
+ 从根往下写,特指度高过 row 档,有层与无层两份产物里都生效 */
127
+ [data-scope='radio-group'][data-part='root'] [data-scope='radio-group'][data-part='item'] {
128
+ inline-size: auto;
129
+ }
130
+
128
131
  /* 只读整组都改不动,但不是禁用:颜色照常,把整行的悬停 / 按下面与"可点"这个暗示一起收回来。
129
132
  家族的 :hover / 按压块不排 readonly,只能从槽上收回;排掉禁用项是因为这条选择器权重高过家族的禁用块,
130
133
  不排就会把 not-allowed 覆盖回 default */
@@ -137,7 +140,7 @@
137
140
  --xh-action-cursor-focus-visible: default;
138
141
  }
139
142
 
140
- /* 圆圈是字段家族的控制盒(字段静息形态):透明底 + --xh-border-control 描边 + 无影。
143
+ /* 圆圈是控件盒:透明底 + --xh-border-strong 描边(与 Checkbox 方框同一重量)+ 无影。
141
144
  不缩放(行级只换面),过渡只有底与描边;按下走 press 时间线、释放同走 micro */
142
145
  [data-scope='radio-group'][data-part='indicator'] {
143
146
  display: inline-flex;
@@ -146,7 +149,7 @@
146
149
  justify-content: center;
147
150
  inline-size: var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator));
148
151
  block-size: var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator));
149
- border: var(--xh-stroke-thin) solid var(--xh-radio-group-indicator-border, var(--xh-border-control));
152
+ border: var(--xh-stroke-thin) solid var(--xh-radio-group-indicator-border, var(--xh-border-strong));
150
153
  border-radius: var(--xh-radio-group-indicator-radius, var(--xh-shape-circle));
151
154
  background: var(--xh-radio-group-indicator-bg, transparent);
152
155
  transition:
@@ -290,27 +293,31 @@
290
293
  }
291
294
 
292
295
  /* —— segmented 形态 ——
293
- 一条淡底轨道装着首尾相接的若干段,选中段由 thumb 部件标出:一块白色抬起的滑块,换段时滑过去。
296
+ 一条轨道装着首尾相接的若干段,选中段由 thumb 部件标出:一块品牌淡底的滑块,换段时滑过去。
294
297
  轨道就是 root:滑块绝对定位于它,段与段之间不留缝,所以 gap 归零。
295
- 轨道是一块淡底面:--xh-bg-subtle 底 + 同宽透明占位边 + 无影,边界由滑块的描边与轨道底色的落差承担。
298
+ 轨道与字段外壳同款:最浅一档淡底(--xh-bg-field)+ 1px 字段描边(--xh-border-control)+ control 圆角,
299
+ 内衬 2px,加上描边段离外沿 3px。
296
300
  一行排不下就折行:每个选项都必须看得见、点得到;不改成横向滚动是因为段离轨道内沿只有一格衬距,
297
301
  轨道一旦成为滚动容器,段的焦点环(画在段外侧 2px 处)会被裁掉 */
298
302
  [data-scope='radio-group'][data-part='root'][data-variant='segmented'] {
299
- /* 滑块(有滑块开关的白色抬起面)的底与选中段的文字色;没写 data-tone 时就是这里的取值 */
300
- --xh-_radio-group-thumb-bg: var(--xh-bg-surface-raised);
301
- --xh-_radio-group-segment-fg-checked: var(--xh-fg-default);
302
- /* 轨道是淡底承载面:段坐在它上面,悬停 200 → 按下 300,host 槽向内下发同一副阶梯 */
303
- --xh-action-host-bg-hover: var(--xh-bg-subtle-hover);
304
- --xh-action-host-bg-pressed: var(--xh-bg-subtle-active);
303
+ /* 滑块(选中段的品牌淡底)静息 / 悬停 / 禁用三档与选中段的文字色;没写 data-tone 时就是这里的取值 */
304
+ --xh-_radio-group-thumb-bg: var(--xh-bg-segment-selected);
305
+ --xh-_radio-group-thumb-bg-hover: var(--xh-bg-segment-selected-hover);
306
+ --xh-_radio-group-thumb-bg-disabled: var(--xh-bg-segment-selected-disabled);
307
+ --xh-_radio-group-segment-fg-checked: var(--xh-fg-segment-selected);
308
+ --xh-_radio-group-segment-fg-checked-disabled: var(--xh-fg-segment-selected-disabled);
309
+ /* 轨道底是最浅一档淡底,按白底承载:段悬停 100 → 按下 200,host 槽向内下发同一副阶梯 */
310
+ --xh-action-host-bg-hover: var(--xh-bg-subtle);
311
+ --xh-action-host-bg-pressed: var(--xh-bg-subtle-hover);
305
312
 
306
313
  position: relative;
307
314
  display: inline-flex;
308
315
  flex-wrap: wrap;
309
316
  gap: 0;
310
317
  padding: var(--xh-radio-group-track-padding, var(--xh-space-0_5));
311
- border: var(--xh-stroke-thin) solid var(--xh-radio-group-track-border, transparent);
312
- border-radius: var(--xh-radio-group-track-radius, var(--xh-shape-surface));
313
- background: var(--xh-radio-group-track-bg, var(--xh-bg-subtle));
318
+ border: var(--xh-stroke-thin) solid var(--xh-radio-group-track-border, var(--xh-border-control));
319
+ border-radius: var(--xh-radio-group-track-radius, var(--xh-shape-control));
320
+ background: var(--xh-radio-group-track-bg, var(--xh-bg-field));
314
321
  font-size: var(--xh-radio-group-item-font-size, var(--xh-_radio-group-font-size));
315
322
  }
316
323
 
@@ -366,10 +373,21 @@
366
373
  }
367
374
 
368
375
  /* 语气:选择器带 [data-tone] 限定,不限定的话放在语气容器里的分段会跟着改色。
369
- 语气档的滑块是实心语气面,选中段的字取语气面上的前景 */
376
+ 语气档的滑块换语气淡底(静息 / 悬停 / 禁用三档),选中段的字取语气字色;禁用的选中段与品牌档同口径——
377
+ 滑块退到 8%、字往承载面兑一半,不回落到品牌色 */
370
378
  [data-scope='radio-group'][data-part='root'][data-variant='segmented'][data-tone] {
371
- --xh-_radio-group-thumb-bg: var(--xh-_tone, var(--xh-bg-surface-raised));
372
- --xh-_radio-group-segment-fg-checked: var(--xh-_tone-on, var(--xh-fg-default));
379
+ --xh-_radio-group-thumb-bg: var(--xh-_tone-subtle, var(--xh-bg-segment-selected));
380
+ --xh-_radio-group-thumb-bg-hover: var(--xh-_tone-subtle-hover, var(--xh-bg-segment-selected-hover));
381
+ --xh-_radio-group-thumb-bg-disabled: color-mix(in oklab, var(--xh-_tone) 8%, var(--xh-bg-surface));
382
+ --xh-_radio-group-segment-fg-checked: var(--xh-_tone-fg, var(--xh-fg-segment-selected));
383
+ --xh-_radio-group-segment-fg-checked-disabled: color-mix(in oklab, var(--xh-_tone-fg) 50%, var(--xh-bg-surface));
384
+ }
385
+
386
+ /* 深色档与品牌档同口径:选中面提到 20%、悬停 28%,深底上 12% 读不出是一块选中面。
387
+ 语气淡底三档是语气层按固定比例兑的、不随主题换,这里按主题各取一档 */
388
+ :is([data-theme='dark'] *, [data-theme='dark'])[data-scope='radio-group'][data-part='root'][data-variant='segmented'][data-tone] {
389
+ --xh-_radio-group-thumb-bg: var(--xh-_tone-subtle-hover, var(--xh-bg-segment-selected));
390
+ --xh-_radio-group-thumb-bg-hover: var(--xh-_tone-subtle-active, var(--xh-bg-segment-selected-hover));
373
391
  }
374
392
 
375
393
  /* 段:轨道里铺开的一格,不投影 Action Control 家族(与 Tabs segment 档同),面与字写在段自己身上。
@@ -415,32 +433,53 @@
415
433
  display: none;
416
434
  }
417
435
 
418
- /* 选中态读 data-state,不读 ARIA。文字色也要跟着变——滑块是可选部件,作者不渲染它时"当前是哪一段"仍然要看得出来 */
436
+ /* 选中态读 data-state,不读 ARIA:品牌字 + medium。字也要跟着变——滑块是可选部件,作者不渲染它时"当前是哪一段"仍然要看得出来 */
419
437
  [data-scope='radio-group'][data-part='root'][data-variant='segmented']
420
438
  > [data-scope='radio-group'][data-part='item'][data-state='checked'] {
421
439
  color: var(--xh-radio-group-segment-fg-checked, var(--xh-_radio-group-segment-fg-checked));
440
+ font-weight: var(--xh-radio-group-segment-font-weight-checked, var(--xh-font-weight-medium));
422
441
  }
423
442
 
424
- /* 滑块在场时选中段自己透空,环紧挨着的是压在它底下、与它同一块矩形的滑块实心底;
425
- 环色与那块底同族就看不出来,改取选中段自己的前景色——那一支本来就配着这块底定的 */
426
- [data-scope='radio-group'][data-part='root'][data-variant='segmented']:has(> [data-scope='radio-group'][data-part='thumb']:not([hidden]))
427
- > [data-scope='radio-group'][data-part='item'][data-state='checked']:focus-visible {
428
- --xh-_ring-color: currentColor;
443
+ /* 段间分隔线:1px 装饰边色,长度取段高的一半再收一格半阶(md 档 32 / 2 − 2 = 14px),竖在后一段的起始缘上。
444
+ 只在横排画:竖排的段上下相接,分隔交给轨道的留白。与选中段、悬停段相邻的那几道收起(底色淡成透明)——
445
+ 那两段铺了面,再夹一道线就把面切出了缺口。
446
+ 已知限制:折行后下一行首段的起始缘也会画出这一道。样式层拿不到段落在第几行(不用容器查询,
447
+ 轨道也不能裁内容,否则段的焦点环与粗指针命中区一并被裁),设计真源与组件文档注明了尽量一行排下 */
448
+ [data-scope='radio-group'][data-part='root'][data-variant='segmented'][data-orientation='horizontal']
449
+ > [data-scope='radio-group'][data-part='item'] + [data-scope='radio-group'][data-part='item']::after {
450
+ content: '';
451
+ position: absolute;
452
+ inset-block-start: 50%;
453
+ inset-inline-start: 0;
454
+ inline-size: var(--xh-stroke-thin);
455
+ block-size: calc(var(--xh-radio-group-segment-h, var(--xh-_radio-group-segment-h)) / 2 - var(--xh-space-0_5));
456
+ background-color: var(--xh-radio-group-segment-separator, var(--xh-border-default));
457
+ translate: 0 -50%;
458
+ pointer-events: none;
459
+ transition: background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
429
460
  }
430
461
 
431
- /* 悬停只提亮未选中的那几段:选中段的底下压着滑块,再变色就成了两套强调。
432
- 底色用中性的悬停档:段坐在淡底轨道里,悬停取 200;只读收回悬停,与列表形态同一个决定 */
462
+ [data-scope='radio-group'][data-part='root'][data-variant='segmented'][data-orientation='horizontal']
463
+ > [data-scope='radio-group'][data-part='item']:is([data-state='checked'], :not([data-disabled], [data-readonly]):hover)::after,
464
+ [data-scope='radio-group'][data-part='root'][data-variant='segmented'][data-orientation='horizontal']
465
+ > [data-scope='radio-group'][data-part='item']:is([data-state='checked'], :not([data-disabled], [data-readonly]):hover)
466
+ + [data-scope='radio-group'][data-part='item']::after {
467
+ background-color: transparent;
468
+ }
469
+
470
+ /* 悬停时未选中段自己换面:选中段的底下压着滑块,悬停由滑块升一档表出(见滑块块)。
471
+ 底色用中性的悬停档:轨道底是最浅一档淡底,按白底承载取 100;只读收回悬停,与列表形态同一个决定 */
433
472
  [data-scope='radio-group'][data-part='root'][data-variant='segmented']
434
473
  > [data-scope='radio-group'][data-part='item']:not([data-disabled]):not([data-readonly]):not([data-state='checked']):hover {
435
- background-color: var(--xh-radio-group-segment-bg-hover, var(--xh-bg-subtle-hover));
474
+ background-color: var(--xh-radio-group-segment-bg-hover, var(--xh-bg-subtle));
436
475
  color: var(--xh-radio-group-segment-fg-hover, var(--xh-fg-default));
437
476
  }
438
477
 
439
- /* 按下去要有回应:未选中段换到按下面(淡底承载 300),几何不动。
440
- 选中段不叠按下面:它压着的白色滑块本身就是选中身份(有滑块开关无叠加态) */
478
+ /* 按下去要有回应:未选中段换到按下面(白底承载 200),几何不动。
479
+ 选中段不叠按下面:它压着的品牌淡底滑块本身就是选中身份(有滑块开关无叠加态) */
441
480
  [data-scope='radio-group'][data-part='root'][data-variant='segmented']
442
481
  > [data-scope='radio-group'][data-part='item']:not([data-disabled]):not([data-readonly]):not([data-state='checked']):is(:active, [data-pressed]) {
443
- background-color: var(--xh-radio-group-segment-bg-pressed, var(--xh-bg-subtle-active));
482
+ background-color: var(--xh-radio-group-segment-bg-pressed, var(--xh-bg-subtle-hover));
444
483
  transition-duration: var(--xh-motion-duration-press);
445
484
  transition-timing-function: var(--xh-motion-ease-press);
446
485
  }
@@ -459,11 +498,10 @@
459
498
  cursor: not-allowed;
460
499
  }
461
500
 
462
- /* 禁用且选中的那一段不换文字色:它压着的是滑块的实心底,换成 fg-disabled 后六族语气只剩 1.04–3.01 的对比度,
463
- 「当前选的是哪一段」当场看不见。禁用由轨道底色、未选中段的文字色与光标表达,选中段保持可读 */
501
+ /* 禁用且选中的那一段:字退到浅品牌色、滑块退到 8% 淡底,仍看得出选的是哪一段 */
464
502
  [data-scope='radio-group'][data-part='root'][data-variant='segmented']
465
503
  > [data-scope='radio-group'][data-part='item'][data-disabled][data-state='checked'] {
466
- color: var(--xh-radio-group-segment-fg-checked-disabled, var(--xh-_radio-group-segment-fg-checked));
504
+ color: var(--xh-radio-group-segment-fg-checked-disabled, var(--xh-_radio-group-segment-fg-checked-disabled));
467
505
  }
468
506
 
469
507
  [data-scope='radio-group'][data-part='thumb'] {
@@ -484,38 +522,43 @@
484
522
  inline-size: var(--xh-_radio-group-thumb-w);
485
523
  block-size: var(--xh-_radio-group-thumb-h);
486
524
  translate: calc(var(--xh-_radio-group-thumb-x) * var(--xh-direction-sign)) var(--xh-_radio-group-thumb-y);
487
- /* 白色抬起面三件(有滑块开关):surface-raised 底 + border-default 描边 + raised 影,描边必须在,影只是加成。
525
+ /* 选中段的品牌淡底:平面一块,无边无影。描边位留着透明(作者给槽才画),
488
526
  尺寸由连接层按段的盒量出,描边吃进盒里(border-box),滑块与段仍是同一块矩形 */
489
- border: var(--xh-stroke-thin) solid var(--xh-radio-group-thumb-border, var(--xh-border-default));
527
+ border: var(--xh-stroke-thin) solid var(--xh-radio-group-thumb-border, transparent);
490
528
  border-radius: var(--xh-radio-group-thumb-radius, var(--xh-shape-inset));
491
529
  background: var(--xh-radio-group-thumb-bg, var(--xh-_radio-group-thumb-bg));
492
- box-shadow: var(--xh-radio-group-thumb-shadow, var(--xh-elevation-raised));
530
+ box-shadow: var(--xh-radio-group-thumb-shadow, none);
493
531
  /* 段压在它上面,点击一律交给段;作者把它写在段之后时也不至于吞掉点击 */
494
532
  pointer-events: none;
495
533
  /* 用连续档而不是进场那条:滑块是被推过去的,起步就该有速度,纯减速曲线看着像自己飘过去。
496
- 四个几何量同时走,段宽不等时才不会先变形再挪位。投影单列一项:整组禁用时滑块落回轨道平面,那层投影跟着收 */
534
+ 四个几何量同时走,段宽不等时才不会先变形再挪位。底色单列一项:选中段悬停、禁用时滑块换档是淡变 */
497
535
  transition:
498
536
  translate var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
499
537
  inline-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
500
538
  block-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
501
- box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
539
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
502
540
  }
503
541
 
504
- /* 语气档的滑块是实心语气面,描边与底同色:raised 面必带描边,这里的描边只是把边位补齐,不另画一圈 */
505
- [data-scope='radio-group'][data-part='root'][data-variant='segmented'][data-tone] > [data-scope='radio-group'][data-part='thumb'] {
506
- border-color: var(--xh-radio-group-thumb-border, var(--xh-_tone, var(--xh-border-default)));
542
+ /* 选中段悬停:滑块压在它底下,由滑块升一档表出 */
543
+ [data-scope='radio-group'][data-part='root'][data-variant='segmented']:has(
544
+ > [data-scope='radio-group'][data-part='item'][data-state='checked']:not([data-disabled]):not([data-readonly]):hover
545
+ )
546
+ > [data-scope='radio-group'][data-part='thumb'] {
547
+ background: var(--xh-radio-group-thumb-bg-hover, var(--xh-_radio-group-thumb-bg-hover));
507
548
  }
508
549
 
509
- /* 整组禁用时滑块落回轨道平面(不再浮起),但底色一点不兑淡:
510
- 它上面压着选中段的文字,往 muted 兑哪怕一成,brand 的对比度就从 5.08 掉到 4.24 */
511
- [data-scope='radio-group'][data-part='root'][data-disabled] > [data-scope='radio-group'][data-part='thumb'] {
512
- box-shadow: var(--xh-radio-group-thumb-shadow-disabled, none);
550
+ /* 选中段禁用(含整组禁用):滑块退到 8% 淡底,与退到浅品牌色的字一起读出「选着、但动不了」 */
551
+ [data-scope='radio-group'][data-part='root'][data-variant='segmented']:has(
552
+ > [data-scope='radio-group'][data-part='item'][data-state='checked'][data-disabled]
553
+ )
554
+ > [data-scope='radio-group'][data-part='thumb'] {
555
+ background: var(--xh-radio-group-thumb-bg-disabled, var(--xh-_radio-group-thumb-bg-disabled));
513
556
  }
514
557
 
515
558
  /* 首次落位与同一项的重量(窗口缩放、换上正式字体)直接到位,只有换项才滑:连接层在这一落点投影
516
- data-instant。投影的淡变照留,整组禁用时滑块落回轨道平面仍是淡变 */
559
+ data-instant。底色的淡变照留 */
517
560
  [data-scope='radio-group'][data-part='thumb'][data-instant] {
518
- transition: box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
561
+ transition: background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
519
562
  }
520
563
 
521
564
  /* 液态档:两沿由弹簧逐帧推着走(连接层每一帧写好盒子),几何量不再补过渡;
@@ -524,7 +567,7 @@
524
567
  --xh-_radio-group-thumb-squash: max(var(--xh-motion-scale-squash), calc(1 - var(--xh-_radio-group-thumb-stretch) * (1 - var(--xh-motion-scale-squash))));
525
568
 
526
569
  scale: 1 var(--xh-_radio-group-thumb-squash);
527
- transition: box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
570
+ transition: background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
528
571
  }
529
572
 
530
573
  :where([data-material='liquid']) [data-scope='radio-group'][data-part='root'][data-orientation='vertical']
@@ -539,14 +582,30 @@
539
582
  min-block-size: 0;
540
583
  }
541
584
 
542
- /* segmented 的段不归家族:手指的落点比一段高,命中区由伪元素向块轴两侧外扩,段的盒与轨道内的分格一点不动。
543
- 只扩块轴——段与段在行内轴上首尾相接,往两侧扩会与相邻段的命中区叠上。
544
- 外扩一格 space-2 是按最矮的 sm 档算的(28 + 8 × 2 = 44),md 与 lg 档更宽裕 */
585
+ /* segmented 的段不归家族:手指的落点比一段大,命中区由伪元素补足到粗指针下限(--xh-control-hit-coarse),
586
+ 段的盒与轨道内的分格一点不动。竖排与折行时段与段沿块轴首尾相接、行内轴上也挨着,补足的命中区必然叠进
587
+ 相邻段的盒——轨道建一个层叠上下文,伪元素垫在负一层:每一段的盒都压在别段外扩的命中区之上,
588
+ 叠上的那一截归盒子本来所在的那一段,外扩只落在段与段之间没有盒的地方(轨道衬距、轨道外沿)。
589
+ 纯 CSS 拿不到「这一段在第几行」,于是不按行开关外扩,靠层序让段的盒自己说了算。
590
+ 块首外扩不越过轨道外沿再加一格标签间距(space-2):单行时上沿停在字段标签下缘之外,点在标签上仍归标签;
591
+ 少扩的一截落到块尾,命中区总高仍是下限 */
592
+ [data-scope='radio-group'][data-part='root'][data-variant='segmented'] {
593
+ isolation: isolate;
594
+ }
595
+
545
596
  [data-scope='radio-group'][data-part='root'][data-variant='segmented'] > [data-scope='radio-group'][data-part='item']::before {
546
597
  content: '';
547
598
  position: absolute;
548
- inset-block: calc(-1 * var(--xh-space-2));
549
- inset-inline: 0;
599
+ z-index: -1;
600
+ inset-block-start: min(
601
+ 0px,
602
+ max(
603
+ (100% - var(--xh-control-hit-coarse)) / 2,
604
+ -1 * (var(--xh-radio-group-track-padding, var(--xh-space-0_5)) + var(--xh-stroke-thin) + var(--xh-space-2))
605
+ )
606
+ );
607
+ inset-inline: min(0px, (100% - var(--xh-control-hit-coarse)) / 2);
608
+ block-size: max(100%, var(--xh-control-hit-coarse));
550
609
  }
551
610
  }
552
611
 
@@ -579,6 +638,12 @@
579
638
  background-color: Highlight;
580
639
  color: HighlightText;
581
640
  }
641
+
642
+ /* 选中段的品牌淡底在这一档里被换成 Canvas,与没选中的段一模一样:滑块描一圈系统前景边框出选中段 */
643
+ [data-scope='radio-group'][data-part='root'][data-variant='segmented'] > [data-scope='radio-group'][data-part='thumb'] {
644
+ border-color: ButtonText;
645
+ }
646
+
582
647
  }
583
648
 
584
649
  @media print {
@@ -588,7 +653,7 @@
588
653
  border: var(--xh-stroke-thick) solid currentColor;
589
654
  }
590
655
 
591
- /* segmented 的滑块那块底与它的落影都不画,「当前选的是哪一段」在纸上没了:选中段改画一圈实边、字加粗 */
656
+ /* segmented 的滑块那块淡底不画,「当前选的是哪一段」在纸上没了:选中段改画一圈实边、字加粗 */
592
657
  [data-scope='radio-group'][data-part='root'][data-variant='segmented']
593
658
  > [data-scope='radio-group'][data-part='item'][data-state='checked'] {
594
659
  border: var(--xh-stroke-thin) solid currentColor;
package/css/rating.css CHANGED
@@ -17,10 +17,12 @@
17
17
  根上不留基准它就会贴到更外层的定位祖先上,原生校验提示跟着飘到页面别处。 */
18
18
  [data-scope='rating'][data-part='root'] {
19
19
  /* 尺寸档只换这三个私有槽,星星与分值都从 root 继承它们,换档不必给每个部件各写一条选择器。
20
- 星是控件内的字形,按档取 --xh-glyph-size-sm / md / lg;标签字号不随档 */
20
+ 星是评分的主体而不是控件里的附属图标,比同档控件内图标大一档:sm / md / lg 取
21
+ --xh-glyph-size-md / lg / xl(20 / 24 / 32px);盒比星大一圈 4px(24 / 28 / 36px),星落在家族那圈透明边位之内、
22
+ 不被挤偏。标签字号不随档 */
21
23
  --xh-_rating-item-gap: var(--xh-control-gap-md);
22
- --xh-_rating-item-size: var(--xh-glyph-size-md);
23
- --xh-_rating-item-box-size: var(--xh-control-action-size);
24
+ --xh-_rating-item-size: var(--xh-glyph-size-lg);
25
+ --xh-_rating-item-box-size: calc(var(--xh-_rating-item-size) + var(--xh-space-1));
24
26
  --xh-_rating-font-size: var(--xh-control-font-md);
25
27
  --xh-icon-size: var(--xh-rating-item-font-size, var(--xh-_rating-item-size));
26
28
  /* 点亮色随语气走。没写 data-tone 时 --xh-_tone 没被声明,退回原来的警示色 */
@@ -36,25 +38,27 @@
36
38
  /* —— 尺寸 —— */
37
39
  [data-scope='rating'][data-part='root'][data-size='sm'] {
38
40
  --xh-_rating-item-gap: var(--xh-control-gap-sm);
39
- --xh-_rating-item-size: var(--xh-glyph-size-sm);
41
+ --xh-_rating-item-size: var(--xh-glyph-size-md);
40
42
  --xh-_rating-font-size: var(--xh-control-font-sm);
41
43
  }
42
44
 
43
45
  [data-scope='rating'][data-part='root'][data-size='lg'] {
44
46
  --xh-_rating-item-gap: var(--xh-control-gap-lg);
45
- --xh-_rating-item-size: var(--xh-glyph-size-lg);
47
+ --xh-_rating-item-size: var(--xh-glyph-size-xl);
46
48
  --xh-_rating-font-size: var(--xh-control-font-lg);
47
49
  }
48
50
 
49
- /* 字段标签:14 / 500 / fg-default,禁用换到 --xh-fg-subtle;文字部件不叠 opacity */
51
+ /* 字段标签:14 / 400 / fg-muted,与控件隔 space-2,禁用不另变色;文字部件不叠 opacity */
50
52
  [data-scope='rating'][data-part='label'] {
51
- color: var(--xh-rating-label-fg, var(--xh-fg-default));
53
+ /* 竖排时标签与控件之间的距离:根的 gap 之上补一段差值,--xh-rating-label-gap 给多少最终就是多少 */
54
+ margin-block-end: calc(var(--xh-rating-label-gap, var(--xh-space-2)) - var(--xh-rating-gap, var(--xh-space-1)));
55
+ color: var(--xh-rating-label-fg, var(--xh-fg-muted));
52
56
  font-size: var(--xh-rating-label-font-size, var(--xh-text-label-size));
53
57
  font-weight: var(--xh-rating-label-font-weight, var(--xh-text-label-weight));
54
58
  }
55
59
 
56
60
  [data-scope='rating'][data-part='label'][data-disabled] {
57
- color: var(--xh-rating-label-fg-disabled, var(--xh-fg-subtle));
61
+ color: var(--xh-rating-label-fg-disabled, var(--xh-fg-muted));
58
62
  }
59
63
 
60
64
  [data-scope='rating'][data-part='control'] {
@@ -78,7 +82,7 @@
78
82
  justify-content: start;
79
83
  }
80
84
 
81
- [data-scope='rating'][data-part='root']:has(> [data-part='value-text']) > [data-part='label'] {
85
+ [data-scope='rating'][data-part='root']:has(> [data-part='value-text']) > [data-part='label']:where([data-scope='rating']) {
82
86
  grid-column: 1 / -1;
83
87
  }
84
88
 
@@ -106,10 +110,14 @@
106
110
 
107
111
  /* 条目固定成一枚方形图标盒:连接层用 clientWidth 判定指针落在左半还是右半,
108
112
  固定盒能让半档分界与图形中心严格重合。
109
- 星接 Action Control icon 档(定尺的星):盒型、按下 / 禁用面、0.97 缩放与换底、焦点环与过渡由家族配方给,
113
+ 星接 Action Control icon 档(定尺的星):盒型、按下 / 禁用面、换底、焦点环与过渡由家族配方给,
110
114
  这里只把使用者槽映射到桥接槽。静息透明(ghost 形态);悬停不换底——悬停预览由点亮的星形(data-highlighted)
111
- 表达,再给盒换面是重复的通道;按下换到 200 档中性面(白底承载)。前景五态映射同一个值:点亮时五态一起换到
112
- 点亮色,家族的悬停 / 按下块才不会把点亮色换回静息色;禁用不换前景,星带整体的压暗落在 control 的 opacity 上 */
115
+ 表达,再给盒换面是重复的通道。缩放是统一按压反馈的登记例外:悬停与键盘聚焦把这颗星放大到
116
+ --xh-motion-scale-emphasis(1.2)强调落点,按下保持放大(不取 --xh-motion-scale-press)并换到 200 档中性面
117
+ (白底承载)——按压的回执是换面,不往回缩。悬停放大只给能悬停的设备:触屏点过之后 :hover 会一直留在那颗星上,
118
+ 放大跟着停住。减弱动效下放大比例为 1,只留换色。
119
+ 前景五态映射同一个值:点亮时五态一起换到点亮色,家族的悬停 / 按下块才不会把点亮色换回静息色;
120
+ 禁用不换前景,星带整体的压暗落在 control 的 opacity 上 */
113
121
  [data-scope='rating'][data-part='item'] {
114
122
  --xh-_rating-item-bg-pressed: var(--xh-rating-item-bg-pressed, var(--xh-bg-subtle-hover));
115
123
 
@@ -119,6 +127,8 @@
119
127
  --xh-action-font-size: var(--xh-rating-item-font-size, var(--xh-_rating-item-size));
120
128
  --xh-action-bg-hover: transparent;
121
129
  --xh-action-bg-pressed: var(--xh-_rating-item-bg-pressed);
130
+ --xh-action-scale-focus-visible: var(--xh-motion-scale-emphasis);
131
+ --xh-action-scale-pressed: var(--xh-motion-scale-emphasis);
122
132
  --xh-action-fg-rest: var(--xh-rating-item-fg, var(--xh-fg-subtle));
123
133
  --xh-action-fg-hover: var(--xh-rating-item-fg, var(--xh-fg-subtle));
124
134
  --xh-action-fg-pressed: var(--xh-rating-item-fg, var(--xh-fg-subtle));
@@ -131,8 +141,14 @@
131
141
  --xh-action-border-disabled: transparent;
132
142
  }
133
143
 
144
+ @media (hover: hover) {
145
+ [data-scope='rating'][data-part='item'] {
146
+ --xh-action-scale-hover: var(--xh-motion-scale-emphasis);
147
+ }
148
+ }
149
+
134
150
  /* 家族 icon 档在粗指针下用 ::after 扩热区到 44px:五颗星密排,44px 热区会压住相邻的星,
135
- 连接层又按 currentTarget 的宽度判半颗,热区串到邻星上半档就判错;星本身仍是 24px 盒,热区不外扩。
151
+ 连接层又按 currentTarget 的宽度判半颗,热区串到邻星上半档就判错;星本身仍是不小于 24px 的盒,热区不外扩。
136
152
  空条目的 ::after 是点亮那层星形,下限归零才不会被撑成 44px */
137
153
  @media (pointer: coarse) {
138
154
  [data-scope='rating'][data-part='item']::after {
@@ -205,10 +221,11 @@
205
221
  clip-path: inset(0 calc(50% * var(--xh-_rating-end)) 0 calc(50% * var(--xh-_rating-start)));
206
222
  }
207
223
 
208
- /* 只读仍进得了 Tab 序列、读屏也念得出,只是改不动:收掉手型,别暗示"点这儿能改";
209
- 家族的按压块由这里的映射钉回静息面——按下不缩放、不换底 */
224
+ /* 只读仍进得了 Tab 序列、读屏也念得出,只是改不动:收掉手型与悬停放大,别暗示"点这儿能改";
225
+ 家族的按压块由这里的映射钉回静息面——按下不缩放、不换底;键盘聚焦的放大留着,那是焦点落点 */
210
226
  [data-scope='rating'][data-part='item'][data-readonly]:not([data-disabled]) {
211
227
  --xh-_rating-item-bg-pressed: transparent;
228
+ --xh-action-scale-hover: none;
212
229
  --xh-action-scale-pressed: none;
213
230
  --xh-action-cursor-rest: default;
214
231
  --xh-action-cursor-hover: default;
package/css/select.css CHANGED
@@ -72,6 +72,7 @@
72
72
  --xh-_select-h: var(--xh-control-h-md);
73
73
  --xh-_select-px: var(--xh-control-px-md);
74
74
  --xh-_select-item-py: var(--xh-list-option-py-md);
75
+ --xh-_select-item-h: var(--xh-list-option-h-md);
75
76
  --xh-_select-item-px: var(--xh-control-px-md);
76
77
  --xh-_select-gap: var(--xh-control-gap-md);
77
78
  --xh-_select-font-size: var(--xh-control-font-md);
@@ -105,6 +106,7 @@
105
106
  --xh-_select-h: var(--xh-control-h-sm);
106
107
  --xh-_select-px: var(--xh-control-px-sm);
107
108
  --xh-_select-item-py: var(--xh-list-option-py-sm);
109
+ --xh-_select-item-h: var(--xh-list-option-h-sm);
108
110
  --xh-_select-item-px: var(--xh-control-px-sm);
109
111
  --xh-_select-gap: var(--xh-control-gap-sm);
110
112
  --xh-_select-font-size: var(--xh-control-font-sm);
@@ -123,20 +125,23 @@
123
125
  --xh-_select-h: var(--xh-control-h-lg);
124
126
  --xh-_select-px: var(--xh-control-px-lg);
125
127
  --xh-_select-item-py: var(--xh-list-option-py-lg);
128
+ --xh-_select-item-h: var(--xh-list-option-h-lg);
126
129
  --xh-_select-item-px: var(--xh-control-px-lg);
127
130
  --xh-_select-gap: var(--xh-control-gap-lg);
128
131
  --xh-_select-font-size: var(--xh-control-font-lg);
129
132
  }
130
133
 
131
134
  [data-scope='select'][data-part='label'] {
132
- color: var(--xh-select-label-fg, var(--xh-fg-default));
135
+ /* 竖排时标签与控件之间的距离:根的 gap 之上补一段差值,--xh-select-label-gap 给多少最终就是多少 */
136
+ margin-block-end: calc(var(--xh-select-label-gap, var(--xh-space-2)) - var(--xh-select-gap, var(--xh-space-1)));
137
+ color: var(--xh-select-label-fg, var(--xh-fg-muted));
133
138
  font-size: var(--xh-select-label-font-size, var(--xh-text-label-size));
134
139
  font-weight: var(--xh-select-label-font-weight, var(--xh-text-label-weight));
135
140
  line-height: var(--xh-leading-none);
136
141
  }
137
142
 
138
143
  [data-scope='select'][data-part='label'][data-disabled] {
139
- color: var(--xh-select-label-fg-disabled, var(--xh-fg-subtle));
144
+ color: var(--xh-select-label-fg-disabled, var(--xh-fg-muted));
140
145
  }
141
146
 
142
147
  /* 盒:描边、底色、圆角、控件高度、行内内衬、聚焦环、五态与悬停由 Field Chrome 家族画在这一层,
@@ -157,8 +162,6 @@
157
162
  --xh-field-border-hover: var(--xh-select-control-border-hover, var(--xh-_field-variant-border-hover));
158
163
  --xh-field-border-focus: var(--xh-select-control-border-focus, var(--xh-_field-variant-border-focus));
159
164
  --xh-field-border-invalid: var(--xh-select-control-border-invalid, var(--xh-_field-variant-border-invalid));
160
- --xh-field-ring-focus: var(--xh-ring-focus);
161
- --xh-field-ring-invalid: var(--xh-ring-invalid);
162
165
  --xh-field-shadow-rest: var(--xh-select-control-shadow, none);
163
166
  --xh-field-cursor-rest: pointer;
164
167
  /* 家族 chrome 会重写 --xh-icon-size,使用者图标槽必须经桥接槽下发才能在盒内生效 */
@@ -224,7 +227,7 @@
224
227
 
225
228
  /* 标签行露面时 value-text 让位:两者是触发器里的同一格,占位文字与标签不同屏。
226
229
  value-text 留在 DOM 里,trigger 的可及名仍从它取到完整的选中项文本 */
227
- [data-scope='select'][data-part='trigger']:has([data-part='tag-list']:not([hidden])) [data-part='value-text'] {
230
+ [data-scope='select'][data-part='trigger']:has([data-part='tag-list']:not([hidden])) [data-part='value-text']:where([data-scope='select']) {
228
231
  display: none;
229
232
  }
230
233
 
@@ -256,7 +259,7 @@
256
259
  /* 有值时清空钮顶上来,箭头让位:两个图标并排堆着,用户分不清点哪个。
257
260
  判据查的是盒里此刻真有一颗没收起的清空钮,不是「有没有值」——
258
261
  作者没摆清空钮时箭头照常留着,不然让了位没人接,指示符整个消失 */
259
- [data-scope='select'][data-part='control']:has([data-part='clear-trigger']:not([hidden])) [data-part='indicator'] {
262
+ [data-scope='select'][data-part='control']:has([data-part='clear-trigger']:not([hidden])) [data-part='indicator']:where([data-scope='select']) {
260
263
  display: none;
261
264
  }
262
265
 
@@ -312,7 +315,7 @@
312
315
  max-inline-size: var(--xh-select-content-max-w, none);
313
316
  max-block-size: min(var(--xh-select-content-max-h, var(--xh-overlay-menu-max-h)), var(--xh-_select-available-h));
314
317
  padding-block: var(--xh-select-content-py, var(--xh-space-1));
315
- padding-inline: var(--xh-select-content-px, var(--xh-space-1));
318
+ padding-inline: var(--xh-select-content-px, 0);
316
319
  border-radius: var(--xh-select-content-radius, var(--xh-shape-overlay));
317
320
  /* 条目的悬停底色是方角,滚到两端时会探出外壳的圆角 */
318
321
  overflow: hidden;
@@ -462,10 +465,11 @@
462
465
  [data-scope='select'][data-part='item'] {
463
466
  /* 公开 Select 槽只映射到家族合同;网格、尺寸与状态选择器不在组件皮肤复制。pressed 面与 selected 各态由家族按 overlay 上下文给出。 */
464
467
  --xh-collection-block-padding: var(--xh-select-item-py, var(--xh-_select-item-py));
468
+ --xh-collection-row-h: var(--xh-select-item-h, var(--xh-_select-item-h));
465
469
  --xh-collection-inline-padding: var(--xh-select-item-px, var(--xh-_select-item-px));
466
470
  --xh-collection-gap: var(--xh-select-item-gap, var(--xh-_select-gap));
467
471
  --xh-collection-font-size: var(--xh-select-item-font-size, var(--xh-_select-font-size));
468
- --xh-collection-radius: var(--xh-select-item-radius, var(--xh-shape-inset));
472
+ --xh-collection-radius: var(--xh-select-item-radius, 0);
469
473
  --xh-collection-fg-rest: var(--xh-select-item-fg, var(--xh-material-frosted-fg));
470
474
  --xh-collection-fg-hover: var(--xh-select-item-fg, var(--xh-material-frosted-fg));
471
475
  --xh-collection-fg-keyboard-highlight: var(--xh-select-item-fg, var(--xh-material-frosted-fg));
@@ -474,10 +478,10 @@
474
478
  --xh-collection-fg-selected-hover: var(--xh-select-item-fg-selected, var(--xh-select-item-fg, var(--xh-material-frosted-fg)));
475
479
  --xh-collection-fg-selected-pressed: var(--xh-select-item-fg-selected, var(--xh-select-item-fg, var(--xh-material-frosted-fg)));
476
480
  --xh-collection-fg-pressed: var(--xh-select-item-fg, var(--xh-material-frosted-fg));
477
- --xh-collection-font-weight-selected: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-regular));
478
- --xh-collection-font-weight-selected-highlight: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-regular));
479
- --xh-collection-font-weight-selected-hover: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-regular));
480
- --xh-collection-font-weight-selected-pressed: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-regular));
481
+ --xh-collection-font-weight-selected: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-medium));
482
+ --xh-collection-font-weight-selected-highlight: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-medium));
483
+ --xh-collection-font-weight-selected-hover: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-medium));
484
+ --xh-collection-font-weight-selected-pressed: var(--xh-select-item-font-weight-selected, var(--xh-font-weight-medium));
481
485
  --xh-collection-bg-hover: var(--xh-select-item-bg-hover, var(--xh-bg-subtle));
482
486
  --xh-collection-bg-keyboard-highlight: var(--xh-select-item-bg-hover, var(--xh-bg-subtle));
483
487
  --xh-collection-bg-selected-highlight: var(--xh-select-item-bg-hover, var(--xh-bg-subtle));
package/css/separator.css CHANGED
@@ -16,7 +16,7 @@
16
16
  * 各自取用:换档只改槽,画在哪个节点上互不影响。
17
17
  */
18
18
  [data-scope='separator'][data-part='root'] {
19
- --xh-_separator-color: var(--xh-separator-color, var(--xh-material-frosted-separator));
19
+ --xh-_separator-color: var(--xh-separator-color, var(--xh-border-default));
20
20
  --xh-_separator-dash: var(--xh-separator-dash-length, var(--xh-space-1_5));
21
21
  --xh-_separator-dash-gap: var(--xh-separator-dash-gap, var(--xh-space-1_5));
22
22
  --xh-_separator-paint: var(--xh-_separator-color);
@@ -26,15 +26,20 @@
26
26
  background: var(--xh-_separator-paint);
27
27
  }
28
28
 
29
+ /* 分隔线自带上下(竖向为左右)留白:横向上下各 20px,竖向左右各 12px,放进内容里不必另包一层加边距 */
29
30
  [data-scope='separator'][data-part='root'][data-orientation='horizontal'] {
30
31
  inline-size: 100%;
31
32
  block-size: var(--xh-separator-thickness, var(--xh-stroke-thin));
33
+ margin-block: var(--xh-separator-my, var(--xh-space-5));
32
34
  }
33
35
 
34
36
  [data-scope='separator'][data-part='root'][data-orientation='vertical'] {
35
37
  align-self: stretch;
36
38
  inline-size: var(--xh-separator-thickness, var(--xh-stroke-thin));
37
39
  block-size: 100%;
40
+ /* 父容器没有高度时也留一截与文字等高的线 */
41
+ min-block-size: var(--xh-glyph-size-text);
42
+ margin-inline: var(--xh-separator-mx, var(--xh-space-3));
38
43
  }
39
44
 
40
45
  /* —— 形态 ——
@@ -74,7 +79,9 @@
74
79
  align-items: center;
75
80
  inline-size: 100%;
76
81
  block-size: auto;
77
- gap: var(--xh-separator-gap, var(--xh-space-3));
82
+ gap: var(--xh-separator-gap, var(--xh-space-4));
83
+ /* 文字自带一行行高,上下留白收一半,整段占的高度与单线时相当 */
84
+ margin-block: var(--xh-separator-my, var(--xh-space-2_5));
78
85
  background: none;
79
86
  }
80
87
 
@@ -102,18 +109,29 @@
102
109
  /* 分节文字:不参与等分,也不折行 */
103
110
  [data-scope='separator'][data-part='content'] {
104
111
  flex: none;
105
- color: var(--xh-separator-content-fg, var(--xh-fg-muted));
106
- font-size: var(--xh-separator-content-font-size, var(--xh-text-secondary-size));
112
+ color: var(--xh-separator-content-fg, var(--xh-fg-default));
113
+ font-size: var(--xh-separator-content-font-size, var(--xh-text-body-size));
114
+ font-weight: var(--xh-separator-content-font-weight, var(--xh-font-weight-medium));
107
115
  line-height: var(--xh-leading-normal);
108
116
  white-space: nowrap;
109
117
  }
110
118
 
111
119
  /* 文字靠边:靠哪边就把那一侧的线收成一小截,另一侧照旧等分 */
112
- [data-scope='separator'][data-part='root'][data-align='start'] > [data-part='line']:first-child,
113
- [data-scope='separator'][data-part='root'][data-align='end'] > [data-part='line']:last-child {
120
+ [data-scope='separator'][data-part='root'][data-align='start'] > [data-part='line']:where([data-scope='separator']):first-child,
121
+ [data-scope='separator'][data-part='root'][data-align='end'] > [data-part='line']:where([data-scope='separator']):last-child {
114
122
  flex: 0 0 var(--xh-separator-align-length, var(--xh-space-6));
115
123
  }
116
124
 
125
+ /* 强制色:线是底色(与虚线的渐变)画的,系统会把底色换成 Canvas,线就此消失。
126
+ 线退出强制换色、颜色直接取 CanvasText,实线与虚线同一条槽 */
127
+ @media (forced-colors: active) {
128
+ [data-scope='separator']:is([data-part='root'], [data-part='line']) {
129
+ --xh-_separator-color: CanvasText;
130
+
131
+ forced-color-adjust: none;
132
+ }
133
+ }
134
+
117
135
  /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
118
136
  写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
119
137
  [data-scope='separator'][data-part='root'][hidden] {