@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
@@ -9,6 +9,7 @@
9
9
  独立皮肤同时传递引入选项行与四颗钮的动作控件配方,full bundle 递归去重。 */
10
10
  @import '../family/motion.css';
11
11
  @import '../family/action-control.css';
12
+ @import '../family/check-mark.css';
12
13
 
13
14
  @layer xihan.components {
14
15
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
@@ -16,10 +17,10 @@
16
17
  --xh-question-flow-skin: 1;
17
18
  }
18
19
 
19
- /* 一张静态内容面:--xh-border-default 描边 + surface 底 + 无影(§5.3 边界只由描边承担)。
20
+ /* 一张静态内容面:--xh-border-default 描边 + surface 底 + 无影(边界只由描边承担)。
20
21
  三个视觉轴都落在 root 上:形态管底与描边怎么画,语气管用哪族颜色,尺寸管内衬、按钮高度与字号 */
21
22
  [data-scope='question-flow'][data-part='root'] {
22
- /* 作者塞进翻页钮的图标按档取尺(§6.5),与皮肤画的兜底字形同一把尺 */
23
+ /* 作者塞进翻页钮的图标按档取尺,与皮肤画的兜底字形同一把尺 */
23
24
  --xh-icon-size: var(--xh-question-flow-icon-size, var(--xh-glyph-size-md));
24
25
  /* 尺寸缺省档:不写 data-size 时按中档走 */
25
26
  --xh-_question-flow-p: var(--xh-space-4);
@@ -37,7 +38,11 @@
37
38
  border-radius: var(--xh-question-flow-radius, var(--xh-shape-surface));
38
39
  background: var(--xh-question-flow-bg, var(--xh-bg-surface));
39
40
  box-shadow: var(--xh-question-flow-shadow, none);
40
- animation: xh-question-flow-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
41
+ }
42
+
43
+ /* 卡片出现时滑入;落在首帧就在的列表条目里(历史消息)时直接呈现,不跟着整屏一起入场 */
44
+ [data-scope='question-flow'][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);
41
46
  }
42
47
 
43
48
  /* 上面声明的 display 会盖掉 UA 的 [hidden]{display:none},这里补回 */
@@ -49,7 +54,7 @@
49
54
  /* 描边式是缺省档,写在上面那条基础规则里 */
50
55
  /* 填充式:底色顶替描边表达边界。描边只退成透明而不去掉,
51
56
  1px 的位置留着,与 outline 档并排时基线对得上;
52
- 淡底承载面向选项行与几颗中性钮下发 hover 200 → pressed 300(§7.2) */
57
+ 淡底承载面向选项行与几颗中性钮下发 hover 200 → pressed 300 */
53
58
  [data-scope='question-flow'][data-part='root'][data-variant='subtle'] {
54
59
  --xh-action-host-bg-hover: var(--xh-bg-subtle-hover);
55
60
  --xh-action-host-bg-pressed: var(--xh-bg-subtle-active);
@@ -104,7 +109,7 @@
104
109
  display: block;
105
110
  overflow: hidden;
106
111
  block-size: var(--xh-question-flow-viewport-h, var(--xh-_question-flow-viewport-h));
107
- transition: block-size var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous);
112
+ transition: block-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
108
113
  }
109
114
 
110
115
  [data-scope='question-flow'][data-part='viewport'][hidden] {
@@ -119,7 +124,7 @@
119
124
  flex-direction: column;
120
125
  gap: var(--xh-question-flow-track-gap, var(--xh-_question-flow-gap));
121
126
  translate: 0 var(--xh-question-flow-track-y, var(--xh-_question-flow-track-y));
122
- transition: translate var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous);
127
+ transition: translate var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
123
128
  }
124
129
 
125
130
  [data-scope='question-flow'][data-part='track'][hidden] {
@@ -145,7 +150,7 @@
145
150
  pointer-events: auto;
146
151
  }
147
152
 
148
- /* 题干就是这一题的标题,也是选项组的可访问名:走 Surface 标题档 14/600(§6.4) */
153
+ /* 题干就是这一题的标题,也是选项组的可访问名:走 Surface 标题档 14/600 */
149
154
  [data-scope='question-flow'][data-part='prompt'] {
150
155
  display: block;
151
156
  margin: 0;
@@ -170,9 +175,9 @@
170
175
  }
