@xihan-ui/styles 2.1.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 (152) hide show
  1. package/CHANGELOG.md +1227 -0
  2. package/README.md +6 -1
  3. package/component-tokens.d.ts +505 -96
  4. package/components.tokens.json +34636 -25846
  5. package/css/accordion.css +34 -8
  6. package/css/alert.css +59 -1
  7. package/css/anchor.css +46 -8
  8. package/css/approval.css +116 -76
  9. package/css/avatar-group.css +1 -1
  10. package/css/avatar.css +13 -5
  11. package/css/back-top.css +61 -42
  12. package/css/badge.css +62 -12
  13. package/css/bar-code.css +1 -1
  14. package/css/breadcrumb.css +62 -3
  15. package/css/button-group.css +4 -4
  16. package/css/button.css +67 -19
  17. package/css/calendar-picker.css +19 -0
  18. package/css/calendar-range-picker.css +39 -2
  19. package/css/card.css +115 -1
  20. package/css/carousel.css +148 -43
  21. package/css/cartesian-chart.css +830 -0
  22. package/css/cascader.css +181 -65
  23. package/css/checkbox-group.css +59 -89
  24. package/css/checkbox.css +16 -49
  25. package/css/citation.css +470 -0
  26. package/css/clipboard.css +20 -63
  27. package/css/code-view.css +101 -6
  28. package/css/collapsible.css +34 -8
  29. package/css/color-field.css +18 -0
  30. package/css/color-picker.css +55 -58
  31. package/css/color-slider.css +22 -15
  32. package/css/color-swatch-picker.css +3 -1
  33. package/css/combobox.css +80 -33
  34. package/css/command.css +45 -43
  35. package/css/context-menu.css +39 -22
  36. package/css/date-field.css +23 -0
  37. package/css/date-picker.css +57 -22
  38. package/css/date-range-picker.css +301 -12
  39. package/css/description.css +17 -1
  40. package/css/descriptions.css +42 -0
  41. package/css/dialog.css +94 -36
  42. package/css/diff-view.css +97 -12
  43. package/css/download-trigger.css +44 -78
  44. package/css/drawer.css +160 -119
  45. package/css/editable.css +19 -0
  46. package/css/empty-state.css +7 -6
  47. package/css/field-array.css +36 -0
  48. package/css/field.css +16 -18
  49. package/css/file-upload.css +125 -135
  50. package/css/flex.css +324 -8
  51. package/css/float-button.css +165 -38
  52. package/css/floating-panel.css +53 -19
  53. package/css/form.css +23 -17
  54. package/css/funnel-chart.css +106 -0
  55. package/css/graph-chart.css +205 -0
  56. package/css/grid-list.css +235 -0
  57. package/css/grid.css +252 -1
  58. package/css/heatmap.css +119 -36
  59. package/css/hierarchy-chart.css +298 -0
  60. package/css/hover-card.css +31 -14
  61. package/css/icon.css +100 -0
  62. package/css/image-cropper.css +33 -7
  63. package/css/image-viewer.css +167 -22
  64. package/css/image.css +23 -4
  65. package/css/input-group.css +11 -13
  66. package/css/json-viewer.css +50 -2
  67. package/css/layout.css +68 -18
  68. package/css/liquid.css +106 -0
  69. package/css/list.css +1 -1
  70. package/css/listbox.css +46 -6
  71. package/css/loading-bar.css +27 -13
  72. package/css/log.css +129 -33
  73. package/css/markdown-stream.css +1 -1
  74. package/css/marquee.css +163 -7
  75. package/css/matrix-code.css +1 -1
  76. package/css/mention.css +35 -19
  77. package/css/menu.css +35 -21
  78. package/css/menubar.css +36 -20
  79. package/css/message-feed.css +172 -51
  80. package/css/navigation-menu.css +172 -11
  81. package/css/notification.css +429 -108
  82. package/css/number-field.css +22 -0
  83. package/css/page-header.css +3 -1
  84. package/css/pagination.css +126 -24
  85. package/css/password-input.css +40 -8
  86. package/css/pie-chart.css +247 -0
  87. package/css/popconfirm.css +44 -50
  88. package/css/popover.css +50 -14
  89. package/css/progress.css +308 -10
  90. package/css/prompt-input.css +36 -0
  91. package/css/question-flow.css +97 -57
  92. package/css/radar-chart.css +233 -0
  93. package/css/radio-group.css +363 -5
  94. package/css/rating.css +21 -23
  95. package/css/reasoning.css +61 -54
  96. package/css/resizable.css +6 -1
  97. package/css/sankey-chart.css +174 -0
  98. package/css/scroll-area.css +32 -0
  99. package/css/scrollbar.css +1 -1
  100. package/css/select.css +74 -55
  101. package/css/side-nav.css +173 -24
  102. package/css/signature-pad.css +16 -1
  103. package/css/skeleton.css +13 -14
  104. package/css/slider.css +35 -13
  105. package/css/sortable.css +37 -7
  106. package/css/sparkline.css +164 -0
  107. package/css/spinner.css +50 -22
  108. package/css/splitter.css +7 -1
  109. package/css/statistic.css +10 -0
  110. package/css/steps.css +248 -29
  111. package/css/switch.css +23 -48
  112. package/css/table.css +158 -118
  113. package/css/tabs.css +231 -19
  114. package/css/tag-group.css +27 -3
  115. package/css/tag.css +53 -12
  116. package/css/tags-input.css +40 -3
  117. package/css/text-field.css +19 -0
  118. package/css/time-field.css +20 -1
  119. package/css/time-picker.css +44 -15
  120. package/css/time-range-picker.css +45 -16
  121. package/css/timeline.css +1 -1
  122. package/css/toggle-group.css +4 -4
  123. package/css/toggle.css +4 -3
  124. package/css/tool-call.css +59 -51
  125. package/css/toolbar.css +101 -3
  126. package/css/tooltip.css +15 -2
  127. package/css/tour.css +42 -12
  128. package/css/transfer.css +98 -75
  129. package/css/tree-select.css +232 -53
  130. package/css/tree.css +201 -55
  131. package/css/truncate.css +55 -12
  132. package/css/typography.css +93 -0
  133. package/css/virtualizer.css +56 -0
  134. package/css/watermark.css +23 -0
  135. package/family/action-control.css +14 -5
  136. package/family/chart.css +480 -0
  137. package/family/check-mark.css +94 -0
  138. package/family/choice-card.css +97 -0
  139. package/family/collection-item.css +9 -15
  140. package/family/field-chrome.css +1 -12
  141. package/family/loading-ring.css +95 -0
  142. package/family/material.css +72 -0
  143. package/family/menu-choice.css +56 -0
  144. package/family/motion.css +207 -10
  145. package/family/tag-list.css +59 -0
  146. package/index.css +22997 -13678
  147. package/index.unlayered.css +12928 -3605
  148. package/package.json +20 -8
  149. package/css/gradient-text.css +0 -91
  150. package/css/icon-wrapper.css +0 -81
  151. package/css/segmented.css +0 -280
  152. package/css/toast.css +0 -499
