@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
@@ -0,0 +1,247 @@
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
+ /* 定义 pie chart 样式。 */
7
+
8
+ /* 淡入关键帧由 family/motion.css 提供;标题、视口、图例、提示框、空态、焦点环与引导线走 Chart 家族配方。
9
+ 本皮肤 @import 它们,单独引入仍成立。 */
10
+ @import '../family/motion.css';
11
+ @import '../family/chart.css';
12
+ @import '../family/loading-ring.css';
13
+
14
+ @layer xihan.components {
15
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
16
+ [data-scope='pie-chart'] {
17
+ --xh-pie-chart-skin: 1;
18
+ }
19
+
20
+ /* 几何要用的像素值以这里的私有槽为真源:机器挂载后从计算样式读它们,作者覆盖组件槽即改变几何 */
21
+ [data-scope='pie-chart'][data-part='root'] {
22
+ --xh-_chart-metric-bar-max: var(--xh-chart-bar-max);
23
+ --xh-_chart-metric-gap: var(--xh-pie-chart-slice-gap, var(--xh-chart-gap));
24
+ --xh-_chart-metric-line-width: var(--xh-chart-line-width);
25
+ --xh-_chart-metric-point-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-pie-chart-slice-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-pie-chart-gap, var(--xh-space-3));
33
+ }
34
+
35
+ /* —— 家族配方的组件槽:标题、视口、图例、提示框与空态由 family/chart.css 画,本图表的覆盖槽写在
36
+ 对应部件上接进配方的私有槽,作者在部件或它的祖先上覆盖都生效 —— */
37
+ [data-scope='pie-chart'][data-part='viewport'] {
38
+ --xh-_chart-height: var(--xh-pie-chart-height, var(--xh-chart-height));
39
+ }
40
+
41
+ [data-scope='pie-chart'][data-part='legend'] {
42
+ --xh-_chart-legend-gap: var(--xh-pie-chart-legend-gap, var(--xh-space-1));
43
+ }
44
+
45
+ [data-scope='pie-chart'][data-part='legend-swatch'] {
46
+ --xh-_chart-legend-swatch-radius: var(--xh-pie-chart-legend-swatch-radius, var(--xh-shape-inset));
47
+ }
48
+
49
+ [data-scope='pie-chart'][data-part='tooltip'] {
50
+ --xh-_chart-tooltip-gap: var(--xh-pie-chart-tooltip-gap, var(--xh-space-1));
51
+ --xh-_chart-tooltip-py: var(--xh-pie-chart-tooltip-py, var(--xh-surface-pad-sm));
52
+ --xh-_chart-tooltip-px: var(--xh-pie-chart-tooltip-px, var(--xh-surface-pad-sm));
53
+ --xh-_chart-tooltip-radius: var(--xh-pie-chart-tooltip-radius, var(--xh-shape-overlay));
54
+ --xh-_chart-tooltip-shadow: var(--xh-pie-chart-tooltip-shadow, var(--xh-material-frosted-shadow));
55
+ }
56
+
57
+ [data-scope='pie-chart'][data-part='tooltip-row'] {
58
+ --xh-_chart-tooltip-row-gap: var(--xh-pie-chart-tooltip-row-gap, var(--xh-space-2));
59
+ }
60
+
61
+ [data-scope='pie-chart'][data-part='tooltip-swatch'] {
62
+ --xh-_chart-tooltip-swatch-radius: var(--xh-pie-chart-tooltip-swatch-radius, var(--xh-shape-inset));
63
+ }
64
+
65
+ [data-scope='pie-chart'][data-part='empty'][data-state='loading'] {
66
+ --xh-_chart-empty-gap: var(--xh-pie-chart-empty-gap, var(--xh-space-2));
67
+ }
68
+
69
+ /* —— 色槽:身份由色槽承担,作者可以在扇区上覆盖 --xh-pie-chart-series-color ——
70
+ 扇区、内侧标签、图例项与提示框的行都带着色槽,各自从这里取系列色与配对的前景色 */
71
+ [data-scope='pie-chart'][data-xh-chart-slot='1'] {
72
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-1));
73
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-1);
74
+ }
75
+
76
+ [data-scope='pie-chart'][data-xh-chart-slot='2'] {
77
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-2));
78
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-2);
79
+ }
80
+
81
+ [data-scope='pie-chart'][data-xh-chart-slot='3'] {
82
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-3));
83
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-3);
84
+ }
85
+
86
+ [data-scope='pie-chart'][data-xh-chart-slot='4'] {
87
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-4));
88
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-4);
89
+ }
90
+
91
+ [data-scope='pie-chart'][data-xh-chart-slot='5'] {
92
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-5));
93
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-5);
94
+ }
95
+
96
+ [data-scope='pie-chart'][data-xh-chart-slot='6'] {
97
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-6));
98
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-6);
99
+ }
100
+
101
+ [data-scope='pie-chart'][data-xh-chart-slot='7'] {
102
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-7));
103
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-7);
104
+ }
105
+
106
+ [data-scope='pie-chart'][data-xh-chart-slot='8'] {
107
+ --xh-_chart-series: var(--xh-pie-chart-series-color, var(--xh-chart-categorical-8));
108
+ --xh-_chart-on-series: var(--xh-chart-on-categorical-8);
109
+ }
110
+
111
+ /* 合并出来的「其他」取中性色:它不是一个类目,不占分类色 */
112
+ [data-scope='pie-chart'][data-xh-chart-slot='other'] {
113
+ --xh-_chart-series: var(--xh-chart-categorical-other);
114
+ }
115
+
116
+ /* —— 扇区:相邻扇区之间的间隙由几何留出,不画描边;悬停时其余扇区淡出,被指着的不位移 —— */
117
+ [data-scope='pie-chart'][data-part='slice'] {
118
+ fill: var(--xh-_chart-series);
119
+ stroke: none;
120
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
121
+ }
122
+
123
+ [data-scope='pie-chart'][data-part='slice'][data-dimmed],
124
+ [data-scope='pie-chart'][data-part='slice-label'][data-dimmed] {
125
+ opacity: var(--xh-chart-dim-alpha);
126
+ }
127
+
128
+ /* 外侧标签是标注:标注字色,不取扇区色;引导线的画法在配方里 */
129
+ [data-scope='pie-chart'][data-part='slice-label'] {
130
+ fill: var(--xh-chart-label);
131
+ }
132
+
133
+ /* 内侧标签压在扇区色上:取与色槽配对的前景色 */
134
+ [data-scope='pie-chart'][data-part='slice-label'][data-xh-chart-slot] {
135
+ fill: var(--xh-_chart-on-series);
136
+ font-weight: var(--xh-font-weight-medium);
137
+ }
138
+
139
+ /* —— 环形中心:叠在视口上,圆心与内径由几何给出;文字不超出内圈 —— */
140
+ /* 首次出现:外侧标签等扫开的边缘到了才淡入,连接层写入它占入场时长的比例,乘上入场时长就是延迟;
141
+ 环形中心等整圈扫完再淡入 */
142
+ [data-scope='pie-chart'][data-part='slice-label'][data-drawing] {
143
+ animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter) both;
144
+ animation-delay: calc(var(--xh-motion-duration-reveal) * var(--xh-_chart-reveal-at));
145
+ }
146
+
147
+ [data-scope='pie-chart'][data-part='center'][data-drawing] {
148
+ animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter) both;
149
+ animation-delay: var(--xh-motion-duration-reveal);
150
+ }
151
+
152
+ [data-scope='pie-chart'][data-part='center'] {
153
+ position: absolute;
154
+ inset-block-start: var(--xh-_chart-center-y, 50%);
155
+ /* stylelint-disable-next-line property-disallowed-list -- 绘图区不随 RTL 镜像,圆心横坐标由连接层按物理左缘写入 */
156
+ left: var(--xh-_chart-center-x, 50%);
157
+ display: flex;
158
+ flex-direction: column;
159
+ align-items: center;
160
+ gap: var(--xh-pie-chart-center-gap, var(--xh-space-0_5));
161
+ max-inline-size: calc(var(--xh-_chart-center-size, 0px) * 0.8);
162
+ text-align: center;
163
+ /* 中心不接指针:它压在内圈的空洞上,不挡扇区的命中 */
164
+ pointer-events: none;
165
+ translate: -50% -50%;
166
+ }
167
+
168
+ [data-scope='pie-chart'][data-part='center'][data-placement='top'] {
169
+ translate: -50% -100%;
170
+ }
171
+
172
+ [data-scope='pie-chart'][data-part='center'][hidden] {
173
+ display: none;
174
+ }
175
+
176
+ [data-scope='pie-chart'][data-part='center-value'] {
177
+ color: var(--xh-fg-default);
178
+ font-size: var(--xh-pie-chart-center-value-font-size, var(--xh-text-heading-3-size));
179
+ font-weight: var(--xh-font-weight-semibold);
180
+ line-height: var(--xh-leading-tight);
181
+ font-variant-numeric: tabular-nums;
182
+ }
183
+
184
+ [data-scope='pie-chart'][data-part='center-label'] {
185
+ color: var(--xh-fg-muted);
186
+ font-size: var(--xh-text-secondary-size);
187
+ }
188
+
189
+ /* —— 纹理:颜色不可用或不可靠时(强制色、打印、祖先写了 data-xh-chart-patterns),扇区改用本色槽在 defs 里的
190
+ 纹理填充、描出轮廓(「其他」不带纹理);压在扇区上的标签改用标签色、描一圈承载面色。色标的纹理在配方里 —— */
191
+ :where([data-xh-chart-patterns]) [data-scope='pie-chart'][data-part='slice'][data-xh-chart-pattern] {
192
+ fill: var(--xh-_chart-pattern);
193
+ stroke: var(--xh-_chart-series);
194
+ stroke-width: var(--xh-stroke-thin);
195
+ }
196
+
197
+ :where([data-xh-chart-patterns]) [data-scope='pie-chart'][data-part='slice-label'][data-xh-chart-slot] {
198
+ fill: var(--xh-chart-label);
199
+ stroke: var(--xh-chart-surface);
200
+ stroke-width: var(--xh-stroke-thick);
201
+ paint-order: stroke;
202
+ }
203
+
204
+ /* 强制色:扇区改成系统色的面与描边;纹理总是开启;焦点环、引导线与色标在配方里 */
205
+ @media (forced-colors: active) {
206
+ [data-scope='pie-chart'][data-part='slice'] {
207
+ fill: Canvas;
208
+ stroke: CanvasText;
209
+ stroke-width: var(--xh-stroke-thin);
210
+ }
211
+
212
+ [data-scope='pie-chart'][data-part='slice-label'],
213
+ [data-scope='pie-chart'][data-part='slice-label'][data-xh-chart-slot] {
214
+ fill: CanvasText;
215
+ }
216
+
217
+ [data-scope='pie-chart'][data-part='slice'][data-xh-chart-pattern] {
218
+ forced-color-adjust: none;
219
+ fill: var(--xh-_chart-pattern);
220
+ stroke: CanvasText;
221
+ stroke-width: var(--xh-stroke-thin);
222
+ }
223
+
224
+ [data-scope='pie-chart'][data-part='slice-label'][data-xh-chart-slot] {
225
+ fill: CanvasText;
226
+ stroke: Canvas;
227
+ stroke-width: var(--xh-stroke-thick);
228
+ paint-order: stroke;
229
+ }
230
+ }
231
+
232
+ /* 打印:纹理开启;提示框与焦点环在配方里 */
233
+ @media print {
234
+ [data-scope='pie-chart'][data-part='slice'][data-xh-chart-pattern] {
235
+ fill: var(--xh-_chart-pattern);
236
+ stroke: var(--xh-_chart-series);
237
+ stroke-width: var(--xh-stroke-thin);
238
+ }
239
+
240
+ [data-scope='pie-chart'][data-part='slice-label'][data-xh-chart-slot] {
241
+ fill: var(--xh-chart-label);
242
+ stroke: var(--xh-chart-surface);
243
+ stroke-width: var(--xh-stroke-thick);
244
+ paint-order: stroke;
245
+ }
246
+ }
247
+ }
@@ -8,16 +8,8 @@
8
8
  /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
