@xihan-ui/styles 2.0.0 → 3.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 (156) hide show
  1. package/CHANGELOG.md +1328 -0
  2. package/README.md +6 -1
  3. package/component-tokens.d.ts +505 -111
  4. package/components.tokens.json +34750 -26291
  5. package/css/accordion.css +39 -13
  6. package/css/alert.css +61 -3
  7. package/css/anchor.css +49 -11
  8. package/css/approval.css +124 -84
  9. package/css/avatar-group.css +1 -1
  10. package/css/avatar.css +13 -5
  11. package/css/back-top.css +63 -44
  12. package/css/badge.css +63 -13
  13. package/css/bar-code.css +1 -1
  14. package/css/breadcrumb.css +63 -4
  15. package/css/button-group.css +5 -5
  16. package/css/button.css +69 -21
  17. package/css/calendar-picker.css +27 -8
  18. package/css/calendar-range-picker.css +48 -11
  19. package/css/card.css +116 -2
  20. package/css/carousel.css +153 -48
  21. package/css/cartesian-chart.css +830 -0
  22. package/css/cascader.css +184 -70
  23. package/css/checkbox-group.css +69 -99
  24. package/css/checkbox.css +21 -54
  25. package/css/citation.css +470 -0
  26. package/css/clipboard.css +23 -66
  27. package/css/code-view.css +103 -8
  28. package/css/collapsible.css +37 -11
  29. package/css/color-field.css +18 -0
  30. package/css/color-picker.css +57 -62
  31. package/css/color-slider.css +26 -19
  32. package/css/color-swatch-picker.css +8 -6
  33. package/css/combobox.css +82 -37
  34. package/css/command.css +48 -48
  35. package/css/context-menu.css +43 -28
  36. package/css/date-field.css +23 -0
  37. package/css/date-picker.css +57 -24
  38. package/css/date-range-picker.css +301 -14
  39. package/css/description.css +17 -1
  40. package/css/descriptions.css +43 -1
  41. package/css/dialog.css +99 -43
  42. package/css/diff-view.css +101 -16
  43. package/css/download-trigger.css +46 -80
  44. package/css/drawer.css +168 -133
  45. package/css/editable.css +19 -0
  46. package/css/empty-state.css +8 -7
  47. package/css/field-array.css +36 -0
  48. package/css/field.css +17 -19
  49. package/css/fieldset.css +1 -1
  50. package/css/file-upload.css +126 -136
  51. package/css/flex.css +324 -8
  52. package/css/float-button.css +168 -41
  53. package/css/floating-panel.css +59 -27
  54. package/css/form.css +26 -20
  55. package/css/funnel-chart.css +106 -0
  56. package/css/graph-chart.css +205 -0
  57. package/css/grid-list.css +235 -0
  58. package/css/grid.css +252 -1
  59. package/css/heatmap.css +119 -36
  60. package/css/hierarchy-chart.css +298 -0
  61. package/css/hover-card.css +33 -18
  62. package/css/icon.css +100 -0
  63. package/css/image-cropper.css +34 -8
  64. package/css/image-viewer.css +169 -26
  65. package/css/image.css +23 -4
  66. package/css/infinite-scroll.css +2 -2
  67. package/css/input-group.css +13 -15
  68. package/css/json-viewer.css +55 -7
  69. package/css/kbd.css +1 -1
  70. package/css/layout.css +71 -21
  71. package/css/liquid.css +106 -0
  72. package/css/list.css +2 -2
  73. package/css/listbox.css +72 -23
  74. package/css/loading-bar.css +27 -13
  75. package/css/log.css +131 -35
  76. package/css/markdown-stream.css +1 -1
  77. package/css/marquee.css +163 -7
  78. package/css/matrix-code.css +1 -1
  79. package/css/mention.css +35 -21
  80. package/css/menu.css +40 -28
  81. package/css/menubar.css +42 -28
  82. package/css/message-feed.css +174 -53
  83. package/css/navigation-menu.css +177 -18
  84. package/css/notification.css +431 -110
  85. package/css/number-field.css +22 -0
  86. package/css/page-header.css +4 -2
  87. package/css/pagination.css +129 -29
  88. package/css/password-input.css +40 -8
  89. package/css/pie-chart.css +247 -0
  90. package/css/popconfirm.css +50 -58
  91. package/css/popover.css +55 -21
  92. package/css/progress.css +308 -10
  93. package/css/prompt-input.css +37 -1
  94. package/css/question-flow.css +104 -64
  95. package/css/radar-chart.css +233 -0
  96. package/css/radio-group.css +372 -14
  97. package/css/rating.css +25 -27
  98. package/css/reasoning.css +62 -55
  99. package/css/reset.css +1 -1
  100. package/css/resizable.css +6 -1
  101. package/css/sankey-chart.css +174 -0
  102. package/css/scroll-area.css +32 -0
  103. package/css/scrollbar.css +1 -1
  104. package/css/select.css +76 -59
  105. package/css/side-nav.css +177 -30
  106. package/css/signature-pad.css +23 -8
  107. package/css/skeleton.css +13 -14
  108. package/css/slider.css +39 -17
  109. package/css/sortable.css +38 -8
  110. package/css/sparkline.css +164 -0
  111. package/css/spinner.css +50 -22
  112. package/css/splitter.css +8 -2
  113. package/css/statistic.css +10 -0
  114. package/css/steps.css +257 -38
  115. package/css/switch.css +30 -55
  116. package/css/table.css +168 -128
  117. package/css/tabs.css +243 -31
  118. package/css/tag-group.css +65 -37
  119. package/css/tag.css +55 -14
  120. package/css/tags-input.css +40 -3
  121. package/css/text-field.css +19 -0
  122. package/css/time-field.css +20 -1
  123. package/css/time-picker.css +44 -17
  124. package/css/time-range-picker.css +45 -18
  125. package/css/timeline.css +1 -1
  126. package/css/toggle-group.css +8 -8
  127. package/css/toggle.css +6 -5
  128. package/css/tool-call.css +64 -56
  129. package/css/toolbar.css +105 -7
  130. package/css/tooltip.css +18 -7
  131. package/css/tour.css +49 -21
  132. package/css/transfer.css +104 -81
  133. package/css/tree-select.css +235 -58
  134. package/css/tree.css +240 -147
  135. package/css/truncate.css +55 -12
  136. package/css/typography.css +93 -0
  137. package/css/virtualizer.css +57 -1
  138. package/css/watermark.css +23 -0
  139. package/family/action-control.css +14 -5
  140. package/family/chart.css +480 -0
  141. package/family/check-mark.css +94 -0
  142. package/family/choice-card.css +97 -0
  143. package/family/collection-item.css +70 -27
  144. package/family/field-chrome.css +1 -12
  145. package/family/loading-ring.css +95 -0
  146. package/family/material.css +72 -0
  147. package/family/menu-choice.css +56 -0
  148. package/family/motion.css +208 -11
  149. package/family/tag-list.css +59 -0
  150. package/index.css +23363 -14091
  151. package/index.unlayered.css +23198 -13922
  152. package/package.json +20 -8
  153. package/css/gradient-text.css +0 -91
  154. package/css/icon-wrapper.css +0 -81
  155. package/css/segmented.css +0 -280
  156. package/css/toast.css +0 -499
