@xihan-ui/styles 3.1.0 → 4.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 (290) hide show
  1. package/CHANGELOG.md +470 -0
  2. package/component-tokens.d.ts +230 -60
  3. package/components.tokens.json +5156 -1557
  4. package/css/accordion.css +47 -20
  5. package/css/alert.css +16 -17
  6. package/css/anchor.css +2 -2
  7. package/css/approval.css +41 -17
  8. package/css/avatar-group.css +9 -12
  9. package/css/avatar.css +20 -18
  10. package/css/back-top.css +21 -7
  11. package/css/badge.css +5 -5
  12. package/css/breadcrumb.css +18 -16
  13. package/css/button-group.css +4 -6
  14. package/css/button.css +13 -12
  15. package/css/calendar-picker.css +178 -95
  16. package/css/calendar-range-picker.css +207 -122
  17. package/css/card.css +34 -6
  18. package/css/carousel.css +94 -46
  19. package/css/cartesian-chart.css +11 -11
  20. package/css/cascader.css +51 -39
  21. package/css/checkbox-group.css +9 -6
  22. package/css/checkbox.css +5 -4
  23. package/css/citation.css +9 -4
  24. package/css/clipboard.css +20 -4
  25. package/css/code-view.css +6 -6
  26. package/css/collapsible.css +29 -14
  27. package/css/color-field.css +4 -4
  28. package/css/color-picker.css +77 -23
  29. package/css/color-slider.css +10 -8
  30. package/css/color-swatch-picker.css +14 -9
  31. package/css/combobox.css +26 -14
  32. package/css/command.css +14 -9
  33. package/css/context-menu.css +10 -5
  34. package/css/date-field.css +12 -6
  35. package/css/date-picker.css +178 -109
  36. package/css/date-range-picker.css +199 -130
  37. package/css/description.css +10 -6
  38. package/css/descriptions.css +47 -19
  39. package/css/dialog.css +50 -35
  40. package/css/diff-view.css +8 -8
  41. package/css/drawer.css +75 -21
  42. package/css/editable.css +15 -41
  43. package/css/empty-state.css +21 -3
  44. package/css/field-array.css +5 -2
  45. package/css/field.css +17 -18
  46. package/css/fieldset.css +33 -13
  47. package/css/file-upload.css +66 -33
  48. package/css/float-button.css +60 -35
  49. package/css/floating-panel.css +1 -1
  50. package/css/form.css +30 -16
  51. package/css/graph-chart.css +2 -2
  52. package/css/grid-list.css +1 -1
  53. package/css/highlight.css +5 -5
  54. package/css/hover-card.css +19 -12
  55. package/css/image-viewer.css +77 -27
  56. package/css/image.css +13 -5
  57. package/css/infinite-scroll.css +8 -4
  58. package/css/input-group.css +74 -26
  59. package/css/kbd.css +1 -1
  60. package/css/label.css +27 -11
  61. package/css/layout.css +17 -10
  62. package/css/list.css +13 -9
  63. package/css/listbox.css +12 -7
  64. package/css/loading-bar.css +3 -0
  65. package/css/mention.css +11 -9
  66. package/css/menu.css +10 -5
  67. package/css/menubar.css +13 -8
  68. package/css/message-feed.css +1 -1
  69. package/css/navigation-menu.css +2 -2
  70. package/css/notification.css +132 -49
  71. package/css/number-animation.css +2 -2
  72. package/css/number-field.css +75 -52
  73. package/css/page-header.css +64 -27
  74. package/css/pagination.css +35 -38
  75. package/css/password-input.css +12 -68
  76. package/css/pin-input.css +18 -26
  77. package/css/popconfirm.css +23 -14
  78. package/css/popover.css +18 -12
  79. package/css/progress.css +14 -13
  80. package/css/prompt-input.css +3 -3
  81. package/css/question-flow.css +41 -15
  82. package/css/radar-chart.css +6 -6
  83. package/css/radio-group.css +120 -55
  84. package/css/rating.css +32 -15
  85. package/css/select.css +16 -12
  86. package/css/separator.css +24 -6
  87. package/css/side-nav.css +29 -24
  88. package/css/signature-pad.css +23 -9
  89. package/css/skeleton.css +12 -12
  90. package/css/slider.css +77 -48
  91. package/css/sortable.css +2 -2
  92. package/css/sparkline.css +8 -2
  93. package/css/spinner.css +40 -20
  94. package/css/statistic.css +14 -14
  95. package/css/steps.css +115 -84
  96. package/css/switch.css +9 -7
  97. package/css/table.css +29 -12
  98. package/css/tabs.css +35 -12
  99. package/css/tag-group.css +17 -6
  100. package/css/tag.css +54 -29
  101. package/css/tags-input.css +39 -20
  102. package/css/text-field.css +5 -5
  103. package/css/time-field.css +4 -4
  104. package/css/time-picker.css +150 -64
  105. package/css/time-range-picker.css +91 -62
  106. package/css/timeline.css +37 -20
  107. package/css/timer.css +3 -3
  108. package/css/toggle-group.css +4 -4
  109. package/css/tool-call.css +13 -11
  110. package/css/toolbar.css +6 -5
  111. package/css/tooltip.css +16 -17
  112. package/css/tour.css +14 -7
  113. package/css/transfer.css +22 -16
  114. package/css/tree-select.css +12 -12
  115. package/css/tree.css +26 -25
  116. package/css/typography.css +28 -25
  117. package/dist/css/accordion.css +296 -0
  118. package/dist/css/affix.css +47 -0
  119. package/dist/css/alert.css +246 -0
  120. package/dist/css/anchor.css +252 -0
  121. package/dist/css/approval.css +525 -0
  122. package/dist/css/avatar-group.css +96 -0
  123. package/dist/css/avatar.css +100 -0
  124. package/dist/css/back-top.css +175 -0
  125. package/dist/css/badge.css +205 -0
  126. package/dist/css/bar-code.css +62 -0
  127. package/dist/css/breadcrumb.css +232 -0
  128. package/dist/css/button-group.css +261 -0
  129. package/dist/css/button.css +216 -0
  130. package/dist/css/calendar-picker.css +550 -0
  131. package/dist/css/calendar-range-picker.css +639 -0
  132. package/dist/css/card.css +249 -0
  133. package/dist/css/carousel.css +726 -0
  134. package/dist/css/cartesian-chart.css +830 -0
  135. package/dist/css/cascader.css +973 -0
  136. package/dist/css/checkbox-group.css +361 -0
  137. package/dist/css/checkbox.css +258 -0
  138. package/dist/css/citation.css +475 -0
  139. package/dist/css/clipboard.css +331 -0
  140. package/dist/css/code-view.css +374 -0
  141. package/dist/css/collapsible.css +200 -0
  142. package/dist/css/color-field.css +176 -0
  143. package/dist/css/color-picker.css +649 -0
  144. package/dist/css/color-slider.css +283 -0
  145. package/dist/css/color-swatch-picker.css +250 -0
  146. package/dist/css/color-swatch.css +35 -0
  147. package/dist/css/combobox.css +578 -0
  148. package/dist/css/command.css +404 -0
  149. package/dist/css/context-menu.css +425 -0
  150. package/dist/css/date-field.css +317 -0
  151. package/dist/css/date-picker.css +931 -0
  152. package/dist/css/date-range-picker.css +949 -0
  153. package/dist/css/description.css +71 -0
  154. package/dist/css/descriptions.css +327 -0
  155. package/dist/css/dialog.css +470 -0
  156. package/dist/css/diff-view.css +513 -0
  157. package/dist/css/download-trigger.css +151 -0
  158. package/dist/css/drawer.css +606 -0
  159. package/dist/css/editable.css +269 -0
  160. package/dist/css/empty-state.css +181 -0
  161. package/dist/css/field-array.css +229 -0
  162. package/dist/css/field.css +165 -0
  163. package/dist/css/fieldset.css +122 -0
  164. package/dist/css/file-upload.css +462 -0
  165. package/dist/css/flex.css +441 -0
  166. package/dist/css/float-button.css +579 -0
  167. package/dist/css/floating-panel.css +429 -0
  168. package/dist/css/focus.css +46 -0
  169. package/dist/css/forced-colors.css +93 -0
  170. package/dist/css/form.css +407 -0
  171. package/dist/css/funnel-chart.css +106 -0
  172. package/dist/css/graph-chart.css +205 -0
  173. package/dist/css/grid-list.css +235 -0
  174. package/dist/css/grid.css +1201 -0
  175. package/dist/css/heatmap.css +552 -0
  176. package/dist/css/hierarchy-chart.css +298 -0
  177. package/dist/css/highlight.css +41 -0
  178. package/dist/css/hover-card.css +233 -0
  179. package/dist/css/icon.css +225 -0
  180. package/dist/css/image-cropper.css +373 -0
  181. package/dist/css/image-viewer.css +588 -0
  182. package/dist/css/image.css +106 -0
  183. package/dist/css/infinite-scroll.css +81 -0
  184. package/dist/css/input-group.css +323 -0
  185. package/dist/css/json-viewer.css +379 -0
  186. package/dist/css/kbd.css +72 -0
  187. package/dist/css/label.css +94 -0
  188. package/dist/css/layers.css +7 -0
  189. package/dist/css/layout.css +379 -0
  190. package/dist/css/liquid.css +106 -0
  191. package/dist/css/list.css +156 -0
  192. package/dist/css/listbox.css +395 -0
  193. package/dist/css/loading-bar.css +144 -0
  194. package/dist/css/log.css +306 -0
  195. package/dist/css/markdown-stream.css +149 -0
  196. package/dist/css/marquee.css +378 -0
  197. package/dist/css/masonry.css +70 -0
  198. package/dist/css/matrix-code.css +67 -0
  199. package/dist/css/mention.css +395 -0
  200. package/dist/css/menu.css +369 -0
  201. package/dist/css/menubar.css +461 -0
  202. package/dist/css/message-feed.css +318 -0
  203. package/dist/css/navigation-menu.css +513 -0
  204. package/dist/css/notification.css +865 -0
  205. package/dist/css/number-animation.css +44 -0
  206. package/dist/css/number-field.css +275 -0
  207. package/dist/css/overlay-arrow.css +56 -0
  208. package/dist/css/page-header.css +221 -0
  209. package/dist/css/pagination.css +447 -0
  210. package/dist/css/password-input.css +335 -0
  211. package/dist/css/pie-chart.css +247 -0
  212. package/dist/css/pin-input.css +191 -0
  213. package/dist/css/pointer.css +36 -0
  214. package/dist/css/popconfirm.css +329 -0
  215. package/dist/css/popover.css +285 -0
  216. package/dist/css/progress.css +502 -0
  217. package/dist/css/prompt-input.css +260 -0
  218. package/dist/css/question-flow.css +579 -0
  219. package/dist/css/radar-chart.css +233 -0
  220. package/dist/css/radio-group.css +663 -0
  221. package/dist/css/rating.css +311 -0
  222. package/dist/css/reasoning.css +343 -0
  223. package/dist/css/reset.css +117 -0
  224. package/dist/css/resizable.css +242 -0
  225. package/dist/css/sankey-chart.css +174 -0
  226. package/dist/css/scroll-area.css +240 -0
  227. package/dist/css/scrollbar.css +204 -0
  228. package/dist/css/select.css +616 -0
  229. package/dist/css/separator.css +140 -0
  230. package/dist/css/side-nav.css +481 -0
  231. package/dist/css/signature-pad.css +193 -0
  232. package/dist/css/skeleton.css +161 -0
  233. package/dist/css/slider.css +403 -0
  234. package/dist/css/sortable.css +228 -0
  235. package/dist/css/sparkline.css +170 -0
  236. package/dist/css/spinner.css +256 -0
  237. package/dist/css/splitter.css +159 -0
  238. package/dist/css/statistic.css +137 -0
  239. package/dist/css/steps.css +658 -0
  240. package/dist/css/switch.css +353 -0
  241. package/dist/css/table.css +1162 -0
  242. package/dist/css/tabs.css +967 -0
  243. package/dist/css/tag-group.css +258 -0
  244. package/dist/css/tag.css +335 -0
  245. package/dist/css/tags-input.css +341 -0
  246. package/dist/css/text-field.css +197 -0
  247. package/dist/css/time-field.css +277 -0
  248. package/dist/css/time-picker.css +793 -0
  249. package/dist/css/time-range-picker.css +775 -0
  250. package/dist/css/timeline.css +440 -0
  251. package/dist/css/timer.css +123 -0
  252. package/dist/css/timestamp.css +34 -0
  253. package/dist/css/toggle-group.css +424 -0
  254. package/dist/css/toggle.css +146 -0
  255. package/dist/css/tone.css +189 -0
  256. package/dist/css/tool-call.css +431 -0
  257. package/dist/css/toolbar.css +366 -0
  258. package/dist/css/tooltip.css +217 -0
  259. package/dist/css/tour.css +446 -0
  260. package/dist/css/transfer.css +644 -0
  261. package/dist/css/tree-select.css +878 -0
  262. package/dist/css/tree.css +734 -0
  263. package/dist/css/truncate.css +108 -0
  264. package/dist/css/typography.css +475 -0
  265. package/dist/css/undefined.css +58 -0
  266. package/dist/css/virtualizer.css +166 -0
  267. package/dist/css/visually-hidden.css +20 -0
  268. package/dist/css/watermark.css +82 -0
  269. package/dist/family/action-control.css +493 -0
  270. package/dist/family/chart.css +537 -0
  271. package/dist/family/check-mark.css +94 -0
  272. package/dist/family/choice-card.css +97 -0
  273. package/dist/family/collection-item.css +768 -0
  274. package/dist/family/field-chrome.css +296 -0
  275. package/dist/family/loading-ring.css +102 -0
  276. package/dist/family/material.css +72 -0
  277. package/dist/family/menu-choice.css +56 -0
  278. package/dist/family/motion.css +363 -0
  279. package/dist/family/swatch.css +59 -0
  280. package/dist/family/tag-list.css +65 -0
  281. package/family/action-control.css +33 -36
  282. package/family/chart.css +57 -0
  283. package/family/collection-item.css +12 -8
  284. package/family/field-chrome.css +28 -19
  285. package/family/loading-ring.css +20 -13
  286. package/family/swatch.css +4 -4
  287. package/family/tag-list.css +6 -0
  288. package/index.css +10349 -8756
  289. package/index.unlayered.css +10350 -8758
  290. package/package.json +165 -164
