@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
@@ -8,6 +8,7 @@
8
8
  /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
9
9
  @import '../family/motion.css';
10
10
  @import '../family/action-control.css';
11
+ @import '../family/material.css';
11
12
 
12
13
  @layer xihan.components {
13
14
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
@@ -84,7 +85,8 @@
84
85
  面板整棵子树都在 positioner 底下,它一收就不生成盒子,退场动画一帧都播不出来。
85
86
  真正的收起由宿主在退场结束后落成内联 display:none。 */
86
87
 
87
- [data-scope='floating-panel'][data-part='positioner'][data-state='open'] {
88
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
89
+ [data-scope='floating-panel'][data-part='positioner'][data-state='open']:not([data-instant]) {
88
90
  animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
89
91
  }
90
92
 
@@ -95,39 +97,52 @@
95
97
  }
96
98
 
97
99
  [data-scope='floating-panel'][data-part='content'] {
100
+ /* 材质由家族配方画(family/material.css 的 frosted 面:描边、底、1px 顶光、前景、投影与背景滤镜),
101
+ 这里只把使用者槽接进来 */
102
+ --xh-frosted-bg: var(--xh-floating-panel-bg, var(--xh-_material-bg));
103
+ --xh-frosted-border: var(--xh-floating-panel-border, var(--xh-_material-border));
104
+ --xh-frosted-fg: var(--xh-floating-panel-fg, var(--xh-_material-fg));
105
+ --xh-frosted-shadow: var(--xh-floating-panel-shadow, var(--xh-_material-shadow));
106
+
98
107
  position: relative;
99
108
  block-size: 100%;
100
109
  display: flex;
101
110
  flex-direction: column;
102
111
  overflow: hidden;
103
- /* 默认态是 M2 磨砂面:背景、边缘、高光、投影与光学采样同出一张配方。
104
- 作者既有的面板槽仍排在外层;没有覆写时才落进这套磨砂令牌。 */
105
- border: var(--xh-stroke-thin) solid var(--xh-floating-panel-border, var(--xh-material-frosted-border));
106
112
  border-radius: var(--xh-floating-panel-radius, var(--xh-shape-overlay));
107
- background:
108
- linear-gradient(
109
- to bottom,
110
- var(--xh-material-frosted-highlight) 0 var(--xh-stroke-thin),
111
- transparent var(--xh-stroke-thin)
112
- ),
113
- var(--xh-floating-panel-bg, var(--xh-material-frosted-bg));
114
- color: var(--xh-floating-panel-fg, var(--xh-material-frosted-fg));
115
- box-shadow: var(--xh-floating-panel-shadow, var(--xh-material-frosted-shadow));
116
- -webkit-backdrop-filter: var(--xh-material-frosted-backdrop);
117
- backdrop-filter: var(--xh-material-frosted-backdrop);
118
- /* 铺满那一档要把投影整个撤掉,海拔的这一跳跟着过渡走 */
119
- transition: box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
113
+ /* 铺满那一档要把投影与描边色整个撤掉,海拔的这一跳跟着过渡走 */
114
+ transition:
115
+ box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
116
+ border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
120
117
  }
121
118
 
122
119
  /* 最大化时几何层把面板写成铺满视口(left/top 归零、宽高 100%),四条边全贴着视口:
123
120
  圆角会在四角把底下的页面露出来,描边缩成一圈贴边的多余框线,投影整块落在视口之外。
124
- 三样一起撤,与抽屉贴住视口的那条边不圆角是同一回事。 */
121
+ 三样一起撤,与抽屉贴住视口的那条边不圆角是同一回事。描边只撤颜色、不撤宽度,
122
+ 进出最大化时盒子不因描边一收一放跳一像素 */
125
123
  [data-scope='floating-panel'][data-part='content'][data-window-state='maximized'] {
126
- border: 0;
124
+ border-color: transparent;
127
125
  border-radius: 0;
128
126
  box-shadow: none;
129
127
  }
130
128
 
129
+ /* 进出最大化:位置与尺寸按指示档补过去,圆角同步收放,不再瞬切。只在这一段挂——
130
+ 拖动与改尺寸要跟手,平时的定位层不带过渡;减弱动效下即刻到位 */
131
+ [data-scope='floating-panel'][data-part='positioner'][data-animating] {
132
+ transition:
133
+ left var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
134
+ top var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
135
+ width var(--xh-motion-duration-move) var(--xh-motion-ease-continuous),
136
+ height var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
137
+ }
138
+
139
+ [data-scope='floating-panel'][data-part='positioner'][data-animating] [data-scope='floating-panel'][data-part='content'] {
140
+ transition:
141
+ box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
142
+ border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
143
+ border-radius var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
144
+ }
145
+
131
146
  [data-scope='floating-panel'][data-part='content'][hidden] {
132
147
  display: none;
133
148
  }
@@ -392,4 +407,23 @@
392
407
  display: none;
393
408
  }