@@ -63,6 +63,7 @@
63
63
  --xh-_time-picker-control-px: var(--xh-control-px-md);
64
64
  --xh-_time-picker-gap: var(--xh-control-gap-md);
65
65
  --xh-_time-picker-font-size: var(--xh-control-font-md);
66
+ --xh-_time-picker-item-py: var(--xh-list-option-py-md);
66
67
 
67
68
  /* 段位强调随语气走:当前段是「当前项」,淡底 + 淡底前景;对号使用普通表面上的前景色。
68
69
  没写 data-tone 时这几个 --xh-_tone* 没被声明,退回品牌色 */
@@ -95,6 +96,7 @@
95
96
  --xh-_time-picker-control-px: var(--xh-control-px-sm);
96
97
  --xh-_time-picker-gap: var(--xh-control-gap-sm);
97
98
  --xh-_time-picker-font-size: var(--xh-control-font-sm);
99
+ --xh-_time-picker-item-py: var(--xh-list-option-py-sm);
98
100
  }
99
101
 
100
102
  [data-scope='time-picker']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
@@ -103,6 +105,7 @@
103
105
  --xh-_time-picker-control-px: var(--xh-control-px-lg);
104
106
  --xh-_time-picker-gap: var(--xh-control-gap-lg);
105
107
  --xh-_time-picker-font-size: var(--xh-control-font-lg);
108
+ --xh-_time-picker-item-py: var(--xh-list-option-py-lg);
106
109
  }
107
110
 
108
111
  /* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
@@ -189,7 +192,7 @@
189
192
  /* 段是 role=spinbutton 的展示节点,双击选中一段文字只会碍事 */
190
193
  user-select: none;
191
194
  transition:
192
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
195
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
193
196
  color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
194
197
  }
195
198
 
@@ -320,7 +323,8 @@
320
323
  outline: none;
321
324
  }
322
325
 
323
- [data-scope='time-picker'][data-part='content'][data-state='open'] {
326
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
327
+ [data-scope='time-picker'][data-part='content'][data-state='open']:not([data-instant]) {
324
328
  animation: xh-overlay-slide-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
325
329
  }
326
330
 
@@ -341,7 +345,7 @@
341
345
  overflow-y: auto;
342
346
  /* 浮层滚动面:滚到头不把页面一起带走 */
343
347
  overscroll-behavior: contain;
344
- border-inline-end: var(--xh-stroke-thin) solid var(--xh-time-picker-column-divider, var(--xh-material-frosted-separator));
348
+ border-inline-end: var(--xh-stroke-thin) solid var(--xh-time-picker-column-divider, var(--xh-material-solid-separator));
345
349
  }
346
350
 
347
351
  [data-scope='time-picker'][data-part='preset-group'][hidden] {
@@ -355,7 +359,7 @@
355
359
  --xh-collection-block-padding: var(--xh-time-picker-preset-py, var(--xh-space-1));
356
360
  --xh-collection-inline-padding: var(--xh-time-picker-preset-px, var(--xh-space-3));
357
361
  --xh-collection-font-size: var(--xh-text-secondary-size);
358
- --xh-collection-radius: var(--xh-time-picker-preset-radius, var(--xh-shape-control));
362
+ --xh-collection-radius: var(--xh-time-picker-preset-radius, var(--xh-shape-inset));
359
363
  /* 面板是实体面(floating),正文取页面前景 */
360
364
  --xh-collection-fg-rest: var(--xh-time-picker-preset-fg, var(--xh-fg-default));
361
365
  --xh-collection-fg-hover: var(--xh-time-picker-preset-fg, var(--xh-fg-default));
@@ -381,7 +385,7 @@
381
385
  /* 对号的末端轨始终留着,切换选中时文字与整列宽度都不移动。 */
382
386
  padding-inline-end: calc(
383
387
  var(--xh-time-picker-preset-px, var(--xh-space-3))
384
- + var(--xh-time-picker-preset-check-size, var(--xh-glyph-size-sm))
388
+ + var(--xh-time-picker-preset-check-size, var(--xh-control-indicator-size))
385
389
  + var(--xh-space-1)
386
390
  );
387
391
  white-space: nowrap;
@@ -402,8 +406,8 @@
402
406
  position: absolute;
403
407
  inset-block-start: 50%;
404
408
  inset-inline-end: var(--xh-time-picker-preset-px, var(--xh-space-3));
405
- inline-size: var(--xh-time-picker-preset-check-size, var(--xh-glyph-size-sm));
406
- block-size: var(--xh-time-picker-preset-check-size, var(--xh-glyph-size-sm));
409
+ inline-size: var(--xh-time-picker-preset-check-size, var(--xh-control-indicator-size));
410
+ block-size: var(--xh-time-picker-preset-check-size, var(--xh-control-indicator-size));
407
411
  background-color: var(--xh-time-picker-preset-check-fg, var(--xh-_time-picker-check-fg));
408
412
  opacity: 0;
409
413
  translate: 0 -50%;
@@ -450,7 +454,7 @@
450
454
 
451
455
  /* 每列后面紧跟着它自己的贴层条子节点,相邻选择器接不到下一列,按「前面有过列」取第二列起 */
452
456
  [data-scope='time-picker'][data-part='column'] ~ [data-scope='time-picker'][data-part='column'] {
453
- border-inline-start: var(--xh-stroke-thin) solid var(--xh-time-picker-column-divider, var(--xh-material-frosted-separator));
457
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-time-picker-column-divider, var(--xh-material-solid-separator));
454
458
  }