package/css/tabs.css CHANGED
@@ -25,7 +25,7 @@
25
25
  /* 缺省是 line 变体:透明标签带,选中项由文字与底部指示条表达。Web Components 升级前还没有
26
26
  data-variant,这组几何基础值也必须画成相同结果,避免定义完成时闪换样式;line 档的面与字色由家族
27
27
  按升级后写入的家族角色给,升级前那一帧只有几何没有面色(与 side-nav / menu 同)。
28
- 悬停与按下的面按承载面分档(§7.2):line 档经家族走白底承载 hover 100 → pressed 200;card 坐在
28
+ 悬停与按下的面按承载面分档:line 档经家族走白底承载 hover 100 → pressed 200;card 坐在
29
29
  画布上 hover 100 → pressed 200;segment 坐在淡底轨道里 hover 200 → pressed 300。card / segment 的
30
30
  六支面槽只在各自形态块里赋值,line 档不消费它们 */
31
31
  --xh-_tabs-list-gap: var(--xh-space-0);
@@ -43,8 +43,11 @@
43
43
  --xh-_tabs-accent-text: var(--xh-_tone-fg, var(--xh-fg-brand-strong));
44
44
 
45
45
  /* 翻页钮的盖底:标签带放不下时它浮在两端,挪到它底下的那截标签要被盖住。line / card 档的标签带是透明的,
46
- 盖底取 surface;坐在别的面上(画布、淡底面板)时由使用者槽换成所在的面。segment 档取轨道的淡底 */
46
+ 盖底取 surface;坐在别的面上(画布、淡底面板)时由使用者槽换成所在的面。segment 档取轨道的淡底。
47
+ 悬停与按下同样要盖得住:淡底阶梯取不透明档,line / card 在白底上 100 → 200,segment 在轨道上 200 → 300 */
47
48
  --xh-_tabs-scroll-trigger-bg: var(--xh-bg-surface);
49
+ --xh-_tabs-scroll-trigger-bg-hover: var(--xh-bg-subtle-opaque);
50
+ --xh-_tabs-scroll-trigger-bg-pressed: var(--xh-bg-subtle-hover-opaque);
48
51
 
49
52
  display: flex;
50
53
  flex-direction: column;
@@ -87,7 +90,7 @@
87
90
  }
88
91
 
89
92
  /* 卡片式:基线收掉,选中的那张标签自己成为一张有描边有底的卡片,顶边一条指示条。
90
- 标签坐在画布上,悬停 100 → 按下 200(§7.2 白底承载) */
93
+ 标签坐在画布上,悬停 100 → 按下 200(白底承载) */
91
94
  [data-scope='tabs'][data-part='root'][data-variant='card'] {
92
95
  --xh-_tabs-list-gap: var(--xh-control-gap-md);
93
96
  --xh-_tabs-list-bg: transparent;
@@ -106,7 +109,7 @@
106
109
  --xh-_tabs-accent-text: var(--xh-_tone-fg, var(--xh-fg-default));
107
110
  }
108
111
 
109
- /* 分段式(§7.3 有滑块开关):淡底轨道承载一块白色抬起的选中面,选中文字保持默认字色。
112
+ /* 分段式(有滑块开关):淡底轨道承载一块白色抬起的选中面,选中文字保持默认字色。
110
113
  未选中标签坐在淡底轨道里,悬停 200 → 按下 300;选中面自己不再叠悬停 / 按下态。
111
114
  选中面的三件(surface-raised 底、border-default 描边、raised 影)写在下面标签自己的规则里 */
112
115
  [data-scope='tabs'][data-part='root'][data-variant='segment'] {
@@ -124,7 +127,9 @@
124
127
  --xh-_tabs-trigger-bg-active-hover: var(--xh-_tone-subtle, var(--xh-bg-surface-raised));
125
128
  --xh-_tabs-trigger-border-active: var(--xh-_tone-border, var(--xh-border-default));
126
129
  --xh-_tabs-accent-text: var(--xh-_tone-fg, var(--xh-fg-default));
127
- --xh-_tabs-scroll-trigger-bg: var(--xh-bg-subtle);
130
+ --xh-_tabs-scroll-trigger-bg: var(--xh-bg-subtle-opaque);
131
+ --xh-_tabs-scroll-trigger-bg-hover: var(--xh-bg-subtle-hover-opaque);
132
+ --xh-_tabs-scroll-trigger-bg-pressed: var(--xh-bg-subtle-active-opaque);
128
133
  }
129
134
 
130
135
  /* 一行排不下不折行:标签整条沿主轴位移露出被裁掉的那截,两端的翻页钮与滚轮驱动,位移量由机器写在
@@ -171,8 +176,8 @@
171
176
  translate: 0 var(--xh-_tabs-scroll);
172
177
  }
173
178
 
174
- /* segment 档的标签带是一块淡底面:--xh-bg-subtle 底 + 一圈透明占位边 + 无影(§8.3 三选一)。
175
- 它同时是标签的淡底承载面,向内下发 hover 200 → pressed 300 的承载阶梯(§7.2);
179
+ /* segment 档的标签带是一块淡底面:--xh-bg-subtle 底 + 一圈透明占位边 + 无影(三选一)。
180
+ 它同时是标签的淡底承载面,向内下发 hover 200 → pressed 300 的承载阶梯;
176
181
  只写在标签带上不写在 root 上:内容面板里的按钮坐在画布上,不该跟着抬一档 */
