@xihan-ui/styles 1.0.0 → 2.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 (171) hide show
  1. package/CHANGELOG.md +5146 -6
  2. package/README.md +22 -2
  3. package/component-tokens.d.ts +4212 -0
  4. package/component-tokens.js +2 -0
  5. package/components.tokens.json +80116 -0
  6. package/css/accordion.css +131 -75
  7. package/css/affix.css +16 -1
  8. package/css/alert.css +114 -67
  9. package/css/anchor.css +99 -27
  10. package/css/approval.css +461 -0
  11. package/css/avatar-group.css +14 -6
  12. package/css/avatar.css +33 -9
  13. package/css/back-top.css +103 -48
  14. package/css/badge.css +42 -14
  15. package/css/bar-code.css +62 -0
  16. package/css/breadcrumb.css +40 -21
  17. package/css/button-group.css +146 -24
  18. package/css/button.css +116 -99
  19. package/css/calendar-picker.css +448 -0
  20. package/css/calendar-range-picker.css +517 -0
  21. package/css/card.css +54 -77
  22. package/css/carousel.css +412 -68
  23. package/css/cascader.css +429 -246
  24. package/css/checkbox-group.css +225 -77
  25. package/css/checkbox.css +174 -37
  26. package/css/clipboard.css +266 -47
  27. package/css/code-view.css +279 -0
  28. package/css/collapsible.css +108 -63
  29. package/css/color-field.css +158 -0
  30. package/css/color-picker.css +172 -184
  31. package/css/color-slider.css +274 -0
  32. package/css/color-swatch-picker.css +243 -0
  33. package/css/color-swatch.css +35 -0
  34. package/css/combobox.css +267 -273
  35. package/css/command.css +399 -0
  36. package/css/context-menu.css +183 -108
  37. package/css/date-field.css +94 -121
  38. package/css/date-picker.css +486 -249
  39. package/css/date-range-picker.css +559 -0
  40. package/css/description.css +51 -0
  41. package/css/descriptions.css +133 -87
  42. package/css/dialog.css +247 -68
  43. package/css/diff-view.css +428 -0
  44. package/css/download-trigger.css +155 -46
  45. package/css/drawer.css +194 -111
  46. package/css/editable.css +172 -152
  47. package/css/empty-state.css +80 -11
  48. package/css/field-array.css +190 -0
  49. package/css/field.css +84 -31
  50. package/css/fieldset.css +51 -18
  51. package/css/file-upload.css +134 -36
  52. package/css/flex.css +20 -1
  53. package/css/float-button.css +238 -57
  54. package/css/floating-panel.css +173 -92
  55. package/css/focus.css +46 -0
  56. package/css/forced-colors.css +93 -0
  57. package/css/form.css +254 -77
  58. package/css/gradient-text.css +34 -10
  59. package/css/grid.css +516 -5
  60. package/css/heatmap.css +87 -29
  61. package/css/highlight.css +20 -5
  62. package/css/hover-card.css +97 -47
  63. package/css/icon-wrapper.css +15 -3
  64. package/css/icon.css +74 -8
  65. package/css/image-cropper.css +143 -29
  66. package/css/image-viewer.css +150 -89
  67. package/css/image.css +30 -1
  68. package/css/infinite-scroll.css +51 -1
  69. package/css/input-group.css +277 -0
  70. package/css/json-viewer.css +102 -45
  71. package/css/kbd.css +72 -0
  72. package/css/label.css +78 -0
  73. package/css/layers.css +5 -0
  74. package/css/layout.css +175 -31
  75. package/css/list.css +24 -3
  76. package/css/listbox.css +208 -67
  77. package/css/loading-bar.css +52 -3
  78. package/css/log.css +144 -9
  79. package/css/markdown-stream.css +149 -0
  80. package/css/marquee.css +27 -1
  81. package/css/masonry.css +7 -0
  82. package/css/matrix-code.css +67 -0
  83. package/css/mention.css +234 -152
  84. package/css/menu.css +180 -83
  85. package/css/menubar.css +204 -136
  86. package/css/message-feed.css +197 -0
  87. package/css/navigation-menu.css +144 -90
  88. package/css/notification.css +178 -100
  89. package/css/number-animation.css +7 -0
  90. package/css/number-field.css +120 -277
  91. package/css/overlay-arrow.css +12 -7
  92. package/css/page-header.css +99 -14
  93. package/css/pagination.css +175 -135
  94. package/css/password-input.css +222 -219
  95. package/css/pin-input.css +101 -67
  96. package/css/pointer.css +36 -0
  97. package/css/popconfirm.css +185 -94
  98. package/css/popover.css +121 -77
  99. package/css/progress.css +60 -12
  100. package/css/prompt-input.css +224 -0
  101. package/css/question-flow.css +513 -0
  102. package/css/radio-group.css +147 -30
  103. package/css/rating.css +193 -43
  104. package/css/reasoning.css +336 -0
  105. package/css/reset.css +84 -6
  106. package/css/resizable.css +237 -0
  107. package/css/scroll-area.css +68 -7
  108. package/css/scrollbar.css +47 -13
  109. package/css/segmented.css +94 -29
  110. package/css/select.css +288 -274
  111. package/css/separator.css +101 -1
  112. package/css/side-nav.css +133 -75
  113. package/css/signature-pad.css +74 -54
  114. package/css/skeleton.css +84 -11
  115. package/css/slider.css +132 -39
  116. package/css/sortable.css +198 -0
  117. package/css/spinner.css +126 -12
  118. package/css/splitter.css +29 -8
  119. package/css/statistic.css +55 -0
  120. package/css/steps.css +206 -72
  121. package/css/switch.css +268 -36
  122. package/css/table.css +695 -118
  123. package/css/tabs.css +604 -42
  124. package/css/tag-group.css +219 -0
  125. package/css/tag.css +118 -28
  126. package/css/tags-input.css +156 -274
  127. package/css/text-field.css +101 -249
  128. package/css/time-field.css +100 -128
  129. package/css/time-picker.css +323 -252
  130. package/css/time-range-picker.css +719 -0
  131. package/css/timeline.css +202 -68
  132. package/css/timer.css +56 -52
  133. package/css/timestamp.css +34 -0
  134. package/css/toast.css +373 -144
  135. package/css/toggle-group.css +309 -76
  136. package/css/toggle.css +116 -85
  137. package/css/tone.css +47 -0
  138. package/css/tool-call.css +421 -0
  139. package/css/toolbar.css +181 -33
  140. package/css/tooltip.css +107 -36
  141. package/css/tour.css +183 -152
  142. package/css/transfer.css +351 -138
  143. package/css/tree-select.css +323 -216
  144. package/css/tree.css +294 -62
  145. package/css/truncate.css +65 -0
  146. package/css/typography.css +228 -5
  147. package/css/undefined.css +10 -1
  148. package/css/virtualizer.css +9 -10
  149. package/css/visually-hidden.css +7 -0
  150. package/css/watermark.css +7 -0
  151. package/family/action-control.css +487 -0
  152. package/family/collection-item.css +721 -0
  153. package/family/field-chrome.css +298 -0
  154. package/family/motion.css +166 -0
  155. package/family/swatch.css +59 -0
  156. package/index.css +41705 -126
  157. package/index.unlayered.css +33692 -17339
  158. package/package.json +51 -17
  159. package/css/calendar.css +0 -367
  160. package/css/code-block.css +0 -91
  161. package/css/composer.css +0 -134
  162. package/css/countdown.css +0 -26
  163. package/css/dynamic-input.css +0 -220
  164. package/css/ellipsis.css +0 -52
  165. package/css/hotkeys.css +0 -90
  166. package/css/popselect.css +0 -391
  167. package/css/qr-code.css +0 -55
  168. package/css/result.css +0 -119
  169. package/css/space.css +0 -117
  170. package/css/thread.css +0 -120
  171. package/css/time.css +0 -25
