@xihan-ui/styles 2.1.0 → 3.1.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 +1261 -0
  2. package/README.md +6 -1
  3. package/component-tokens.d.ts +533 -96
  4. package/components.tokens.json +35461 -26045
  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 +128 -50
  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 +56 -0
  37. package/css/date-picker.css +132 -26
  38. package/css/date-range-picker.css +337 -14
  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 +20 -18
  49. package/css/file-upload.css +125 -135
  50. package/css/flex.css +324 -8
  51. package/css/float-button.css +263 -38
  52. package/css/floating-panel.css +53 -19
  53. package/css/form.css +31 -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 +435 -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 +175 -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 +103 -17
  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 +271 -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 +13824 -4030
  147. package/index.unlayered.css +13403 -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
@@ -5,6 +5,10 @@
5
5
 
6
6
  /* 定义 file upload 样式。 */
7
7
 
8
+ /* 文件行的进场、退场与完成对号的淡入取共享关键帧。 */
9
+ @import '../family/motion.css';
10
+ @import '../family/action-control.css';
11
+
8
12
  @layer xihan.components {
9
13
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
14
  [data-scope='file-upload'] {
@@ -95,54 +99,34 @@
95
99
  color: var(--xh-fg-disabled);
96
100
  }
97
101
 
102
+ /* 「选择文件」是定尺的独立动作按钮:盒型、三档几何、悬停 100 / 按下 200 与 0.97 按压、焦点环、禁用面与
103
+ 粗指针命中区由 Action Control 家族按 text 档 outline 给(连接层投影),不再悬停抬 raised 影。
104
+ 这里只把使用者槽桥接到矩阵之前(使用者槽 → 形态矩阵 → 家族缺省) */
98
105
  [data-scope='file-upload'][data-part='trigger'] {
99
- display: inline-flex;
106
+ --xh-action-bg-rest: var(--xh-file-upload-trigger-bg, var(--xh-_action-variant-bg-rest));
107
+ --xh-action-bg-hover: var(--xh-file-upload-trigger-bg-hover, var(--xh-_action-variant-bg-hover));
108
+ --xh-action-bg-pressed: var(--xh-file-upload-trigger-bg-active, var(--xh-_action-variant-bg-pressed));
109
+ --xh-action-fg-rest: var(--xh-file-upload-trigger-fg, var(--xh-_action-variant-fg-rest));
110
+ --xh-action-fg-hover: var(--xh-file-upload-trigger-fg, var(--xh-_action-variant-fg-hover));
111
+ --xh-action-fg-pressed: var(--xh-file-upload-trigger-fg, var(--xh-_action-variant-fg-pressed));
112
+ --xh-action-border-rest: var(--xh-file-upload-trigger-border, var(--xh-_action-variant-border-rest));
113
+ /* 矩阵各态无影:使用者槽仍可自行加 */
114
+ --xh-action-shadow-hover: var(--xh-file-upload-trigger-shadow-hover, none);
115
+ --xh-action-radius: var(--xh-file-upload-trigger-radius, var(--xh-shape-control));
116
+ --xh-action-visual-size: var(--xh-file-upload-trigger-h, var(--xh-_action-profile-visual-size));
117
+ --xh-action-padding-inline: var(--xh-file-upload-trigger-px, var(--xh-_action-profile-padding-inline));
118
+ --xh-action-gap: var(--xh-file-upload-trigger-gap, var(--xh-_action-profile-gap));
119
+ --xh-action-font-size: var(--xh-file-upload-trigger-font-size, var(--xh-_action-profile-font-size));
120
+ --xh-icon-size: var(--xh-_action-profile-glyph-size);
121
+
100
122
  flex: none;
101
- align-items: center;
102
- justify-content: center;
103
- gap: var(--xh-file-upload-trigger-gap, var(--xh-control-gap-md));
104
- block-size: var(--xh-file-upload-trigger-h, var(--xh-control-h-md));
105
- padding-inline: var(--xh-file-upload-trigger-px, var(--xh-control-px-md));
106
- border: var(--xh-stroke-thin) solid var(--xh-file-upload-trigger-border, var(--xh-border-control));
107
- border-radius: var(--xh-file-upload-trigger-radius, var(--xh-shape-control));
108
- background: var(--xh-file-upload-trigger-bg, var(--xh-bg-surface));
109
- color: var(--xh-file-upload-trigger-fg, var(--xh-fg-default));
110
- /* 表单控件不继承页面字体,只给字号会让按钮用 UA 默认字族 */
111
- font-family: inherit;
112
- font-size: var(--xh-file-upload-trigger-font-size, var(--xh-text-body-size));
113
- line-height: var(--xh-leading-none);
114
- cursor: pointer;
115
- transition:
116
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
117
- box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
118
- scale var(--xh-motion-duration-release) var(--xh-motion-ease-release);
123
+ font-weight: var(--xh-file-upload-trigger-font-weight, var(--xh-text-label-weight));
119
124
  }
120
125
 
121
126
  [data-scope='file-upload'][data-part='trigger'][hidden] {
122
127
  display: none;
123
128
  }
124
129
 
125
- /* 悬停换底色的同时把这块面抬起一档:只换底色的回执在一颗按钮上太轻 */
126
- [data-scope='file-upload'][data-part='trigger']:hover:not(:disabled) {
127
- background: var(--xh-file-upload-trigger-bg-hover, var(--xh-bg-subtle-hover));
128
- box-shadow: var(--xh-file-upload-trigger-shadow-hover, var(--xh-elevation-raised));
129
- }
130
-
131
- /* 按下:换到按压档底色并轻微下压,抬起的那一档同时落回,松手弹回;禁用钮不压 */
132
- [data-scope='file-upload'][data-part='trigger']:not(:disabled):is(:active, [data-pressed]) {
133
- background: var(--xh-file-upload-trigger-bg-active, var(--xh-bg-subtle-active));
134
- box-shadow: none;
135
- scale: var(--xh-motion-scale-press);
136
- transition-duration: var(--xh-motion-duration-press);
137
- transition-timing-function: var(--xh-motion-ease-press);
138
- }
139
-
140
- /* 单体控件走原生 disabled(与集合条目的 aria-disabled 相反),因此用 :disabled */
141
- [data-scope='file-upload'][data-part='trigger']:disabled {
142
- background: var(--xh-bg-subtle);
143
- color: var(--xh-fg-disabled);
144
- }
145
-
146
130
  /* 连接层已经把这一套视觉隐藏写进了内联 style,这里是给元素升级前那一瞬兜底
147
131
  (作者手写的是一个普通 file input,接线完成前它是可见的)。
148
132
  刻意不写 display:藏起来的输入仍要留在布局里,原生表单校验的气泡才有可指的锚点 */
@@ -159,8 +143,10 @@
159
143
  }