177
182
  [data-scope='tabs'][data-part='root'][data-variant='segment'] [data-scope='tabs'][data-part='list'] {
178
183
  --xh-action-host-bg-hover: var(--xh-bg-subtle-hover);
@@ -202,9 +207,9 @@
202
207
  min-inline-size: auto;
203
208
  }
204
209
 
205
- /* line 档(§7.3 导航当前页):把公开槽映射到 Collection Item 的 nav 语境桥接槽。静息 muted / regular,
210
+ /* line 档(导航当前页):把公开槽映射到 Collection Item 的 nav 语境桥接槽。静息 muted / regular,
206
211
  悬停 100 + default 字,按下 200 只换面;当前页透明面 + 品牌深字(随语气的 --xh-_tabs-accent-text)+
207
- medium,叠悬停 100(§9.3)。2px 指示线不由家族按条目画:放了 indicator 部件是 list 上的滑动部件,
212
+ medium,叠悬停 100。2px 指示线不由家族按条目画:放了 indicator 部件是 list 上的滑动部件,
208
213
  没放则由下面的静态线规则画在选中标签自己身上。高度由 block-size 定,块向内边距归零 */
209
214
  [data-scope='tabs'][data-part='root'][data-variant='line'] [data-scope='tabs'][data-part='trigger'] {
210
215
  --xh-collection-block-padding: var(--xh-space-0);
@@ -228,7 +233,7 @@
228
233
  color: var(--xh-tabs-trigger-fg, var(--xh-fg-muted));
229
234
  font-weight: var(--xh-tabs-trigger-font-weight, var(--xh-text-label-weight));
230
235
  cursor: pointer;
231
- /* 标签是铺开的一段(§9.2 Tabs trigger 归行级),按下只换面不缩放:transition 里没有 scale */
236
+ /* 标签是铺开的一段(Tabs trigger 归行级),按下只换面不缩放:transition 里没有 scale */
232
237
  transition:
233
238
  color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
234
239
  background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
@@ -242,7 +247,14 @@
242
247
  flex: 0 0 auto;
243
248
  }
244
249
 
245
- /* segment 档是一条轨道里的格子(与 Segmented 同构):格子按可用宽度等分 */
250
+ /* 竖排标签的高就是控件高,不随标签带压缩:使用者限了高、标签带放不下时,靠位移露出被裁掉的那截(与横排同一套),
251
+ 而不是把每一枚压扁到只剩一行字高 */
252
+ [data-scope='tabs'][data-part='root'][data-orientation='vertical']
253
+ [data-scope='tabs'][data-part='trigger'] {
254
+ flex-shrink: 0;
255
+ }
256
+
257
+ /* segment 档是一条轨道里的格子(与 RadioGroup 的 segmented 形态同构):格子按可用宽度等分 */
246
258
  [data-scope='tabs'][data-part='root'][data-orientation='horizontal'][data-variant='segment']
247
259
  [data-scope='tabs'][data-part='trigger'] {
248
260
  flex: 1 1 0;
@@ -257,7 +269,7 @@
257
269
  }
258
270
 
259
271
  /* 按下去要有回应:card / segment 档的未选中标签换到按下面(card 200、segment 300),几何不动。
260
- 选中标签不叠按下面:card 的卡片面与 segment 的抬起面本身就是选中身份(§7.3 有滑块开关无叠加态) */
272
+ 选中标签不叠按下面:card 的卡片面与 segment 的抬起面本身就是选中身份(有滑块开关无叠加态) */
261
273
  [data-scope='tabs'][data-part='root']:is([data-variant='card'], [data-variant='segment'])
262
274
  [data-scope='tabs'][data-part='trigger']:not([data-disabled]):not([data-state='active']):is(:active, [data-pressed]) {
263
275
  background: var(--xh-tabs-trigger-bg-pressed, var(--xh-_tabs-trigger-bg-pressed));
@@ -276,7 +288,7 @@
276
288
  font-weight: var(--xh-tabs-trigger-font-weight-active, var(--xh-font-weight-medium));
277
289
  }
278
290
 
279
- /* segment 档的选中标签就是那块白色抬起的滑块面(§7.3 有滑块开关):surface-raised 底 +
291
+ /* segment 档的选中标签就是那块白色抬起的滑块面(有滑块开关):surface-raised 底 +
280
292
  border-default 描边 + raised 影三件写在标签自己身上。标签带里放了 indicator 部件时,
281
293
  这块面搬到部件上跟着滑(见下面的 indicator 规则),标签自己透空、只留字 */
282
294
  [data-scope='tabs'][data-part='root'][data-variant='segment']
@@ -459,17 +471,26 @@
459
471
  --xh-_tabs-indicator-y: 0;
460
472
  --xh-_tabs-indicator-w: 0;
461
473
  --xh-_tabs-indicator-h: 0;
474
+ --xh-_tabs-indicator-stretch: 0;
462
475
 
476
+ /* 摆在行首,落点交给 transform(只走合成),长度跟着标签宽走。标签带挪动时整条孩子
477
+ 共用的 translate 叠在它之上,两者互不覆盖,过渡也只挂在 transform 上 */
463
478
  position: absolute;
464
479
  inset-block-end: 0;
465
- inset-inline-start: var(--xh-_tabs-indicator-x);
480
+ inset-inline-start: 0;
466
481
  inline-size: var(--xh-_tabs-indicator-w);
467
482
  block-size: var(--xh-tabs-indicator-thickness, var(--xh-stroke-thick));
468
483
  border-radius: var(--xh-tabs-indicator-radius, var(--xh-shape-pill));
469
484
  background: var(--xh-tabs-indicator-color, var(--xh-_tabs-accent));
485
+ transform: translate(var(--xh-_tabs-indicator-x), 0);
470
486
  transition:
471
- inset-inline-start var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous),
472
- inline-size var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous);
487
+ transform var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
488
+ inline-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
489
+ }
490
+
491
+ /* transform 只认物理方向:RTL 下行首在右边,起始缘量出的距离往左推 */
492
+ [data-scope='tabs'][data-part='indicator']:dir(rtl) {
493
+ transform: translate(calc(-1 * var(--xh-_tabs-indicator-x)), 0);
473
494
  }
474
495
 
475
496
  /* 卡片变体已经由卡片面表达状态,不再叠一条下划线。 */
@@ -477,15 +498,15 @@
477
498
  display: none;
478
499
  }
479
500
 
480
- /* segment 档(§7.3 有滑块开关):部件就是那块白色抬起的滑块面,四个几何量都取、整块跟着滑——
481
- surface-raised 底 + border-default 描边 + raised 影三件与 Segmented 的滑块同一套;
501
+ /* segment 档(有滑块开关):部件就是那块白色抬起的滑块面,四个几何量都取、整块跟着滑——
502
+ surface-raised 底 + border-default 描边 + raised 影三件与 RadioGroup segmented 形态的滑块同一套;
482
503
  描边吃进盒里(border-box),面与标签仍是同一块矩形。标签压在它上面,点击一律交给标签。
483
504
  用连续档而不是进场那条:滑块是被推过去的,起步就该有速度;四个几何量同时走,标签宽不等时才不会先变形再挪位 */
484
505
  [data-scope='tabs'][data-part='indicator'][data-variant='segment'] {
485
506
  inset-block-end: auto;
486
507
  inset-inline-end: auto;
487
- inset-inline-start: var(--xh-_tabs-indicator-x);
488
- inset-block-start: var(--xh-_tabs-indicator-y);
508
+ inset-inline-start: 0;
509
+ inset-block-start: 0;
489
510
  inline-size: var(--xh-_tabs-indicator-w);
490
511
  block-size: var(--xh-_tabs-indicator-h);
491
512
  box-sizing: border-box;
@@ -494,14 +515,18 @@
494
515
  background: var(--xh-tabs-trigger-bg-active, var(--xh-_tone-subtle, var(--xh-bg-surface-raised)));
495
516
  box-shadow: var(--xh-tabs-trigger-shadow-active, var(--xh-elevation-raised));
496
517
  pointer-events: none;
518
+ transform: translate(var(--xh-_tabs-indicator-x), var(--xh-_tabs-indicator-y));
497
519
  transition:
498
- inset-inline-start var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous),
499
- inset-block-start var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous),
500
- inline-size var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous),
501
- block-size var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous);
520
+ transform var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
521
+ inline-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
522
+ block-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
523
+ }
524
+
525
+ [data-scope='tabs'][data-part='indicator'][data-variant='segment']:dir(rtl) {
526
+ transform: translate(calc(-1 * var(--xh-_tabs-indicator-x)), var(--xh-_tabs-indicator-y));
502
527
  }
503
528
 
504
- /* line 档没放 indicator 部件时,选中标签自画一条静态指示线(§7.3 导航当前页):
529
+ /* line 档没放 indicator 部件时,选中标签自画一条静态指示线(导航当前页):
505
530
  横向缺省也要像纵向示例那样有一条选中线,作者不必为了这条线多放一个部件。
506
531
  线画在选中标签的 ::after 上,以标签盒为定位参照(基础规则里已是 position: relative),
507
532
  厚度 / 颜色 / 圆角与 indicator 部件读同一组槽与缺省——作者改一处,部件与静态线一起改。
@@ -543,12 +568,32 @@
543
568
  inset-block-end: auto;
544
569
  inset-inline-start: auto;
545
570
  inset-inline-end: 0;
546
- inset-block-start: var(--xh-_tabs-indicator-y);
571
+ inset-block-start: 0;
547
572
  block-size: var(--xh-_tabs-indicator-h);
548
573
  inline-size: var(--xh-tabs-indicator-thickness, var(--xh-stroke-thick));
574
+ transform: translate(0, var(--xh-_tabs-indicator-y));
549
575
  transition:
550
- inset-block-start var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous),
551
- block-size var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous);
576
+ transform var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
577
+ block-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
578
+ }
579
+
580
+ /* 首次落位与同一项的重量(窗口缩放、换上正式字体)直接到位,只有换项才滑:连接层在这一落点投影
581
+ data-instant。选择器带上排布与形态,压得过上面按它们单写的过渡 */
582
+ [data-scope='tabs'][data-part='indicator'][data-orientation][data-variant][data-instant] {
583
+ transition: none;
584
+ }
585
+
586
+ /* 液态档:两沿由弹簧逐帧推着走(连接层每一帧写好盒子),几何量不再补过渡(选择器带上排布与形态,压得过上面按它们单写的过渡);
587
+ 被拉长时在另一个方向上压扁,表达体积守恒,拉长到目标的两倍时压到 --xh-motion-scale-squash */
588
+ :where([data-material='liquid']) [data-scope='tabs'][data-part='indicator'][data-orientation][data-variant] {
589
+ --xh-_tabs-indicator-squash: max(var(--xh-motion-scale-squash), calc(1 - var(--xh-_tabs-indicator-stretch) * (1 - var(--xh-motion-scale-squash))));
590
+
591
+ scale: 1 var(--xh-_tabs-indicator-squash);
592
+ transition: none;
593
+ }
594
+
595
+ :where([data-material='liquid']) [data-scope='tabs'][data-part='indicator'][data-orientation='vertical'][data-variant] {
596
+ scale: var(--xh-_tabs-indicator-squash) 1;
552
597
  }
553
598
 
554
599
  /* 标签之间的细线:横排时是一条竖线,竖排时躺平 */