9
9
  @import '../family/motion.css';
10
10
  @import '../family/action-control.css';
11
-
12
- @layer xihan.motion {
13
- /* 转圈的关键帧定义在本文件里:引用别处文件的动画名时那份文件不一定在场,动画会静默不跑 */
14
- @keyframes xh-popconfirm-rotate {
15
- to {
16
- transform: rotate(1turn);
17
- }
18
- }
19
- }
20
-
11
+ @import '../family/loading-ring.css';
12
+ @import '../family/material.css';
21
13
 
22
14
  @layer xihan.components {
23
15
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
@@ -31,7 +23,7 @@
31
23
  }
32
24
 
33
25
  /*
34
- * 触发器是页面上的独立文字按钮(§9.1):盒型、md 档几何、outline 四态面、0.97 按压并换底与粗指针命中区
26
+ * 触发器是页面上的独立文字按钮:盒型、md 档几何、outline 四态面、0.97 按压并换底与粗指针命中区
35
27
  * 由家族配方按连接层投影的 data-xh-action-variant / -size 给出。皮肤没有自己的外观规则,
36
28
  * 只把作者塞进按钮的图标接到随档字形尺(md = 20px)。
37
29
  */
@@ -90,10 +82,38 @@
90
82
  --xh-_overlay-enter-left: 1;