455
459
 
456
460
  /* 焦点落在列上有两种情形:指针打开、这一段还空着、还没有任何格当锚点,或整列被界裁空。
@@ -472,13 +476,13 @@
472
476
  [data-scope='time-picker'][data-part='item'] {
473
477
  --xh-_time-picker-item-rail: max(
474
478
  var(--xh-time-picker-item-px, var(--xh-space-0_5)),
475
- calc(var(--xh-time-picker-item-check-size, var(--xh-glyph-size-sm)) + var(--xh-space-0_5))
479
+ calc(var(--xh-time-picker-item-check-size, var(--xh-control-indicator-size)) + var(--xh-space-0_5))
476
480
  );
477
- --xh-collection-block-padding: var(--xh-time-picker-item-py, 0);
481
+ --xh-collection-block-padding: var(--xh-time-picker-item-py, var(--xh-_time-picker-item-py));
478
482
  /* 两侧留同宽轨:对号绝对落在末端,数字仍在整格的数学中心。 */
479
483
  --xh-collection-inline-padding: var(--xh-_time-picker-item-rail);
480
484
  --xh-collection-font-size: var(--xh-time-picker-item-font-size, var(--xh-_time-picker-font-size));
481
- --xh-collection-radius: var(--xh-time-picker-item-radius, var(--xh-shape-control));
485
+ --xh-collection-radius: var(--xh-time-picker-item-radius, var(--xh-shape-inset));
482
486
  --xh-collection-fg-rest: var(--xh-time-picker-item-fg, var(--xh-material-frosted-fg));
483
487
  --xh-collection-fg-hover: var(--xh-time-picker-item-fg, var(--xh-material-frosted-fg));
484
488
  --xh-collection-fg-keyboard-highlight: var(--xh-time-picker-item-fg, var(--xh-material-frosted-fg));
@@ -505,9 +509,9 @@
505
509
  flex: none;
506
510
  align-items: center;
507
511
  justify-content: center;
508
- block-size: var(--xh-time-picker-item-h, var(--xh-overlay-column-item-h));
512
+ block-size: var(--xh-time-picker-item-h, auto);
509
513
  /* 居中的单个数字格没有截断层,行高保持紧排,列内多露几格 */
510
- line-height: var(--xh-leading-none);
514
+ line-height: var(--xh-leading-normal);
511
515
  white-space: nowrap;
512
516
  user-select: none;
513
517
  }
@@ -530,8 +534,8 @@
530
534
  position: absolute;
531
535
  inset-block-start: 50%;
532
536
  inset-inline-end: var(--xh-space-0_5);
533
- inline-size: var(--xh-time-picker-item-check-size, var(--xh-glyph-size-sm));
534
- block-size: var(--xh-time-picker-item-check-size, var(--xh-glyph-size-sm));
537
+ inline-size: var(--xh-time-picker-item-check-size, var(--xh-control-indicator-size));
538
+ block-size: var(--xh-time-picker-item-check-size, var(--xh-control-indicator-size));
535
539
  background-color: var(--xh-time-picker-item-check-fg, var(--xh-_time-picker-check-fg));
536
540
  opacity: 0;
537
541
  translate: 0 -50%;
@@ -564,6 +568,12 @@
564
568
  forced-color-adjust: none;
565
569
  }
566
570
 
571
+ /* 按下与没被高亮时的悬停,家族把条目涂成 Highlight,对号跟着换 HighlightText */
572
+ [data-scope='time-picker'][data-part='preset']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted]))::after,
573
+ [data-scope='time-picker'][data-part='item']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted]))::after {
574
+ background-color: HighlightText;
575
+ }
576
+
567
577
  [data-scope='time-picker'][data-part='preset'][data-disabled]::after,
568
578
  [data-scope='time-picker'][data-part='item'][data-disabled]::after {
569
579
  background-color: GrayText;
@@ -608,6 +618,25 @@
608
618
  -webkit-mask: var(--xh-glyph-mark-clock) center / contain no-repeat;
609
619
  mask: var(--xh-glyph-mark-clock) center / contain no-repeat;
610
620
  }
621
+
622
+ @media (forced-colors: active) {
623
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
624
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
625
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
626
+ 禁用取 GrayText */
627
+ [data-scope='time-picker']:is([data-part='clear-trigger'], [data-part='trigger']):empty::before {
628
+ forced-color-adjust: none;
629
+ background-color: ButtonText;
630
+ }
631
+
632
+ [data-scope='time-picker']:is([data-part='clear-trigger'], [data-part='trigger']):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
633
+ background-color: HighlightText;
634
+ }
635
+
636
+ [data-scope='time-picker']:is([data-part='clear-trigger'], [data-part='trigger'])[data-disabled]:empty::before {
637
+ background-color: GrayText;
638
+ }
639
+ }
611
640
  }
612
641
 