@@ -571,11 +616,13 @@
571
616
  /* 标签带放不下时浮在两端的单图标钮,接 Action Control icon 档 ghost 面(连接层投影 profile / variant / size):
572
617
  盒取标签同高的正方形,四态面、0.97 按压与粗指针 44px 命中区由家族配方给。绝对定位贴在标签带两端、
573
618
  不随标签位移;挪到它底下的那截标签由静息底盖住(透明 ghost 面盖不住字,静息 / 焦点 / 禁用三列换成盖底槽,
574
- 悬停与按下仍走 ghost 的阶梯——line / card 在白底上 100 → 200,segment 由轨道下发 200 → 300) */
619
+ 悬停与按下换成盖底档的不透明阶梯——line / card 在白底上 100 → 200,segment 在轨道上 200 → 300) */
575
620
  [data-scope='tabs'][data-part='prev-trigger'],
576
621
  [data-scope='tabs'][data-part='next-trigger'] {
577
622
  --xh-action-visual-size: var(--xh-tabs-trigger-h, var(--xh-_tabs-trigger-h));
578
623
  --xh-action-bg-rest: var(--xh-tabs-scroll-trigger-bg, var(--xh-_tabs-scroll-trigger-bg));
624
+ --xh-action-bg-hover: var(--xh-_tabs-scroll-trigger-bg-hover);
625
+ --xh-action-bg-pressed: var(--xh-_tabs-scroll-trigger-bg-pressed);
579
626
  --xh-action-bg-focus-visible: var(--xh-tabs-scroll-trigger-bg, var(--xh-_tabs-scroll-trigger-bg));
580
627
  --xh-action-bg-disabled: var(--xh-tabs-scroll-trigger-bg, var(--xh-_tabs-scroll-trigger-bg));
581
628
  --xh-action-fg-rest: var(--xh-tabs-scroll-trigger-fg, var(--xh-fg-muted));
@@ -661,15 +708,159 @@
661
708
  mask-image: var(--xh-glyph-mark-chevron-down);
662
709
  }
663
710
 