91
83
  }
92
84
 
85
+ /* 交叉轴原点按对齐取:start / end 对齐时面板与锚点在那一端齐平,缩放从那一端涨开,贴着小触发器的面板
86
+ 才像是从触发器里长出来;居中对齐留在中线。上下两侧的 start / end 是行内轴上的逻辑对齐,RTL 下起始缘在右;
87
+ 左右两侧的 start / end 落在块轴上,不随书写方向翻 */
88
+ /* 起始缘与末尾缘按就近的书写方向取:LTR 起始在左,RTL 起始在右 */
89
+ [data-scope='popconfirm'][data-part='positioner']:is([data-placement='top-start'], [data-placement='bottom-start']) {
90
+ --xh-_overlay-origin-x: var(--xh-direction-start);
91
+ }
92
+
93
+ [data-scope='popconfirm'][data-part='positioner']:is([data-placement='top-end'], [data-placement='bottom-end']) {
94
+ --xh-_overlay-origin-x: var(--xh-direction-end);
95
+ }
96
+
97
+ [data-scope='popconfirm'][data-part='positioner']:is([data-placement='left-start'], [data-placement='right-start']) {
98
+ --xh-_overlay-origin-y: 0;
99
+ }
100
+
101
+ [data-scope='popconfirm'][data-part='positioner']:is([data-placement='left-end'], [data-placement='right-end']) {
102
+ --xh-_overlay-origin-y: 100%;
103
+ }
104
+
93
105
  /* 面板排成三列:左列吃掉剩余宽度,右两列各摆一颗按钮。
94
106
  标题、说明与作者塞进来的内容各占一整行,两颗按钮因此并排落在最后一行的右侧。 */