613
642
  @layer xihan.motion {
@@ -70,6 +70,7 @@
70
70
  --xh-_time-range-picker-control-px: var(--xh-control-px-md);
71
71
  --xh-_time-range-picker-gap: var(--xh-control-gap-md);
72
72
  --xh-_time-range-picker-font-size: var(--xh-control-font-md);
73
+ --xh-_time-range-picker-item-py: var(--xh-list-option-py-md);
73
74
 
74
75
  /* 段位强调随语气走:当前段是「当前项」,淡底 + 淡底前景;对号使用普通表面上的前景色。
75
76
  没写 data-tone 时这几个 --xh-_tone* 没被声明,退回品牌色 */
@@ -102,6 +103,7 @@
102
103
  --xh-_time-range-picker-control-px: var(--xh-control-px-sm);
103
104
  --xh-_time-range-picker-gap: var(--xh-control-gap-sm);
104
105
  --xh-_time-range-picker-font-size: var(--xh-control-font-sm);
106
+ --xh-_time-range-picker-item-py: var(--xh-list-option-py-sm);
105
107
  }
106
108
 
107
109
  [data-scope='time-range-picker']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
@@ -110,6 +112,7 @@
110
112
  --xh-_time-range-picker-control-px: var(--xh-control-px-lg);
111
113
  --xh-_time-range-picker-gap: var(--xh-control-gap-lg);
112
114
  --xh-_time-range-picker-font-size: var(--xh-control-font-lg);
115
+ --xh-_time-range-picker-item-py: var(--xh-list-option-py-lg);
113
116
  }
114
117
 
115
118
  /* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
@@ -222,7 +225,7 @@
222
225
  /* 段是 role=spinbutton 的展示节点,双击选中一段文字只会碍事 */
223
226
  user-select: none;
224
227
  transition:
225
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
228
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
226
229
  color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
227
230
  }
228
231
 
@@ -359,7 +362,8 @@
359
362
  outline: none;
360
363
  }
361
364
 
362
- [data-scope='time-range-picker'][data-part='content'][data-state='open'] {
365
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
366
+ [data-scope='time-range-picker'][data-part='content'][data-state='open']:not([data-instant]) {
363
367
  animation: xh-overlay-slide-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
364
368
  }
365
369
 
@@ -380,7 +384,7 @@
380
384
  overflow-y: auto;
381
385
  /* 浮层滚动面:滚到头不把页面一起带走 */
382
386
  overscroll-behavior: contain;
383
- border-inline-end: var(--xh-stroke-thin) solid var(--xh-time-range-picker-column-divider, var(--xh-material-frosted-separator));
387
+ border-inline-end: var(--xh-stroke-thin) solid var(--xh-time-range-picker-column-divider, var(--xh-material-solid-separator));
384
388
  }
385
389
 
386
390
  [data-scope='time-range-picker'][data-part='preset-group'][hidden] {
@@ -394,7 +398,7 @@
394
398
  --xh-collection-block-padding: var(--xh-time-range-picker-preset-py, var(--xh-space-1));
395
399
  --xh-collection-inline-padding: var(--xh-time-range-picker-preset-px, var(--xh-space-3));
396
400
  --xh-collection-font-size: var(--xh-text-secondary-size);
397
- --xh-collection-radius: var(--xh-time-range-picker-preset-radius, var(--xh-shape-control));
401
+ --xh-collection-radius: var(--xh-time-range-picker-preset-radius, var(--xh-shape-inset));
398
402
  /* 面板是实体面(floating),正文取页面前景 */
399
403
  --xh-collection-fg-rest: var(--xh-time-range-picker-preset-fg, var(--xh-fg-default));
400
404
  --xh-collection-fg-hover: var(--xh-time-range-picker-preset-fg, var(--xh-fg-default));
@@ -420,7 +424,7 @@
420
424
  /* 对号的末端轨始终留着,切换选中时文字与整列宽度都不移动。 */
421
425
  padding-inline-end: calc(
422
426
  var(--xh-time-range-picker-preset-px, var(--xh-space-3))
423
- + var(--xh-time-range-picker-preset-check-size, var(--xh-glyph-size-sm))
427
+ + var(--xh-time-range-picker-preset-check-size, var(--xh-control-indicator-size))
424
428
  + var(--xh-space-1)
425
429
  );
426
430
  white-space: nowrap;
@@ -441,8 +445,8 @@
441
445
  position: absolute;
442
446
  inset-block-start: 50%;
443
447
  inset-inline-end: var(--xh-time-range-picker-preset-px, var(--xh-space-3));
444
- inline-size: var(--xh-time-range-picker-preset-check-size, var(--xh-glyph-size-sm));
445
- block-size: var(--xh-time-range-picker-preset-check-size, var(--xh-glyph-size-sm));
448
+ inline-size: var(--xh-time-range-picker-preset-check-size, var(--xh-control-indicator-size));
449
+ block-size: var(--xh-time-range-picker-preset-check-size, var(--xh-control-indicator-size));
446
450
  background-color: var(--xh-time-range-picker-preset-check-fg, var(--xh-_time-range-picker-check-fg));
447
451
  opacity: 0;
448
452
  translate: 0 -50%;
@@ -497,7 +501,7 @@
497
501
  [data-scope='time-range-picker'][data-part='column-group'] + [data-scope='time-range-picker'][data-part='column-group'] {
498
502
  margin-inline-start: var(--xh-time-range-picker-column-group-gap, var(--xh-space-2));
499
503
  padding-inline-start: var(--xh-time-range-picker-column-group-gap, var(--xh-space-2));
500
- border-inline-start: var(--xh-stroke-thin) solid var(--xh-time-range-picker-column-group-divider, var(--xh-material-frosted-separator));
504
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-time-range-picker-column-group-divider, var(--xh-material-solid-separator));
501
505
  }
502
506
 
503
507
  /* 组顶上的小标题:独占一行,字号走辅助文本档 */