@@ -1,3 +1,13 @@
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
+ /* 定义 notification 样式。 */
7
+
8
+ /* Notification 独立皮肤同时传递引入操作 / 关闭钮的动作控件配方;full bundle 递归去重。 */
9
+ @import '../family/action-control.css';
10
+
1
11
  @layer xihan.motion {
2
12
  /*
3
13
  * 九个位共用同一条进出场,位移不跟着落位走:要按位置分方向,就得从 group 的
@@ -26,6 +36,17 @@
26
36
  }
27
37
  }
28
38
 
39
+ /* 倒计时条:从占满一整条收到零。走一遍就到头,时长由连接层写进时长槽 */
40
+ @keyframes xh-countdown {
41
+ from {
42
+ inline-size: 100%;
43
+ }
44
+
45
+ to {
46
+ inline-size: 0%;
47
+ }
48
+ }
49
+
29
50
  @keyframes xh-notification-out {
30
51
  from {
31
52
  opacity: 1;
@@ -36,7 +57,7 @@
36
57
  to {
37
58
  opacity: 0;
38
59
  translate: 0 var(--xh-motion-distance-md);
39
- scale: var(--xh-motion-scale-enter);
60
+ scale: var(--xh-motion-scale-exit);
40
61
  }
41
62
  }
42
63
  }
@@ -79,8 +100,17 @@
79
100
  /* 基线按默认落位 bottom-end 写,下面只覆盖跟它不同的那几个位 */
80
101
  justify-content: flex-end;
81
102
  align-items: center;
82
- padding-block: var(--xh-notification-inset, var(--xh-space-6));
83
- padding-inline: var(--xh-notification-inset, var(--xh-space-6));
103
+ /* 贴边与安全区取大的一头:刘海、圆角与底部横条压住的那一段由系统给出,
104
+ 贴边比它窄时卡片会被切掉一角。桌面上 env() 恒为 0,取值与贴边槽完全一致。
105
+ 两条内联的 env 一起取大值:安全区只有物理方向的四个名字,
106
+ 分左右写在 RTL 下会翻错边,两侧同取较宽的那一段。 */
107
+ padding-block-start: max(var(--xh-notification-inset, var(--xh-space-6)), env(safe-area-inset-top));
108
+ padding-block-end: max(var(--xh-notification-inset, var(--xh-space-6)), env(safe-area-inset-bottom));
109
+ padding-inline: max(
110
+ var(--xh-notification-inset, var(--xh-space-6)),
111
+ env(safe-area-inset-left),
112
+ env(safe-area-inset-right)
113
+ );
84
114
  /* 摞内间距由连接层写进内联 style(两个适配器共用同一份),这里绝不重复写:
85
115
  写了也会被内联盖掉,只会让人误以为间距归样式层管 */
86
116
  /* 整面铺开就等于罩住了整块视口。面本身不吃指针,只有卡片吃(见下),
@@ -121,31 +151,35 @@
121
151
  * 竖排 flex 里这两件事都做不到(叉会变成第三行)。
122
152
  * 底与描边一律中性,语气只由左列那枚字形承载:整片兑色是轻提示那条的做法,
123
153
  * 一张有标题有正文的卡片全片染色会把两层文字都压在同一片语气色上。
154
+ * 面走 sheet 三件套(§8.4:--xh-material-elevated-bg / -border / -shadow,与 toast 同一套)。
155
+ *
156
+ * 卡片的槽带 item 段(--xh-notification-item-*),与摞的 --xh-notification-inset 分开。
124
157
  */
125
158
  [data-scope='notification'][data-part='item'] {
126
- /* 叉与操作钮的兜底字形按控件指示符那一档走;左列那枚类型字形另有自己的尺寸 */
127
- --xh-icon-size: var(--xh-notification-icon-size, var(--xh-control-indicator-size));
159
+ /* 作者塞进卡片里的图标与皮肤画的兜底字形同一把尺:Feedback 指示符统一 md 档(§6.5);
160
+ 左列那枚类型字形另有自己的尺寸槽,叉与操作钮的字形各按按钮档取值 */
161
+ --xh-icon-size: var(--xh-notification-icon-size, var(--xh-glyph-size-md));
128
162
 
129
163
  position: relative;
130
164
  display: grid;
131
165
  /* 左列宽度由字形自己决定,作者不放指示符时它就是 0,正文自然贴到左内衬 */
132
166
  grid-template-columns: auto 1fr;
133
167
  align-items: start;
134
- column-gap: var(--xh-notification-gap, var(--xh-space-3));
135
- row-gap: var(--xh-notification-row-gap, var(--xh-space-2));
136
- inline-size: var(--xh-notification-w, var(--xh-overlay-max-w-lg));
168
+ column-gap: var(--xh-notification-item-gap, var(--xh-space-3));
169
+ row-gap: var(--xh-notification-item-row-gap, var(--xh-space-2));
170
+ inline-size: var(--xh-notification-item-w, var(--xh-overlay-max-w-lg));
137
171
  /* 摞是整面视口宽的定位面且带内边距,取 100% 就等于自动让出两侧留白,
138
172
  窄屏上不必再算一遍 viewport 减法 */
139
173
  max-inline-size: 100%;
140
- padding-block: var(--xh-notification-py, var(--xh-space-4));
141
- padding-inline: var(--xh-notification-px, var(--xh-space-4));
142
- border: var(--xh-stroke-thin) solid var(--xh-notification-border, var(--xh-border-default));
143
- border-radius: var(--xh-notification-radius, var(--xh-shape-surface));
144
- background: var(--xh-notification-bg, var(--xh-bg-surface-raised));
145
- color: var(--xh-notification-fg, var(--xh-fg-default));
146
- box-shadow: var(--xh-notification-shadow, var(--xh-elevation-sheet));
147
- font-size: var(--xh-notification-font-size, var(--xh-text-body-size));
148
- line-height: var(--xh-notification-leading, var(--xh-text-body-leading));
174
+ padding-block: var(--xh-notification-item-py, var(--xh-surface-pad-lg));
175
+ padding-inline: var(--xh-notification-item-px, var(--xh-surface-pad-lg));
176
+ border: var(--xh-stroke-thin) solid var(--xh-notification-item-border, var(--xh-material-elevated-border));
177
+ border-radius: var(--xh-notification-item-radius, var(--xh-shape-overlay));
178
+ background: var(--xh-notification-item-bg, var(--xh-material-elevated-bg));
179
+ color: var(--xh-notification-item-fg, var(--xh-material-elevated-fg));
180
+ box-shadow: var(--xh-notification-item-shadow, var(--xh-material-elevated-shadow));
181
+ font-size: var(--xh-notification-item-font-size, var(--xh-text-body-size));
182
+ line-height: var(--xh-notification-item-leading, var(--xh-text-body-leading));
149
183
  /* 摞的定位面整面铺开且不吃指针,卡片必须自己吃回来:
150
184
  悬停按住计时、按钮可点、焦点进出,全指着这一条 */
151
185
  pointer-events: auto;
@@ -164,7 +198,29 @@
164
198
 
165
199
  /* 生命周期只有三段,unmounted 那段由上面的 [hidden] 收走,这里只管前两段 */
166
200
  [data-scope='notification'][data-part='item'][data-state='visible'] {
167
- animation: xh-notification-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
201
+ animation: xh-notification-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
202
+ }
203
+
204
+ /* 一摞里的多条按位次错开开幕。backwards 不能省:等待期间起帧不生效的话,
205
+ 卡片会先以全不透明度露一下再跳回起帧。第 6 条起并到同一拍上 */
206
+ [data-scope='notification'][data-part='item'][data-state='visible']:nth-child(2) {
207
+ animation-delay: calc(var(--xh-motion-stagger-step) * 1);
208
+ }
209
+
210
+ [data-scope='notification'][data-part='item'][data-state='visible']:nth-child(3) {
211
+ animation-delay: calc(var(--xh-motion-stagger-step) * 2);
212
+ }
213
+
214
+ [data-scope='notification'][data-part='item'][data-state='visible']:nth-child(4) {
215
+ animation-delay: calc(var(--xh-motion-stagger-step) * 3);
216
+ }
217
+
218
+ [data-scope='notification'][data-part='item'][data-state='visible']:nth-child(5) {
219
+ animation-delay: calc(var(--xh-motion-stagger-step) * 4);
220
+ }
221
+
222
+ [data-scope='notification'][data-part='item'][data-state='visible']:nth-child(n + 6) {
223
+ animation-delay: calc(var(--xh-motion-stagger-step) * 5);
168
224
  }
169
225
 
170
226
  /* forwards 不能省:退场窗口(removeDelay 默认 200ms)比退场动画长,
@@ -205,42 +261,38 @@
205
261
  mask: var(--xh-glyph-mark-info) center / contain no-repeat;
206
262
  }
207
263
 
208
- [data-scope='notification'][data-part='item'][data-type='success'] [data-part='item-indicator']:empty::before {
264
+ [data-scope='notification'][data-part='item'][data-tone='success'] [data-part='item-indicator']:empty::before {
209
265
  -webkit-mask-image: var(--xh-glyph-mark-check);
210
266
  mask-image: var(--xh-glyph-mark-check);
211
267
  }
212
268
 
213
- [data-scope='notification'][data-part='item'][data-type='warning'] [data-part='item-indicator']:empty::before {
269
+ [data-scope='notification'][data-part='item'][data-tone='warning'] [data-part='item-indicator']:empty::before {
214
270
  -webkit-mask-image: var(--xh-glyph-mark-warning);
215
271
  mask-image: var(--xh-glyph-mark-warning);
216
272
  }
217
273
 
218
- [data-scope='notification'][data-part='item'][data-type='error'] [data-part='item-indicator']:empty::before {
274
+ [data-scope='notification'][data-part='item'][data-tone='danger'] [data-part='item-indicator']:empty::before {
219
275
  -webkit-mask-image: var(--xh-glyph-mark-close);
220
276
  mask-image: var(--xh-glyph-mark-close);
221
277
  }
222
278
 
223
- /* loading 说的是「事情还没完」,不是好消息也不是坏消息:走中性前景档而不是语气色 */
224
- [data-scope='notification'][data-part='item'][data-type='loading'] [data-part='item-indicator'] {
225
- color: var(--xh-notification-indicator-fg, var(--xh-fg-muted));
226
- }
227
-
228
- [data-scope='notification'][data-part='item'][data-type='loading'] [data-part='item-indicator']:empty::before {
279
+ /* 加载中不是语气:只换字形,颜色沿用当前语气的前景档;写在四档语气之后,转圈压过它们 */
280
+ [data-scope='notification'][data-part='item'][data-loading] [data-part='item-indicator']:empty::before {
229
281
  -webkit-mask-image: var(--xh-glyph-mark-rotate-right);
230
282
  mask-image: var(--xh-glyph-mark-rotate-right);
231
- animation: xh-notification-spin var(--xh-spin-duration) linear infinite;
283
+ animation: xh-notification-spin var(--xh-spin-duration) var(--xh-motion-ease-loop) infinite;
232
284
  }
233
285
 
234
286
  /* 减少动效:转圈停下,静止的箭头仍然读得出「还没好」;
235
287
  "在等什么"由卡片上的 role=status 与可见文案继续承担。
236
288
  两组规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
237
289
  @media (prefers-reduced-motion: reduce) {
238
- [data-scope='notification'][data-part='item'][data-type='loading'] [data-part='item-indicator']:empty::before {
290
+ [data-scope='notification'][data-part='item'][data-loading] [data-part='item-indicator']:empty::before {
239
291
  animation: none;
240
292
  }
241
293
  }
242
294
 
243
- :where([data-motion='reduce']) [data-scope='notification'][data-part='item'][data-type='loading'] [data-part='item-indicator']:empty::before {
295
+ :where([data-motion='reduce']) [data-scope='notification'][data-part='item'][data-loading] [data-part='item-indicator']:empty::before {
244
296
  animation: none;
245
297
  }
246
298
 
@@ -253,9 +305,13 @@
253
305
  line-height: var(--xh-notification-title-leading, var(--xh-leading-tight));
254
306
  }
255
307
 
256
- /* 叉钉在右上角,标题得给它让位;说明与操作在第二行往下,不受影响 */
308
+ /* 叉钉在右上角,标题得给它让位;说明与操作在第二行往下,不受影响。
309
+ 让位量与叉的贴边取同一个值,作者改了贴边槽,标题让出的那段跟着走 */
257
310
  [data-scope='notification'][data-part='item']:has([data-part='item-close-trigger']) [data-part='item-title'] {
258
- padding-inline-end: calc(var(--xh-notification-close-size, var(--xh-control-h-sm)) + var(--xh-space-2));
311
+ padding-inline-end: calc(
312
+ var(--xh-notification-close-size, var(--xh-control-h-sm)) +
313
+ var(--xh-notification-close-inset, var(--xh-surface-action-inset))
314
+ );
259
315
  }
260
316
 
261
317
  [data-scope='notification'][data-part='item-description'] {
@@ -276,91 +332,98 @@
276
332
  display: none;
277
333
  }
278
334
 
279
- [data-scope='notification'][data-part='item-action-trigger'] {
280
- /* 网格列默认拉满,按钮要贴着起始侧收成自己的宽度 */
281
- justify-self: start;
282
- display: inline-flex;
283
- align-items: center;
284
- justify-content: center;
285
- block-size: var(--xh-notification-action-h, var(--xh-control-h-sm));
286
- padding-inline: var(--xh-notification-action-px, var(--xh-control-px-sm));
287
- border: var(--xh-stroke-thin) solid var(--xh-notification-action-border, var(--xh-border-default));
288
- border-radius: var(--xh-notification-action-radius, var(--xh-shape-control));
289
- background: var(--xh-notification-action-bg, var(--xh-bg-subtle));
290
- color: var(--xh-notification-action-fg, var(--xh-fg-default));
291
- /* 按钮不继承字族字号,不接回来的话卡片里会突然冒出一段系统 UI 字体 */
292
- font: inherit;
293
- font-weight: var(--xh-notification-action-font-weight, var(--xh-font-weight-medium));
294
- line-height: var(--xh-leading-none);
295
- cursor: pointer;
335
+ /* 倒计时条横跨整张卡片:它不是正文的一部分,不跟着第二列走 */
336
+ [data-scope='notification'][data-part='item'] > [data-part='item-progress'] {
337
+ grid-column: 1 / -1;
296
338
  }
297
339
 
298
- [data-scope='notification'][data-part='item-action-trigger'][hidden] {
299
- display: none;
340
+ /*
341
+ * 倒计时条。总时长由连接层写进 --xh-notification-progress-duration(不自动消失的那些
342
+ * 整条收起),计时被按住时动画一并停住——停表这件事此前没有任何可画的地方。
343
+ * 取装饰档 --xh-_tone-soft:压在卡片底色上仍看得出来。
344
+ */
345
+ [data-scope='notification'][data-part='item-progress'] {
346
+ overflow: hidden;
347
+ inline-size: 100%;
348
+ block-size: var(--xh-notification-progress-thickness, var(--xh-space-0_5));
349
+ border-radius: var(--xh-notification-progress-radius, var(--xh-shape-pill));
350
+ background: var(--xh-notification-progress-bg, var(--xh-_tone-soft));
351
+ animation: xh-countdown var(--xh-notification-progress-duration, var(--xh-motion-duration-slide)) var(--xh-motion-ease-loop) forwards;
300
352
  }
301
353
 
302
- [data-scope='notification'][data-part='item-action-trigger']:hover:not(:disabled) {
303
- background: var(--xh-notification-action-bg-hover, var(--xh-bg-subtle-hover));
354
+ [data-scope='notification'][data-part='item'][data-paused] [data-part='item-progress'] {
355
+ animation-play-state: paused;
304
356
  }
305
357
 
306
- [data-scope='notification'][data-part='item-action-trigger']:active:not(:disabled) {
307
- background: var(--xh-notification-action-bg-active, var(--xh-bg-subtle-active));
358
+ [data-scope='notification'][data-part='item-progress'][hidden] {
359
+ display: none;
308
360
  }
309
361
 
310
- [data-scope='notification'][data-part='item-action-trigger']:focus-visible {
311
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
312
- outline-offset: var(--xh-ring-offset);
313
- }
362
+ /* 操作钮是带文案的离散动作钮:盒几何、悬停 / 按下与 0.97 按压、粗指针热区、焦点环、禁用面全由 Action Control
363
+ 的 text outline 档给(连接层投 sm;非 Button 的触发器缺省中性描边、透明底,§7.2.2),组件只映射既有使用者槽。
364
+ 语气只落到左列字形:这颗钮坐在带 data-tone 的卡片里,底 / 边 / 字钉在中性语义面上,不随语气;
365
+ 卡片是 sheet 白面承载:hover --xh-bg-subtle(100)→ pressed --xh-bg-subtle-hover(200) */
366
+ [data-scope='notification'][data-part='item-action-trigger'] {
367
+ --xh-action-visual-size: var(--xh-notification-action-h, var(--xh-_action-profile-visual-size));
368
+ --xh-action-padding-inline: var(--xh-notification-action-px, var(--xh-_action-profile-padding-inline));
369
+ --xh-action-radius: var(--xh-notification-action-radius, var(--xh-shape-control));
370
+ --xh-action-bg-rest: var(--xh-notification-action-bg, transparent);
371
+ --xh-action-bg-hover: var(--xh-notification-action-bg-hover, var(--xh-bg-subtle));
372
+ --xh-action-bg-pressed: var(--xh-notification-action-bg-active, var(--xh-bg-subtle-hover));
373
+ --xh-action-fg-rest: var(--xh-notification-action-fg, var(--xh-fg-default));
374
+ --xh-action-fg-hover: var(--xh-notification-action-fg, var(--xh-fg-default));
375
+ --xh-action-fg-pressed: var(--xh-notification-action-fg, var(--xh-fg-default));
376
+ --xh-action-border-rest: var(--xh-notification-action-border, var(--xh-border-control));
377
+ --xh-action-border-hover: var(--xh-notification-action-border, var(--xh-border-control-hover));
378
+ --xh-action-border-pressed: var(--xh-notification-action-border, var(--xh-border-control-hover));
379
+ --xh-action-highlight-rest: transparent;
380
+ --xh-action-shadow-rest: none;
381
+ --xh-action-shadow-hover: none;
382
+ --xh-action-shadow-pressed: none;
383
+ /* 作者塞进钮里的图标按按钮档取字形尺寸 */
384
+ --xh-icon-size: var(--xh-notification-icon-size, var(--xh-_action-profile-glyph-size));
314
385
 
315
- /* 钉在右上角的内衬处,不参与网格排布——留在流里它会变成正文下面的第三行 */
316
- [data-scope='notification'][data-part='item-close-trigger'] {
317
- position: absolute;
318
- inset-block-start: var(--xh-notification-close-inset, var(--xh-space-3));
319
- inset-inline-end: var(--xh-notification-close-inset, var(--xh-space-3));
320
- display: inline-flex;
321
- align-items: center;
322
- justify-content: center;
323
- block-size: var(--xh-notification-close-size, var(--xh-control-h-sm));
324
- inline-size: var(--xh-notification-close-size, var(--xh-control-h-sm));
325
- border: 0;
326
- border-radius: var(--xh-notification-close-radius, var(--xh-shape-control));
327
- background: transparent;
328
- color: var(--xh-notification-close-fg, var(--xh-fg-muted));
329
- font: inherit;
330
- line-height: var(--xh-leading-none);
331
- cursor: pointer;
332
- transition:
333
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
334
- color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
335
- scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
386
+ /* 网格列默认拉满,按钮要贴着起始侧收成自己的宽度 */
387
+ justify-self: start;
388
+ font-weight: var(--xh-notification-action-font-weight, var(--xh-font-weight-medium));
336
389
  }
337
390
 
338
- /* closable=false 时连接层同时给了 hidden disabled,这条是它真正收起的那一半:
339
- 上面声明了 display,不补回来就会留下一个按不动的叉,比压根没有叉更让人困惑 */
340
- [data-scope='notification'][data-part='item-close-trigger'][hidden] {
391
+ /* 家族那条 display 会把 UA 的 [hidden]{display:none} 盖掉 */
392
+ [data-scope='notification'][data-part='item-action-trigger'][hidden] {
341
393
  display: none;
342
394
  }
343
395
 
344
- [data-scope='notification'][data-part='item-close-trigger']:hover:not(:disabled) {
345
- background: var(--xh-notification-close-bg-hover, var(--xh-bg-subtle-hover));
346
- color: var(--xh-notification-close-fg-hover, var(--xh-fg-default));
347
- }
348
-
349
- [data-scope='notification'][data-part='item-close-trigger']:active {
350
- background: var(--xh-notification-close-bg-active, var(--xh-bg-subtle-active));
351
- scale: var(--xh-motion-scale-press);
352
- }
396
+ /* 关闭钮是只有字形的离散动作钮:盒几何、悬停 / 按下与 0.97 按压、粗指针热区、焦点环、禁用面全由 Action Control
397
+ icon ghost 档给(连接层投 sm:32px 正方盒,面板角上的叉与此前 --xh-control-h-sm 同尺寸),组件只映射既有
398
+ 使用者槽。静息透明,sheet 白面承载 hover 100 → pressed 200,写了语气时悬停底跟着语气走(--xh-_tone-subtle)。
399
+ 钉在右上角的内衬处,不参与网格排布——留在流里它会变成正文下面的第三行 */
400
+ [data-scope='notification'][data-part='item-close-trigger'] {
401
+ --xh-action-visual-size: var(--xh-notification-close-size, var(--xh-_action-profile-visual-size));
402
+ --xh-action-min-inline-size: var(--xh-notification-close-size, var(--xh-_action-profile-visual-size));
403
+ --xh-action-radius: var(--xh-notification-close-radius, var(--xh-shape-control));
404
+ --xh-action-bg-hover: var(--xh-notification-close-bg-hover, var(--xh-_action-variant-bg-hover));
405
+ --xh-action-bg-pressed: var(--xh-notification-close-bg-active, var(--xh-_action-variant-bg-pressed));
406
+ --xh-action-fg-rest: var(--xh-notification-close-fg, var(--xh-fg-muted));
407
+ --xh-action-fg-hover: var(--xh-notification-close-fg-hover, var(--xh-fg-default));
408
+ --xh-action-fg-pressed: var(--xh-notification-close-fg-hover, var(--xh-fg-default));
409
+ --xh-action-border-rest: transparent;
410
+ --xh-action-highlight-rest: transparent;
411
+ --xh-action-shadow-rest: none;
412
+ --xh-action-shadow-hover: none;
413
+ --xh-action-shadow-pressed: none;
414
+ /* 叉的字形按钮档取值(sm → 16px),与左列那枚 md 档的类型字形分开 */
415
+ --xh-icon-size: var(--xh-notification-icon-size, var(--xh-_action-profile-glyph-size));
353
416
 
354
- /* 单体控件用原生 disabled。常规路径下它与 hidden 同时出现看不见,
355
- 但作者若在覆盖层把收起改了回来,至少还能看出这颗叉是按不动的 */
356
- [data-scope='notification'][data-part='item-close-trigger']:disabled {
357
- color: var(--xh-fg-disabled);
358
- cursor: not-allowed;
417
+ position: absolute;
418
+ inset-block-start: var(--xh-notification-close-inset, var(--xh-surface-action-inset));
419
+ inset-inline-end: var(--xh-notification-close-inset, var(--xh-surface-action-inset));
420
+ border-width: 0;
359
421
  }
360
422
 
361
- [data-scope='notification'][data-part='item-close-trigger']:focus-visible {
362
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
363
- outline-offset: var(--xh-ring-offset);
423
+ /* closable=false 时连接层同时给了 hidden 与 disabled,这条是它真正收起的那一半:
424
+ 家族那条 display 会把 UA 的 [hidden]{display:none} 盖掉,不补回来就会留下一个按不动的叉 */
425
+ [data-scope='notification'][data-part='item-close-trigger'][hidden] {
426
+ display: none;
364
427
  }
365
428
 
366
429
  /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
@@ -374,4 +437,19 @@
374
437
  -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
375
438
  mask: var(--xh-glyph-mark-close) center / contain no-repeat;
376
439
  }
440
+
441
+ @media print {
442
+ /* 打印:动画会被定格在任意一帧——转了一半的圈、扫到一半的微光。这里换成静止的表达,
443
+ 取值与减弱动效那一档相同。两档各写一块、不并进一条媒体查询列表:减弱动效另有一份
444
+ :where([data-motion='reduce']) 的钩子版本与它成对,打印没有对应的钩子可配,
445
+ 并成一条之后这层配对关系在文本上就断了。 */
446
+ /* 通知组固定在视口上,打印那一刻在场就会盖住正文。 */
447
+ [data-scope='notification'][data-part='group'] {
448
+ display: none;
449
+ }
450
+
451
+ [data-scope='notification'][data-part='item'][data-loading] [data-part='item-indicator']:empty::before {
452
+ animation: none;
453
+ }
454
+ }
377
455
  }
@@ -1,3 +1,10 @@
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
+ /* 定义 number animation 样式。 */
7
+
1
8
  @layer xihan.components {
2
9
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
10
  [data-scope='number-animation'] {