95
107
  [data-scope='popconfirm'][data-part='content'] {
96
- /* 作者塞进面板里的图标按控件档取(§6.5);两颗动作钮另由家族配方按 sm 档下发字形尺 */
108
+ /* 材质由家族配方画(family/material.css 的 frosted 面:描边、底、1px 顶光、前景、投影与背景滤镜),
109
+ 这里只把使用者槽接进来 */
110
+ --xh-frosted-bg: var(--xh-popconfirm-bg, var(--xh-_material-bg));
111
+ --xh-frosted-border: var(--xh-popconfirm-border, var(--xh-_material-border));
112
+ --xh-frosted-fg: var(--xh-popconfirm-fg, var(--xh-_material-fg));
113
+ --xh-frosted-shadow: var(--xh-popconfirm-shadow, var(--xh-_material-shadow));
114
+ --xh-frosted-backdrop: var(--xh-popconfirm-backdrop, var(--xh-_material-backdrop));
115
+
116
+ /* 作者塞进面板里的图标按控件档取;两颗动作钮另由家族配方按 sm 档下发字形尺 */
97
117
  --xh-icon-size: var(--xh-popconfirm-icon-size, var(--xh-glyph-size-md));
98
118
  /* 尺寸档只换这两个私有槽 */
99
119
  --xh-_popconfirm-pad: var(--xh-surface-pad-md);
@@ -110,24 +130,11 @@
110
130
  /* 说明文案长度由作者给,矮视口下不限高面板会整块伸出视口且滚不到 */
111
131
  max-block-size: min(var(--xh-popconfirm-max-h, var(--xh-overlay-max-h)), var(--xh-_popconfirm-available-h));
112
132
  overflow-y: auto;
113
- /* 浮在页面之上的 Overlay 滚动面(§6.6):滚到头不把页面一起带走 */
133
+ /* 浮在页面之上的 Overlay 滚动面:滚到头不把页面一起带走 */
114
134
  overscroll-behavior: contain;
115
135
  padding-block: var(--xh-popconfirm-py, var(--xh-_popconfirm-pad));
116
136
  padding-inline: var(--xh-popconfirm-px, var(--xh-_popconfirm-pad));
117
- border: var(--xh-stroke-thin) solid var(--xh-popconfirm-border, var(--xh-material-frosted-border));
118
137
  border-radius: var(--xh-popconfirm-radius, var(--xh-shape-overlay));
119
- /* 与 Popover 共用 M2 配方:透明 tint 在底层,内侧一像素顶光只表达材质厚度。 */
120
- background:
121
- linear-gradient(
122
- to bottom,
123
- var(--xh-material-frosted-highlight) 0 var(--xh-stroke-thin),
124
- transparent var(--xh-stroke-thin)
125
- ),
126
- var(--xh-popconfirm-bg, var(--xh-material-frosted-bg));
127
- color: var(--xh-popconfirm-fg, var(--xh-material-frosted-fg));
128
- box-shadow: var(--xh-popconfirm-shadow, var(--xh-material-frosted-shadow));
129
- -webkit-backdrop-filter: var(--xh-popconfirm-backdrop, var(--xh-material-frosted-backdrop));
130
- backdrop-filter: var(--xh-popconfirm-backdrop, var(--xh-material-frosted-backdrop));
131
138
  pointer-events: auto;
132
139
  /* 进退场的缩放锚在贴着锚点的那条边上;两个分量由 positioner 按 placement 写进私有槽 */
133
140
  transform-origin: var(--xh-_overlay-origin-x, 50%) var(--xh-_overlay-origin-y, 50%);
@@ -152,10 +159,9 @@
152
159
  outline: none;
153
160
  }