@@ -546,7 +550,7 @@
546
550
 
547
551
  /* 每列后面紧跟着它自己的贴层条子节点,相邻选择器接不到下一列,按「前面有过列」取第二列起 */
548
552
  [data-scope='time-range-picker'][data-part='column'] ~ [data-scope='time-range-picker'][data-part='column'] {
549
- border-inline-start: var(--xh-stroke-thin) solid var(--xh-time-range-picker-column-divider, var(--xh-material-frosted-separator));
553
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-time-range-picker-column-divider, var(--xh-material-solid-separator));
550
554
  }
551
555
 
552
556
  /* 焦点落在列上有两种情形:指针打开、这一段还空着、还没有任何格当锚点,或整列被界裁空。
@@ -568,13 +572,13 @@
568
572
  [data-scope='time-range-picker'][data-part='item'] {
569
573
  --xh-_time-range-picker-item-rail: max(
570
574
  var(--xh-time-range-picker-item-px, var(--xh-space-0_5)),
571
- calc(var(--xh-time-range-picker-item-check-size, var(--xh-glyph-size-sm)) + var(--xh-space-0_5))
575
+ calc(var(--xh-time-range-picker-item-check-size, var(--xh-control-indicator-size)) + var(--xh-space-0_5))
572
576
  );
573
- --xh-collection-block-padding: var(--xh-time-range-picker-item-py, 0);
577
+ --xh-collection-block-padding: var(--xh-time-range-picker-item-py, var(--xh-_time-range-picker-item-py));
574
578
  /* 两侧留同宽轨:对号绝对落在末端,数字仍在整格的数学中心。 */
575
579
  --xh-collection-inline-padding: var(--xh-_time-range-picker-item-rail);
576
580
  --xh-collection-font-size: var(--xh-time-range-picker-item-font-size, var(--xh-_time-range-picker-font-size));
577
- --xh-collection-radius: var(--xh-time-range-picker-item-radius, var(--xh-shape-control));
581
+ --xh-collection-radius: var(--xh-time-range-picker-item-radius, var(--xh-shape-inset));
578
582
  --xh-collection-fg-rest: var(--xh-time-range-picker-item-fg, var(--xh-material-frosted-fg));
579
583
  --xh-collection-fg-hover: var(--xh-time-range-picker-item-fg, var(--xh-material-frosted-fg));
580
584
  --xh-collection-fg-keyboard-highlight: var(--xh-time-range-picker-item-fg, var(--xh-material-frosted-fg));
@@ -601,9 +605,9 @@
601
605
  flex: none;
602
606
  align-items: center;
603
607
  justify-content: center;
604
- block-size: var(--xh-time-range-picker-item-h, var(--xh-overlay-column-item-h));
608
+ block-size: var(--xh-time-range-picker-item-h, auto);
605
609
  /* 居中的单个数字格没有截断层,行高保持紧排,列内多露几格 */
606
- line-height: var(--xh-leading-none);
610
+ line-height: var(--xh-leading-normal);
607
611
  white-space: nowrap;
608
612
  user-select: none;
609
613
  }
@@ -626,8 +630,8 @@
626
630
  position: absolute;
627
631
  inset-block-start: 50%;
628
632
  inset-inline-end: var(--xh-space-0_5);
629
- inline-size: var(--xh-time-range-picker-item-check-size, var(--xh-glyph-size-sm));
630
- block-size: var(--xh-time-range-picker-item-check-size, var(--xh-glyph-size-sm));
633
+ inline-size: var(--xh-time-range-picker-item-check-size, var(--xh-control-indicator-size));
634
+ block-size: var(--xh-time-range-picker-item-check-size, var(--xh-control-indicator-size));
631
635
  background-color: var(--xh-time-range-picker-item-check-fg, var(--xh-_time-range-picker-check-fg));
632
636
  opacity: 0;
633
637
  translate: 0 -50%;
@@ -660,6 +664,12 @@
660
664
  forced-color-adjust: none;
661
665
  }
662
666
 
667
+ /* 按下与没被高亮时的悬停,家族把条目涂成 Highlight,对号跟着换 HighlightText */
668
+ [data-scope='time-range-picker'][data-part='preset']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted]))::after,
669
+ [data-scope='time-range-picker'][data-part='item']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted]))::after {
670
+ background-color: HighlightText;
671
+ }
672
+
663
673
  [data-scope='time-range-picker'][data-part='preset'][data-disabled]::after,
664
674
  [data-scope='time-range-picker'][data-part='item'][data-disabled]::after {
665
675
  background-color: GrayText;
@@ -704,6 +714,25 @@
704
714
  -webkit-mask: var(--xh-glyph-mark-clock) center / contain no-repeat;
705
715
  mask: var(--xh-glyph-mark-clock) center / contain no-repeat;
706
716
  }
717
+
718
+ @media (forced-colors: active) {
719
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
720
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
721
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
722
+ 禁用取 GrayText */
723
+ [data-scope='time-range-picker']:is([data-part='clear-trigger'], [data-part='trigger']):empty::before {
724
+ forced-color-adjust: none;
725
+ background-color: ButtonText;
726
+ }
727
+
728
+ [data-scope='time-range-picker']:is([data-part='clear-trigger'], [data-part='trigger']):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
729
+ background-color: HighlightText;
730
+ }
731
+
732
+ [data-scope='time-range-picker']:is([data-part='clear-trigger'], [data-part='trigger'])[data-disabled]:empty::before {
733
+ background-color: GrayText;
734
+ }
735
+ }
707
736
  }
708
737
 
709
738
  @layer xihan.motion {
package/css/timeline.css CHANGED
@@ -107,7 +107,7 @@
107
107
  /* 语气色由每条自己的数据给,同一条的语气改了(事情办成了、出错了)走一遍过渡,
108
108
  整列圆点不在数据回来的那一帧集体跳色 */
109
109
  transition:
110
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
110
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
111
111
  color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
112
112
  }