711
+ /* —— 「更多」钮 —— */
712
+ /* 放了「更多」钮:钮排在标签带之后、同一行(竖排是同一列的列尾)。它不能放进标签带——tablist 只收 tab,
713
+ 所以是 root 的孩子;root 换成两轨网格,标签带占能伸缩的那一轨、钮占按内容的那一轨,面板等其余孩子横跨两轨排在
714
+ 下面(竖排排在右侧)。钮收着(hidden)时那一轨是 0,标签带铺满;钮与标签带之间的间距挂在钮自己身上,
715
+ 收着时一并让开。标签带的可用长度因此随钮的有无变:放不放得下由机器按让回钮那一截算,钮不会自己把自己留住 */
716
+ [data-scope='tabs'][data-part='root']:has(> [data-scope='tabs'][data-part='overflow-trigger']) {
717
+ display: grid;
718
+ grid-template-columns: minmax(0, 1fr) auto;
719
+ column-gap: 0;
720
+ row-gap: var(--xh-tabs-gap, var(--xh-stack-gap-md));
721
+ }
722
+
723
+ [data-scope='tabs'][data-part='root']:has(> [data-scope='tabs'][data-part='overflow-trigger']) > * {
724
+ grid-column: 1 / -1;
725
+ }
726
+
727
+ [data-scope='tabs'][data-part='root']:has(> [data-scope='tabs'][data-part='overflow-trigger'])
728
+ > [data-scope='tabs'][data-part='list'] {
729
+ grid-row: 1;
730
+ grid-column: 1;
731
+ }
732
+
733
+ [data-scope='tabs'][data-part='root']:has(> [data-scope='tabs'][data-part='overflow-trigger'])
734
+ > [data-scope='tabs'][data-part='overflow-trigger'] {
735
+ grid-row: 1;
736
+ grid-column: 2;
737
+ align-self: center;
738
+ margin-inline-start: var(--xh-space-1);
739
+ }
740
+
741
+ /* 竖排:标签带与钮上下叠成左侧一列(钮在列尾),面板占右侧那一轨、跨两行 */
742
+ [data-scope='tabs'][data-part='root'][data-orientation='vertical']:has(> [data-scope='tabs'][data-part='overflow-trigger']) {
743
+ grid-template-rows: minmax(0, 1fr) auto;
744
+ grid-template-columns: auto minmax(0, 1fr);
745
+ column-gap: var(--xh-tabs-gap, var(--xh-stack-gap-md));
746
+ row-gap: 0;
747
+ }
748
+
749
+ [data-scope='tabs'][data-part='root'][data-orientation='vertical']:has(> [data-scope='tabs'][data-part='overflow-trigger']) > * {
750
+ grid-row: 1 / -1;
751
+ grid-column: 2;
752
+ }
753
+
754
+ [data-scope='tabs'][data-part='root'][data-orientation='vertical']:has(> [data-scope='tabs'][data-part='overflow-trigger'])
755
+ > [data-scope='tabs'][data-part='list'] {
756
+ grid-row: 1;
757
+ grid-column: 1;
758
+ }
759
+
760
+ [data-scope='tabs'][data-part='root'][data-orientation='vertical']:has(> [data-scope='tabs'][data-part='overflow-trigger'])
761
+ > [data-scope='tabs'][data-part='overflow-trigger'] {
762
+ grid-row: 2;
763
+ grid-column: 1;
764
+ align-self: auto;
765
+ margin-inline-start: 0;
766
+ margin-block-start: var(--xh-space-1);
767
+ }
768
+
769
+ /* 钮本身:接 Action Control icon 档 ghost 面(连接层投影 profile / variant / size),盒取标签同高的正方形,
770
+ 与两端翻页钮同一身份;四态面、0.97 按压、焦点环与粗指针 44px 命中区由家族配方给。它坐在 root 的面上
771
+ (不在标签带里),承载面阶梯走家族缺省的白底 100 → 200;字取次要色,与静息的标签、翻页钮同档 */
772
+ [data-scope='tabs'][data-part='overflow-trigger'] {
773
+ --xh-action-visual-size: var(--xh-tabs-trigger-h, var(--xh-_tabs-trigger-h));
774
+ --xh-action-fg-rest: var(--xh-fg-muted);
775
+ /* 作者塞进来的图标跟着 icon 档走,与皮肤画的兜底字形同一把尺 */
776
+ --xh-icon-size: var(--xh-_action-profile-glyph-size);
777
+
778
+ touch-action: manipulation;
779
+ }
780
+
781
+ /* 竖排:与竖排的翻页钮一样躺平成横贯标签带那一列的一条 */
782
+ [data-scope='tabs'][data-part='overflow-trigger'][data-orientation='vertical'] {
783
+ inline-size: auto;
784
+ }
785
+
786
+ /* 下拉开着:与悬停同档的中性面,不用品牌色、不另画环;列的是哪几个标签由下拉本身说明 */
787
+ [data-scope='tabs'][data-part='overflow-trigger'][data-state='open'] {
788
+ --xh-action-bg-rest: var(--xh-_action-variant-bg-hover);
789
+ --xh-action-bg-focus-visible: var(--xh-_action-variant-bg-hover);
790
+ }
791
+
792
+ /* 没写内容就由皮肤画兜底字形:横排三点(与工具条的「更多」同一枚)。作者塞了自己的图标这条即不命中 */
793
+ [data-scope='tabs'][data-part='overflow-trigger']:empty::before {
794
+ content: '';
795
+ display: inline-block;
796
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
797
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
798
+ background-color: currentColor;
799
+ -webkit-mask: var(--xh-glyph-mark-ellipsis) center / contain no-repeat;
800
+ mask: var(--xh-glyph-mark-ellipsis) center / contain no-repeat;
801
+ }
802
+
803
+ /* —— 关闭钮 —— */
804
+ /* 关闭钮与所属标签平级、紧跟其后(不嵌进 role=tab 的按钮里),画面上收进标签面的行尾:标签在行尾让出一格
805
+ (钮的边长 + 与行尾的留白 + 与文字的间距),钮以负的起始外边距退回这一格,结束外边距补回同样的留白,
806
+ 下一枚标签的起点与没有关闭钮时一致。留白取标签与钮高度差的一半,钮在标签里上下左右都居中对齐。
807
+ 面归 Action Control icon 档 ghost 面、xs 档(连接层投影):四态面、0.97 按压与粗指针命中区由家族配方给,
808
+ 这里只管落位与字色。悬停落在钮上时标签自己回到静息面,只有钮亮起,按下去关的是哪一个一目了然 */
809
+ [data-scope='tabs'][data-part='root'] {
810
+ --xh-_tabs-close-size: var(--xh-control-action-size);
811
+ --xh-_tabs-close-inset: calc((var(--xh-tabs-trigger-h, var(--xh-_tabs-trigger-h)) - var(--xh-_tabs-close-size)) / 2);
812
+ /* 钮退回去的距离:横排退过自己、行尾留白与标签带间距;竖排退过半个标签高、半个钮高与标签带间距 */
813
+ --xh-_tabs-close-offset: calc(var(--xh-_tabs-close-size) + var(--xh-_tabs-close-inset) + var(--xh-tabs-list-gap, var(--xh-_tabs-list-gap)));
814
+ --xh-_tabs-close-offset-block: calc((var(--xh-tabs-trigger-h, var(--xh-_tabs-trigger-h)) + var(--xh-_tabs-close-size)) / 2 + var(--xh-tabs-list-gap, var(--xh-_tabs-list-gap)));
815
+ }
816
+
817
+ [data-scope='tabs'][data-part='trigger']:has(+ [data-scope='tabs'][data-part='close-trigger']:not([hidden])) {
818
+ padding-inline-end: calc(var(--xh-_tabs-close-size) + var(--xh-_tabs-close-inset) + var(--xh-space-1));
819
+ }
820
+
821
+ [data-scope='tabs'][data-part='close-trigger'] {
822
+ --xh-action-fg-rest: var(--xh-fg-muted);
823
+ /* 作者塞进来的图标跟着 xs 档走,与皮肤画的兜底字形同一把尺 */
824
+ --xh-icon-size: var(--xh-_action-profile-glyph-size);
825
+
826
+ flex: none;
827
+ /* segment 档的标签抬了一层压在滑动的抬起面上,钮排在标签之后、同一层即压在标签上 */
828
+ z-index: 1;
829
+ margin-inline-start: calc(-1 * var(--xh-_tabs-close-offset));
830
+ margin-inline-end: var(--xh-_tabs-close-inset);
831
+ }
832
+
833
+ /* 竖排:标签上下排开,钮退回的是上一行——起始外边距改在块向,行向贴到行尾 */
834
+ [data-scope='tabs'][data-part='root'][data-orientation='vertical'] [data-scope='tabs'][data-part='close-trigger'] {
835
+ align-self: flex-end;
836
+ margin-block-start: calc(-1 * var(--xh-_tabs-close-offset-block));
837
+ margin-block-end: var(--xh-_tabs-close-inset);
838
+ margin-inline-start: 0;
839
+ }
840
+
841
+ /* 没写内容就由皮肤画一枚叉;作者塞了自己的图形这一条即不命中 */
842
+ [data-scope='tabs'][data-part='close-trigger']:empty::before {
843
+ content: '';
844
+ display: inline-block;
845
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
846
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
847
+ vertical-align: var(--xh-glyph-baseline-shift);
848
+ background-color: currentColor;
849
+ -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
850
+ mask: var(--xh-glyph-mark-close) center / contain no-repeat;
851
+ }
852
+
664
853
  /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
665
854
  写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
666
855
  [data-scope='tabs'][data-part='root'][hidden],
667
856
  [data-scope='tabs'][data-part='list'][hidden],
668
857
  [data-scope='tabs'][data-part='trigger'][hidden],
858
+ [data-scope='tabs'][data-part='close-trigger'][hidden],
669
859
  [data-scope='tabs'][data-part='indicator'][hidden],
670
860
  [data-scope='tabs'][data-part='separator'][hidden],
671
861
  [data-scope='tabs'][data-part='prev-trigger'][hidden],
672
862
  [data-scope='tabs'][data-part='next-trigger'][hidden],
863
+ [data-scope='tabs'][data-part='overflow-trigger'][hidden],
673
864
  [data-scope='tabs'][data-part='tab-drag-trigger'][hidden] {
674
865
  display: none;
675
866
  }
@@ -723,10 +914,31 @@
723
914
  text-decoration: underline;
724
915
  }
725
916
 