154
161
 
155
- [data-scope='popconfirm'][data-part='content'][data-state='open'] {
162
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
163
+ [data-scope='popconfirm'][data-part='content'][data-state='open']:not([data-instant]) {
156
164
  animation: xh-overlay-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
157
- /* 只在开着的这一档挂:合成层随 data-state 一起收走,收起后不再占着 */
158
- will-change: opacity, scale, translate;
159
165
  }
160
166
 
161
167
  /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
@@ -186,7 +192,7 @@
186
192
  color: var(--xh-popconfirm-title-fg, var(--xh-material-frosted-fg));
187
193
  }
188
194
 
189
- /* 说明文字走说明档(§6.4):13px + fg-muted */
195
+ /* 说明文字走说明档:13px + fg-muted */
190
196
  [data-scope='popconfirm'][data-part='description'] {
191
197
  margin: 0;
192
198
  min-inline-size: 0;
@@ -211,7 +217,7 @@
211
217
 
212
218
  /*
213
219
  * —— 两颗按钮 ——
214
- * 确认与取消都是浮层末行的文字按钮(§9.1):盒型、sm 档几何、四态面、0.97 按压并换底、粗指针命中区与
220
+ * 确认与取消都是浮层末行的文字按钮:盒型、sm 档几何、四态面、0.97 按压并换底、粗指针命中区与
215
221
  * 强制色由家族配方按连接层投影的 data-xh-action-variant / -size 给出。这里只把公开槽桥接到矩阵之前
216
222
  * (使用者槽 → 形态矩阵 → 家族缺省)与几何映射;内衬与圆角槽取两颗共用的 action 段。
217
223
  */
@@ -236,7 +242,7 @@
236
242
  grid-column: 3;
237
243
  }