113
113
 
@@ -215,18 +215,18 @@
215
215
  font-weight: var(--xh-toggle-group-item-font-weight, var(--xh-text-label-weight));
216
216
  }
217
217
 
218
- /* 共边:后一段往回挪一个描边宽度,两条相邻的边重合成一条。
218
+ /* 共边只画一次:后一段不画起始边,由前一段的末端边承担。墨色描边半透明,两条重合会加深。
219
219
  方向跟着 data-orientation 走,横排收 inline 轴、竖排收 block 轴 */
220
220
  [data-scope='toggle-group'][data-part='root'][data-orientation='horizontal']
221
221
  > [data-scope='toggle-group'][data-part='item']
222
222
  + [data-scope='toggle-group'][data-part='item'] {
223
- margin-inline-start: calc(-1 * var(--xh-stroke-thin));
223
+ border-inline-start-width: 0;
224
224
  }
225
225
 
226
226
  [data-scope='toggle-group'][data-part='root'][data-orientation='vertical']
227
227
  > [data-scope='toggle-group'][data-part='item']
228
228
  + [data-scope='toggle-group'][data-part='item'] {
229
- margin-block-start: calc(-1 * var(--xh-stroke-thin));
229
+ border-block-start-width: 0;
230
230
  }
231
231
 
232
232
  /* 两端圆角用逻辑角属性写,rtl 与竖排都跟着换边,不必另写一套。
@@ -270,7 +270,7 @@
270
270
  --xh-action-bg-focus-visible: var(--xh-toggle-group-item-bg-on, var(--xh-_toggle-group-item-bg-on));
271
271
  --xh-action-bg-disabled: var(
272
272
  --xh-toggle-group-item-bg-on-disabled,
273
- color-mix(in oklab, var(--xh-_toggle-group-item-bg-on) 50%, var(--xh-bg-muted))
273
+ color-mix(in oklab, var(--xh-_toggle-group-item-bg-on) 50%, var(--xh-bg-muted-opaque))
274
274
  );
275
275
  --xh-action-fg-rest: var(--xh-toggle-group-item-fg-on, var(--xh-_toggle-group-item-fg-on));
276
276
  --xh-action-fg-hover: var(--xh-toggle-group-item-fg-on, var(--xh-_toggle-group-item-fg-on));
package/css/toggle.css CHANGED
@@ -34,10 +34,11 @@
34
34
  );
35
35
  --xh-_toggle-fg-on: var(--xh-toggle-fg-on, var(--xh-_tone-fg, var(--xh-fg-on-brand-subtle)));
36
36
  --xh-_toggle-border-on: var(--xh-toggle-border-on, transparent);
37
- /* 禁用同时降级前景与表面,不靠 opacity;选中且禁用时底色掺一半中性面,选中信息不丢。 */
37
+ /* 禁用同时降级前景与表面,不靠 opacity;选中且禁用时底色掺一半中性面,选中信息不丢。
38
+ 掺的是淡底的不透明档:墨色淡底半透明,掺进去整块面会跟着变半透明 */
38
39
  --xh-_toggle-bg-on-disabled: var(
39
40
  --xh-toggle-bg-on-disabled,
40
- color-mix(in oklab, var(--xh-_toggle-bg-on) 50%, var(--xh-bg-subtle))
41
+ color-mix(in oklab, var(--xh-_toggle-bg-on) 50%, var(--xh-bg-subtle-opaque))
41
42
  );
42
43
  --xh-_toggle-fg-on-disabled: var(--xh-toggle-fg-on-disabled, var(--xh-_toggle-fg-on));
43
44
  --xh-action-bg-rest: var(--xh-toggle-bg, var(--xh-_action-variant-bg-rest));
@@ -113,7 +114,7 @@
113
114
  [data-scope='toggle'][data-part='root'][data-variant='solid'][data-state='on'] {
114
115
  --xh-action-bg-disabled: var(
115
116
  --xh-toggle-bg-on-disabled,
116
- color-mix(in oklab, var(--xh-_action-variant-bg-rest) 50%, var(--xh-bg-subtle))
117
+ color-mix(in oklab, var(--xh-_action-variant-bg-rest) 50%, var(--xh-bg-subtle-opaque))
117
118
  );
118
119
  --xh-action-fg-disabled: var(--xh-toggle-fg-on-disabled, var(--xh-_action-variant-fg-rest));
119
120
  --xh-action-highlight-rest: var(--xh-_highlight-tone);
package/css/tool-call.css CHANGED
@@ -22,8 +22,8 @@
22
22
  [data-scope='tool-call'][data-part='root'] {
23
23
  /* 尺寸缺省档:不写 data-size 时的取值。三档都只写这三个私有槽,
24
24
  公开槽留在读处当首选,作者在祖先上设的覆盖才赢得过档位声明 */
25
- --xh-_tool-call-px: var(--xh-space-3);
26
- --xh-_tool-call-py: var(--xh-space-2);
25
+ --xh-_tool-call-px: var(--xh-space-4);
26
+ --xh-_tool-call-py: var(--xh-space-4);
27
27
  --xh-_tool-call-font-size: var(--xh-control-font-md);
28
28
 
29
29
  /* 影另落一份进私有槽给语气档:它要把影与左侧色条叠成一条 box-shadow,缺省无影写成零影占位 */
@@ -38,7 +38,11 @@
38
38
  border-radius: var(--xh-tool-call-radius, var(--xh-shape-surface));
39
39
  background: var(--xh-tool-call-bg, var(--xh-bg-surface));
40
40
  box-shadow: var(--xh-tool-call-shadow, none);
41
- animation: xh-tool-call-enter var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) both;
41
+ }
42
+
43
+ /* 卡片出现时滑入;落在首帧就在的列表条目里(历史消息)时直接呈现,不跟着整屏一起入场 */
44
+ [data-scope='tool-call'][data-part='root']:not([data-scope][data-part='item'][data-instant] *) {
45
+ animation: xh-item-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) both;
42
46
  }