171
176
 
172
177
  /* 一个选项:整行可点、可聚焦,记号在左。盒型、悬停 / 按下 / 禁用面由 Action Control 的 row 档给
173
- (ghost 形态:白底承载 hover 100 → pressed 200,按下只换面不缩放,§9.2;禁用守卫认 data-disabled),
178
+ (ghost 形态:白底承载 hover 100 → pressed 200,按下只换面不缩放;禁用守卫认 data-disabled),
174
179
  这里只把使用者槽映射到桥接槽,内衬与间距沿用本组件的档位;字色三态同一支,选中档在下面换一档。
175
- 行高不吃家族的单行档:row 档允许换行、高度随内容,一条会折行的选项文案走正文行高(§6.4) */
180
+ 行高不吃家族的单行档:row 档允许换行、高度随内容,一条会折行的选项文案走正文行高 */
176
181
  [data-scope='question-flow'][data-part='item'] {
177
182
  --xh-action-gap: var(--xh-question-flow-item-gap, var(--xh-space-1_5));
178
183
  --xh-action-padding-inline: var(--xh-question-flow-item-px, var(--xh-space-2));
@@ -192,30 +197,31 @@
192
197
  display: none;
193
198
  }
194
199
 
195
- /* 当前题的选项按位次错开开幕,换题时随 data-current 重跑。
200
+ /* 当前题的选项按位次错开开幕,换题时随 data-current 重跑:一道题的选项总是同一批一起露面,
201
+ 位次就是到达顺序。落在首帧就在的列表条目里(历史消息)时直接呈现。
196
202
  backwards 不能省:等待期间起帧不生效的话,后面几条会先露一下再跳回去。
197
203
  第 6 条起并到同一拍上 */