238
244
 
239
- /* 确认是实心的主操作(§7.2 第 2 条)。底色走共享语气槽:作者在 content 上写 data-tone="danger"
245
+ /* 确认是实心的主操作。底色走共享语气槽:作者在 content 上写 data-tone="danger"
240
246
  就整体换成危险色,不写则用品牌色——配方 solid 列本就读 --xh-_tone,这里只桥接使用者槽 */
241
247
  [data-scope='popconfirm'][data-part='confirm-trigger'] {
242
248
  --xh-action-bg-rest: var(--xh-popconfirm-confirm-bg, var(--xh-_action-variant-bg-rest));
@@ -256,16 +262,18 @@
256
262
  --xh-action-ring-color-focus-visible: currentColor;
257
263
  }
258
264
 
259
- /* 异步确认挂起:确认文案前转一枚圆环;不是禁用,焦点与对比度都保持,在途指针由家族 loading 面给 */
260
- [data-scope='popconfirm'][data-part='confirm-trigger'][data-loading]::before {
261
- content: '';
262
- inline-size: 1em;
263
- block-size: 1em;
264
- margin-inline-end: var(--xh-space-1);
265
- border: var(--xh-stroke-thin) solid transparent;
266
- border-block-start-color: currentcolor;
267
- border-radius: var(--xh-shape-circle);
268
- animation: xh-popconfirm-rotate var(--xh-popconfirm-loading-duration, var(--xh-spin-duration)) var(--xh-motion-ease-loop) infinite;
265
+ /* 异步确认挂起:环由加载环配方压在确认钮正中(连接层投影 data-xh-loading-ring="overlay"),直径取钮的图标档,
266
+ 起始边取钮的真实前景、转速认使用者槽。不是禁用,焦点与对比度都保持,在途指针由家族 loading 面给。
267
+ 确认文案随前景淡到透明留位:进入挂起等一个 micro 才起淡(快速落定什么都不闪),落定时不等、按 micro 淡回 */
268
+ [data-scope='popconfirm'][data-part='confirm-trigger'] {
269
+ --xh-_loading-ring-fg: var(--xh-popconfirm-confirm-fg, var(--xh-_action-variant-fg-loading));
270
+ --xh-_loading-ring-duration: var(--xh-popconfirm-loading-duration, var(--xh-motion-loop-spin));
271
+ }
272
+
273
+ [data-scope='popconfirm'][data-part='confirm-trigger'][data-loading] {
274
+ --xh-action-fg-loading: transparent;
275
+
276
+ transition-delay: var(--xh-motion-duration-micro);
269
277
  }
270
278
 
271
279
  /* 取消是中性的次要出口,不参与语气:content 上的 data-tone 会把 --xh-_tone-* 一路继承下来,
@@ -287,22 +295,6 @@
287
295
  --xh-action-border-focus-visible: var(--xh-popconfirm-cancel-border, var(--xh-border-control));
288
296
  }
289
297
 
290
- /* 减少动效:圆环停下并整圈换成虚线,静止的形状仍然读得出"还没好"。
291
- 两条规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
292
- @media (prefers-reduced-motion: reduce) {
293
- [data-scope='popconfirm'][data-part='confirm-trigger'][data-loading]::before {
294
- border-style: dotted;
295
- border-color: currentColor;
296
- animation: none;
297
- }
298
- }
299
-
300
- :where([data-motion='reduce']) [data-scope='popconfirm'][data-part='confirm-trigger'][data-loading]::before {
301
- border-style: dotted;
302
- border-color: currentColor;
303
- animation: none;
304
- }
305
-
306
298
  @media (forced-colors: active) {
307
299
  /* 系统色接管内容边界;装饰顶光在这一档没有额外信息。两颗按钮的强制色由家族配方给 */
308
300
  [data-scope='popconfirm'][data-part='content'] {
package/css/popover.css CHANGED
@@ -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 探一次,取不到就说明这份皮肤没被引入。 */
@@ -61,8 +62,28 @@
61
62
  --xh-_overlay-enter-left: 1;
62
63
  }
63
64
 
65
+ /* 交叉轴原点按对齐取:start / end 对齐时面板与锚点在那一端齐平,缩放从那一端涨开,贴着小触发器的面板
66
+ 才像是从触发器里长出来;居中对齐留在中线。上下两侧的 start / end 是行内轴上的逻辑对齐,RTL 下起始缘在右;
67
+ 左右两侧的 start / end 落在块轴上,不随书写方向翻 */
68
+ /* 起始缘与末尾缘按就近的书写方向取:LTR 起始在左,RTL 起始在右 */
69
+ [data-scope='popover'][data-part='positioner']:is([data-placement='top-start'], [data-placement='bottom-start']) {
70
+ --xh-_overlay-origin-x: var(--xh-direction-start);
71
+ }
72
+
73
+ [data-scope='popover'][data-part='positioner']:is([data-placement='top-end'], [data-placement='bottom-end']) {
74
+ --xh-_overlay-origin-x: var(--xh-direction-end);
75
+ }
76
+
77
+ [data-scope='popover'][data-part='positioner']:is([data-placement='left-start'], [data-placement='right-start']) {
78
+ --xh-_overlay-origin-y: 0;
79
+ }
80
+
81
+ [data-scope='popover'][data-part='positioner']:is([data-placement='left-end'], [data-placement='right-end']) {
82
+ --xh-_overlay-origin-y: 100%;
83
+ }
84
+
64
85
  /*
65
- * 触发器是页面上的独立文字按钮(§9.1):盒型、md 档几何、outline 四态面、0.97 按压并换底与粗指针命中区
86
+ * 触发器是页面上的独立文字按钮:盒型、md 档几何、outline 四态面、0.97 按压并换底与粗指针命中区
66
87
  * 由家族配方按连接层投影的 data-xh-action-variant / -size 给出。皮肤没有自己的外观规则,
67
88
  * 只把作者塞进按钮的图标接到随档字形尺(md = 20px)。
68
89
  */
@@ -76,7 +97,15 @@
76
97
  }