43
47
 
44
48
  /* 上面声明的 display 会盖掉 UA 的 [hidden]{display:none},这里补回 */
@@ -111,8 +115,12 @@
111
115
  align-items: center;
112
116
  justify-content: center;
113
117
  color: var(--xh-tool-call-indicator-fg, var(--xh-fg-subtle));
114
- /* 与详情展开同时长同曲线:箭头先转完、内容后到位会像是两件事 */
115
- transition: rotate var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
118
+ }
119
+
120
+ /* 与详情开合同时长:箭头先转完、内容后到位会像是两件事。收起取 collapse 档,展开(下面的打开态)取 expand 档。
121
+ 首帧就在的朝向直接呈现(data-instant),第一次开合起才转 */
122
+ [data-scope='tool-call'][data-part='indicator']:not([data-instant]) {
123
+ transition: rotate var(--xh-motion-duration-collapse) var(--xh-motion-ease-enter-strong);
116
124
  }
117
125
 
118
126
  /* 没写内容就由皮肤画;作者往部件里塞了自己的图形,这条规则即不命中 */
@@ -137,6 +145,10 @@
137
145
  rotate: 90deg;
138
146
  }
139
147
 
148
+ [data-scope='tool-call'][data-part='indicator'][data-state='open']:not([data-instant]) {
149
+ transition: rotate var(--xh-motion-duration-expand) var(--xh-motion-ease-enter-strong);
150
+ }
151
+
140
152
  [dir='rtl'] [data-scope='tool-call'][data-part='indicator'] {
141
153
  rotate: 180deg;
142
154
  }
@@ -151,6 +163,8 @@
151
163
  overflow: hidden;
152
164
  flex: 1 1 auto;
153
165
  font-family: var(--xh-tool-call-label-font, var(--xh-font-family-mono));
166
+ /* 面级披露的触发条文字取标签角色,与 Accordion、Collapsible、Reasoning 同一档字重 */
167
+ font-weight: var(--xh-tool-call-label-font-weight, var(--xh-text-label-weight));
154
168
  text-overflow: ellipsis;
155
169
  white-space: nowrap;
156
170
  }
@@ -197,29 +211,31 @@
197
211
  display: none;
198
212
  }
199
213
 