726
- /* 纸上翻不了页,两只钮不上纸 */
917
+ /* 纸上翻不了页、关不了标签、也弹不出下拉,这几只钮不上纸 */
727
918
  [data-scope='tabs'][data-part='prev-trigger'],
728
- [data-scope='tabs'][data-part='next-trigger'] {
919
+ [data-scope='tabs'][data-part='next-trigger'],
920
+ [data-scope='tabs'][data-part='overflow-trigger'],
921
+ [data-scope='tabs'][data-part='close-trigger'] {
729
922
  display: none;
730
923
  }
731
924
  }
925
+
926
+ @media (forced-colors: active) {
927
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
928
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
929
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
930
+ 禁用取 GrayText */
931
+ [data-scope='tabs']:is([data-part='prev-trigger'], [data-part='next-trigger'], [data-part='close-trigger'], [data-part='overflow-trigger']):empty::before {
932
+ forced-color-adjust: none;
933
+ background-color: ButtonText;
934
+ }
935
+
936
+ [data-scope='tabs']:is([data-part='prev-trigger'], [data-part='next-trigger'], [data-part='close-trigger'], [data-part='overflow-trigger']):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
937
+ background-color: HighlightText;
938
+ }
939
+
940
+ [data-scope='tabs']:is([data-part='prev-trigger'], [data-part='next-trigger'], [data-part='close-trigger'], [data-part='overflow-trigger'])[data-disabled]:empty::before {
941
+ background-color: GrayText;
942
+ }
943
+ }
732
944
  }
package/css/tag-group.css CHANGED
@@ -5,6 +5,9 @@
5
5
 
6
6
  /* 定义 tag group 样式。 */
7
7
 
8
+ /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
9
+ @import '../family/motion.css';
10
+
8
11
  @layer xihan.components {
9
12
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
13
  [data-scope='tag-group'] {
@@ -61,10 +64,23 @@
61
64
  标签这时是拿焦点的那个节点,按下与松手之间要有回应;选中与锚点的过渡也挂在这一层 */
62
65
  [data-scope='tag-group'][data-part='list'] > [data-scope='tag'][data-part='root'] {
63
66
  user-select: none;
67
+ /* 增删一枚、其余标签换到新位置时,由列表动效先反向补偿、再沿 translate 这条滑过去 */
64
68
  transition:
65
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
69
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
66
70
  color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
67
- scale var(--xh-motion-duration-release) var(--xh-motion-ease-release);
71
+ scale var(--xh-motion-duration-release) var(--xh-motion-ease-release),
72
+ translate var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
73
+ }
74
+
75
+ /* 新加的标签原地弹出(横排胶囊不用竖向上浮),同一批按到达顺序错开;首帧就在的直接呈现 */
76
+ [data-scope='tag-group'][data-part='list']:not([data-instant]) > [data-scope='tag'][data-part='root']:not([data-instant], [data-state='closed']) {
77
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
78
+ animation-delay: calc(var(--xh-_stagger-index, 0) * var(--xh-motion-stagger-step));
79
+ }
80
+
81
+ /* 删掉的标签:替身留在原处淡出,播完即移除 */
82
+ [data-scope='tag-group'][data-part='list'] > [data-scope='tag'][data-part='root'][data-state='closed'] {
83
+ animation: xh-fade-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
68
84
  }
69
85
 
70
86
  /* 参与选中的标签才是点击目标,只是标记的那些不给手势暗示 */
@@ -72,7 +88,7 @@
72
88
  cursor: pointer;
73
89
  }
74
90
 
75
- /* 按下去要有回应:可选的芯片是一颗定尺的离散控件(§9.1),整枚轻微下压并同时换底
91
+ /* 按下去要有回应:可选的芯片是一颗定尺的离散控件,整枚轻微下压并同时换底
76
92
  (白底承载 hover 100 → pressed 200),松手即弹回。置灰的不压;
77
93
  指针 :active 与 Headless 投影的 data-pressed 看见同一副按压面 */
78
94
  [data-scope='tag-group'][data-part='list']
@@ -106,7 +122,7 @@
106
122
  background: var(--xh-tag-group-item-bg-pressed-solid, var(--xh-_tone-active, var(--xh-bg-brand-active)));
107
123
  }
108
124
 
109
- /* 悬停与键盘锚点共用白底承载的 hover 档(§7.2:hover 100 → pressed 200):
125
+ /* 悬停与键盘锚点共用白底承载的 hover 档(hover 100 → pressed 200):
110
126
  data-highlighted 跟的是连接层记的焦点标签,与选中互相独立。
111
127
  实心标签不进这里:它的字是实心底上配对的那支前景色,换成灰底就读不出来了;
112
128
  实心档在这两档里面不换,回执落在按压缩放与聚焦环上 */
@@ -129,32 +145,8 @@
129
145
  }
130
146
 
131
147
  /* —— 选中 —— */
132
- /* 页内持久集合的选中(§7.3):品牌淡底行面 + 配对前景 + 前导对号(item-indicator),描边退到透明边位;
133
- 悬停与按下在淡底上派生 20% / 28%,键盘锚点同悬停档。
134
- 标了语气的组从语气层取同一条曲线。置灰的标签不进这里:它的边与字都已退成置灰色。
135
- 实心档另有一条:它的面本身就是那族色,淡底与配对前景压在上面都读不出来 */
136
- [data-scope='tag-group'][data-part='list']
137
- > [data-scope='tag'][data-part='root'][data-selected]:not([data-disabled]):not([data-variant='solid']) {
138
- border-color: var(--xh-tag-group-item-border-selected, transparent);
139
- background: var(--xh-tag-group-item-bg-selected, var(--xh-_tone-subtle, var(--xh-bg-brand-subtle)));
140
- color: var(--xh-tag-group-item-fg-selected, var(--xh-_tone-fg, var(--xh-fg-on-brand-subtle)));
141
- }
142
-
143
- [data-scope='tag-group'][data-part='list']
144
- > [data-scope='tag'][data-part='root'][data-selected]:not([data-disabled]):not([data-variant='solid']):is(:hover, [data-highlighted]) {
145
- background: var(--xh-tag-group-item-bg-selected-hover, var(--xh-_tone-subtle-hover, var(--xh-bg-brand-subtle-hover)));
146
- }
147
-
148
- [data-scope='tag-group'][data-part='list']
149
- > [data-scope='tag'][data-part='root'][data-selected][data-selectable]:not([data-disabled]):not([data-variant='solid']):is(:active, [data-pressed]) {
150
- background: var(--xh-tag-group-item-bg-selected-pressed, var(--xh-_tone-subtle-active, var(--xh-bg-brand-subtle-active)));
151
- }
152
-
153
- /* 实心标签选中:字不换(仍是 tag.css 给的面配对前景色,作者的 --xh-tag-fg 照旧生效),
154
- 描边取字色,在实心底上描出一圈;环由 tag.css 取 currentColor,跟着字走 */
155
- [data-scope='tag-group'][data-part='list'] > [data-scope='tag'][data-part='root'][data-variant='solid'][data-selected]:not([data-disabled]) {
156
- border-color: var(--xh-tag-group-item-border-selected, currentColor);
157
- }
148
+ /* 与树选择同一种读法:选中的标签面、字与描边都不换,悬停 / 锚点 / 按下沿用未选中的那条阶梯,
149
+ 只在文字后亮一枚对号(见下面 item-indicator 那几块) */
158
150
 