160
144
 
161
145
  /* 文件条数由用户一次选进来多少给,行数没有尽头:
162
- 列表到这个高度就不再长,剩下的行在列表内滚出来,投放区与触发钮不会被推出视野 */
146
+ 列表到这个高度就不再长,剩下的行在列表内滚出来,投放区与触发钮不会被推出视野。
147
+ 定位是给列表动效放离场替身用的:删掉的那一行在原排布位上播完退场 */
163
148
  [data-scope='file-upload'][data-part='list'] {
149
+ position: relative;
164
150
  display: flex;
165
151
  max-block-size: var(--xh-file-upload-list-max-h, var(--xh-viewport-h-md));
166
152
  overflow-y: auto;
@@ -192,6 +178,23 @@
192
178
  font-size: var(--xh-file-upload-item-font-size, var(--xh-text-body-size));
193
179
  }
194
180
 
181
+ /* 列表动效:新收下的文件进场,同一批按到达顺序错开;首帧就在的直接呈现(自己或列表带 data-instant)。
182
+ 删掉的那一行由替身留在原处淡出,播完即移除;其余行先按旧位置反向补偿、再沿 translate 过渡滑到新位置 */
183
+ [data-scope='file-upload'][data-part='item'] {
184
+ transition: translate var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
185
+ }
186
+
187
+ [data-scope='file-upload'][data-part='item']:not([data-instant], [data-instant] > *) {
188
+ animation: xh-item-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
189
+ animation-delay: calc(var(--xh-_stagger-index, 0) * var(--xh-motion-stagger-step));
190
+ }
191
+
192
+ /* 替身的 data-state 换成了 closed,传输状态从进度条(同一份状态事实)上读回来:
193
+ 失败与传完那一行退场时仍带着行首标记与失败配色,文件名不会在淡出途中往行首一跳 */
194
+ [data-scope='file-upload'][data-part='item'][data-state='closed'] {
195
+ animation: xh-fade-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
196
+ }
197
+
195
198
  [data-scope='file-upload'][data-part='item'][hidden] {
196
199
  display: none;
197
200
  }