200
- /* 三档落定的阶段收成药丸:淡底 + 同族深字。在跑的两档不带底,让扫光自己说话 */
201
- [data-scope='tool-call'][data-part='status'][data-state='awaiting-approval'],
202
- [data-scope='tool-call'][data-part='status'][data-state='output-available'],
203
- [data-scope='tool-call'][data-part='status'][data-state='output-error'] {
214
+ /* 三档落定的阶段收成状态 chip:几何与 Tag 的 sm 档同一把尺,淡底 + 同族可读字取连接层投影的语气。
215
+ 在跑的两档不带底,让扫光自己说话 */
216
+ [data-scope='tool-call'][data-part='status'][data-tone] {
204
217
  padding-block: var(--xh-tool-call-status-py, var(--xh-space-0_5));
205
- padding-inline: var(--xh-tool-call-status-px, var(--xh-space-2));
218
+ padding-inline: var(--xh-tool-call-status-px, var(--xh-space-1_5));
219
+ border: var(--xh-stroke-thin) solid transparent;
206
220
  border-radius: var(--xh-tool-call-status-radius, var(--xh-shape-pill));
221
+ font-weight: var(--xh-font-weight-medium);
222
+ line-height: var(--xh-control-indicator-md);
207
223
  }
208
224
 
209
- /* 各阶段的状态色:与语气轴分开走,语气是作者定的强调 */
225
+ /* 各阶段的覆盖槽仍按阶段给:作者可以单独改某一档 */
210
226
  [data-scope='tool-call'][data-part='status'][data-state='awaiting-approval'] {
211
- background: var(--xh-tool-call-status-bg-approval, color-mix(in oklab, var(--xh-fg-warning) 12%, var(--xh-bg-surface)));
212
- color: var(--xh-tool-call-status-fg-approval, color-mix(in oklab, var(--xh-fg-warning) 60%, var(--xh-fg-default)));
227
+ background: var(--xh-tool-call-status-bg-approval, var(--xh-_tone-subtle));
228
+ color: var(--xh-tool-call-status-fg-approval, var(--xh-_tone-fg));
213
229
  }
214
230
 
215
231
  [data-scope='tool-call'][data-part='status'][data-state='output-available'] {
216
- background: var(--xh-tool-call-status-bg-done, color-mix(in oklab, var(--xh-fg-success) 12%, var(--xh-bg-surface)));
217
- color: var(--xh-tool-call-status-fg-done, color-mix(in oklab, var(--xh-fg-success) 60%, var(--xh-fg-default)));
232
+ background: var(--xh-tool-call-status-bg-done, var(--xh-_tone-subtle));
233
+ color: var(--xh-tool-call-status-fg-done, var(--xh-_tone-fg));
218
234
  }
219
235
 
220
236
  [data-scope='tool-call'][data-part='status'][data-state='output-error'] {
221
- background: var(--xh-tool-call-status-bg-error, color-mix(in oklab, var(--xh-fg-danger) 12%, var(--xh-bg-surface)));
222
- color: var(--xh-tool-call-status-fg-error, color-mix(in oklab, var(--xh-fg-danger) 60%, var(--xh-fg-default)));
237
+ background: var(--xh-tool-call-status-bg-error, var(--xh-_tone-subtle));
238
+ color: var(--xh-tool-call-status-fg-error, var(--xh-_tone-fg));
223
239
  }
224
240
 
225
241
  /* 在跑的时候状态文字自己扫一道光:data-loading 此前在皮肤里没有任何表达,
@@ -237,7 +253,7 @@
237
253
  background-clip: text;
238
254
  color: transparent;
239
255
  -webkit-text-fill-color: transparent;
240
- animation: xh-tool-call-shimmer var(--xh-tool-call-shimmer-duration, var(--xh-shimmer-duration)) var(--xh-motion-ease-loop) infinite;
256
+ animation: xh-shimmer var(--xh-tool-call-shimmer-duration, var(--xh-motion-loop-shimmer)) var(--xh-motion-ease-loop) infinite;
241
257
  }
242
258
 
243
259
  /* 减少动效:整道光撤掉换回平色,"在跑"仍由状态文字本身表达——只停动画的话,
@@ -303,15 +319,14 @@
303
319
  border-block-start: var(--xh-stroke-thin) solid var(--xh-tool-call-divider, var(--xh-border-subtle));
304
320
  }
305
321
 
306
- /* 展开那一档才提前备好行高这条通道:属性随 data-state 一起消失,收起后不长期占着 */
307
- [data-scope='tool-call'][data-part='content'][data-state='open'] {
308
- will-change: grid-template-rows;
309
- animation: xh-disclosure-expand var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
322
+ /* 展开与收起只在开合时播:首帧就在的展开 / 收起直接呈现(data-instant) */
323
+ [data-scope='tool-call'][data-part='content'][data-state='open']:not([data-instant]) {
324
+ animation: xh-disclosure-expand var(--xh-motion-duration-expand) var(--xh-motion-ease-enter-strong);
310
325
  }
311
326
 
312
327
  /* 退场走 exit 档曲线 */
313
- [data-scope='tool-call'][data-part='content'][data-state='closed'] {
314
- animation: xh-disclosure-collapse var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
328
+ [data-scope='tool-call'][data-part='content'][data-state='closed']:not([data-instant]) {
329
+ animation: xh-disclosure-collapse var(--xh-motion-duration-collapse) var(--xh-motion-ease-exit) forwards;
315
330
  }
316
331
 
317
332
  [data-scope='tool-call'][data-part='input'],
@@ -338,20 +353,20 @@
338
353
 
339
354
  /* 尺寸档只改内衬与字号 */
340
355
  [data-scope='tool-call'][data-part='root'][data-size='sm'] {
341
- --xh-_tool-call-px: var(--xh-space-2);
342
- --xh-_tool-call-py: var(--xh-space-1);
356
+ --xh-_tool-call-px: var(--xh-space-3);
357
+ --xh-_tool-call-py: var(--xh-space-3);
343
358
  --xh-_tool-call-font-size: var(--xh-control-font-sm);
344
359
  }
345
360
 
346
361
  [data-scope='tool-call'][data-part='root'][data-size='md'] {
347
- --xh-_tool-call-px: var(--xh-space-3);
348
- --xh-_tool-call-py: var(--xh-space-2);
362
+ --xh-_tool-call-px: var(--xh-space-4);
363
+ --xh-_tool-call-py: var(--xh-space-4);
349
364
  --xh-_tool-call-font-size: var(--xh-control-font-md);
350
365
  }
351
366
 
352
367
  [data-scope='tool-call'][data-part='root'][data-size='lg'] {
353
- --xh-_tool-call-px: var(--xh-space-4);
354
- --xh-_tool-call-py: var(--xh-space-3);
368
+ --xh-_tool-call-px: var(--xh-space-5);
369
+ --xh-_tool-call-py: var(--xh-space-5);
355
370
  --xh-_tool-call-font-size: var(--xh-control-font-lg);
356
371
  }
357
372
 
@@ -362,35 +377,28 @@
362
377
  inset var(--xh-tool-call-tone-bar, var(--xh-stroke-thick)) 0 0 0 var(--xh-tool-call-tone-fg, var(--xh-_tone-soft, var(--xh-bg-brand))),
363
378
  var(--xh-_tool-call-shadow);
364
379
  }
365
- }
366
380
 
367
- @layer xihan.motion {
368
- /* 组件专属关键帧写在自己身上;共享的 disclosure 关键帧由 family/motion.css 提供。
369
- 幅度走令牌,减弱动效时由令牌层归零 */
370
- @keyframes xh-tool-call-enter {
371
- from {
372
- opacity: 0;
373
- translate: 0 var(--xh-motion-distance-md);
374
- }
375
-
376
- to {
377
- opacity: 1;
378
- translate: 0 0;
381
+ @media (forced-colors: active) {
382
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
383
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
384
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
385
+ 禁用取 GrayText */
386
+ [data-scope='tool-call'][data-part='indicator']:empty::before {
387
+ forced-color-adjust: none;
388
+ background-color: ButtonText;
379
389
  }
380
- }
381
390
 
382
- /* 一道比字色亮的窄带从右扫到左。背景图比自身宽一倍,靠移动背景位置扫过去,
383
- 不动布局也不动 transform */
384
- @keyframes xh-tool-call-shimmer {
385
- from {
386
- background-position: 150% center;
391
+ [data-scope='tool-call'][data-part='trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]) [data-scope='tool-call'][data-part='indicator']:empty::before {
392
+ background-color: HighlightText;
387
393
  }
388
394
 
389
- to {
390
- background-position: -50% center;
395
+ [data-scope='tool-call'][data-part='trigger'][data-disabled] [data-scope='tool-call'][data-part='indicator']:empty::before {
396
+ background-color: GrayText;
391
397
  }
392
398
  }
399
+ }
393
400
 
401
+ @layer xihan.motion {
394
402
  @media print {
395
403
  /* 打印:动画会被定格在任意一帧——转了一半的圈、扫到一半的微光。这里换成静止的表达,
396
404
  取值与减弱动效那一档相同。两档各写一块、不并进一条媒体查询列表:减弱动效另有一份