198
- [data-scope='question-flow'][data-part='question'][data-current] [data-part='item'] {
204
+ [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:not([data-scope][data-part='item'][data-instant] *) {
199
205
  animation: xh-rise-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
200
206
  }
201
207
 
202
- [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(2) {
208
+ [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(2):not([data-scope][data-part='item'][data-instant] *) {
203
209
  animation-delay: calc(var(--xh-motion-stagger-step) * 1);
204
210
  }
205
211
 
206
- [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(3) {
212
+ [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(3):not([data-scope][data-part='item'][data-instant] *) {
207
213
  animation-delay: calc(var(--xh-motion-stagger-step) * 2);
208
214
  }
209
215
 
210
- [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(4) {
216
+ [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(4):not([data-scope][data-part='item'][data-instant] *) {
211
217
  animation-delay: calc(var(--xh-motion-stagger-step) * 3);
212
218
  }
213
219
 
214
- [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(5) {
220
+ [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(5):not([data-scope][data-part='item'][data-instant] *) {
215
221
  animation-delay: calc(var(--xh-motion-stagger-step) * 4);
216
222
  }
217
223
 
218
- [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(n + 6) {
224
+ [data-scope='question-flow'][data-part='question'][data-current] [data-part='item']:nth-child(n + 6):not([data-scope][data-part='item'][data-instant] *) {
219
225
  animation-delay: calc(var(--xh-motion-stagger-step) * 5);
220
226
  }
221
227
 
@@ -244,7 +250,7 @@
244
250
  inline-size: var(--xh-question-flow-indicator-size, var(--xh-_question-flow-indicator));
245
251
  block-size: var(--xh-question-flow-indicator-size, var(--xh-_question-flow-indicator));
246
252
  transition:
247
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
253
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
248
254
  border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
249
255
  color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
250
256
  }
@@ -253,31 +259,34 @@
253
259
  display: none;
254
260
  }
255
261
 
256
- /* 单选那一档把方格收成圆:正方盒取 circle(§6.3) */
262
+ /* 单选那一档把方格收成圆:正方盒取 circle */
257
263
  [data-scope='question-flow'][data-part='item-indicator'][data-select-mode='single'] {
258
264
  border-radius: var(--xh-question-flow-indicator-radius-single, var(--xh-shape-circle));
259
265
  }
260
266
 
261
- /* 没写内容就由皮肤画勾;作者往部件里塞了自己的图形,这条规则即不命中 */
262
- [data-scope='question-flow'][data-part='item-indicator']:empty::before {
267
+ /* 多选的记号是勾选格:没写内容时勾由勾选标记配方画在 ::before 上,常驻、按状态淡变并轻缩放;
268
+ 作者往部件里塞了自己的图形,配方与下面的圆点都不画。
269
+ 单选那一档画实心点,由伪元素自己的底色画;直径按记号盒的一半量,与其余单选控件的圆点同源——
270
+ 盒换档时点跟着换。圆点与 RadioGroup 同一套动效:没选中时缩放为 0(盒留在原位,翻面时整行不跳),
271
+ 选中时落位略涨过 1 再收回、收起走强减速不过冲,换色走 micro */
272
+ [data-scope='question-flow'][data-part='item-indicator'][data-select-mode='single']:empty::before {
263
273
  content: '';
264
274
  display: inline-block;
265
- inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
266
- block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
267
- vertical-align: var(--xh-glyph-baseline-shift);
268
- background-color: currentColor;
269
- -webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
270
- mask: var(--xh-glyph-mark-check) center / contain no-repeat;
271
- }
272
-
273
- /* 单选那一档把勾换成实心点:mask 撤掉,圆点由伪元素自己的底色画。
274
- 直径按记号盒的一半量,与其余单选控件的圆点同源——盒换档时点跟着换 */
275
- [data-scope='question-flow'][data-part='item-indicator'][data-select-mode='single']:empty::before {
276
275
  inline-size: var(--xh-question-flow-dot-size, calc(var(--xh-question-flow-indicator-size, var(--xh-_question-flow-indicator)) / 2));
277
276
  block-size: var(--xh-question-flow-dot-size, calc(var(--xh-question-flow-indicator-size, var(--xh-_question-flow-indicator)) / 2));
278
277
  border-radius: var(--xh-question-flow-dot-radius, var(--xh-shape-circle));
279
- -webkit-mask: none;
280
- mask: none;
278
+ background-color: currentColor;
279
+ scale: 0;
280
+ transition:
281
+ scale var(--xh-motion-duration-nudge) var(--xh-motion-ease-enter-strong),
282
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
283
+ }
284
+
285
+ [data-scope='question-flow'][data-part='item-indicator'][data-select-mode='single'][data-state='checked']:empty::before {
286
+ scale: 1;
287
+ transition:
288
+ scale var(--xh-motion-duration-nudge) var(--xh-motion-ease-settle),
289
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
281
290
  }
282
291
 
283
292
  [data-scope='question-flow'][data-part='item-indicator'][data-state='checked'] {
@@ -285,11 +294,6 @@
285
294
  background: var(--xh-question-flow-indicator-bg-checked, var(--xh-_tone, var(--xh-bg-brand)));
286
295
  }
287
296
 
288
- /* 没选中时把记号隐去而不是撤掉:盒留在原位,翻面时整行不跳 */
289
- [data-scope='question-flow'][data-part='item-indicator'][data-state='unchecked'] {
290
- color: transparent;
291
- }
292
-
293
297
  [data-scope='question-flow'][data-part='item-text'] {
294
298
  display: block;
295
299
  flex: 1 1 auto;
@@ -299,6 +303,38 @@
299
303
  display: none;
300
304
  }
301
305
 
306
+ /* 选项带一行说明:说明另起一行、与文字左缘对齐,两行之间不留行距;字色取次级、字号小一档 */
307
+ [data-scope='question-flow'][data-part='item']:has(> [data-part='item-description']) {
308
+ flex-wrap: wrap;
309
+ row-gap: 0;
310
+ }
311
+
312
+ [data-scope='question-flow'][data-part='item-description'] {
313
+ display: block;
314
+ flex: 1 0 100%;
315
+ padding-inline-start: calc(var(--xh-question-flow-indicator-size, var(--xh-_question-flow-indicator)) + var(--xh-question-flow-item-gap, var(--xh-space-1_5)));
316
+ color: var(--xh-question-flow-item-description-fg, var(--xh-fg-subtle));
317
+ font-size: var(--xh-question-flow-item-description-font-size, var(--xh-text-caption-size));
318
+ text-align: start;
319
+ }
320
+
321
+ [data-scope='question-flow'][data-part='item-description'][hidden] {
322
+ display: none;
323
+ }
324
+
325
+ /* 题目说明(含多选的数量要求):题干下一行的次级文字 */
326
+ [data-scope='question-flow'][data-part='description'] {
327
+ display: block;
328
+ margin: 0;
329
+ color: var(--xh-question-flow-description-fg, var(--xh-fg-muted));
330
+ font-size: var(--xh-question-flow-description-font-size, var(--xh-text-secondary-size));
331
+ line-height: var(--xh-leading-normal);
332
+ }
333
+
334
+ [data-scope='question-flow'][data-part='description'][hidden] {
335
+ display: none;
336
+ }
337
+
302
338
  /* 自由文本:与选项同等算数的一条答案,占满整行 */
303
339
  [data-scope='question-flow'][data-part='note'] {
304
340
  display: block;
@@ -455,15 +491,21 @@
455
491
  display: inline-flex;
456
492
  align-self: flex-start;
457
493
  align-items: center;
458
- gap: var(--xh-question-flow-result-gap, var(--xh-space-1_5));
459
- padding-inline: var(--xh-question-flow-result-px, var(--xh-space-2));
460
- padding-block: var(--xh-question-flow-result-py, var(--xh-space-1));
494
+ gap: var(--xh-question-flow-result-gap, var(--xh-space-1));
495
+ padding-inline: var(--xh-question-flow-result-px, var(--xh-space-1_5));
496
+ padding-block: var(--xh-question-flow-result-py, var(--xh-space-0_5));
497
+ border: var(--xh-stroke-thin) solid transparent;
461
498
  border-radius: var(--xh-question-flow-result-radius, var(--xh-shape-pill));
462
- background: var(--xh-question-flow-result-bg, var(--xh-bg-subtle));
463
- color: var(--xh-question-flow-result-fg, var(--xh-fg-success));
499
+ background: var(--xh-question-flow-result-bg, var(--xh-_tone-subtle));
500
+ color: var(--xh-question-flow-result-fg, var(--xh-_tone-fg));
464
501
  font-size: var(--xh-question-flow-result-font-size, var(--xh-text-caption-size));
465
- font-weight: var(--xh-question-flow-result-font-weight, var(--xh-text-label-weight));
466
- animation: xh-question-flow-result-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
502
+ font-weight: var(--xh-question-flow-result-font-weight, var(--xh-font-weight-medium));
503
+ line-height: var(--xh-control-indicator-md);
504
+ }
505
+
506
+ /* 落定结果弹出;落在首帧就在的列表条目里(历史消息)时直接呈现,不跟着整屏一起入场 */
507
+ [data-scope='question-flow'][data-part='result']:not([data-scope][data-part='item'][data-instant] *) {
508
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
467
509
  }
468
510
 
469
511
  [data-scope='question-flow'][data-part='result'][hidden] {
@@ -482,32 +524,30 @@
482
524
  clip-path: inset(50%);
483
525
  white-space: nowrap;
484
526
  }
485
- }
486
527
 
487
- @layer xihan.motion {
488
- /* 组件专属关键帧写在自己身上;共享的 xh-rise-in 由 family/motion.css 提供。 */
489
- /* 幅度走令牌,减弱动效时由令牌层归零;位移用独立属性而非 transform 简写 */
490
- @keyframes xh-question-flow-in {
491
- from {
492
- opacity: 0;
493
- translate: 0 var(--xh-motion-distance-md);
528
+ @media (forced-colors: active) {
529
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
530
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
531
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
532
+ 落在勾选盒自己的实心面上(这一档里是 Canvas),整行悬停不换面,取 CanvasText;
533
+ 禁用取 GrayText */
534
+ [data-scope='question-flow'][data-part='item-indicator'][data-select-mode='single']:empty::before {
535
+ forced-color-adjust: none;
536
+ background-color: CanvasText;
494
537
  }
495
538
 
496
- to {
497
- opacity: 1;
498
- translate: 0 0;
539
+ [data-scope='question-flow']:is([data-part='prev-trigger'], [data-part='next-trigger']):empty::before {
540
+ forced-color-adjust: none;
541
+ background-color: ButtonText;
499
542
  }
500
- }
501
543
 
502
- @keyframes xh-question-flow-result-in {
503
- from {
504
- opacity: 0;
505
- scale: var(--xh-motion-scale-enter);
544
+ [data-scope='question-flow']:is([data-part='prev-trigger'], [data-part='next-trigger']):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
545
+ background-color: HighlightText;
506
546
  }
507
547
 
508
- to {
509
- opacity: 1;
510
- scale: 1;
548
+ [data-scope='question-flow'][data-part='item'][data-disabled] [data-scope='question-flow'][data-part='item-indicator'][data-select-mode='single']:empty::before,
549
+ [data-scope='question-flow']:is([data-part='prev-trigger'], [data-part='next-trigger'])[data-disabled]:empty::before {
550
+ background-color: GrayText;
511
551
  }
512
552
  }
513
553
  }
@@ -0,0 +1,233 @@
1
+ /*
2
+ * Copyright (c) 2021-Present XiHanFun and contributors.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ */
5
+
6
+ /* 定义 radar chart 样式。 */
7
+
8
+ /* 标题、视口、图例、提示框、空态与焦点环走 Chart 家族配方。本皮肤 @import 它,单独引入仍成立。 */
9
+ @import '../family/motion.css';
10
+ @import '../family/chart.css';
11
+ @import '../family/loading-ring.css';
12
+
13
+ @layer xihan.components {
14
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
15
+ [data-scope='radar-chart'] {
16
+ --xh-radar-chart-skin: 1;
17
+ }
18
+
19
+ /* 几何要用的像素值以这里的私有槽为真源:机器挂载后从计算样式读它们,作者覆盖组件槽即改变几何 */
20
+ [data-scope='radar-chart'][data-part='root'] {
21
+ --xh-_chart-metric-bar-max: var(--xh-chart-bar-max);
22
+ --xh-_chart-metric-gap: var(--xh-chart-gap);
23
+ --xh-_chart-metric-line-width: var(--xh-radar-chart-line-width, var(--xh-chart-line-width));
24
+ --xh-_chart-metric-point-size: var(--xh-radar-chart-point-size, var(--xh-chart-point-size));
25
+ --xh-_chart-metric-hit-min: var(--xh-chart-hit-min);
26
+ --xh-_chart-metric-tick-length: var(--xh-chart-tick-length);
27
+ --xh-_chart-metric-label-gap: var(--xh-chart-label-gap);
28
+ --xh-_chart-metric-radius: var(--xh-shape-inset);
29
+ --xh-_chart-metric-font-size: var(--xh-text-caption-size);
30
+ --xh-_chart-metric-leading: var(--xh-leading-tight);
31
+ --xh-_chart-gap: var(--xh-radar-chart-gap, var(--xh-space-3));
32
+ }
33
+
34
+ /* —— 家族配方的组件槽:标题、视口、图例、提示框与空态由 family/chart.css 画,本图表的覆盖槽写在
35
+ 对应部件上接进配方的私有槽,作者在部件或它的祖先上覆盖都生效 —— */
36
+ [data-scope='radar-chart'][data-part='viewport'] {
37
+ --xh-_chart-height: var(--xh-radar-chart-height, var(--xh-chart-height));
38
+ }
39
+
40
+ [data-scope='radar-chart'][data-part='legend'] {
41
+ --xh-_chart-legend-gap: var(--xh-radar-chart-legend-gap, var(--xh-space-1));
42
+ }
43
+
44
+ [data-scope='radar-chart'][data-part='legend-swatch'] {
45
+ --xh-_chart-legend-swatch-radius: var(--xh-radar-chart-legend-swatch-radius, var(--xh-shape-inset));
46
+ }
47
+
48
+ [data-scope='radar-chart'][data-part='tooltip'] {
49
+ --xh-_chart-tooltip-gap: var(--xh-radar-chart-tooltip-gap, var(--xh-space-1));
50
+ --xh-_chart-tooltip-py: var(--xh-radar-chart-tooltip-py, var(--xh-surface-pad-sm));
51
+ --xh-_chart-tooltip-px: var(--xh-radar-chart-tooltip-px, var(--xh-surface-pad-sm));
52
+ --xh-_chart-tooltip-radius: var(--xh-radar-chart-tooltip-radius, var(--xh-shape-overlay));
53
+ --xh-_chart-tooltip-shadow: var(--xh-radar-chart-tooltip-shadow, var(--xh-material-frosted-shadow));
54
+ }
55
+
56
+ [data-scope='radar-chart'][data-part='tooltip-row'] {
57
+ --xh-_chart-tooltip-row-gap: var(--xh-radar-chart-tooltip-row-gap, var(--xh-space-2));
58
+ }
59
+
60
+ /* 提示框里被指着的那个实体:数值加粗,其余行照常 */
61
+ [data-scope='radar-chart'][data-part='tooltip-row'][data-current] {
62
+ font-weight: var(--xh-font-weight-semibold);
63
+ }
64
+
65
+ [data-scope='radar-chart'][data-part='tooltip-swatch'] {
66
+ --xh-_chart-tooltip-swatch-radius: var(--xh-radar-chart-tooltip-swatch-radius, var(--xh-shape-inset));
67
+ }
68
+
69
+ [data-scope='radar-chart'][data-part='empty'][data-state='loading'] {
70
+ --xh-_chart-empty-gap: var(--xh-radar-chart-empty-gap, var(--xh-space-2));
71
+ }
72
+
73
+ /* —— 色槽:身份由色槽承担,作者可以在系列上覆盖 --xh-radar-chart-series-color ——
74
+ 系列分组、图例项与提示框的行都带着色槽,各自从这里取系列色 */
75
+ [data-scope='radar-chart'][data-xh-chart-slot='1'] {
76
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-1));
77
+ }
78
+
79
+ [data-scope='radar-chart'][data-xh-chart-slot='2'] {
80
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-2));
81
+ }
82
+
83
+ [data-scope='radar-chart'][data-xh-chart-slot='3'] {
84
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-3));
85
+ }
86
+
87
+ [data-scope='radar-chart'][data-xh-chart-slot='4'] {
88
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-4));
89
+ }
90
+
91
+ [data-scope='radar-chart'][data-xh-chart-slot='5'] {
92
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-5));
93
+ }
94
+
95
+ [data-scope='radar-chart'][data-xh-chart-slot='6'] {
96
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-6));
97
+ }
98
+
99
+ [data-scope='radar-chart'][data-xh-chart-slot='7'] {
100
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-7));
101
+ }
102
+
103
+ [data-scope='radar-chart'][data-xh-chart-slot='8'] {
104
+ --xh-_chart-series: var(--xh-radar-chart-series-color, var(--xh-chart-categorical-8));
105
+ }
106
+
107
+ /* —— 图表家具:网格圈与指标轴是不承载数据的结构线,指标名是次级标注 —— */
108
+ [data-scope='radar-chart'][data-part='grid-ring'] {
109
+ fill: none;
110
+ stroke: var(--xh-chart-grid);
111
+ stroke-width: var(--xh-stroke-thin);
112
+ }
113
+
114
+ [data-scope='radar-chart'][data-part='spoke'] {
115
+ fill: none;
116
+ stroke: var(--xh-chart-axis);
117
+ stroke-width: var(--xh-stroke-thin);
118
+ }
119
+
120
+ [data-scope='radar-chart'][data-part='indicator-label'] {
121
+ fill: var(--xh-chart-label);
122
+ }
123
+
124
+ /* 各圈的数值:比指标名再退一层,只作量程的参照 */
125
+ [data-scope='radar-chart'][data-part='ring-label'] {
126
+ fill: var(--xh-radar-chart-ring-label-fg, var(--xh-chart-label));
127
+ opacity: var(--xh-radar-chart-ring-label-opacity, 0.8);
128
+ }
129
+
130
+ /* 激活的指标那根轴:准线色,压在网格之上、数据之下 */
131
+ [data-scope='radar-chart'][data-part='crosshair'] {
132
+ fill: none;
133
+ stroke: var(--xh-chart-crosshair);
134
+ stroke-width: var(--xh-stroke-thick);
135
+ }
136
+
137
+ /* —— 数据标记:一个实体一个分组,悬停图例或指着一个顶点时其余实体淡出 —— */
138
+ [data-scope='radar-chart'][data-part='series'] {
139
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
140
+ }
141
+
142
+ [data-scope='radar-chart'][data-part='series'][data-dimmed] {
143
+ opacity: var(--xh-chart-dim-alpha);
144
+ }
145
+
146
+ /* 面积:系列色淡洗,边上是同一条实色轮廓 */
147
+ [data-scope='radar-chart'][data-part='area-fill'] {
148
+ fill: var(--xh-_chart-series);
149
+ fill-opacity: var(--xh-chart-area-alpha);
150
+ stroke: none;
151
+ }
152
+
153
+ [data-scope='radar-chart'][data-part='line'] {
154
+ fill: none;
155
+ stroke: var(--xh-_chart-series);
156
+ stroke-width: var(--xh-_chart-metric-line-width);
157
+ stroke-linejoin: round;
158
+ stroke-linecap: round;
159
+ }
160
+
161
+ /* 顶点带一圈承载面色的描边环,压在别的实体的轮廓上也分得开 */
162
+ [data-scope='radar-chart'][data-part='point'] {
163
+ fill: var(--xh-_chart-series);
164
+ stroke: var(--xh-chart-surface);
165
+ stroke-width: var(--xh-chart-gap);
166
+ }
167
+
168
+ /* —— 纹理:颜色不可用或不可靠时(强制色、打印、祖先写了 data-xh-chart-patterns),面积改用本系列在 defs 里的
169
+ 纹理填充、描出轮廓,轮廓换线型。色标的纹理在配方里 —— */
170
+ :where([data-xh-chart-patterns]) [data-scope='radar-chart'][data-xh-chart-pattern] > [data-part='area-fill'] {
171
+ fill: var(--xh-_chart-pattern);
172
+ fill-opacity: 1;
173
+ }
174
+
175
+ :where([data-xh-chart-patterns]) [data-scope='radar-chart'][data-xh-chart-pattern] > [data-part='line'] {
176
+ stroke-dasharray: var(--xh-_chart-dash);
177
+ }
178
+
179
+ /* 强制色:数据标记改成系统色,网格取灰字色;纹理总是开启;焦点环与色标在配方里 */
180
+ @media (forced-colors: active) {
181
+ [data-scope='radar-chart'][data-part='grid-ring'] {
182
+ stroke: GrayText;
183
+ }
184
+
185
+ [data-scope='radar-chart'][data-part='spoke'] {
186
+ stroke: CanvasText;
187
+ }
188
+
189
+ [data-scope='radar-chart'][data-part='indicator-label'],
190
+ [data-scope='radar-chart'][data-part='ring-label'] {
191
+ fill: CanvasText;
192
+ }
193
+
194
+ [data-scope='radar-chart'][data-part='crosshair'] {
195
+ stroke: Highlight;
196
+ }
197
+
198
+ [data-scope='radar-chart'][data-part='line'] {
199
+ stroke: CanvasText;
200
+ }
201
+
202
+ [data-scope='radar-chart'][data-part='point'] {
203
+ fill: CanvasText;
204
+ stroke: Canvas;
205
+ }
206
+
207
+ [data-scope='radar-chart'][data-xh-chart-pattern] > [data-part='area-fill'] {
208
+ forced-color-adjust: none;
209
+ fill: var(--xh-_chart-pattern);
210
+ fill-opacity: 1;
211
+ }
212
+
213
+ [data-scope='radar-chart'][data-xh-chart-pattern] > [data-part='line'] {
214
+ stroke-dasharray: var(--xh-_chart-dash);
215
+ }
216
+ }
217
+
218
+ /* 打印:纸上没有指针,准线不印;纹理开启;提示框与焦点环在配方里 */
219
+ @media print {
220
+ [data-scope='radar-chart'][data-part='crosshair'] {
221
+ display: none;
222
+ }
223
+
224
+ [data-scope='radar-chart'][data-xh-chart-pattern] > [data-part='area-fill'] {
225
+ fill: var(--xh-_chart-pattern);
226
+ fill-opacity: 1;
227
+ }
228
+
229
+ [data-scope='radar-chart'][data-xh-chart-pattern] > [data-part='line'] {
230
+ stroke-dasharray: var(--xh-_chart-dash);
231
+ }
232
+ }
233
+ }