159
151
  /* 标签里那一格:文字与摘除钮排在一条线上。它是 tag 根与 tag 的 label / close-trigger 之间的一层,
160
152
  间距照抄所在标签的那一档,有它与没它标签长得一样 */
@@ -170,7 +162,8 @@
170
162
  display: none;
171
163
  }
172
164
 
173
- /* 选中标记:领在文字前面的一枚对号,与摘除钮的叉同一把随文尺(标签是纯行内文字组件);
165
+ /* 选中标记:跟在文字后面的一枚对号,与摘除钮的叉同一把随文尺(标签是纯行内文字组件);
166
+ 作者写在格里哪儿都排到文字与作者内容之后、摘除钮之前。
174
167
  作者塞进来的图标读同一支 --xh-icon-size。连接层没选中时给 hidden,UA 的 display:none 被上面的 display 盖住,
175
168
  这里压回去 */
176
169
  [data-scope='tag-group'][data-part='item-indicator'] {
@@ -178,17 +171,34 @@
178
171
 
179
172
  display: inline-flex;
180
173
  flex: none;
174
+ order: 1;
181
175
  align-items: center;
182
176
  justify-content: center;
183
177
  inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
184
178
  block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
185
- color: var(--xh-tag-group-item-indicator-fg, currentColor);
179
+ /* 与树选择的行尾对号同色:标了语气的组取语气字色,没写语气取品牌前景 */
180
+ color: var(--xh-tag-group-item-indicator-fg, var(--xh-_tone-fg, var(--xh-fg-brand)));
186
181
  }
187
182
 
188
183
  [data-scope='tag-group'][data-part='item-indicator'][hidden] {
189
184
  display: none;
190
185
  }
191
186
 
187
+ /* 实心标签的面本身就是那族色,品牌 / 语气字色压在上面读不出来:对号取面配对的那支前景色 */
188
+ [data-scope='tag'][data-part='root'][data-variant='solid'] [data-scope='tag-group'][data-part='item-indicator'] {
189
+ color: var(--xh-tag-group-item-indicator-fg, currentColor);
190
+ }
191
+
192
+ /* 置灰的标签里对号跟着字一起退成置灰色 */
193
+ [data-scope='tag-group'][data-part='item-indicator'][data-disabled] {
194
+ color: inherit;
195
+ }
196
+
197
+ /* 摘除钮是操作,排在对号之后、格的最末 */
198
+ [data-scope='tag-group'][data-part='cell'] > [data-scope='tag'][data-part='close-trigger'] {
199
+ order: 2;
200
+ }
201
+
192
202
  /* 没写内容就由皮肤画兜底对号;作者往部件里塞了自己的图形,这条即不命中 */
193
203
  [data-scope='tag-group'][data-part='item-indicator']:empty::before {
194
204
  content: '';
@@ -201,12 +211,23 @@
201
211
  }
202
212
 
203
213
  @media (forced-colors: active) {
204
- /* 选中靠淡底与配对前景表出,这一档里两者都被统一换掉;用系统高亮反色画回,前导对号是字形节点、自己活得下来 */
214
+ /* 选中只由对号表达:遮罩出来的那块底色退出强制换色、用系统高亮色画,按下时标签整枚反成 Highlight,对号换成反白;
215
+ 禁用的标签取 GrayText */
216
+ [data-scope='tag-group'][data-part='item-indicator']:empty::before {
217
+ forced-color-adjust: none;
218
+ background-color: Highlight;
219
+ }
220
+
205
221
  [data-scope='tag-group'][data-part='list']
206
- > [data-scope='tag'][data-part='root'][data-selected]:not([data-disabled]):not([data-variant='solid']) {
207
- border-color: Highlight;
208
- background: Highlight;
209
- color: HighlightText;
222
+ > [data-scope='tag'][data-part='root'][data-disabled]
223
+ [data-scope='tag-group'][data-part='item-indicator']:empty::before {
224
+ background-color: GrayText;
225
+ }
226
+
227
+ [data-scope='tag-group'][data-part='list']
228
+ > [data-scope='tag'][data-part='root'][data-selectable]:not([data-disabled]):not([data-variant='solid']):is(:active, [data-pressed])
229
+ [data-scope='tag-group'][data-part='item-indicator']:empty::before {
230
+ background-color: HighlightText;
210
231
  }
211
232
 
212
233
  /* 按下:常态靠底色深一档表出,这一档里底色被统一换成 Canvas;按住那一下用系统高亮反色画回来 */
@@ -216,4 +237,11 @@
216
237
  color: HighlightText;
217
238
  }
218
239
  }
240
+
241
+ @media print {
242
+ /* 打印默认丢底色,而对号是遮罩出来的一块底色:标签本就不换面,丢了它选中在纸上就没了踪影 */
243
+ [data-scope='tag-group'][data-part='item-indicator'] {
244
+ print-color-adjust: exact;
245
+ }
246
+ }
219
247
  }