77
98
 
78
99
  [data-scope='popover'][data-part='content'] {
79
- /* 作者塞进面板里的图标按控件档取(§6.5);关闭钮另由家族配方按 sm 档下发字形尺 */
100
+ /* 材质由家族配方画(family/material.css 的 frosted 面:描边、底、1px 顶光、前景、投影与背景滤镜),
101
+ 这里只把使用者槽接进来 */
102
+ --xh-frosted-bg: var(--xh-popover-bg, var(--xh-_material-bg));
103
+ --xh-frosted-border: var(--xh-popover-border, var(--xh-_material-border));
104
+ --xh-frosted-fg: var(--xh-popover-fg, var(--xh-_material-fg));
105
+ --xh-frosted-shadow: var(--xh-popover-shadow, var(--xh-_material-shadow));
106
+ --xh-frosted-backdrop: var(--xh-popover-backdrop, var(--xh-_material-backdrop));
107
+
108
+ /* 作者塞进面板里的图标按控件档取;关闭钮另由家族配方按 sm 档下发字形尺 */
80
109
  --xh-icon-size: var(--xh-popover-icon-size, var(--xh-glyph-size-md));
81
110
 
82
111
  /* 尺寸档只换这两个私有槽。popover 没有 root 部件,size 落在浮层树最外层的 content 上。
@@ -94,24 +123,11 @@
94
123
  /* 内容由作者给,长度不可预知:不限高就整块伸出视口且滚不到 */
95
124
  max-block-size: min(var(--xh-popover-max-h, var(--xh-overlay-max-h)), var(--xh-_popover-available-h));
96
125
  overflow-y: auto;
97
- /* 浮在页面之上的 Overlay 滚动面(§6.6):滚到头不把页面一起带走 */
126
+ /* 浮在页面之上的 Overlay 滚动面:滚到头不把页面一起带走 */
98
127
  overscroll-behavior: contain;
99
128
  padding-block: var(--xh-popover-py, var(--xh-_popover-pad));
100
129
  padding-inline: var(--xh-popover-px, var(--xh-_popover-pad));
101
- border: var(--xh-stroke-thin) solid var(--xh-popover-border, var(--xh-material-frosted-border));
102
130
  border-radius: var(--xh-popover-radius, var(--xh-shape-overlay));
103
- /* 顶光只占内侧一像素;透明 tint 是底层,正文自己保持不透明。 */
104
- background:
105
- linear-gradient(
106
- to bottom,
107
- var(--xh-material-frosted-highlight) 0 var(--xh-stroke-thin),
108
- transparent var(--xh-stroke-thin)
109
- ),
110
- var(--xh-popover-bg, var(--xh-material-frosted-bg));
111
- color: var(--xh-popover-fg, var(--xh-material-frosted-fg));
112
- box-shadow: var(--xh-popover-shadow, var(--xh-material-frosted-shadow));
113
- -webkit-backdrop-filter: var(--xh-popover-backdrop, var(--xh-material-frosted-backdrop));
114
- backdrop-filter: var(--xh-popover-backdrop, var(--xh-material-frosted-backdrop));
115
131
  pointer-events: auto;
116
132
  /* 进退场的缩放锚在贴着锚点的那条边上;两个分量由 positioner 按 placement 写进私有槽 */
117
133
  transform-origin: var(--xh-_overlay-origin-x, 50%) var(--xh-_overlay-origin-y, 50%);
@@ -127,10 +143,9 @@
127
143
  outline: none;
128
144
  }
