@xihan-ui/styles 3.0.0 → 3.2.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 (221) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +1 -1
  3. package/component-tokens.d.ts +29 -0
  4. package/components.tokens.json +683 -27
  5. package/css/alert.css +2 -2
  6. package/css/approval.css +4 -4
  7. package/css/button.css +9 -5
  8. package/css/calendar-picker.css +3 -3
  9. package/css/calendar-range-picker.css +7 -7
  10. package/css/carousel.css +45 -13
  11. package/css/cartesian-chart.css +11 -11
  12. package/css/cascader.css +10 -10
  13. package/css/citation.css +2 -2
  14. package/css/code-view.css +6 -6
  15. package/css/color-picker.css +81 -0
  16. package/css/color-swatch-picker.css +9 -4
  17. package/css/combobox.css +12 -4
  18. package/css/command.css +1 -1
  19. package/css/date-field.css +39 -0
  20. package/css/date-picker.css +86 -9
  21. package/css/date-range-picker.css +47 -7
  22. package/css/diff-view.css +8 -8
  23. package/css/field-array.css +1 -1
  24. package/css/field.css +4 -0
  25. package/css/file-upload.css +1 -1
  26. package/css/float-button.css +140 -27
  27. package/css/form.css +14 -6
  28. package/css/graph-chart.css +2 -2
  29. package/css/highlight.css +1 -1
  30. package/css/image.css +1 -1
  31. package/css/mention.css +1 -1
  32. package/css/message-feed.css +1 -1
  33. package/css/notification.css +26 -20
  34. package/css/number-field.css +18 -18
  35. package/css/page-header.css +2 -2
  36. package/css/password-input.css +2 -2
  37. package/css/popconfirm.css +3 -3
  38. package/css/question-flow.css +8 -8
  39. package/css/radar-chart.css +6 -6
  40. package/css/rating.css +1 -1
  41. package/css/select.css +2 -2
  42. package/css/separator.css +2 -2
  43. package/css/side-nav.css +13 -13
  44. package/css/skeleton.css +5 -5
  45. package/css/slider.css +6 -6
  46. package/css/sortable.css +2 -2
  47. package/css/table.css +19 -2
  48. package/css/tags-input.css +1 -1
  49. package/css/time-picker.css +59 -2
  50. package/css/tool-call.css +7 -7
  51. package/css/tooltip.css +1 -1
  52. package/css/tree-select.css +2 -2
  53. package/css/tree.css +81 -11
  54. package/dist/css/accordion.css +269 -0
  55. package/dist/css/affix.css +47 -0
  56. package/dist/css/alert.css +247 -0
  57. package/dist/css/anchor.css +252 -0
  58. package/dist/css/approval.css +501 -0
  59. package/dist/css/avatar-group.css +99 -0
  60. package/dist/css/avatar.css +98 -0
  61. package/dist/css/back-top.css +161 -0
  62. package/dist/css/badge.css +205 -0
  63. package/dist/css/bar-code.css +62 -0
  64. package/dist/css/breadcrumb.css +230 -0
  65. package/dist/css/button-group.css +263 -0
  66. package/dist/css/button.css +219 -0
  67. package/dist/css/calendar-picker.css +467 -0
  68. package/dist/css/calendar-range-picker.css +554 -0
  69. package/dist/css/card.css +221 -0
  70. package/dist/css/carousel.css +710 -0
  71. package/dist/css/cartesian-chart.css +830 -0
  72. package/dist/css/cascader.css +961 -0
  73. package/dist/css/checkbox-group.css +358 -0
  74. package/dist/css/checkbox.css +257 -0
  75. package/dist/css/citation.css +470 -0
  76. package/dist/css/clipboard.css +315 -0
  77. package/dist/css/code-view.css +374 -0
  78. package/dist/css/collapsible.css +185 -0
  79. package/dist/css/color-field.css +176 -0
  80. package/dist/css/color-picker.css +595 -0
  81. package/dist/css/color-slider.css +281 -0
  82. package/dist/css/color-swatch-picker.css +250 -0
  83. package/dist/css/color-swatch.css +35 -0
  84. package/dist/css/combobox.css +574 -0
  85. package/dist/css/command.css +399 -0
  86. package/dist/css/context-menu.css +420 -0
  87. package/dist/css/date-field.css +317 -0
  88. package/dist/css/date-picker.css +868 -0
  89. package/dist/css/date-range-picker.css +886 -0
  90. package/dist/css/description.css +67 -0
  91. package/dist/css/descriptions.css +299 -0
  92. package/dist/css/dialog.css +455 -0
  93. package/dist/css/diff-view.css +513 -0
  94. package/dist/css/download-trigger.css +151 -0
  95. package/dist/css/drawer.css +552 -0
  96. package/dist/css/editable.css +295 -0
  97. package/dist/css/empty-state.css +163 -0
  98. package/dist/css/field-array.css +226 -0
  99. package/dist/css/field.css +166 -0
  100. package/dist/css/fieldset.css +102 -0
  101. package/dist/css/file-upload.css +429 -0
  102. package/dist/css/flex.css +441 -0
  103. package/dist/css/float-button.css +569 -0
  104. package/dist/css/floating-panel.css +429 -0
  105. package/dist/css/focus.css +46 -0
  106. package/dist/css/forced-colors.css +93 -0
  107. package/dist/css/form.css +393 -0
  108. package/dist/css/funnel-chart.css +106 -0
  109. package/dist/css/graph-chart.css +205 -0
  110. package/dist/css/grid-list.css +235 -0
  111. package/dist/css/grid.css +1201 -0
  112. package/dist/css/heatmap.css +552 -0
  113. package/dist/css/hierarchy-chart.css +298 -0
  114. package/dist/css/highlight.css +41 -0
  115. package/dist/css/hover-card.css +226 -0
  116. package/dist/css/icon.css +225 -0
  117. package/dist/css/image-cropper.css +373 -0
  118. package/dist/css/image-viewer.css +538 -0
  119. package/dist/css/image.css +98 -0
  120. package/dist/css/infinite-scroll.css +77 -0
  121. package/dist/css/input-group.css +275 -0
  122. package/dist/css/json-viewer.css +379 -0
  123. package/dist/css/kbd.css +72 -0
  124. package/dist/css/label.css +78 -0
  125. package/dist/css/layers.css +7 -0
  126. package/dist/css/layout.css +372 -0
  127. package/dist/css/liquid.css +106 -0
  128. package/dist/css/list.css +152 -0
  129. package/dist/css/listbox.css +390 -0
  130. package/dist/css/loading-bar.css +141 -0
  131. package/dist/css/log.css +306 -0
  132. package/dist/css/markdown-stream.css +149 -0
  133. package/dist/css/marquee.css +378 -0
  134. package/dist/css/masonry.css +70 -0
  135. package/dist/css/matrix-code.css +67 -0
  136. package/dist/css/mention.css +393 -0
  137. package/dist/css/menu.css +364 -0
  138. package/dist/css/menubar.css +456 -0
  139. package/dist/css/message-feed.css +318 -0
  140. package/dist/css/navigation-menu.css +513 -0
  141. package/dist/css/notification.css +782 -0
  142. package/dist/css/number-animation.css +44 -0
  143. package/dist/css/number-field.css +252 -0
  144. package/dist/css/overlay-arrow.css +56 -0
  145. package/dist/css/page-header.css +184 -0
  146. package/dist/css/pagination.css +450 -0
  147. package/dist/css/password-input.css +391 -0
  148. package/dist/css/pie-chart.css +247 -0
  149. package/dist/css/pin-input.css +199 -0
  150. package/dist/css/pointer.css +36 -0
  151. package/dist/css/popconfirm.css +320 -0
  152. package/dist/css/popover.css +279 -0
  153. package/dist/css/progress.css +501 -0
  154. package/dist/css/prompt-input.css +260 -0
  155. package/dist/css/question-flow.css +553 -0
  156. package/dist/css/radar-chart.css +233 -0
  157. package/dist/css/radio-group.css +598 -0
  158. package/dist/css/rating.css +294 -0
  159. package/dist/css/reasoning.css +343 -0
  160. package/dist/css/reset.css +117 -0
  161. package/dist/css/resizable.css +242 -0
  162. package/dist/css/sankey-chart.css +174 -0
  163. package/dist/css/scroll-area.css +240 -0
  164. package/dist/css/scrollbar.css +204 -0
  165. package/dist/css/select.css +612 -0
  166. package/dist/css/separator.css +122 -0
  167. package/dist/css/side-nav.css +476 -0
  168. package/dist/css/signature-pad.css +179 -0
  169. package/dist/css/skeleton.css +161 -0
  170. package/dist/css/slider.css +374 -0
  171. package/dist/css/sortable.css +228 -0
  172. package/dist/css/sparkline.css +164 -0
  173. package/dist/css/spinner.css +236 -0
  174. package/dist/css/splitter.css +159 -0
  175. package/dist/css/statistic.css +137 -0
  176. package/dist/css/steps.css +627 -0
  177. package/dist/css/switch.css +351 -0
  178. package/dist/css/table.css +1145 -0
  179. package/dist/css/tabs.css +944 -0
  180. package/dist/css/tag-group.css +247 -0
  181. package/dist/css/tag.css +310 -0
  182. package/dist/css/tags-input.css +322 -0
  183. package/dist/css/text-field.css +197 -0
  184. package/dist/css/time-field.css +277 -0
  185. package/dist/css/time-picker.css +707 -0
  186. package/dist/css/time-range-picker.css +746 -0
  187. package/dist/css/timeline.css +423 -0
  188. package/dist/css/timer.css +123 -0
  189. package/dist/css/timestamp.css +34 -0
  190. package/dist/css/toggle-group.css +424 -0
  191. package/dist/css/toggle.css +146 -0
  192. package/dist/css/tone.css +189 -0
  193. package/dist/css/tool-call.css +429 -0
  194. package/dist/css/toolbar.css +365 -0
  195. package/dist/css/tooltip.css +218 -0
  196. package/dist/css/tour.css +439 -0
  197. package/dist/css/transfer.css +638 -0
  198. package/dist/css/tree-select.css +878 -0
  199. package/dist/css/tree.css +733 -0
  200. package/dist/css/truncate.css +108 -0
  201. package/dist/css/typography.css +472 -0
  202. package/dist/css/undefined.css +58 -0
  203. package/dist/css/virtualizer.css +166 -0
  204. package/dist/css/visually-hidden.css +20 -0
  205. package/dist/css/watermark.css +82 -0
  206. package/dist/family/action-control.css +487 -0
  207. package/dist/family/chart.css +480 -0
  208. package/dist/family/check-mark.css +94 -0
  209. package/dist/family/choice-card.css +97 -0
  210. package/dist/family/collection-item.css +764 -0
  211. package/dist/family/field-chrome.css +287 -0
  212. package/dist/family/loading-ring.css +95 -0
  213. package/dist/family/material.css +72 -0
  214. package/dist/family/menu-choice.css +56 -0
  215. package/dist/family/motion.css +363 -0
  216. package/dist/family/swatch.css +59 -0
  217. package/dist/family/tag-list.css +59 -0
  218. package/family/action-control.css +3 -12
  219. package/index.css +7307 -6759
  220. package/index.unlayered.css +7309 -6761
  221. package/package.json +165 -164