@@ -206,12 +209,14 @@
206
209
  警示与下面的勾都是固定状态标记(不是 :empty 兜底,作者塞进条目的部件顶不掉):按指示符档取尺
207
210
  (comfortable 16 / compact 14,随密度换档),不读只管作者图标的 --xh-icon-size——随文 1em 落在
208
211
  14 上下,comfortable 下比同一行里的指示符档小一圈、compact 下又不换档 */
209
- [data-scope='file-upload'][data-part='item'][data-state='error'] {
212
+ [data-scope='file-upload'][data-part='item'][data-state='error'],
213
+ [data-scope='file-upload'][data-part='item'][data-state='closed']:has(> [data-part='item-progress'][data-state='error']) {
210
214
  border-color: var(--xh-file-upload-item-border-error, var(--xh-border-invalid));
211
215
  color: var(--xh-file-upload-item-fg-error, var(--xh-fg-danger));
212
216
  }
213
217
 
214
- [data-scope='file-upload'][data-part='item'][data-state='error']::before {
218
+ [data-scope='file-upload'][data-part='item'][data-state='error']::before,
219
+ [data-scope='file-upload'][data-part='item'][data-state='closed']:has(> [data-part='item-progress'][data-state='error'])::before {
215
220
  content: '';
216
221
  flex: none;
217
222
  inline-size: var(--xh-file-upload-item-mark-size, var(--xh-control-indicator-size));
@@ -223,7 +228,8 @@
223
228
 
224
229
  /* 传完的那一行补一枚对勾,与失败那一枚警示字形对称:
225
230
  不标出来的话「传完了」与「还没开始」在这一行上看不出分别 */
226
- [data-scope='file-upload'][data-part='item'][data-state='done']::before {
231
+ [data-scope='file-upload'][data-part='item'][data-state='done']::before,
232
+ [data-scope='file-upload'][data-part='item'][data-state='closed']:has(> [data-part='item-progress'][data-state='done'])::before {
227
233
  content: '';
228
234
  flex: none;
229
235
  inline-size: var(--xh-file-upload-item-mark-size, var(--xh-control-indicator-size));
@@ -233,30 +239,42 @@
233
239
  mask: var(--xh-glyph-mark-check) center / contain no-repeat;
234
240
  }
235
241
 
236
- /* 传输进度条:只在传输中露面,宽度按连接层写下的比例走。
237
- 进度是连续量,走 continuous 曲线,不是入场曲线 */
242
+ /* 这一会儿才传完的那一行:进度条走满之后与对号交叉——条子淡出、对号淡入。
243
+ 已经落定的与远程附件没有进度条可播,对号直接呈现 */
244
+ [data-scope='file-upload'][data-part='item'][data-state='done']:has(> [data-part='item-progress']:not([hidden]))::before {
245
+ animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter) var(--xh-motion-duration-move) backwards;
246
+ }
247
+
248
+ /* 传输进度条:只在传输中不透明,填充按连接层写下的比例平移到位;进度是连续量,走 continuous 曲线。
249
+ 传完那一刻不当场收起:填充先走满(move),随后整条淡出(exit,延后一个 move),播完连接层才写 hidden。
250
+ 没在传也没刚传完的由连接层写 hidden */
238
251
  [data-scope='file-upload'][data-part='item-progress'] {
239
- display: none;
252
+ display: block;
240
253
  overflow: hidden;
241
254
  flex: none;
242
255
  inline-size: var(--xh-file-upload-item-progress-w, calc(var(--xh-control-h-md) * 2));
243
256
  block-size: var(--xh-file-upload-item-progress-h, var(--xh-stroke-thick));
244
257
  border-radius: var(--xh-file-upload-item-progress-radius, var(--xh-shape-pill));
245
258
  background: var(--xh-file-upload-item-progress-track, var(--xh-bg-subtle));
259
+ opacity: 0;
260
+ transition: opacity var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) var(--xh-motion-duration-move);
246
261
  }
247
262
 
248
263
  [data-scope='file-upload'][data-part='item-progress'][data-state='uploading'] {
249
- display: block;
264
+ opacity: 1;
250
265
  }
251
266
 
252
- [data-scope='file-upload'][data-part='item-progress'][data-state='uploading']::before {
267
+ /* 铺满轨道,往行首平移藏起未完成的那一截、由轨道裁掉:推进只走合成,不重排也不重绘。
268
+ translate 只认物理方向,乘书写方向的符号,RTL 下平移方向翻转 */
269
+ [data-scope='file-upload'][data-part='item-progress']::before {
253
270
  content: '';
254
271
  display: block;
255
272
  block-size: 100%;
256
273
  border-radius: inherit;
257
274
  background: var(--xh-file-upload-item-progress-fill, var(--xh-bg-brand));
258
- inline-size: calc(var(--xh-_file-upload-progress, 0) * 100%);
259
- transition: inline-size var(--xh-motion-duration-micro) var(--xh-motion-ease-continuous);
275
+ inline-size: 100%;
276
+ translate: calc((var(--xh-_file-upload-progress, 0) - 1) * 100% * var(--xh-direction-sign)) 0;
277
+ transition: translate var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
260
278
  }
261
279
 
262
280
  [data-scope='file-upload'][data-part='item-progress'][hidden] {
@@ -320,108 +338,52 @@
320
338
  color: var(--xh-fg-disabled);
321
339
  }
322
340
 
323
- /* 删除是一行里的小图标按钮:正方形、无边框,靠底色表达 hover */
341
+ /* 删除是一行里的小图标钮:Action Control icon 档 ghost、xs 视觉盒,悬停 100 / 按下 200 与 0.97 按压由家族给;
342
+ 悬停与按下时字换危险色,说明这一下会删掉。钮里的叉按 xs 档的字形尺画 */
324
343
  [data-scope='file-upload'][data-part='item-delete-trigger'] {
325
- display: inline-flex;
344
+ --xh-action-bg-hover: var(--xh-file-upload-delete-bg-hover, var(--xh-_action-variant-bg-hover));
345
+ --xh-action-bg-pressed: var(--xh-file-upload-delete-bg-active, var(--xh-_action-variant-bg-pressed));
346
+ --xh-action-fg-rest: var(--xh-file-upload-delete-fg, var(--xh-fg-muted));
347
+ --xh-action-fg-hover: var(--xh-file-upload-delete-fg-hover, var(--xh-fg-danger-hover));
348
+ --xh-action-fg-pressed: var(--xh-file-upload-delete-fg-hover, var(--xh-fg-danger-hover));
349
+ --xh-action-radius: var(--xh-file-upload-delete-radius, var(--xh-shape-control));
350
+ --xh-action-visual-size: var(--xh-file-upload-delete-size, var(--xh-_action-profile-visual-size));
351
+ --xh-icon-size: var(--xh-_action-profile-glyph-size);
352
+
326
353
  flex: none;
327
- align-items: center;
328
- justify-content: center;
329
- inline-size: var(--xh-file-upload-delete-size, var(--xh-control-action-size));
330
- block-size: var(--xh-file-upload-delete-size, var(--xh-control-action-size));
331
- padding: 0;
332
- border: 0;
333
- border-radius: var(--xh-file-upload-delete-radius, var(--xh-shape-control));
334
- background: transparent;
335
- color: var(--xh-file-upload-delete-fg, var(--xh-fg-muted));
336
- font-family: inherit;
337
- line-height: var(--xh-leading-none);
338
- cursor: pointer;
339
- transition:
340
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
341
- scale var(--xh-motion-duration-release) var(--xh-motion-ease-release);
342
354
  }
343
355
 
344
356
  [data-scope='file-upload'][data-part='item-delete-trigger'][hidden] {
345
357
  display: none;
346
358
  }
347
359
 
348
- [data-scope='file-upload'][data-part='item-delete-trigger']:hover:not(:disabled) {
349
- background: var(--xh-file-upload-delete-bg-hover, var(--xh-bg-subtle-hover));
350
- color: var(--xh-file-upload-delete-fg-hover, var(--xh-fg-danger-hover));
351
- }
352
-
353
- /* 按下:换到按压档底色并轻微下压,松手弹回;禁用钮不压 */
354
- [data-scope='file-upload'][data-part='item-delete-trigger']:not(:disabled):is(:active, [data-pressed]) {
355
- background: var(--xh-file-upload-delete-bg-active, var(--xh-bg-subtle-active));
356
- scale: var(--xh-motion-scale-press);
357
- transition-duration: var(--xh-motion-duration-press);
358
- transition-timing-function: var(--xh-motion-ease-press);
359
- }
360
-
361
- [data-scope='file-upload'][data-part='item-delete-trigger']:disabled {
362
- color: var(--xh-fg-disabled);
363
- }
364
-
365
- /* 清空是收尾动作,画成不带底色的文字按钮:它比"选择文件"次要 */
360
+ /* 清空是收尾动作,画成不带底的文字钮:Action Control text 档 ghost、sm,比「选择文件」小一档 */
366
361
  [data-scope='file-upload'][data-part='clear-trigger'] {
367
- display: inline-flex;
362
+ --xh-action-bg-hover: var(--xh-file-upload-clear-bg-hover, var(--xh-_action-variant-bg-hover));
363
+ --xh-action-bg-pressed: var(--xh-file-upload-clear-bg-active, var(--xh-_action-variant-bg-pressed));
364
+ --xh-action-fg-rest: var(--xh-file-upload-clear-fg, var(--xh-fg-muted));
365
+ --xh-action-fg-hover: var(--xh-file-upload-clear-fg-hover, var(--xh-fg-default));
366
+ --xh-action-fg-pressed: var(--xh-file-upload-clear-fg-hover, var(--xh-fg-default));
367
+ --xh-action-radius: var(--xh-file-upload-clear-radius, var(--xh-shape-control));
368
+ --xh-action-visual-size: var(--xh-file-upload-clear-h, var(--xh-_action-profile-visual-size));
369
+ --xh-action-padding-inline: var(--xh-file-upload-clear-px, var(--xh-_action-profile-padding-inline));
370
+ --xh-action-gap: var(--xh-file-upload-clear-gap, var(--xh-_action-profile-gap));
371
+ --xh-action-font-size: var(--xh-file-upload-clear-font-size, var(--xh-_action-profile-font-size));
372
+ --xh-icon-size: var(--xh-_action-profile-glyph-size);
373
+
368
374
  flex: none;
369
375
  align-self: flex-start;
370
- align-items: center;
371
- justify-content: center;
372
- gap: var(--xh-file-upload-clear-gap, var(--xh-control-gap-sm));
373
- block-size: var(--xh-file-upload-clear-h, var(--xh-control-h-sm));
374
- padding-inline: var(--xh-file-upload-clear-px, var(--xh-control-px-sm));
375
- border: 0;
376
- border-radius: var(--xh-file-upload-clear-radius, var(--xh-shape-control));
377
- background: transparent;
378
- color: var(--xh-file-upload-clear-fg, var(--xh-fg-muted));
379
- font-family: inherit;
380
- font-size: var(--xh-file-upload-clear-font-size, var(--xh-text-caption-size));
381
- line-height: var(--xh-leading-none);
382
- cursor: pointer;
383
- transition:
384
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
385
- scale var(--xh-motion-duration-release) var(--xh-motion-ease-release);
386
376
  }
387
377
 
388
378
  [data-scope='file-upload'][data-part='clear-trigger'][hidden] {
389
379
  display: none;
390
380
  }
391
381
 
392
- [data-scope='file-upload'][data-part='clear-trigger']:hover:not(:disabled) {
393
- background: var(--xh-file-upload-clear-bg-hover, var(--xh-bg-subtle-hover));
394
- color: var(--xh-file-upload-clear-fg-hover, var(--xh-fg-default));
395
- }
396
-
397
- /* 按下:换到按压档底色并轻微下压,松手弹回;禁用钮不压 */
398
- [data-scope='file-upload'][data-part='clear-trigger']:not(:disabled):is(:active, [data-pressed]) {
399
- background: var(--xh-file-upload-clear-bg-active, var(--xh-bg-subtle-active));
400
- scale: var(--xh-motion-scale-press);
401
- transition-duration: var(--xh-motion-duration-press);
402
- transition-timing-function: var(--xh-motion-ease-press);
403
- }
404
-
405
- /* 空列表时按钮照常可按(收起它会让焦点掉回 body),只把前景压淡一档 */
382
+ /* 空列表时按钮照常可按(收起它会让焦点掉回 body),只把前景压淡一档;三态一起压,家族的悬停规则更特定 */
406
383
  [data-scope='file-upload'][data-part='clear-trigger'][data-empty] {
407
- color: var(--xh-fg-subtle);
408
- }
409
-
410
- [data-scope='file-upload'][data-part='clear-trigger']:disabled {
411
- color: var(--xh-fg-disabled);
412
- }
413
-
414
- /*
415
- * 高对比档:三颗钮的按压面常态靠换底表出,这一档里底色被统一换成 Canvas,按住那一下与静息塌成同一个样子;
416
- * 用系统高亮反色画回来,兜底字形读 currentColor、自己跟着换
417
- */
418
- @media (forced-colors: active) {
419
- [data-scope='file-upload'][data-part='trigger']:not(:disabled):is(:active, [data-pressed]),
420
- [data-scope='file-upload'][data-part='item-delete-trigger']:not(:disabled):is(:active, [data-pressed]),
421
- [data-scope='file-upload'][data-part='clear-trigger']:not(:disabled):is(:active, [data-pressed]) {
422
- background: Highlight;
423
- color: HighlightText;
424
- }
384
+ --xh-action-fg-rest: var(--xh-fg-subtle);
385
+ --xh-action-fg-hover: var(--xh-fg-subtle);
386
+ --xh-action-fg-pressed: var(--xh-fg-subtle);
425
387
  }
426
388
 
427
389
  /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
@@ -436,4 +398,32 @@
436
398
  -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
437
399
  mask: var(--xh-glyph-mark-close) center / contain no-repeat;
438
400
  }
401
+
402
+ @media (forced-colors: active) {
403
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
404
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
405
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
406
+ 落在 Canvas 面上的取 CanvasText;
407
+ 禁用取 GrayText */
408
+ [data-scope='file-upload'][data-part='item'][data-state='error']::before,
409
+ [data-scope='file-upload'][data-part='item'][data-state='closed']:has(> [data-part='item-progress'][data-state='error'])::before,
410
+ [data-scope='file-upload'][data-part='item'][data-state='done']::before,
411
+ [data-scope='file-upload'][data-part='item'][data-state='closed']:has(> [data-part='item-progress'][data-state='done'])::before {
412
+ forced-color-adjust: none;
413
+ background-color: CanvasText;
414
+ }
415
+
416
+ [data-scope='file-upload']:is([data-part='item-delete-trigger'], [data-part='clear-trigger']):empty::before {
417
+ forced-color-adjust: none;
418
+ background-color: ButtonText;
419
+ }
420
+
421
+ [data-scope='file-upload']:is([data-part='item-delete-trigger'], [data-part='clear-trigger']):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
422
+ background-color: HighlightText;
423
+ }
424
+
425
+ [data-scope='file-upload']:is([data-part='item-delete-trigger'], [data-part='clear-trigger'])[data-disabled]:empty::before {
426
+ background-color: GrayText;
427
+ }
428
+ }
439
429
  }