129
145
 
130
- [data-scope='popover'][data-part='content'][data-state='open'] {
146
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
147
+ [data-scope='popover'][data-part='content'][data-state='open']:not([data-instant]) {
131
148
  animation: xh-overlay-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
132
- /* 只在开着的这一档挂:合成层随 data-state 一起收走,收起后不再占着 */
133
- will-change: opacity, scale, translate;
134
149
  }
135
150
 
136
151
  /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
@@ -158,7 +173,7 @@
158
173
  color: var(--xh-popover-title-fg, var(--xh-material-frosted-fg));
159
174
  }
160
175
 
161
- /* 说明文字走说明档(§6.4):13px + fg-muted */
176
+ /* 说明文字走说明档:13px + fg-muted */
162
177
  [data-scope='popover'][data-part='description'] {
163
178
  margin: 0;
164
179
  font-size: var(--xh-popover-description-font-size, var(--xh-text-secondary-size));
@@ -173,7 +188,7 @@
173
188
  }
174
189
 
175
190
  /*
176
- * 关闭钮是浮层角落的单图标钮(§9.1):正方盒、sm 档几何、ghost 四态面、0.97 按压并换底与粗指针命中区
191
+ * 关闭钮是浮层角落的单图标钮:正方盒、sm 档几何、ghost 四态面、0.97 按压并换底与粗指针命中区
177
192
  * 由家族配方给出——磨砂白面上走画布承载阶梯悬停 --xh-bg-subtle(100)→ 按下 --xh-bg-subtle-hover(200),
178
193
  * 焦点面透明吃库环。这里只把公开槽桥接到矩阵之前(使用者槽 → 形态矩阵 → 家族缺省)与摆放,
179
194
  * 聚焦档的 -bg-focus / -fg-focus 两槽同样桥到配方的 focus-visible 面,缺省仍是透明底与悬停字色:
@@ -242,4 +257,23 @@
242
257
  display: none;
243
258
  }
244
259
  }
260
+
261
+ @media (forced-colors: active) {
262
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
263
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
264
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
265
+ 禁用取 GrayText */
266
+ [data-scope='popover'][data-part='close-trigger']:empty::before {
267
+ forced-color-adjust: none;
268
+ background-color: ButtonText;
269
+ }
270
+
271
+ [data-scope='popover'][data-part='close-trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
272
+ background-color: HighlightText;
273
+ }
274
+
275
+ [data-scope='popover'][data-part='close-trigger'][data-disabled]:empty::before {
276
+ background-color: GrayText;
277
+ }
278
+ }
245
279
  }