@@ -0,0 +1,501 @@
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
+ /* 定义 approval 样式。 */
7
+
8
+ /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
9
+ @import '../family/motion.css';
10
+ /* 独立皮肤同时传递引入授权行与两颗钮的动作控件配方,full bundle 递归去重。 */
11
+ @import '../family/action-control.css';
12
+ @import '../family/loading-ring.css';
13
+
14
+ @layer xihan.components {
15
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
16
+ .xh-scope-approval {
17
+ --xh-approval-skin: 1;
18
+ }
19
+
20
+ /* 一块要人做决定的静态内容面:--xh-border-default 描边 + surface 底 + 无影(边界只由描边承担),
21
+ 作者打了语气时描边染成语气色作强调(下面那条),判定落定后描边退回中性 */
22
+ .xh-scope-approval[data-part='root'] {
23
+ /* 作者塞进标题 / 说明 / 结果条里的图标按档取尺,缺省 md;勾选记号另按盒比例量 */
24
+ --xh-_approval-icon-size: var(--xh-glyph-size-md);
25
+ --xh-icon-size: var(--xh-approval-icon-size, var(--xh-_approval-icon-size));
26
+
27
+ /* 尺寸缺省档:不写 data-size 时的取值。三档都只写这批私有槽,
28
+ 公开槽留在读处当首选,作者在祖先上设的覆盖才赢得过档位声明 */
29
+ --xh-_approval-gap: var(--xh-space-3);
30
+ --xh-_approval-p: var(--xh-space-4);
31
+ --xh-_approval-action-h: var(--xh-control-h-md);
32
+ --xh-_approval-action-px: var(--xh-control-px-md);
33
+ --xh-_approval-item-font-size: var(--xh-control-font-md);
34
+ --xh-_approval-note-font-size: var(--xh-control-font-md);
35
+
36
+ /* 定位基准:待决的呼吸点钉在右上角 */
37
+ position: relative;
38
+ display: flex;
39
+ flex-direction: column;
40
+ gap: var(--xh-approval-gap, var(--xh-_approval-gap));
41
+ padding: var(--xh-approval-p, var(--xh-_approval-p));
42
+ border: var(--xh-stroke-thin) solid var(--xh-approval-border, var(--xh-border-default));
43
+ border-radius: var(--xh-approval-radius, var(--xh-shape-surface));
44
+ background: var(--xh-approval-bg, var(--xh-bg-surface));
45
+ box-shadow: var(--xh-approval-shadow, none);
46
+ /* 判定落定时描边随语气换色:属状态换色,与别处悬停、选中、校验的换色同一档 */
47
+ transition: border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
48
+ }
49
+
50
+ /* 卡片出现时滑入;落在首帧就在的列表条目里(历史消息)时直接呈现,不跟着整屏一起入场 */
51
+ .xh-scope-approval[data-part='root']:not([data-scope][data-part='item'][data-instant] :where(.xh-scope-approval)) {
52
+ animation: xh-item-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
53
+ }
54
+
55
+ /* 上面声明的 display 会盖掉 UA 的 [hidden]{display:none},这里补回 */
56
+ .xh-scope-approval[data-part='root'][hidden] {
57
+ display: none;
58
+ }
59
+
60
+ /* 待决的呼吸点:钉在右上角(RTL 下左上),不占作者排的版面;颜色随语气,没写语气时取警示色。
61
+ 呼吸只表达「正在进行、需要被察觉」:明暗与缩放的起伏持续到判定落定,外扩光环同周期播 3 轮后停下;
62
+ 判过了连接层就收起它,由结果那一格接着表达 */
63
+ .xh-scope-approval[data-part='pending-indicator'] {
64
+ position: absolute;
65
+ inset-block-start: var(--xh-approval-p, var(--xh-_approval-p));
66
+ inset-inline-end: var(--xh-approval-p, var(--xh-_approval-p));
67
+ inline-size: var(--xh-approval-pending-indicator-size, var(--xh-space-2));
68
+ block-size: var(--xh-approval-pending-indicator-size, var(--xh-space-2));
69
+ border-radius: var(--xh-approval-pending-indicator-radius, var(--xh-shape-circle));
70
+ background: var(--xh-approval-pending-indicator-color, var(--xh-_tone, var(--xh-fg-warning)));
71
+ animation: xh-breathe var(--xh-motion-loop-breathe) var(--xh-motion-ease-breathe) infinite;
72
+ }
73
+
74
+ .xh-scope-approval[data-part='pending-indicator']::after {
75
+ content: '';
76
+ position: absolute;
77
+ inset: 0;
78
+ border-radius: inherit;
79
+ background: inherit;
80
+ opacity: 0;
81
+ pointer-events: none;
82
+ animation: xh-breathe-halo var(--xh-motion-loop-breathe) var(--xh-motion-ease-breathe) 3;
83
+ }
84
+
85
+ /* 减弱动效:两者都停,圆点停在满不透明度,光环不出现 */
86
+ @media (prefers-reduced-motion: reduce) {
87
+ .xh-scope-approval[data-part='pending-indicator'],
88
+ .xh-scope-approval[data-part='pending-indicator']::after {
89
+ animation: none;
90
+ }
91
+ }
92
+
93
+ :where([data-motion='reduce']) .xh-scope-approval[data-part='pending-indicator'],
94
+ :where([data-motion='reduce']) .xh-scope-approval[data-part='pending-indicator']::after {
95
+ animation: none;
96
+ }
97
+
98
+ .xh-scope-approval[data-part='pending-indicator'][hidden] {
99
+ display: none;
100
+ }
101
+
102
+ /* 语气只染描边:作者定的强调,待决时把这块面从正文里提出来 */
103
+ .xh-scope-approval[data-part='root'][data-tone] {
104
+ border-color: var(--xh-approval-border, var(--xh-_tone, var(--xh-border-default)));
105
+ }
106
+
107
+ /* 判过了就不再抢注意力:语气色边退回中性描边(根面外边不取 subtle)。
108
+ 排在语气那条之后:同等特指度,落定要盖得过语气 */
109
+ .xh-scope-approval[data-part='root']:not([data-state='pending']) {
110
+ border-color: var(--xh-approval-border-settled, var(--xh-border-default));
111
+ }
112
+
113
+ /* —— 形态 —— */
114
+ /* 缺省档即 outline,写在上面那条基础规则里。
115
+ 两档排在落定那条之后:它们把描边整个撤掉,排在前面会被落定那条按同等特指度盖回来 */
116
+ /* 底色分区:描边让位给底色,闸门嵌在别人的面里时不再多一圈线;
117
+ 淡底承载面向授权行与拒绝钮下发 hover 200 → pressed 300 */
118
+ .xh-scope-approval[data-part='root'][data-variant='subtle'] {
119
+ --xh-action-host-bg-hover: var(--xh-bg-subtle-hover);
120
+ --xh-action-host-bg-pressed: var(--xh-bg-subtle-active);
121
+
122
+ border-color: transparent;
123
+ background: var(--xh-approval-bg, var(--xh-bg-subtle));
124
+ }
125
+
126
+ /* 无壳内联:卡中卡时不再自带一张面,跟着外层的底走 */
127
+ .xh-scope-approval[data-part='root'][data-variant='ghost'] {
128
+ border-color: transparent;
129
+ background: none;
130
+ box-shadow: none;
131
+ }
132
+
133
+ /* 标题走 Surface 标题档 14/600 */
134
+ .xh-scope-approval[data-part='title'] {
135
+ display: block;
136
+ margin: 0;
137
+ color: var(--xh-approval-title-fg, var(--xh-fg-default));
138
+ font-size: var(--xh-approval-title-font-size, var(--xh-text-label-size));
139
+ font-weight: var(--xh-approval-title-font-weight, var(--xh-font-weight-semibold));
140
+ line-height: var(--xh-leading-tight);
141
+ }
142
+
143
+ .xh-scope-approval[data-part='title'][hidden] {
144
+ display: none;
145
+ }
146
+
147
+ .xh-scope-approval[data-part='description'] {
148
+ display: block;
149
+ margin: 0;
150
+ color: var(--xh-approval-description-fg, var(--xh-fg-muted));
151
+ font-size: var(--xh-approval-description-font-size, var(--xh-text-secondary-size));
152
+ line-height: var(--xh-leading-normal);
153
+ }
154
+
155
+ .xh-scope-approval[data-part='description'][hidden] {
156
+ display: none;
157
+ }
158
+
159
+ /* 视觉隐藏的播报区:不能 display:none,那样读屏就取不到它了 */
160
+ .xh-scope-approval[data-part='live-region'] {
161
+ position: absolute;
162
+ inline-size: 1px;
163
+ block-size: 1px;
164
+ padding: 0;
165
+ margin: -1px;
166
+ border: 0;
167
+ overflow: hidden;
168
+ clip-path: inset(50%);
169
+ white-space: nowrap;
170
+ }
171
+
172
+ .xh-scope-approval[data-part='group'] {
173
+ display: flex;
174
+ flex-direction: column;
175
+ gap: var(--xh-approval-group-gap, var(--xh-space-1));
176
+ }
177
+
178
+ .xh-scope-approval[data-part='group'][hidden] {
179
+ display: none;
180
+ }
181
+
182
+ /* 一项授权:整行可点、可聚焦,勾选记号在左。盒型、悬停 / 按下 / 禁用面由 Action Control 的 row 档给
183
+ (ghost 形态:白底承载 hover 100 → pressed 200,按下只换面不缩放;禁用守卫认 data-disabled),
184
+ 这里只把使用者槽映射到桥接槽,内衬与间距沿用本组件的档位。
185
+ 行高不吃家族的单行档:row 档允许换行、高度随内容,一条会折行的授权文案走正文行高 */
186
+ .xh-scope-approval[data-part='item'] {
187
+ --xh-action-gap: var(--xh-approval-item-gap, var(--xh-space-1_5));
188
+ --xh-action-padding-inline: var(--xh-approval-item-px, var(--xh-space-2));
189
+ --xh-action-padding-block: var(--xh-approval-item-py, var(--xh-space-1));
190
+ --xh-action-radius: var(--xh-approval-item-radius, var(--xh-_action-profile-radius));
191
+ --xh-action-font-size: var(--xh-approval-item-font-size, var(--xh-_approval-item-font-size));
192
+ --xh-action-bg-hover: var(--xh-approval-item-bg-hover, var(--xh-_action-variant-bg-hover));
193
+
194
+ line-height: var(--xh-leading-normal);
195
+ }
196
+
197
+ .xh-scope-approval[data-part='item'][hidden] {
198
+ display: none;
199
+ }
200
+
201
+ /* 勾选记号:方框 + 选中态填色,纯装饰不进可访问名。
202
+ 勾按盒比例量(与 Checkbox 同一比例),作者塞进来的图标读同一把尺,不随根上的整档图标放大撑破盒 */
203
+ .xh-scope-approval[data-part='item-indicator'] {
204
+ --xh-_approval-indicator-glyph: calc(var(--xh-approval-indicator-size, var(--xh-control-indicator-size)) * 0.75);
205
+ --xh-icon-size: var(--xh-approval-indicator-icon-size, var(--xh-_approval-indicator-glyph));
206
+
207
+ display: inline-flex;
208
+ flex: none;
209
+ align-items: center;
210
+ justify-content: center;
211
+ border: var(--xh-stroke-thin) solid var(--xh-approval-indicator-border, var(--xh-border-control));
212
+ border-radius: var(--xh-approval-indicator-radius, var(--xh-shape-inset));
213
+ color: var(--xh-approval-indicator-fg, var(--xh-fg-on-brand));
214
+ inline-size: var(--xh-approval-indicator-size, var(--xh-control-indicator-size));
215
+ block-size: var(--xh-approval-indicator-size, var(--xh-control-indicator-size));
216
+ transition:
217
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
218
+ border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
219
+ color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
220
+ }
221
+
222
+ .xh-scope-approval[data-part='item-indicator'][hidden] {
223
+ display: none;
224
+ }
225
+
226
+ /* 没写内容就由皮肤画勾;作者往部件里塞了自己的图形,这条规则即不命中 */
227
+ .xh-scope-approval[data-part='item-indicator']:empty::before {
228
+ content: '';
229
+ display: inline-block;
230
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
231
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
232
+ vertical-align: var(--xh-glyph-baseline-shift);
233
+ background-color: currentColor;
234
+ -webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
235
+ mask: var(--xh-glyph-mark-check) center / contain no-repeat;
236
+ }
237
+
238
+ .xh-scope-approval[data-part='item-indicator'][data-state='checked'] {
239
+ border-color: var(--xh-approval-indicator-border-checked, var(--xh-bg-brand));
240
+ background: var(--xh-approval-indicator-bg-checked, var(--xh-bg-brand));
241
+ }
242
+
243
+ /* 没勾上时把勾隐去而不是撤掉:盒子留在原位,翻面时整行不跳 */
244
+ .xh-scope-approval[data-part='item-indicator'][data-state='unchecked'] {
245
+ color: transparent;
246
+ }
247
+
248
+ /* 勾上的那条读起来更重一档 */
249
+ .xh-scope-approval[data-part='item-text'] {
250
+ display: block;
251
+ flex: 1 1 auto;
252
+ color: var(--xh-approval-item-text-fg, var(--xh-fg-muted));
253
+ }
254
+
255
+ .xh-scope-approval[data-part='item'][data-state='checked'] [data-part='item-text']:where(.xh-scope-approval) {
256
+ color: var(--xh-approval-item-text-fg-checked, var(--xh-fg-default));
257
+ }
258
+
259
+ /* 排在勾选档之后:禁用项无论勾没勾都是禁用色 */
260
+ .xh-scope-approval[data-part='item'][data-disabled] [data-part='item-text']:where(.xh-scope-approval) {
261
+ color: var(--xh-fg-disabled);
262
+ }
263
+
264
+ .xh-scope-approval[data-part='item-text'][hidden] {
265
+ display: none;
266
+ }
267
+
268
+ /* 备注:附在判定上的一句自由文本,占满整行 */
269
+ .xh-scope-approval[data-part='note'] {
270
+ display: block;
271
+ inline-size: 100%;
272
+ padding-inline: var(--xh-approval-note-px, var(--xh-space-2));
273
+ padding-block: var(--xh-approval-note-py, var(--xh-space-1_5));
274
+ border: var(--xh-stroke-thin) solid var(--xh-approval-note-border, var(--xh-border-control));
275
+ border-radius: var(--xh-approval-note-radius, var(--xh-shape-control));
276
+ background: var(--xh-approval-note-bg, var(--xh-bg-surface));
277
+ color: var(--xh-approval-note-fg, var(--xh-fg-default));
278
+ font-family: inherit;
279
+ font-size: var(--xh-approval-note-font-size, var(--xh-_approval-note-font-size));
280
+ transition: border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
281
+ }
282
+
283
+ .xh-scope-approval[data-part='note'][hidden] {
284
+ display: none;
285
+ }
286
+
287
+ .xh-scope-approval[data-part='note']:disabled {
288
+ color: var(--xh-fg-disabled);
289
+ }
290
+
291
+ /* 要求写理由而空着就按了拒绝:描边换成无效色;焦点也已带到这里,焦点环压在描边外面,一并换色 */
292
+ .xh-scope-approval[data-part='note'][data-invalid] {
293
+ --xh-_ring-color: var(--xh-approval-note-ring-invalid, var(--xh-ring-invalid));
294
+
295
+ border-color: var(--xh-approval-note-border-invalid, var(--xh-border-invalid));
296
+ }
297
+
298
+ /* 剩余时间:等宽数字,逐秒跳字时不左右晃 */
299
+ .xh-scope-approval[data-part='timer'] {
300
+ display: block;
301
+ color: var(--xh-approval-timer-fg, var(--xh-fg-muted));
302
+ font-size: var(--xh-approval-timer-font-size, var(--xh-text-caption-size));
303
+ font-variant-numeric: tabular-nums;
304
+ }
305
+
306
+ .xh-scope-approval[data-part='timer'][hidden] {
307
+ display: none;
308
+ }
309
+
310
+ /* 判定结果条:判过了才露出,语气随判定走 */
311
+ .xh-scope-approval[data-part='result'] {
312
+ display: inline-flex;
313
+ align-self: flex-start;
314
+ align-items: center;
315
+ gap: var(--xh-approval-result-gap, var(--xh-space-1));
316
+ padding-inline: var(--xh-approval-result-px, var(--xh-space-1_5));
317
+ padding-block: var(--xh-approval-result-py, var(--xh-space-0_5));
318
+ border: var(--xh-stroke-thin) solid transparent;
319
+ border-radius: var(--xh-approval-result-radius, var(--xh-shape-pill));
320
+ background: var(--xh-approval-result-bg, var(--xh-_tone-subtle));
321
+ color: var(--xh-approval-result-fg, var(--xh-_tone-fg));
322
+ font-size: var(--xh-approval-result-font-size, var(--xh-text-caption-size));
323
+ font-weight: var(--xh-approval-result-font-weight, var(--xh-font-weight-medium));
324
+ line-height: var(--xh-control-indicator-md);
325
+ }
326
+
327
+ /* 落定结果弹出;落在首帧就在的列表条目里(历史消息)时直接呈现,不跟着整屏一起入场 */
328
+ .xh-scope-approval[data-part='result']:not([data-scope][data-part='item'][data-instant] :where(.xh-scope-approval)) {
329
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
330
+ }
331
+
332
+ .xh-scope-approval[data-part='result'][hidden] {
333
+ display: none;
334
+ }
335
+
336
+ /* 超时按拒绝收口,两者同档(连接层同投 danger 语气):视觉上不该看着像第三种结果 */
337
+ .xh-scope-approval[data-part='result']:is([data-state='denied'], [data-state='expired']) {
338
+ background: var(--xh-approval-result-bg-denied, var(--xh-_tone-subtle));
339
+ color: var(--xh-approval-result-fg-denied, var(--xh-_tone-fg));
340
+ }
341
+
342
+ /* 动作行:两颗按钮靠右排,间距归库管。
343
+ 一行排不下就折行:两颗钮的文案都不折行,靠右排的行溢出时是往行首那侧漫出去,
344
+ 漫出去的那截既不产生横滚也回不来,折行是这一行唯一取得回来的形态。 */
345
+ .xh-scope-approval[data-part='footer'] {
346
+ display: flex;
347
+ flex-wrap: wrap;
348
+ align-items: center;
349
+ justify-content: flex-end;
350
+ gap: var(--xh-approval-footer-gap, var(--xh-space-2));
351
+ }
352
+
353
+ .xh-scope-approval[data-part='footer'][hidden] {
354
+ display: none;
355
+ }
356
+
357
+ /* 两颗按钮是离散动作控件:盒几何、悬停 / 按下与 0.97 按压、焦点环、禁用与在途面全由 Action Control 的
358
+ text 档给,组件只映射既有使用者槽。批准走 solid 档:判定闸门里的主要动作,与 Button 缺省同为品牌实心;
359
+ 拒绝走 outline 档:非 Button 的触发器缺省中性描边。
360
+ 三档守卫由连接层投影:判定在途是 data-loading + aria-disabled(保住可聚焦,家族给在途面:底色不置灰、
361
+ 指针 progress),必选项没勾满与落定是 data-disabled(家族给禁用面:置灰底、置灰字、not-allowed)。
362
+ 两颗共用的几何与字号写在一起 */
363
+ .xh-scope-approval[data-part='approve-trigger'],
364
+ .xh-scope-approval[data-part='deny-trigger'] {
365
+ --xh-action-visual-size: var(--xh-approval-action-h, var(--xh-_approval-action-h));
366
+ --xh-action-padding-inline: var(--xh-approval-action-px, var(--xh-_approval-action-px));
367
+ --xh-action-radius: var(--xh-approval-action-radius, var(--xh-shape-control));
368
+ --xh-action-font-size: var(--xh-approval-action-font-size, var(--xh-text-label-size));
369
+
370
+ font-weight: var(--xh-approval-action-font-weight, var(--xh-text-label-weight));
371
+ }
372
+
373
+ /* 家族那条 display 会把 UA 的 [hidden]{display:none} 盖掉 */
374
+ .xh-scope-approval[data-part='approve-trigger'][hidden],
375
+ .xh-scope-approval[data-part='deny-trigger'][hidden] {
376
+ display: none;
377
+ }
378
+
379
+ /* 批准钮:品牌实心,内顶高光把实心块顶出一道边,与拒绝那颗的描边同一档厚度(三态与在途同一支,
380
+ 禁用面由家族收掉);底 / 字与禁用底映到 solid 档的桥接槽 */
381
+ .xh-scope-approval[data-part='approve-trigger'] {
382
+ --xh-action-bg-rest: var(--xh-approval-approve-bg, var(--xh-_action-variant-bg-rest));
383
+ --xh-action-bg-hover: var(--xh-approval-approve-bg-hover, var(--xh-_action-variant-bg-hover));
384
+ --xh-action-bg-loading: var(--xh-approval-approve-bg, var(--xh-_action-variant-bg-loading));
385
+ --xh-action-bg-disabled: var(--xh-approval-approve-bg-off, var(--xh-_action-variant-bg-disabled));
386
+ --xh-action-fg-rest: var(--xh-approval-approve-fg, var(--xh-_action-variant-fg-rest));
387
+ --xh-action-fg-hover: var(--xh-approval-approve-fg, var(--xh-_action-variant-fg-hover));
388
+ --xh-action-fg-pressed: var(--xh-approval-approve-fg, var(--xh-_action-variant-fg-pressed));
389
+ --xh-action-fg-loading: var(--xh-approval-approve-fg, var(--xh-_action-variant-fg-loading));
390
+ --xh-action-highlight-rest: transparent;
391
+ --xh-action-shadow-rest: var(--xh-approval-approve-shadow, var(--xh-_highlight-tone));
392
+ --xh-action-shadow-hover: var(--xh-approval-approve-shadow, var(--xh-_highlight-tone));
393
+ --xh-action-shadow-pressed: var(--xh-approval-approve-shadow, var(--xh-_highlight-tone));
394
+ --xh-action-shadow-loading: var(--xh-approval-approve-shadow, var(--xh-_highlight-tone));
395
+ }
396
+
397
+ /* 面是实心的,环色与面同族,画在面里就看不出来;环改取面自己的前景色——
398
+ 那一族色本来就要在这块面上把字读清楚,与面的对比是按可读性定的。
399
+ 只对着还铺着实心底的那两档:按得动的常态,与判定在途那一档;
400
+ 禁用档的底换成置灰底、字换成置灰色,环取过来就跟底一起糊了,那一档走公共层的环 */
401
+ .xh-scope-approval[data-part='approve-trigger']:not([data-disabled]) {
402
+ --xh-action-ring-color-focus-visible: currentColor;
403
+ }
404
+
405
+ /* 拒绝钮:中性描边,底 / 边 / 字与禁用面映到 outline 档的桥接槽(透明底 → 100 → 200;
406
+ 落定后描边退回中性,不再像个能按的出口) */
407
+ .xh-scope-approval[data-part='deny-trigger'] {
408
+ --xh-action-bg-rest: var(--xh-approval-deny-bg, var(--xh-_action-variant-bg-rest));
409
+ --xh-action-bg-hover: var(--xh-approval-deny-bg-hover, var(--xh-_action-variant-bg-hover));
410
+ --xh-action-bg-disabled: var(--xh-approval-deny-bg-off, var(--xh-_action-variant-bg-disabled));
411
+ --xh-action-fg-rest: var(--xh-approval-deny-fg, var(--xh-_action-variant-fg-rest));
412
+ --xh-action-fg-hover: var(--xh-approval-deny-fg, var(--xh-_action-variant-fg-hover));
413
+ --xh-action-fg-pressed: var(--xh-approval-deny-fg, var(--xh-_action-variant-fg-pressed));
414
+ --xh-action-border-rest: var(--xh-approval-deny-border, var(--xh-_action-variant-border-rest));
415
+ --xh-action-border-disabled: var(--xh-approval-deny-border-off, var(--xh-_action-variant-border-disabled));
416
+ --xh-action-highlight-rest: transparent;
417
+ --xh-action-shadow-rest: none;
418
+ --xh-action-shadow-hover: none;
419
+ --xh-action-shadow-pressed: none;
420
+ }
421
+
422
+ /* 判定在途:两颗钮那一行里转一枚圆环(指针 progress 由家族的在途面给)。
423
+ 两颗钮此刻确实按不动,但按不动的理由是「你按的那一下正在走」,与「必选项没勾满」
424
+ 的那档灰不是一回事;只留灰的话两种情形长得一模一样,用户读不出系统正在想。
425
+ 所以在途这一档不置灰:颜色与对比度都保持原样,锁住只由圆环与指针说。
426
+ 圆环挂在这一行上而不是某一颗钮上:连接层只拿到「有一条判定在途」,
427
+ 拿不到是哪一颗按下的,画在两颗钮上会有一颗在说假话 */
428
+
429
+ /* 环由加载环配方画在这一行的 ::before 上(连接层投影 data-xh-loading-ring 与 data-loading),
430
+ 随在途淡入淡出、转与停;直径取所在尺寸档的图标档,转速认使用者槽 */
431
+ .xh-scope-approval[data-part='footer'] {
432
+ --xh-_loading-ring-duration: var(--xh-approval-loading-duration, var(--xh-motion-loop-spin));
433
+ }
434
+
435
+ .xh-scope-approval[data-part='footer']::before {
436
+ content: '';
437
+ flex: none;
438
+ inline-size: var(--xh-_approval-icon-size);
439
+ block-size: var(--xh-_approval-icon-size);
440
+ }
441
+
442
+ /* 尺寸档改内衬、间距、按钮高度、行内字号与图标档 */
443
+ .xh-scope-approval[data-part='root'][data-size='sm'] {
444
+ --xh-_approval-icon-size: var(--xh-glyph-size-sm);
445
+ --xh-_approval-p: var(--xh-space-3);
446
+ --xh-_approval-gap: var(--xh-space-2);
447
+ --xh-_approval-action-h: var(--xh-control-h-sm);
448
+ --xh-_approval-action-px: var(--xh-control-px-sm);
449
+ --xh-_approval-item-font-size: var(--xh-control-font-sm);
450
+ --xh-_approval-note-font-size: var(--xh-control-font-sm);
451
+ }
452
+
453
+ .xh-scope-approval[data-part='root'][data-size='md'] {
454
+ --xh-_approval-icon-size: var(--xh-glyph-size-md);
455
+ --xh-_approval-p: var(--xh-space-4);
456
+ --xh-_approval-gap: var(--xh-space-3);
457
+ --xh-_approval-action-h: var(--xh-control-h-md);
458
+ --xh-_approval-action-px: var(--xh-control-px-md);
459
+ --xh-_approval-item-font-size: var(--xh-control-font-md);
460
+ --xh-_approval-note-font-size: var(--xh-control-font-md);
461
+ }
462
+
463
+ .xh-scope-approval[data-part='root'][data-size='lg'] {
464
+ --xh-_approval-icon-size: var(--xh-glyph-size-lg);
465
+ --xh-_approval-p: var(--xh-space-5);
466
+ --xh-_approval-gap: var(--xh-space-4);
467
+ --xh-_approval-action-h: var(--xh-control-h-lg);
468
+ --xh-_approval-action-px: var(--xh-control-px-lg);
469
+ --xh-_approval-item-font-size: var(--xh-control-font-lg);
470
+ --xh-_approval-note-font-size: var(--xh-control-font-lg);
471
+ }
472
+
473
+ /* 强制色:底色会被系统背景吃掉,呼吸点改用系统前景色 */
474
+ @media (forced-colors: active) {
475
+ .xh-scope-approval[data-part='pending-indicator'] {
476
+ background: CanvasText;
477
+ }
478
+ }
479
+
480
+ @media print {
481
+ /* 打印:待决的呼吸点是一瞬间的状态,纸上没有「等着人来判」 */
482
+ .xh-scope-approval[data-part='pending-indicator'] {
483
+ display: none;
484
+ }
485
+ }
486
+
487
+ @media (forced-colors: active) {
488
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
489
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
490
+ 落在勾选盒自己的实心面上(这一档里是 Canvas),整行悬停不换面,取 CanvasText;
491
+ 禁用取 GrayText */
492
+ .xh-scope-approval[data-part='item-indicator']:not([data-state='unchecked']):empty::before {
493
+ forced-color-adjust: none;
494
+ background-color: CanvasText;
495
+ }
496
+
497
+ .xh-scope-approval[data-part='item'][data-disabled] .xh-scope-approval[data-part='item-indicator']:not([data-state='unchecked']):empty::before {
498
+ background-color: GrayText;
499
+ }
500
+ }
501
+ }
@@ -0,0 +1,99 @@
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
+ /* 定义 avatar group 样式。 */
7
+
8
+ @layer xihan.components {
9
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
+ .xh-scope-avatar-group {
11
+ --xh-avatar-group-skin: 1;
12
+ }
13
+
14
+ /* 一排叠放的头像:后一枚压在前一枚上。
15
+ 组内共用的直径与字号在容器上写一次,沿继承流给每一枚——包括自己写了档位的那一枚,
16
+ 它的档位取值也读这两个槽,整排因此始终齐平。单独摆的头像取不到这两个槽,仍按自己的档走 */
17
+ .xh-scope-avatar-group[data-part='root'] {
18
+ /* 组件内那几档层号只在自己人之间排序:建一个层叠上下文把它们关起来,
19
+ 既不让页面上的层号插进来,也不让它们漏出去压住别人 */
20
+ isolation: isolate;
21
+
22
+ /* 私有槽位:整组共用的直径、字号与叠放量,换档只改这三个 */
23
+ --xh-_avatar-group-size: var(--xh-avatar-group-size, var(--xh-control-h-md));
24
+ --xh-_avatar-group-font-size: var(--xh-avatar-group-font-size, var(--xh-control-caption-md));
25
+ --xh-_avatar-group-overlap: var(--xh-avatar-group-overlap, var(--xh-space-2_5));
26
+
27
+ /* 流给组内每一枚 */
28
+ --xh-avatar-size: var(--xh-_avatar-group-size);
29
+ --xh-avatar-font-size: var(--xh-_avatar-group-font-size);
30
+
31
+ display: inline-flex;
32
+ align-items: center;
33
+ }
34
+
35
+ /* 给了 display 的角色节点必须补这条:display 声明会盖掉 UA 的 [hidden]{display:none},
36
+ 不补的话作者给节点加 hidden 后它照样显示 */
37
+ .xh-scope-avatar-group[data-part='root'][hidden] {
38
+ display: none;
39
+ }
40
+
41
+ /* —— 尺寸 —— */
42
+ /* 三档对齐控件档位,缺省档写在上面的基础规则里;
43
+ 字号与叠放量跟着直径一起缩放,小头像里回退字放得下、大头像里压住的那段也按比例长 */
44
+ .xh-scope-avatar-group[data-part='root'][data-size='sm'] {
45
+ --xh-_avatar-group-size: var(--xh-avatar-group-size, var(--xh-control-h-sm));
46
+ --xh-_avatar-group-font-size: var(--xh-avatar-group-font-size, var(--xh-control-caption-sm));
47
+ --xh-_avatar-group-overlap: var(--xh-avatar-group-overlap, var(--xh-space-2));
48
+ }
49
+
50
+ .xh-scope-avatar-group[data-part='root'][data-size='lg'] {
51
+ --xh-_avatar-group-size: var(--xh-avatar-group-size, var(--xh-control-h-lg));
52
+ --xh-_avatar-group-font-size: var(--xh-avatar-group-font-size, var(--xh-control-caption-lg));
53
+ --xh-_avatar-group-overlap: var(--xh-avatar-group-overlap, var(--xh-space-3));
54
+ }
55
+
56
+ /* —— 叠放 —— */
57
+ /* 谁压在谁上面得能指定,所以每一枚都是定位元素;
58
+ 再描一圈底色,被压住的那条边才与上一枚分得开 */
59
+ .xh-scope-avatar-group[data-part='root'] > * {
60
+ position: relative;
61
+ }
62
+
63
+ .xh-scope-avatar-group[data-part='root'] > *,
64
+ .xh-scope-avatar-group[data-part='root'] > * .xh-scope-avatar[data-part='root'] {
65
+ box-shadow: 0 0 0 var(--xh-stroke-thick) var(--xh-avatar-group-ring, var(--xh-bg-surface));
66
+ }
67
+
68
+ /* 后一枚往回挪一段,压在前一枚上 */
69
+ .xh-scope-avatar-group[data-part='root'] > * + * {
70
+ margin-inline-start: calc(-1 * var(--xh-_avatar-group-overlap));
71
+ }
72
+
73
+ /* 指到哪一枚,哪一枚整个露出来 */
74
+ .xh-scope-avatar-group[data-part='root'] > *:hover {
75
+ z-index: 1;
76
+ }
77
+
78
+ /* —— 溢出计数 —— */
79
+ /* 「+N」是这一排里的又一枚:直径、形状与字号跟着组走,里面写什么由作者定 */
80
+ .xh-scope-avatar-group[data-part='overflow-item'] {
81
+ display: inline-flex;
82
+ flex: none;
83
+ align-items: center;
84
+ justify-content: center;
85
+ inline-size: var(--xh-_avatar-group-size);
86
+ block-size: var(--xh-_avatar-group-size);
87
+ border-radius: var(--xh-avatar-group-radius, var(--xh-shape-circle));
88
+ background: var(--xh-avatar-group-overflow-item-bg, var(--xh-bg-muted-opaque));
89
+ color: var(--xh-avatar-group-overflow-item-fg, var(--xh-fg-muted));
90
+ font-size: var(--xh-_avatar-group-font-size);
91
+ font-weight: var(--xh-avatar-group-font-weight, var(--xh-font-weight-medium));
92
+ line-height: var(--xh-leading-none);
93
+ user-select: none;
94
+ }
95
+
96
+ .xh-scope-avatar-group[data-part='overflow-item'][hidden] {
97
+ display: none;
98
+ }
99
+ }