394
409
  }
410
+
411
+ @media (forced-colors: active) {
412
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
413
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
414
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
415
+ 禁用取 GrayText */
416
+ [data-scope='floating-panel']:is([data-part='close-trigger'], [data-part='window-state-trigger']):empty::before {
417
+ forced-color-adjust: none;
418
+ background-color: ButtonText;
419
+ }
420
+
421
+ [data-scope='floating-panel']:is([data-part='close-trigger'], [data-part='window-state-trigger']):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
422
+ background-color: HighlightText;
423
+ }
424
+
425
+ [data-scope='floating-panel']:is([data-part='close-trigger'], [data-part='window-state-trigger'])[data-disabled]:empty::before {
426
+ background-color: GrayText;
427
+ }
428
+ }
395
429
  }
package/css/form.css CHANGED
@@ -5,8 +5,11 @@
5
5
 
6
6
  /* 定义 form 样式。 */
7
7
 
8
+ /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
9
+ @import '../family/motion.css';
8
10
  /* Form 独立皮肤同时传递引入提交 / 重置钮的动作控件配方;full bundle 递归去重。 */
9
11
  @import '../family/action-control.css';
12
+ @import '../family/loading-ring.css';
10
13
 
11
14
  @layer xihan.components {
12
15
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
@@ -204,11 +207,16 @@
204
207
  /* 从收起翻成显出的那一下给一小段入场:读屏靠 role=alert 播报,
205
208
  视觉这边也得有个"它是刚冒出来的"的交代,否则像一直杵在那儿 */
206
209
  [data-scope='form'][data-part='error-summary'][data-state='invalid'] {
207
- animation: xh-form-summary-enter var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
210
+ animation: xh-drop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
211
+ }
212
+
213
+ /* 错误全改完或重置时淡出,播完连接层才写 hidden。收起态常挂 hidden,这条只在退场途中命中 */
214
+ [data-scope='form'][data-part='error-summary'][data-state='idle'] {
215
+ animation: xh-fade-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
208
216
  }
209
217
 
210
218
  /* 摘要里的每一条是一个真链接,指向对应字段容器。铺满一行的集合行:悬停 / 按下只换面不缩放,
211
- 底面坐在摘要的 surface 白底上,走白底承载阶梯 100 → 200;换面走按压时间线,释放回 release 档 */
219
+ 底面坐在摘要的 surface 白底上,走白底承载阶梯 100 → 200;换面按下走 press,其余走 micro */
212
220
  [data-scope='form'][data-part='error-summary-item'] {
213
221
  display: block;
214
222
  padding-inline: var(--xh-form-summary-item-px, var(--xh-space-1));
@@ -220,7 +228,7 @@
220
228
  text-underline-offset: var(--xh-form-summary-item-underline-offset, var(--xh-space-0_5));
221
229
  cursor: pointer;
222
230
  transition:
223
- background-color var(--xh-motion-duration-release) var(--xh-motion-ease-release),
231
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
224
232
  color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
225
233
  }
226
234
 
@@ -232,7 +240,7 @@
232
240
  /* 摘要显出时条目逐条入场,越靠后起步越晚。
233
241
  backwards 让还没轮到的条目停在首帧,不是先显出再重播 */
234
242
  [data-scope='form'][data-part='error-summary'][data-state='invalid'] [data-part='error-summary-item'] {
235
- animation: xh-form-summary-enter var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
243
+ animation: xh-drop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
236
244
  }
237
245
 
238
246
  /* 排序按"前面有几条露面的"数,不按 nth-child:作者一次把所有字段的条目都写上,
@@ -360,20 +368,18 @@
360
368
  --xh-action-shadow-pressed: var(--xh-form-submit-shadow, var(--xh-_highlight-brand));
361
369
  --xh-action-ring-color-focus-visible: currentColor;
362
370
  }
363
- }
364
371
 
365
- @layer xihan.motion {
366
- /* 关键帧写在自己文件里、名字带组件前缀:motion.css 是公共的,
367
- 往那儿加一条只服务本组件的动画会让所有组件都得跟着重下载 */
368
- @keyframes xh-form-summary-enter {
369
- from {
370
- opacity: 0;
371
- translate: 0 calc(-1 * var(--xh-motion-distance-sm));
372
- }
372
+ /* 提交回调在途:环由加载环配方压在提交钮正中(连接层投影 data-xh-loading-ring="overlay"),直径取钮的图标档,
373
+ 起始边取钮的真实前景、转速认使用者槽。不是禁用,焦点与对比度都保持,在途指针由家族 loading 面给。
374
+ 提交文案随前景淡到透明留位:进入在途等一个 micro 才起淡(快速落定什么都不闪),落定时不等、按 micro 淡回 */
375
+ [data-scope='form'][data-part='submit-trigger'] {
376
+ --xh-_loading-ring-fg: var(--xh-form-submit-fg, var(--xh-_action-variant-fg-loading));
377
+ --xh-_loading-ring-duration: var(--xh-form-loading-duration, var(--xh-motion-loop-spin));
378
+ }
373
379
 
374
- to {
375
- opacity: 1;
376
- translate: 0 0;
377
- }
380
+ [data-scope='form'][data-part='submit-trigger'][data-loading] {
381
+ --xh-action-fg-loading: transparent;
382
+
383
+ transition-delay: var(--xh-motion-duration-micro);
378
384
  }
379
385
  }
@@ -0,0 +1,106 @@
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
+ /* 定义 funnel 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='funnel-chart'] {
16
+ --xh-funnel-chart-skin: 1;
17
+ }
18
+
19
+ /* 几何要用的像素值以这里的私有槽为真源:机器挂载后从计算样式读它们,作者覆盖组件槽即改变几何 */
20
+ [data-scope='funnel-chart'][data-part='root'] {
21
+ --xh-_chart-metric-bar-max: var(--xh-chart-bar-max);
22
+ --xh-_chart-metric-gap: var(--xh-funnel-chart-stage-gap, var(--xh-chart-gap));
23
+ --xh-_chart-metric-line-width: var(--xh-chart-line-width);
24
+ --xh-_chart-metric-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-funnel-chart-gap, var(--xh-space-3));
32
+ }
33
+
34
+ /* —— 家族配方的组件槽:标题、视口、提示框与空态由 family/chart.css 画,本图表的覆盖槽写在
35
+ 对应部件上接进配方的私有槽,作者在部件或它的祖先上覆盖都生效 —— */
36
+ [data-scope='funnel-chart'][data-part='viewport'] {
37
+ --xh-_chart-height: var(--xh-funnel-chart-height, var(--xh-chart-height));
38
+ }
39
+
40
+ [data-scope='funnel-chart'][data-part='tooltip'] {
41
+ --xh-_chart-tooltip-gap: var(--xh-funnel-chart-tooltip-gap, var(--xh-space-1));
42
+ --xh-_chart-tooltip-py: var(--xh-funnel-chart-tooltip-py, var(--xh-surface-pad-sm));
43
+ --xh-_chart-tooltip-px: var(--xh-funnel-chart-tooltip-px, var(--xh-surface-pad-sm));
44
+ --xh-_chart-tooltip-radius: var(--xh-funnel-chart-tooltip-radius, var(--xh-shape-overlay));
45
+ --xh-_chart-tooltip-shadow: var(--xh-funnel-chart-tooltip-shadow, var(--xh-material-frosted-shadow));
46
+ }
47
+
48
+ [data-scope='funnel-chart'][data-part='tooltip-row'] {
49
+ --xh-_chart-tooltip-row-gap: var(--xh-funnel-chart-tooltip-row-gap, var(--xh-space-2));
50
+ }
51
+
52
+ [data-scope='funnel-chart'][data-part='tooltip-swatch'] {
53
+ --xh-_chart-tooltip-swatch-radius: var(--xh-funnel-chart-tooltip-swatch-radius, var(--xh-shape-inset));
54
+ }
55
+
56
+ [data-scope='funnel-chart'][data-part='empty'][data-state='loading'] {
57
+ --xh-_chart-empty-gap: var(--xh-funnel-chart-empty-gap, var(--xh-space-2));
58
+ }
59
+
60
+ /* —— 阶段:顺序色阶由深入浅,颜色由 Chart 家族配方按段号与段内百分比兑好放在私有槽里;
61
+ 相邻阶段之间的间隙由几何留出,不画描边;指着一个阶段时其余阶段淡出,被指着的不位移 —— */
62
+ [data-scope='funnel-chart'][data-part='stage'] {
63
+ fill: var(--xh-_chart-seq-fill);
64
+ stroke: none;
65
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
66
+ }
67
+
68
+ [data-scope='funnel-chart'][data-part='stage'][data-dimmed],
69
+ [data-scope='funnel-chart'][data-part='stage-label'][data-dimmed],
70
+ [data-scope='funnel-chart'][data-part='conversion'][data-dimmed] {
71
+ opacity: var(--xh-chart-dim-alpha);
72
+ }
73
+
74
+ /* 阶段标签与转化率是标注:标注字色,不取色阶色 */
75
+ [data-scope='funnel-chart'][data-part='stage-label'],
76
+ [data-scope='funnel-chart'][data-part='conversion'] {
77
+ fill: var(--xh-chart-label);
78
+ font-variant-numeric: tabular-nums;
79
+ }
80
+
81
+ /* 写在阶段里的标签压在色阶色上:深浅两端都要读得清,描一圈承载面色 */
82
+ [data-scope='funnel-chart'][data-part='stage-label'][data-placement='inside'] {
83
+ stroke: var(--xh-chart-surface);
84
+ stroke-width: var(--xh-stroke-thick);
85
+ paint-order: stroke;
86
+ font-weight: var(--xh-font-weight-medium);
87
+ }
88
+
89
+ /* 强制色:阶段改成系统色的面与描边,标注取正文色;焦点环在配方里 */
90
+ @media (forced-colors: active) {
91
+ [data-scope='funnel-chart'][data-part='stage'] {
92
+ fill: Canvas;
93
+ stroke: CanvasText;
94
+ stroke-width: var(--xh-stroke-thin);
95
+ }
96
+
97
+ [data-scope='funnel-chart'][data-part='stage-label'],
98
+ [data-scope='funnel-chart'][data-part='conversion'] {
99
+ fill: CanvasText;
100
+ }
101
+
102
+ [data-scope='funnel-chart'][data-part='stage-label'][data-placement='inside'] {
103
+ stroke: Canvas;
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,205 @@
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
+ /* 定义 graph 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='graph-chart'] {
16
+ --xh-graph-chart-skin: 1;
17
+ }
18
+
19
+ /* 几何要用的像素值以这里的私有槽为真源:机器挂载后从计算样式读它们,作者覆盖组件槽即改变几何。
20
+ 节点的基准半径借点径那一格传进去 */
21
+ [data-scope='graph-chart'][data-part='root'] {
22
+ --xh-_chart-metric-bar-max: var(--xh-chart-bar-max);
23
+ --xh-_chart-metric-gap: var(--xh-chart-gap);
24
+ --xh-_chart-metric-line-width: var(--xh-chart-line-width);
25
+ --xh-_chart-metric-point-size: var(--xh-graph-chart-node-size, var(--xh-chart-point-size));
26
+ --xh-_chart-metric-hit-min: var(--xh-chart-hit-min);
27
+ --xh-_chart-metric-tick-length: var(--xh-chart-tick-length);
28
+ --xh-_chart-metric-label-gap: var(--xh-chart-label-gap);
29
+ --xh-_chart-metric-radius: var(--xh-shape-inset);
30
+ --xh-_chart-metric-font-size: var(--xh-text-caption-size);
31
+ --xh-_chart-metric-leading: var(--xh-leading-tight);
32
+ --xh-_chart-gap: var(--xh-graph-chart-gap, var(--xh-space-3));
33
+ }
34
+
35
+ /* —— 家族配方的组件槽:标题、视口、图例、提示框与空态由 family/chart.css 画,本图表的覆盖槽写在
36
+ 对应部件上接进配方的私有槽,作者在部件或它的祖先上覆盖都生效 —— */
37
+ [data-scope='graph-chart'][data-part='viewport'] {
38
+ --xh-_chart-height: var(--xh-graph-chart-height, var(--xh-chart-height));
39
+ }
40
+
41
+ [data-scope='graph-chart'][data-part='legend'] {
42
+ --xh-_chart-legend-gap: var(--xh-graph-chart-legend-gap, var(--xh-space-1));
43
+ }
44
+
45
+ [data-scope='graph-chart'][data-part='legend-swatch'] {
46
+ --xh-_chart-legend-swatch-radius: var(--xh-graph-chart-legend-swatch-radius, var(--xh-shape-inset));
47
+ }
48
+
49
+ [data-scope='graph-chart'][data-part='tooltip'] {
50
+ --xh-_chart-tooltip-gap: var(--xh-graph-chart-tooltip-gap, var(--xh-space-1));
51
+ --xh-_chart-tooltip-py: var(--xh-graph-chart-tooltip-py, var(--xh-surface-pad-sm));
52
+ --xh-_chart-tooltip-px: var(--xh-graph-chart-tooltip-px, var(--xh-surface-pad-sm));
53
+ --xh-_chart-tooltip-radius: var(--xh-graph-chart-tooltip-radius, var(--xh-shape-overlay));
54
+ --xh-_chart-tooltip-shadow: var(--xh-graph-chart-tooltip-shadow, var(--xh-material-frosted-shadow));
55
+ }
56
+
57
+ [data-scope='graph-chart'][data-part='tooltip-row'] {
58
+ --xh-_chart-tooltip-row-gap: var(--xh-graph-chart-tooltip-row-gap, var(--xh-space-2));
59
+ }
60
+
61
+ [data-scope='graph-chart'][data-part='empty'][data-state='loading'] {
62
+ --xh-_chart-empty-gap: var(--xh-graph-chart-empty-gap, var(--xh-space-2));
63
+ }
64
+
65
+ /* —— 色槽:分组由色槽承担,作者可以在节点上覆盖 --xh-graph-chart-series-color ——
66
+ 节点、被强调的连线、图例项都带着色槽,各自从这里取系列色 */
67
+ [data-scope='graph-chart'][data-xh-chart-slot='1'] {
68
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-1));
69
+ }
70
+
71
+ [data-scope='graph-chart'][data-xh-chart-slot='2'] {
72
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-2));
73
+ }
74
+
75
+ [data-scope='graph-chart'][data-xh-chart-slot='3'] {
76
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-3));
77
+ }
78
+
79
+ [data-scope='graph-chart'][data-xh-chart-slot='4'] {
80
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-4));
81
+ }
82
+
83
+ [data-scope='graph-chart'][data-xh-chart-slot='5'] {
84
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-5));
85
+ }
86
+
87
+ [data-scope='graph-chart'][data-xh-chart-slot='6'] {
88
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-6));
89
+ }
90
+
91
+ [data-scope='graph-chart'][data-xh-chart-slot='7'] {
92
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-7));
93
+ }
94
+
95
+ [data-scope='graph-chart'][data-xh-chart-slot='8'] {
96
+ --xh-_chart-series: var(--xh-graph-chart-series-color, var(--xh-chart-categorical-8));
97
+ }
98
+
99
+ /* —— 连线:次要的中性色细线,有权重时按权重加粗(宽度由连接层写进私有槽);箭头与线同色。
100
+ 指着一个节点时连着它的线换成它的颜色,其余淡出 —— */
101
+ [data-scope='graph-chart'][data-part='link'],
102
+ [data-scope='graph-chart'][data-part='arrow'] {
103
+ --xh-_graph-link: var(--xh-graph-chart-link-color, var(--xh-fg-subtle));
104
+
105
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
106
+ }
107
+
108
+ [data-scope='graph-chart'][data-part='link'] {
109
+ fill: none;
110
+ stroke: var(--xh-_graph-link);
111
+ stroke-width: var(--xh-_graph-link-width, var(--xh-graph-chart-link-width, var(--xh-stroke-thin)));
112
+ stroke-linecap: round;
113
+ }
114
+
115
+ [data-scope='graph-chart'][data-part='arrow'] {
116
+ fill: var(--xh-_graph-link);
117
+ stroke: none;
118
+ }
119
+
120
+ [data-scope='graph-chart'][data-part='link'][data-highlighted],
121
+ [data-scope='graph-chart'][data-part='arrow'][data-highlighted] {
122
+ --xh-_graph-link: var(--xh-_chart-series);
123
+ }
124
+
125
+ /* —— 节点:取分组的系列色,外面描一圈承载面色,节点挨在一起、压在连线上时边界照样分明 —— */
126
+ [data-scope='graph-chart'][data-part='node'] {
127
+ fill: var(--xh-_chart-series);
128
+ stroke: var(--xh-chart-surface);
129
+ stroke-width: var(--xh-chart-gap);
130
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
131
+ }
132
+
133
+ [data-scope='graph-chart'][data-part='link'][data-dimmed],
134
+ [data-scope='graph-chart'][data-part='arrow'][data-dimmed],
135
+ [data-scope='graph-chart'][data-part='node'][data-dimmed],
136
+ [data-scope='graph-chart'][data-part='node-label'][data-dimmed],
137
+ [data-scope='graph-chart'][data-part='link-label'][data-dimmed] {
138
+ opacity: var(--xh-chart-dim-alpha);
139
+ }
140
+
141
+ /* 节点名可能压在连线上:正文色,描一圈承载面色,交叠处也读得清。名字不接指针,命中归节点 */
142
+ [data-scope='graph-chart'][data-part='node-label'] {
143
+ fill: var(--xh-fg-default);
144
+ stroke: var(--xh-chart-surface);
145
+ stroke-width: var(--xh-stroke-thick);
146
+ stroke-linejoin: round;
147
+ paint-order: stroke;
148
+ pointer-events: none;
149
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
150
+ }
151
+
152
+ /* 连线上的字就压在线上:次级文字色与节点名分出主次,同样描一圈承载面色把线从字底下断开 */
153
+ [data-scope='graph-chart'][data-part='link-label'] {
154
+ fill: var(--xh-fg-muted);
155
+ stroke: var(--xh-chart-surface);
156
+ stroke-width: var(--xh-stroke-thick);
157
+ stroke-linejoin: round;
158
+ paint-order: stroke;
159
+ pointer-events: none;
160
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
161
+ }
162
+
163
+ /* —— 直接操纵:能拖的节点给抓手,拖着时整张图是抓紧的手;放大后空白处也能拖着平移。
164
+ 触屏在节点上的拖动归图,其余地方照常滚动页面 —— */
165
+ [data-scope='graph-chart'][data-part='plot'][data-draggable] [data-part='node'] {
166
+ cursor: grab;
167
+ touch-action: none;
168
+ }
169
+
170
+ [data-scope='graph-chart'][data-part='plot'][data-zoomed] {
171
+ cursor: grab;
172
+ touch-action: none;
173
+ }
174
+
175
+ [data-scope='graph-chart'][data-part='plot'][data-dragging],
176
+ [data-scope='graph-chart'][data-part='plot'][data-dragging] [data-part='node'] {
177
+ cursor: grabbing;
178
+ }
179
+
180
+ /* 强制色:节点改成系统色的面与描边,连线取次级系统色、被强调的取高亮色,名字取正文色;
181
+ 焦点环、图例与色标在配方里 */
182
+ @media (forced-colors: active) {
183
+ [data-scope='graph-chart'][data-part='node'] {
184
+ fill: Canvas;
185
+ stroke: CanvasText;
186
+ stroke-width: var(--xh-stroke-thin);
187
+ }
188
+
189
+ [data-scope='graph-chart'][data-part='link'],
190
+ [data-scope='graph-chart'][data-part='arrow'] {
191
+ --xh-_graph-link: GrayText;
192
+ }
193
+
194
+ [data-scope='graph-chart'][data-part='link'][data-highlighted],
195
+ [data-scope='graph-chart'][data-part='arrow'][data-highlighted] {
196
+ --xh-_graph-link: Highlight;
197
+ }
198
+
199
+ [data-scope='graph-chart'][data-part='node-label'],
200
+ [data-scope='graph-chart'][data-part='link-label'] {
201
+ fill: CanvasText;
202
+ stroke: Canvas;
203
+ }
204
+ }
205
+ }