@@ -0,0 +1,395 @@
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
+ /* 定义 listbox 样式。 */
7
+
8
+ @import '../family/action-control.css';
9
+ @import '../family/collection-item.css';
10
+ @import '../family/loading-ring.css';
11
+ @import '../family/motion.css';
12
+
13
+ @layer xihan.components {
14
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
15
+ .xh-scope-listbox {
16
+ --xh-listbox-skin: 1;
17
+ }
18
+
19
+ .xh-scope-listbox[data-part='root'] {
20
+ /* 条目外的字形(空态 / 在途占位里作者塞的图标)按档取尺,缺省 md;条目内的字形由家族随
21
+ data-xh-collection-size 下发。列表框自绘的状态字形(行尾对号所在的标记盒与盒里的勾)不读这支:
22
+ 它们是指示符,走 --xh-control-indicator-* 一族——标记盒在自己身上把 --xh-icon-size 改接到盒的尺 */
23
+ --xh-icon-size: var(--xh-listbox-icon-size, var(--xh-glyph-size-md));
24
+ /* 定高小列表的自绘条挂在根上:根是条子的定位盒,轨道底色关掉才不会在列表右缘糊出一条灰带 */
25
+ --xh-scrollbar-track-bg: transparent;
26
+
27
+ /* 尺寸档只换这四个私有槽,条目、分组标题与空态占位都从 root 继承它们,
28
+ 换档不必给每个部件各写一条选择器 */
29
+ --xh-_listbox-item-py: var(--xh-list-option-py-md);
30
+ --xh-_listbox-item-px: var(--xh-control-px-md);
31
+ --xh-_listbox-gap: var(--xh-control-gap-md);
32
+ --xh-_listbox-font-size: var(--xh-control-font-md);
33
+
34
+ /* 强调色随语气走,只落在勾选标记上;没写 data-tone 时退回品牌色 */
35
+ --xh-_listbox-accent: var(--xh-_tone, var(--xh-fg-brand));
36
+
37
+ position: relative;
38
+ display: flex;
39
+ flex-direction: column;
40
+ gap: var(--xh-listbox-gap, var(--xh-space-2));
41
+ }
42
+
43
+ .xh-scope-listbox[data-part='root'][hidden] {
44
+ display: none;
45
+ }
46
+
47
+ /* —— 尺寸 —— */
48
+ /* 缺省档写在上面的基础规则里 */
49
+ .xh-scope-listbox[data-part='root'][data-size='sm'] {
50
+ --xh-icon-size: var(--xh-listbox-icon-size, var(--xh-glyph-size-sm));
51
+ --xh-_listbox-item-py: var(--xh-list-option-py-sm);
52
+ --xh-_listbox-item-px: var(--xh-control-px-sm);
53
+ --xh-_listbox-gap: var(--xh-control-gap-sm);
54
+ --xh-_listbox-font-size: var(--xh-control-font-sm);
55
+ }
56
+
57
+ .xh-scope-listbox[data-part='root'][data-size='lg'] {
58
+ --xh-icon-size: var(--xh-listbox-icon-size, var(--xh-glyph-size-lg));
59
+ --xh-_listbox-item-py: var(--xh-list-option-py-lg);
60
+ --xh-_listbox-item-px: var(--xh-control-px-lg);
61
+ --xh-_listbox-gap: var(--xh-control-gap-lg);
62
+ --xh-_listbox-font-size: var(--xh-control-font-lg);
63
+ }
64
+
65
+ /* 校验失败:整块列表框换成错误描边,与其余表单控件同一套表达 */
66
+ .xh-scope-listbox[data-part='content'][data-invalid] {
67
+ border-color: var(--xh-listbox-content-border-invalid, var(--xh-border-invalid));
68
+ }
69
+
70
+ /* 只读改不动选中值,但不是禁用:颜色照常,只把"可点"这个暗示收回来。
71
+ 光标由家族按态解算,这里在各态的槽上统一收回;禁用项的 not-allowed 由家族按 aria-disabled 给,不在此列 */
72
+ .xh-scope-listbox[data-part='root'][data-readonly]
73
+ .xh-scope-listbox[data-part='item']:not([data-disabled]) {
74
+ --xh-collection-cursor-rest: default;
75
+ --xh-collection-cursor-hover: default;
76
+ --xh-collection-cursor-keyboard-highlight: default;
77
+ --xh-collection-cursor-pressed: default;
78
+ --xh-collection-cursor-selected: default;
79
+ --xh-collection-cursor-selected-hover: default;
80
+ --xh-collection-cursor-selected-highlight: default;
81
+ --xh-collection-cursor-selected-pressed: default;
82
+ }
83
+
84
+ .xh-scope-listbox[data-part='label'] {
85
+ color: var(--xh-listbox-label-fg, var(--xh-fg-muted));
86
+ font-size: var(--xh-listbox-label-font-size, var(--xh-text-label-size));
87
+ font-weight: var(--xh-listbox-label-font-weight, var(--xh-text-label-weight));
88
+ line-height: var(--xh-leading-none);
89
+ }
90
+
91
+ /* 整组禁用会把 data-disabled 一路打到 label / content / group 上,各处观感保持一致 */
92
+ .xh-scope-listbox[data-part='label'][data-disabled] {
93
+ color: var(--xh-fg-subtle);
94
+ }
95
+
96
+ /* 常驻列表不是浮层:容器留边框与底色,但不投影、不脱离文档流,
97
+ 因此这里既不写 position 也不写 z-index,滚动发生在容器自身 */
98
+ .xh-scope-listbox[data-part='content'] {
99
+ display: flex;
100
+ flex-direction: column;
101
+ gap: var(--xh-listbox-content-gap, var(--xh-list-option-gap));
102
+ max-block-size: var(--xh-listbox-content-max-h, var(--xh-viewport-h-md));
103
+ padding-block: var(--xh-listbox-content-py, var(--xh-space-1));
104
+ padding-inline: var(--xh-listbox-content-px, var(--xh-space-1));
105
+ border: var(--xh-stroke-thin) solid var(--xh-listbox-content-border, var(--xh-border-default));
106
+ border-radius: var(--xh-listbox-content-radius, var(--xh-shape-surface));
107
+ background: var(--xh-listbox-content-bg, var(--xh-bg-surface));
108
+ color: var(--xh-listbox-content-fg, var(--xh-fg-default));
109
+ /* 两轴一起给:条目文字用省略号收口,正常不会横向溢出,
110
+ 但作者塞进宽内容时至少还够得着,而不是被裁掉 */
111
+ overflow: auto;
112
+ }
113
+
114
+ /* display 会盖掉 hidden 属性的 UA 规则,作者手动收起时要显式让位 */
115
+ .xh-scope-listbox[data-part='content'][hidden] {
116
+ display: none;
117
+ }
118
+
119
+ /* 手写结构按真正的条目判断,空白文本与分组标题都不算候选。
120
+ 只排除 content 内部的 hidden 祖先;外层浮层退场时不改变本列表的几何。
121
+ 禁用条目仍是有效内容,不参与此处排除。 */
122
+ .xh-scope-listbox[data-part='content']:not([data-xh-virtualized]):not(:has(
123
+ .xh-scope-listbox[data-part='item']:not([hidden]):not(.xh-scope-listbox[data-part='content'] [hidden] *)
124
+ )),
125
+ .xh-scope-listbox[data-part='group']:not(:has(
126
+ .xh-scope-listbox[data-part='item']:not([hidden]):not(.xh-scope-listbox[data-part='content'] [hidden] *)
127
+ )) {
128
+ display: none;
129
+ }
130
+
131
+ /* 横向列表沿主轴排,此时高度由内容决定,再压最大高度只会白留一条滚动条 */
132
+ .xh-scope-listbox[data-part='content'][data-orientation='horizontal'] {
133
+ flex-direction: row;
134
+ align-items: center;
135
+ max-block-size: none;
136
+ }
137
+
138
+ /* 焦点在列表外时容器自己进 Tab 序列兜底,落焦不画环:高亮永远长在条目上 */
139
+ .xh-scope-listbox[data-part='content']:focus-visible {
140
+ outline: none;
141
+ }
142
+
143
+ .xh-scope-listbox[data-part='group'] {
144
+ display: flex;
145
+ flex-direction: column;
146
+ gap: var(--xh-listbox-group-gap, var(--xh-list-option-gap));
147
+ }
148
+
149
+ .xh-scope-listbox[data-part='group'][hidden] {
150
+ display: none;
151
+ }
152
+
153
+ /* 只在两个有可见条目的分组之间留白;已收起的空组不能把首组额外向下推。 */
154
+ .xh-scope-listbox[data-part='group']:has(
155
+ .xh-scope-listbox[data-part='item']:not([hidden]):not(.xh-scope-listbox[data-part='content'] [hidden] *)
156
+ )
157
+ ~ .xh-scope-listbox[data-part='group']:has(
158
+ .xh-scope-listbox[data-part='item']:not([hidden]):not(.xh-scope-listbox[data-part='content'] [hidden] *)
159
+ ) {
160
+ margin-block-start: var(--xh-listbox-group-spacing, var(--xh-space-1_5));
161
+ }
162
+
163
+ /* 分组标题不是选项、进不了导航,画成小号次要文字,
164
+ 内缩与条目对齐(同一个 padding-inline),标题与条目文字才在一条竖线上 */
165
+ .xh-scope-listbox[data-part='group-label'] {
166
+ display: block;
167
+ padding-block: var(--xh-listbox-group-label-py, var(--xh-space-1));
168
+ padding-inline: var(--xh-listbox-group-label-px, var(--xh-_listbox-item-px));
169
+ color: var(--xh-listbox-group-label-fg, var(--xh-fg-muted));
170
+ font-size: var(--xh-listbox-group-label-font-size, var(--xh-text-caption-size));
171
+ font-weight: var(--xh-listbox-group-label-font-weight, var(--xh-font-weight-medium));
172
+ line-height: var(--xh-leading-none);
173
+ user-select: none;
174
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
175
+ }
176
+
177
+ /* 刷新:已有选项时后台在取,保留上一帧,条目与分组标题按 micro 淡下,数据到了再淡回;在途占位此时让位。
178
+ 淡的是内容不是面:content 自己是描边面,整块淡下去边也跟着淡 */
179
+ .xh-scope-listbox[data-part='content'][aria-busy='true'] .xh-scope-listbox:is([data-part='item'], [data-part='group-label']) {
180
+ opacity: var(--xh-state-disabled-opacity);
181
+ }
182
+
183
+ .xh-scope-listbox[data-part='group-label'][hidden] {
184
+ display: none;
185
+ }
186
+
187
+ .xh-scope-listbox[data-part='group-label'][data-disabled] {
188
+ color: var(--xh-fg-disabled);
189
+ }
190
+
191
+ /* 空态占位:待在 root 里、content 的兄弟(列表框只许拥有 option 与 group)。
192
+ 它只画作者提供的居中文字;零候选的 content 自身收起,不再留下空描边或留白。 */
193
+ .xh-scope-listbox[data-part='empty'] {
194
+ display: block;
195
+ padding-block: var(--xh-listbox-empty-py, var(--xh-space-3));
196
+ padding-inline: var(--xh-listbox-empty-px, var(--xh-_listbox-item-px));
197
+ color: var(--xh-listbox-empty-fg, var(--xh-fg-muted));
198
+ font-size: var(--xh-listbox-empty-font-size, var(--xh-_listbox-font-size));
199
+ line-height: var(--xh-leading-none);
200
+ text-align: center;
201
+ }
202
+
203
+ /* 上面给了 display,UA 的 [hidden]{display:none} 已被盖掉,这里补回来 */
204
+ .xh-scope-listbox[data-part='empty'][hidden] {
205
+ display: none;
206
+ }
207
+
208
+ .xh-scope-listbox[data-part='empty'][data-disabled] {
209
+ color: var(--xh-fg-disabled);
210
+ }
211
+
212
+ /* 在途占位:与空态占位同一个位置、同一副观感,两者不同屏 */
213
+ .xh-scope-listbox[data-part='loading'] {
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ gap: var(--xh-_listbox-gap);
218
+ padding-block: var(--xh-listbox-loading-py, var(--xh-space-3));
219
+ padding-inline: var(--xh-listbox-loading-px, var(--xh-_listbox-item-px));
220
+ color: var(--xh-listbox-loading-fg, var(--xh-fg-muted));
221
+ font-size: var(--xh-listbox-loading-font-size, var(--xh-_listbox-font-size));
222
+ line-height: var(--xh-leading-none);
223
+ text-align: center;
224
+ }
225
+
226
+ .xh-scope-listbox[data-part='loading'][hidden] {
227
+ display: none;
228
+ }
229
+
230
+ /* 首次加载:文案前一枚加载环,由加载环配方画(连接层投影 data-xh-loading-ring 与 data-loading),
231
+ 直径取所在尺寸档的图标档 */
232
+ .xh-scope-listbox[data-part='loading']::before {
233
+ content: '';
234
+ flex: none;
235
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
236
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
237
+ }
238
+
239
+ /* 取下一页的按钮:铺满一行摆在列表尾——铺满一行的独立动作条目,接 Action Control 的 row 档、
240
+ ghost 形态:宽度由容器给、高度随内容、按下只换面不缩放;盒几何、悬停 / 按下 / 禁用面、
241
+ 焦点环与粗指针热区全由家族给,白底承载 hover 100 → pressed 200。
242
+ 这里只把使用者槽映射到桥接槽,文案居中写在下一条 */
243
+ .xh-scope-listbox[data-part='load-more-trigger'] {
244
+ --xh-action-gap: var(--xh-listbox-load-more-trigger-gap, var(--xh-_listbox-gap));
245
+ --xh-action-padding-block: var(--xh-listbox-load-more-trigger-py, var(--xh-_listbox-item-py));
246
+ --xh-action-padding-inline: var(--xh-listbox-load-more-trigger-px, var(--xh-_listbox-item-px));
247
+ --xh-action-radius: var(--xh-listbox-load-more-trigger-radius, var(--xh-shape-control));
248
+ --xh-action-bg-hover: var(--xh-listbox-load-more-trigger-bg-hover, var(--xh-_action-variant-bg-hover));
249
+ --xh-action-fg-rest: var(--xh-listbox-load-more-trigger-fg, var(--xh-_tone-fg, var(--xh-fg-brand-strong)));
250
+ --xh-action-fg-hover: var(--xh-listbox-load-more-trigger-fg, var(--xh-_tone-fg, var(--xh-fg-brand-strong)));
251
+ --xh-action-fg-pressed: var(--xh-listbox-load-more-trigger-fg, var(--xh-_tone-fg, var(--xh-fg-brand-strong)));
252
+ --xh-action-font-size: var(--xh-listbox-load-more-trigger-font-size, var(--xh-_listbox-font-size));
253
+
254
+ /* row 档允许换行、高度随内容,折行的文案走正文行高 */
255
+ line-height: var(--xh-leading-normal);
256
+ }
257
+
258
+ /* 文案居中(单行整段居中,折行逐行居中),盖掉 row 档的靠起始缘排布:它是一行里唯一的东西,
259
+ 靠起始缘会像一条没对齐的条目。选择器点名 row 档,有层与无层两份产物里都压得住它 */
260
+ .xh-scope-listbox[data-part='load-more-trigger'][data-xh-action-profile='row'] {
261
+ justify-content: center;
262
+ text-align: center;
263
+ }
264
+
265
+ .xh-scope-listbox[data-part='load-more-trigger'][hidden] {
266
+ display: none;
267
+ }
268
+
269
+ /* 条目走 Collection Item 的 overlay 语境,与树选择同一种选中读法:网格、尺寸档、悬停 / 高亮 / 按下面
270
+ (白底承载 hover 100 → pressed 200)由家族给,选中不换面、不换字色,只在行尾亮对号,
271
+ 选中叠悬停 / 按下沿用同一条阶梯;禁用面(字色降级、not-allowed、不换面)也归家族。
272
+ 这里只把公开槽映射到桥接槽,不复制任何状态选择器。
273
+ 列表框坐在 surface 白底上,前景走 fg-default 而不是浮层的 frosted 前景 */
274
+ .xh-scope-listbox[data-part='item'] {
275
+ --xh-collection-block-padding: var(--xh-listbox-item-py, var(--xh-_listbox-item-py));
276
+ --xh-collection-inline-padding: var(--xh-listbox-item-px, var(--xh-_listbox-item-px));
277
+ --xh-collection-gap: var(--xh-listbox-item-gap, var(--xh-_listbox-gap));
278
+ --xh-collection-font-size: var(--xh-listbox-item-font-size, var(--xh-_listbox-font-size));
279
+ --xh-collection-radius: var(--xh-listbox-item-radius, var(--xh-shape-inset));
280
+ /* 作者的图标尺槽经桥接槽下发到条目,家族缺省按 data-xh-collection-size 取档 */
281
+ --xh-collection-glyph-size: var(--xh-listbox-icon-size, var(--xh-_collection-glyph-size));
282
+ --xh-collection-fg-rest: var(--xh-listbox-item-fg, var(--xh-fg-default));
283
+ --xh-collection-fg-hover: var(--xh-listbox-item-fg, var(--xh-fg-default));
284
+ --xh-collection-fg-keyboard-highlight: var(--xh-listbox-item-fg, var(--xh-fg-default));
285
+ --xh-collection-fg-pressed: var(--xh-listbox-item-fg, var(--xh-fg-default));
286
+ --xh-collection-fg-selected: var(--xh-listbox-item-fg-selected, var(--xh-listbox-item-fg, var(--xh-fg-default)));
287
+ --xh-collection-fg-selected-hover: var(--xh-listbox-item-fg-selected, var(--xh-listbox-item-fg, var(--xh-fg-default)));
288
+ --xh-collection-fg-selected-highlight: var(--xh-listbox-item-fg-selected, var(--xh-listbox-item-fg, var(--xh-fg-default)));
289
+ --xh-collection-fg-selected-pressed: var(--xh-listbox-item-fg-selected, var(--xh-listbox-item-fg, var(--xh-fg-default)));
290
+ --xh-collection-font-weight-selected: var(--xh-listbox-item-font-weight-selected, var(--xh-font-weight-medium));
291
+ --xh-collection-font-weight-selected-hover: var(--xh-listbox-item-font-weight-selected, var(--xh-font-weight-medium));
292
+ --xh-collection-font-weight-selected-highlight: var(--xh-listbox-item-font-weight-selected, var(--xh-font-weight-medium));
293
+ --xh-collection-font-weight-selected-pressed: var(--xh-listbox-item-font-weight-selected, var(--xh-font-weight-medium));
294
+ --xh-collection-bg-hover: var(--xh-listbox-item-bg-hover, var(--xh-bg-subtle));
295
+ --xh-collection-bg-keyboard-highlight: var(--xh-listbox-item-bg-hover, var(--xh-bg-subtle));
296
+ --xh-collection-bg-pressed: var(--xh-listbox-item-bg-pressed, var(--xh-bg-subtle-hover));
297
+ --xh-collection-bg-selected-hover: var(--xh-listbox-item-bg-hover, var(--xh-bg-subtle));
298
+ --xh-collection-bg-selected-highlight: var(--xh-listbox-item-bg-hover, var(--xh-bg-subtle));
299
+ --xh-collection-bg-selected-pressed: var(--xh-listbox-item-bg-pressed, var(--xh-bg-subtle-hover));
300
+ /* data-highlighted 跟的是连接层记的焦点条目(指针点选也会落焦):只换面,焦点环在 :focus-visible 下再接回 */
301
+ --xh-collection-outline-keyboard-highlight: transparent;
302
+ --xh-collection-outline-selected-highlight: transparent;
303
+ /* 对号随语气走:没写 data-tone 时退回品牌色;槽按本部件取名(item-check-fg),标记部件的旧槽留在兜底位 */
304
+ --xh-collection-indicator-fg-rest: var(--xh-listbox-item-check-fg, var(--xh-listbox-item-indicator-fg, var(--xh-_listbox-accent)));
305
+ --xh-collection-indicator-fg-checked: var(--xh-listbox-item-check-fg, var(--xh-listbox-item-indicator-fg, var(--xh-_listbox-accent)));
306
+ --xh-collection-indicator-fg-selected: var(--xh-listbox-item-check-fg, var(--xh-listbox-item-indicator-fg, var(--xh-_listbox-accent)));
307
+ --xh-collection-indicator-fg-selected-hover: var(--xh-listbox-item-check-fg, var(--xh-listbox-item-indicator-fg, var(--xh-_listbox-accent)));
308
+ --xh-collection-indicator-fg-selected-highlight: var(--xh-listbox-item-check-fg, var(--xh-listbox-item-indicator-fg, var(--xh-_listbox-accent)));
309
+ --xh-collection-indicator-fg-selected-pressed: var(--xh-listbox-item-check-fg, var(--xh-listbox-item-indicator-fg, var(--xh-_listbox-accent)));
310
+
311
+ /* 行高留出文字的上下伸展空间,行内那层 overflow:hidden 才不会把字削掉 */
312
+ line-height: var(--xh-listbox-item-leading, var(--xh-leading-normal));
313
+ white-space: nowrap;
314
+ user-select: none;
315
+ }
316
+
317
+ /* 家族给了 display,UA 的 [hidden]{display:none} 已被盖掉:条目可以按需收起(过滤掉的选项) */
318
+ .xh-scope-listbox[data-part='item'][hidden] {
319
+ display: none;
320
+ }
321
+
322
+ /* 键盘焦点出现时环才接回并立即到位,不压在背景过渡的中间帧上 */
323
+ .xh-scope-listbox[data-part='item']:focus-visible:not(:hover) {
324
+ --xh-collection-outline-keyboard-highlight: var(--xh-ring-focus);
325
+ --xh-collection-outline-selected-highlight: var(--xh-ring-focus);
326
+
327
+ transition: none;
328
+ }
329
+
330
+ .xh-scope-listbox[data-part='item-text'] {
331
+ /* 网格子项默认最小尺寸是内容尺寸,不归零则长文本把行撑破、省略号轮不上 */
332
+ min-inline-size: 0;
333
+ overflow: hidden;
334
+ white-space: nowrap;
335
+ text-overflow: ellipsis;
336
+ }
337
+
338
+ /* 勾选标记落在家族网格行尾的 indicator 列(page 与 overlay 同位);显隐与颜色由家族按选中态给,
339
+ 未选中时占位不塌,切换选中不引起行宽抖动。
340
+ 盒与盒里的勾是指示符:盒按指示符档取尺,并在自己身上把 --xh-icon-size 改接到盒的尺,皮肤画的
341
+ 兜底勾与作者塞进盒里的 XhIcon 读同一把尺、与盒同边长(对号不是勾选格,不取 × 0.75,与 Menu 族同口径);
342
+ 不读家族按档下发到行的 --xh-icon-size——那支只管作者放进条目里的图标,按图标档取的 20px 比 16 / 14 的指示符档大一圈 */
343
+ .xh-scope-listbox[data-part='item-indicator'] {
344
+ --xh-icon-size: var(--xh-listbox-item-indicator-size, var(--xh-control-indicator-size));
345
+
346
+ display: inline-flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+ inline-size: var(--xh-listbox-item-indicator-size, var(--xh-control-indicator-size));
350
+ block-size: var(--xh-listbox-item-indicator-size, var(--xh-control-indicator-size));
351
+ }
352
+
353
+ .xh-scope-listbox[data-part='item-indicator'][hidden] {
354
+ display: none;
355
+ }
356
+
357
+ /* 没写内容就由皮肤画勾;作者往部件里塞了自己的图形,这条规则即不命中。
358
+ 尺寸读标记盒自己改接过的 --xh-icon-size:与盒同边长,随指示符档换档(见上面标记盒那块) */
359
+ .xh-scope-listbox[data-part='item-indicator']:empty::before {
360
+ content: '';
361
+ display: inline-block;
362
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
363
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
364
+ vertical-align: var(--xh-glyph-baseline-shift);
365
+ background-color: currentColor;
366
+ -webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
367
+ mask: var(--xh-glyph-mark-check) center / contain no-repeat;
368
+ }
369
+
370
+ @media print {
371
+ /* 打印默认丢底色,而对号是遮罩出来的一块底色:行本就不换面,丢了它选中在纸上就没了踪影 */
372
+ .xh-scope-listbox[data-part='item-indicator'] {
373
+ print-color-adjust: exact;
374
+ }
375
+ }
376
+
377
+ @media (forced-colors: active) {
378
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
379
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
380
+ 条目面上取 CanvasText;按下与没被高亮时的悬停,家族把条目涂成 Highlight,字形换 HighlightText;
381
+ 禁用取 GrayText */
382
+ .xh-scope-listbox[data-part='item-indicator']:empty::before {
383
+ forced-color-adjust: none;
384
+ background-color: CanvasText;
385
+ }
386
+
387
+ .xh-scope-listbox[data-part='item']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted])) .xh-scope-listbox[data-part='item-indicator']:empty::before {
388
+ background-color: HighlightText;
389
+ }
390
+
391
+ .xh-scope-listbox[data-part='item']:is([aria-disabled='true'], [data-disabled]) .xh-scope-listbox[data-part='item-indicator']:empty::before {
392
+ background-color: GrayText;
393
+ }
394
+ }
395
+ }
@@ -0,0 +1,144 @@
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
+ /* 定义 loading bar 样式。 */
7
+
8
+ @layer xihan.components {
9
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
+ .xh-scope-loading-bar {
11
+ --xh-loading-bar-skin: 1;
12
+ }
13
+
14
+ /*
15
+ * 贴在视口顶边的一条细带。厚度那条轴(block-size)由连接层写进内联样式——
16
+ * height 这个 prop 的缺省值在 connect 里收口,这里再声明一次只会被内联盖掉,
17
+ * 还会让人误以为厚度归样式层管。
18
+ *
19
+ * fixed 认的是视口,祖先上一旦出现 transform / filter / backdrop-filter / contain
20
+ * 就会把包含块抢走,条子立刻贴错位置——覆盖钩子里别加这几个属性。
21
+ */
22
+ .xh-scope-loading-bar[data-part='root'] {
23
+ position: fixed;
24
+ /* 顶到视口上沿的那一条:刘海或状态栏压住的那一段由系统给出,不让位就整条藏在下面。
25
+ 桌面上 env() 恒为 0,条子照旧贴着上沿。 */
26
+ inset-block-start: env(safe-area-inset-top);
27
+ inset-inline: 0;
28
+ z-index: var(--xh-loading-bar-layer, var(--xh-layer-sticky));
29
+
30
+ /* 它只报进度,不吃点击:盖在顶栏上的一条带子若拦住指针,页面顶部就点不动了 */
31
+ pointer-events: none;
32
+ opacity: 1;
33
+ transition: opacity var(--xh-loading-bar-fade, var(--xh-motion-duration-exit)) var(--xh-motion-ease-exit);
34
+ }
35
+
36
+ /* 只要声明过任何 display,就盖掉了 UA 的 [hidden]{display:none};
37
+ 这里虽然没声明,作者层随手给一条 display 也会盖掉,所以补齐这条兜住收起态。
38
+ 连接层只会给 root 写 hidden,track / range 不需要同样的兜底 */
39
+ .xh-scope-loading-bar[data-part='root'][hidden] {
40
+ display: none;
41
+ }
42
+
43
+ /* 走满之后才淡出:complete 期间根节点保持不透明,进度段冲到头的平移播完,机器才进 finishing。
44
+ 满格先停一拍(延迟一个 micro)再淡:用户要看清「走完了」,一到头就开始淡读起来像中途断掉。
45
+ 机器等的是浏览器实际起播的这段过渡(含延迟),不按毫秒猜 */
46
+ .xh-scope-loading-bar[data-part='root'][data-state='finishing'] {
47
+ opacity: 0;
48
+ transition-delay: var(--xh-motion-duration-micro);
49
+ }
50
+
51
+ /* 背景槽。默认透明:顶部加载条通常直接压在页面顶边上,一条贯穿整屏的浅色底
52
+ 在视觉上等于凭空多出一道分隔线 */
53
+ .xh-scope-loading-bar[data-part='track'] {
54
+ overflow: hidden;
55
+ inline-size: 100%;
56
+ block-size: 100%;
57
+ background: var(--xh-loading-bar-track, transparent);
58
+ }
59
+
60
+ /*
61
+ * 进度段。铺满轨道,按连接层交出的比例往行首平移、由轨道裁掉:推进只走合成,
62
+ * 不重排也不重绘;末端的亮边跟着它一起走。背景色不走内联:要别的颜色改 --xh-loading-bar-range 这个槽,或者换语气。
63
+ *
64
+ * 语气取装饰档 --xh-_tone-soft:那一档压在画布上够 3:1,细带才看得出来。
65
+ * 槽位由 root 上的 data-tone 声明,继承下来。
66
+ * 没写 data-tone 时该槽没被声明,退回原来的品牌色。
67
+ */
68
+ .xh-scope-loading-bar[data-part='range'] {
69
+ inline-size: 100%;
70
+ block-size: 100%;
71
+ /* 露出的前端(行尾)是一维对象的圆头;行首一端由轨道与视口边裁掉,保持方头贴边 */
72
+ border-start-end-radius: var(--xh-loading-bar-range-radius, var(--xh-shape-pill));
73
+ border-end-end-radius: var(--xh-loading-bar-range-radius, var(--xh-shape-pill));
74
+ background: var(--xh-loading-bar-range, var(--xh-_tone-soft, var(--xh-bg-brand)));
75
+ translate: calc((var(--xh-_loading-bar-value, 0) - 1) * 100%) 0;
76
+ transition: translate var(--xh-loading-bar-speed, var(--xh-motion-duration-move)) var(--xh-motion-ease-continuous);
77
+ }
78
+
79
+ /* translate 只认物理方向:RTL 下行首在右边,平移方向翻转 */
80
+ .xh-scope-loading-bar[data-part='range']:dir(rtl) {
81
+ translate: calc((1 - var(--xh-_loading-bar-value, 0)) * 100%) 0;
82
+ }
83
+
84
+ /* 渲染了亮边才把进度段变成定位面:亮边贴在它的末端 */
85
+ .xh-scope-loading-bar[data-part='range']:has([data-part='peg']) {
86
+ position: relative;
87
+ }
88
+
89
+ /*
90
+ * 进度段末端那道亮边。它把「条子在往前走」这件事画出来:只有一条渐宽的色带时,
91
+ * 200ms 一跳的推进读起来像卡顿。
92
+ * 颜色接进度段自己的那一支,宽度与厚度各留一个槽。
93
+ */
94
+ .xh-scope-loading-bar[data-part='peg'] {
95
+ position: absolute;
96
+ inset-block: 0;
97
+ inset-inline-end: 0;
98
+ inline-size: var(--xh-loading-bar-peg-w, var(--xh-space-8));
99
+ /* 两端渐隐、中间最亮:亮斑对称,文字方向翻过来也不必再配一次 */
100
+ background: linear-gradient(
101
+ 90deg,
102
+ transparent,
103
+ var(--xh-loading-bar-peg-fg, var(--xh-loading-bar-range, var(--xh-_tone-soft, var(--xh-bg-brand)))),
104
+ transparent
105
+ );
106
+ }
107
+
108
+ /* 条子还没起步时亮边一起收着:进度为 0 的末端不该先亮出一道边 */
109
+ .xh-scope-loading-bar[data-part='peg'][data-state='idle'] {
110
+ opacity: 0;
111
+ }
112
+
113
+ .xh-scope-loading-bar[data-part='peg'][hidden] {
114
+ display: none;
115
+ }
116
+
117
+ /* 减少动效:作者写进两个时长槽的值不作数,退回令牌——进度段的平移随几何时长立刻到位,
118
+ 收尾的淡出保留减弱档的那一小段。一条按 200ms 一拍持续推进的带子正是最容易引发不适的那种动效。
119
+ 两条规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
120
+ @media (prefers-reduced-motion: reduce) {
121
+ .xh-scope-loading-bar[data-part='root'] {
122
+ transition-duration: var(--xh-motion-duration-exit);
123
+ }
124
+
125
+ .xh-scope-loading-bar[data-part='range'] {
126
+ transition-duration: var(--xh-motion-duration-move);
127
+ }
128
+ }
129
+
130
+ :where([data-motion='reduce']) .xh-scope-loading-bar[data-part='root'] {
131
+ transition-duration: var(--xh-motion-duration-exit);
132
+ }
133
+
134
+ :where([data-motion='reduce']) .xh-scope-loading-bar[data-part='range'] {
135
+ transition-duration: var(--xh-motion-duration-move);
136
+ }
137
+
138
+ @media print {
139
+ /* 打印:加载进度条画的是「正在等」,落到纸上是一条没有含义的色带。 */
140
+ .xh-scope-loading-bar[data-part='root'] {
141
+ display: none;
142
+ }
143
+ }
144
+ }