@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,649 @@
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
+ /* 定义 color picker 样式。 */
7
+
8
+ @import '../family/field-chrome.css';
9
+ @import '../family/action-control.css';
10
+ @import '../family/swatch.css';
11
+ @import '../family/motion.css';
12
+ @import '../family/tag-list.css';
13
+
14
+ @layer xihan.components {
15
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
16
+ .xh-scope-color-picker {
17
+ --xh-color-picker-skin: 1;
18
+ }
19
+
20
+ /* 定位分工:取色区拇指的两条轴(inset-inline-start / inset-block-start)、浮层坐标、取色区底色,
21
+ 全都由连接层每帧写进内联样式。这份皮肤一个都不碰:内联优先级高于样式表,
22
+ 写了不但是死声明,还会跟连接层抢位置。皮肤只管尺寸、颜色、圆角与状态表现。
23
+ 色相 / 透明度两条滑块与预设色板是内嵌组件,各自的皮归 color-slider.css 与 color-swatch-picker.css;
24
+ 这里只画三个挂载点——它们同时充当内嵌组件的根节点,根上那几条规则要在这儿照抄一遍。 */
25
+
26
+ /* 标签一行、盒一行的两行堆叠 */
27
+ .xh-scope-color-picker[data-part='root'] {
28
+ /* 盒的度量走私有槽中转,与同族的下拉选择一处对一处 */
29
+ --xh-_color-picker-h: var(--xh-control-h-md);
30
+ --xh-_color-picker-px: var(--xh-control-px-md);
31
+ --xh-_color-picker-gap: var(--xh-control-gap-md);
32
+
33
+
34
+ display: inline-flex;
35
+ flex-direction: column;
36
+ gap: var(--xh-color-picker-gap, var(--xh-space-1));
37
+
38
+ /* 不传尺寸时一律这么宽,宽度不随内容走;父容器给不出这么宽时整件跟着收,地板同步让步,不越出父容器。
39
+ 地板不高过缺省宽:使用者把缺省宽钉到底线以下时不必再放开底线 */
40
+ inline-size: var(--xh-color-picker-control-w, var(--xh-control-w));
41
+ min-inline-size: min(var(--xh-color-picker-control-w, var(--xh-control-w)), var(--xh-color-picker-control-min-w, var(--xh-control-min-w)), 100%);
42
+ max-inline-size: 100%;
43
+ }
44
+
45
+ /* —— 尺寸 —— */
46
+ /* 缺省档写在上面的基础规则里。浮层那一侧也要挂:positioner 被搬到 portal 落点,
47
+ 继承不到根上的私有槽,所以两个部件一起收 */
48
+ .xh-scope-color-picker:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
49
+ --xh-_color-picker-h: var(--xh-control-h-sm);
50
+ --xh-_color-picker-px: var(--xh-control-px-sm);
51
+ --xh-_color-picker-gap: var(--xh-control-gap-sm);
52
+ }
53
+
54
+ .xh-scope-color-picker:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
55
+ --xh-_color-picker-h: var(--xh-control-h-lg);
56
+ --xh-_color-picker-px: var(--xh-control-px-lg);
57
+ --xh-_color-picker-gap: var(--xh-control-gap-lg);
58
+ }
59
+
60
+ .xh-scope-color-picker[data-part='label'] {
61
+ /* 竖排时标签与控件之间的距离:根的 gap 之上补一段差值,--xh-color-picker-label-gap 给多少最终就是多少 */
62
+ margin-block-end: calc(var(--xh-color-picker-label-gap, var(--xh-space-2)) - var(--xh-color-picker-gap, var(--xh-space-1)));
63
+ color: var(--xh-color-picker-label-fg, var(--xh-fg-muted));
64
+ /* 字段标签不随档:与同族字段同一档标签字号 */
65
+ font-size: var(--xh-color-picker-label-font-size, var(--xh-text-label-size));
66
+ font-weight: var(--xh-color-picker-label-font-weight, var(--xh-text-label-weight));
67
+ }
68
+
69
+ /* 盒:接字段外壳家族(data-xh-field-chrome),描边、底色、控件高度、行内内衬、悬停与聚焦面
70
+ 都由家族按 data-variant 与状态画,与同族的下拉选择一处对一处;这里只把组件自己的覆盖槽桥接进去。
71
+ 静息无影、悬停取家族的 45% 淡底、聚焦边一律 --xh-border-control-focus(不随语气) */
72
+ .xh-scope-color-picker[data-part='control'] {
73
+ --xh-field-control-height: var(--xh-color-picker-control-h, var(--xh-_color-picker-h));
74
+ --xh-field-control-padding-inline: var(--xh-color-picker-control-px, var(--xh-_color-picker-px));
75
+ --xh-field-control-gap: var(--xh-color-picker-control-gap, var(--xh-_color-picker-gap));
76
+ --xh-field-control-min-inline-size: var(--xh-color-picker-control-min-w, var(--xh-control-min-w));
77
+ --xh-field-control-radius: var(--xh-color-picker-control-radius, var(--xh-shape-control));
78
+ --xh-field-bg-rest: var(--xh-color-picker-control-bg, var(--xh-_field-variant-bg-rest));
79
+ --xh-field-bg-hover: var(--xh-color-picker-control-bg-hover, var(--xh-_field-variant-bg-hover));
80
+ --xh-field-bg-read-only: var(--xh-color-picker-control-bg-readonly, var(--xh-_field-variant-bg-read-only));
81
+ --xh-field-bg-disabled: var(--xh-color-picker-control-bg-disabled, var(--xh-_field-variant-bg-disabled));
82
+ --xh-field-fg-rest: var(--xh-color-picker-control-fg, var(--xh-fg-default));
83
+ --xh-field-border-rest: var(--xh-color-picker-control-border, var(--xh-_field-variant-border-rest));
84
+ --xh-field-border-hover: var(--xh-color-picker-control-border-hover, var(--xh-_field-variant-border-hover));
85
+ --xh-field-border-focus: var(--xh-color-picker-control-border-focus, var(--xh-_field-variant-border-focus));
86
+ --xh-field-shadow-rest: var(--xh-color-picker-control-shadow, none);
87
+ --xh-field-cursor-rest: pointer;
88
+ }
89
+
90
+ .xh-scope-color-picker[data-part='control'][hidden] {
91
+ display: none;
92
+ }
93
+
94
+ /* 多选的标签行:选中的颜色在盒里排成标签,超过 maxTagCount 的折进 +N。
95
+ 行里每一枚都是 tag(data-scope="tag"),样子归 tag.css;行怎么排、标签怎么进出归标签行家族配方。
96
+ 基准取 0:只吃触发钮剩下的宽度、在自己里面折行;按内容宽算基准的话,盒子会先在钮前面折行,把钮挤到最后一行 */
97
+ .xh-scope-color-picker[data-part='tag-list'] {
98
+ --xh-tag-list-gap: var(--xh-color-picker-tag-list-gap, var(--xh-space-1));
99
+
100
+ flex: 1 1 0;
101
+ flex-wrap: wrap;
102
+ }
103
+
104
+ /* 颜色标签是定长的值串,截短了就读不出是哪个颜色:不收缩,排不下就折到下一行,
105
+ 盒随行数长高(字段家族的 multi-tag 布局给),到上限后在盒内滚动 */
106
+ .xh-scope-color-picker[data-part='tag-list'] > .xh-scope-tag[data-part='root'] {
107
+ flex: none;
108
+ }
109
+
110
+ /* 每枚标签前一个色点,颜色由连接层写进内联私有槽;+N 那一枚没有 data-value,不画。
111
+ 白色与近底色的颜色靠一圈默认描边从标签底上分出来 */
112
+ .xh-scope-color-picker[data-part='tag-list'] > .xh-scope-tag[data-part='root'][data-value]::before {
113
+ flex: none;
114
+ box-sizing: border-box;
115
+ inline-size: var(--xh-color-picker-tag-dot-size, var(--xh-control-indicator-sm));
116
+ block-size: var(--xh-color-picker-tag-dot-size, var(--xh-control-indicator-sm));
117
+ border: var(--xh-stroke-thin) solid var(--xh-color-picker-tag-dot-border, var(--xh-border-default));
118
+ border-radius: var(--xh-shape-circle);
119
+ background-color: var(--xh-_color-picker-tag-color, transparent);
120
+ content: '';
121
+ print-color-adjust: exact;
122
+ }
123
+
124
+ .xh-scope-color-picker[data-part='control'][data-xh-field-layout='multi-tag'] {
125
+ max-block-size: var(--xh-color-picker-control-max-h, var(--xh-viewport-h-sm));
126
+ overflow-y: auto;
127
+ }
128
+
129
+ /* 多选时值文字让位,触发钮只剩一颗显示工作色的色块:不再占满剩余宽度,标签行吃掉余下的位置 */
130
+ .xh-scope-color-picker[data-part='control'][data-xh-field-layout='multi-tag'] > .xh-scope-color-picker[data-part='trigger'] {
131
+ flex: none;
132
+ }
133
+
134
+ /* 盒内那颗可聚焦的按钮:不画描边不铺底也不自带高度,只占满剩余宽度、排布色块与值文本 */
135
+ .xh-scope-color-picker[data-part='trigger'] {
136
+ display: inline-flex;
137
+ flex: 1 1 auto;
138
+ align-items: center;
139
+ gap: var(--xh-color-picker-trigger-gap, var(--xh-_color-picker-gap));
140
+ min-inline-size: 0;
141
+ padding: 0;
142
+ border: 0;
143
+ background: transparent;
144
+ color: var(--xh-color-picker-trigger-fg, var(--xh-fg-default));
145
+ font-family: inherit;
146
+ font-size: var(--xh-color-picker-trigger-font-size, var(--xh-text-body-size));
147
+ line-height: var(--xh-leading-none);
148
+ text-align: start;
149
+ cursor: pointer;
150
+ }
151
+
152
+ .xh-scope-color-picker[data-part='trigger'][hidden] {
153
+ display: none;
154
+ }
155
+
156
+ /* 单体控件用原生 disabled */
157
+ .xh-scope-color-picker[data-part='trigger']:disabled {
158
+ color: var(--xh-fg-disabled);
159
+ }
160
+
161
+ /* 当前颜色的色块:面、棋盘格、描边与尺寸档全由色块面家族画(带 data-xh-swatch),
162
+ 半透明色铺在棋盘格上;组件层只把自己的公开槽映射到家族合同 */
163
+ .xh-scope-color-picker[data-part='swatch'] {
164
+ --xh-swatch-size: var(--xh-color-picker-swatch-size, var(--xh-_swatch-size));
165
+ --xh-swatch-radius: var(--xh-color-picker-swatch-radius, var(--xh-shape-inset));
166
+ --xh-swatch-border: var(--xh-color-picker-swatch-border, var(--xh-border-default));
167
+ }
168
+
169
+ /* 值串可能很长,必须能截断;框宽由盒定,这里得允许自己被压缩 */
170
+ .xh-scope-color-picker[data-part='value-text'] {
171
+ overflow: hidden;
172
+ flex: 1 1 auto;
173
+ min-inline-size: 0;
174
+ color: var(--xh-color-picker-value-fg, var(--xh-fg-default));
175
+ font-size: var(--xh-color-picker-value-font-size, var(--xh-text-body-size));
176
+ text-align: start;
177
+ text-overflow: ellipsis;
178
+ white-space: nowrap;
179
+ }
180
+
181
+ /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
182
+ .xh-scope-color-picker[data-part='positioner'] {
183
+ /* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,内容层继承它限高;
184
+ 引擎没算(尚未落位 / 无引擎 / 贴边归零)时不额外限高 */
185
+ --xh-_color-picker-available-h: 100vh;
186
+ /* 落定那一侧的可用宽度,同样由定位引擎经内联自定义属性写进来,内容层据此夹住行内轴;
187
+ 引擎没算(尚未落位 / 无引擎 / 贴边归零)时退到视口宽 */
188
+ --xh-_color-picker-available-w: 100vw;
189
+ /* 每个面板按自身落位方向进入,截断祖先浮层方向的继承。 */
190
+ --xh-_overlay-enter-up: 0;
191
+ --xh-_overlay-enter-down: 0;
192
+ --xh-_overlay-enter-left: 0;
193
+ --xh-_overlay-enter-right: 0;
194
+
195
+ /* 面板的自绘条浮在内容之上:轨道不上底色,实色轨道会在面板右缘糊出一条竖灰带 */
196
+ --xh-scrollbar-track-bg: transparent;
197
+
198
+ position: fixed;
199
+ z-index: var(--xh-color-picker-layer, var(--xh-_layer, var(--xh-layer-popover)));
200
+ /* 空壳不吃指针,交互只发生在 content 上 */
201
+ pointer-events: none;
202
+ }
203
+
204
+ .xh-scope-color-picker[data-part='positioner'][data-placement^='top'] {
205
+ --xh-_overlay-enter-down: 1;
206
+ }
207
+
208
+ .xh-scope-color-picker[data-part='positioner'][data-placement^='bottom'] {
209
+ --xh-_overlay-enter-up: 1;
210
+ }
211
+
212
+ .xh-scope-color-picker[data-part='positioner'][data-placement^='left'] {
213
+ --xh-_overlay-enter-right: 1;
214
+ }
215
+
216
+ .xh-scope-color-picker[data-part='positioner'][data-placement^='right'] {
217
+ --xh-_overlay-enter-left: 1;
218
+ }
219
+
220
+ /* 锚点被滚出可视区:整个浮层随之收起 */
221
+ .xh-scope-color-picker[data-part='positioner'][data-hidden] {
222
+ visibility: hidden;
223
+ }
224
+
225
+ .xh-scope-color-picker[data-part='content'] {
226
+ /* 内衬落进私有槽:贴顶通栏的取色区与色板区的通栏分隔按同一份内衬往外撑 */
227
+ --xh-_color-picker-content-py: var(--xh-color-picker-content-py, var(--xh-space-3));
228
+ --xh-_color-picker-content-px: var(--xh-color-picker-content-px, var(--xh-space-3));
229
+
230
+ position: relative;
231
+ display: flex;
232
+ flex-direction: column;
233
+ gap: var(--xh-color-picker-content-gap, var(--xh-space-3));
234
+ inline-size: var(--xh-color-picker-content-w, var(--xh-overlay-max-w-sm));
235
+ /* 定宽的面板也要夹一道:窄视口下伸出去,右半边的取色区就点不到了 */
236
+ max-inline-size: var(--xh-_color-picker-available-w);
237
+ padding-block: var(--xh-_color-picker-content-py);
238
+ padding-inline: var(--xh-_color-picker-content-px);
239
+ max-block-size: min(var(--xh-color-picker-max-h, var(--xh-viewport-h-lg)), var(--xh-_color-picker-available-h));
240
+ overflow-y: auto;
241
+ /* 浮层滚动面:滚到头不把页面一起带走 */
242
+ overscroll-behavior: contain;
243
+ /* 面域 + 滑杆 + 通道输入的表单型多列面板,走 floating 材质——实体底 + --xh-border-default 描边 +
244
+ --xh-elevation-floating 落影,不透景、不画顶部边界光 */
245
+ border: var(--xh-stroke-thin) solid var(--xh-color-picker-content-border, var(--xh-border-default));
246
+ border-radius: var(--xh-color-picker-content-radius, var(--xh-shape-overlay));
247
+ background: var(--xh-color-picker-content-bg, var(--xh-bg-surface));
248
+ color: var(--xh-color-picker-content-fg, var(--xh-fg-default));
249
+ box-shadow: var(--xh-color-picker-content-shadow, var(--xh-elevation-floating));
250
+ pointer-events: auto;
251
+ }
252
+
253
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现;常驻形态的取色面一直在,没有进退场 */
254
+ .xh-scope-color-picker[data-part='content'][data-state='open']:not([data-instant], [data-inline]) {
255
+ animation: xh-overlay-slide-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
256
+ }
257
+
258
+ /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
259
+ 免得动画结束到真收起之间闪一下原样 */
260
+ .xh-scope-color-picker[data-part='content'][data-state='closed']:not([data-inline]) {
261
+ animation: xh-overlay-slide-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
262
+ }
263
+
264
+ /* 浮层本身只是个容器(tabindex=-1 是焦点域的兜底落点),落焦时不画环 */
265
+ .xh-scope-color-picker[data-part='content']:focus-visible {
266
+ outline: none;
267
+ }
268
+
269
+ /* 常驻形态:根不再取字段缺省宽,跟着取色面走 */
270
+ .xh-scope-color-picker[data-part='root'][data-inline] {
271
+ inline-size: auto;
272
+ min-inline-size: 0;
273
+ }
274
+
275
+ /* 常驻形态的取色面是页面里的静态内容面(solid):surface 圆角、border-default 描边、实体底、不落影。
276
+ 没有定位层给出可用宽高,不限高也不自己滚;它一直在,没有进退场 */
277
+ .xh-scope-color-picker[data-part='content'][data-inline] {
278
+ max-inline-size: 100%;
279
+ max-block-size: none;
280
+ overflow-y: visible;
281
+ border-radius: var(--xh-color-picker-content-radius, var(--xh-shape-surface));
282
+ box-shadow: var(--xh-color-picker-content-shadow, none);
283
+ }
284
+
285
+ /* 二维取色区。底色是当前色相(连接层内联给),两层渐变盖在上面:
286
+ 横轴由白到透明 = 饱和度,纵轴由透明到黑 = 明度。
287
+ 两层都收在一个 ::before 里:它是盒树里的第一个子节点,作者写的拇指排在它后面,
288
+ 绘制顺序上就压在渐变之上;拆成 ::before + ::after 的话 ::after 是最后一个子节点,
289
+ 会反过来盖住拇指。 */
290
+ .xh-scope-color-picker[data-part='saturation-area'] {
291
+ position: relative;
292
+ display: block;
293
+ flex: none;
294
+ block-size: var(--xh-color-picker-saturation-area-h, var(--xh-overlay-color-area-h));
295
+ border-radius: var(--xh-color-picker-saturation-area-radius, var(--xh-shape-control));
296
+ cursor: crosshair;
297
+ }
298
+
299
+ /* 取色区排在面板最前时贴着面板顶边通栏:往外撑掉顶边与两侧的内衬、不取圆角,
300
+ 四角由面板(滚动面)自己的圆角裁出;后面的内容照常留内衬 */
301
+ .xh-scope-color-picker[data-part='content'] > [data-part='saturation-area']:first-child:where(.xh-scope-color-picker) {
302
+ margin-block-start: calc(-1 * var(--xh-_color-picker-content-py));
303
+ margin-inline: calc(-1 * var(--xh-_color-picker-content-px));
304
+ border-radius: var(--xh-color-picker-saturation-area-radius, 0);
305
+ }
306
+
307
+ /* white / black 是 HSV 色彩空间自带的两个端点,不是主题色,因此不走令牌 */
308
+ .xh-scope-color-picker[data-part='saturation-area']::before {
309
+ position: absolute;
310
+ border-radius: inherit;
311
+ background-image:
312
+ linear-gradient(to bottom, transparent, black),
313
+ linear-gradient(to right, white, transparent);
314
+ content: '';
315
+ inset: 0;
316
+ }
317
+
318
+ /* 渐变方向没有逻辑关键字可用,只能靠 :dir() 分流:
319
+ 拇指走的是 inset-inline-start,rtl 下自动换向,饱和度那层渐变不跟着换就反了 */
320
+ .xh-scope-color-picker[data-part='saturation-area']:dir(rtl)::before {
321
+ background-image:
322
+ linear-gradient(to bottom, transparent, black),
323
+ linear-gradient(to left, white, transparent);
324
+ }
325
+
326
+ .xh-scope-color-picker[data-part='saturation-area'][data-readonly]:not([data-disabled]) {
327
+ cursor: default;
328
+ }
329
+
330
+ .xh-scope-color-picker[data-part='saturation-area'][data-disabled] {
331
+ opacity: var(--xh-state-disabled-opacity);
332
+ }
333
+
334
+ /* 取色区的拇指:镂空的小圆环,中心正好落在值所在的比例点上。
335
+ 内联样式把 inset-* 定在比例上,那是拇指的起始边不是圆心,用负的逻辑外边距回拉半径。
336
+ 刻意不用 translate(-50%):rtl 下 inset-inline-start 映射到 right,
337
+ 位移量是物理方向的,会把拇指推向错误的一侧;负的逻辑外边距自己就跟着换向。
338
+ box-sizing 必须显式写:描边要吃进直径里,否则实际盒子比变量宽两条边,回拉就对不上圆心。
339
+ 两条滑块的拇指归 color-slider 那份皮,与这一颗同一副长相。 */
340
+ .xh-scope-color-picker[data-part='area-thumb'] {
341
+ position: absolute;
342
+ box-sizing: border-box;
343
+ inline-size: var(--xh-color-picker-thumb-size, var(--xh-control-indicator-md));
344
+ block-size: var(--xh-color-picker-thumb-size, var(--xh-control-indicator-md));
345
+ margin-inline-start: calc(var(--xh-color-picker-thumb-size, var(--xh-control-indicator-md)) / -2);
346
+ border: var(--xh-stroke-thick) solid var(--xh-color-picker-thumb-border, var(--xh-color-neutral-0));
347
+ border-radius: var(--xh-color-picker-thumb-radius, var(--xh-shape-circle));
348
+ background: transparent;
349
+ box-shadow: var(--xh-color-picker-thumb-shadow, var(--xh-elevation-raised));
350
+ cursor: grab;
351
+ transition: scale var(--xh-motion-duration-nudge) var(--xh-motion-ease-enter-strong);
352
+ }
353
+
354
+ /* 取色区的纵轴也由连接层给(inset-block-start),回拉同样按 block-start 那侧 */
355
+ .xh-scope-color-picker[data-part='area-thumb'] {
356
+ margin-block-start: calc(var(--xh-color-picker-thumb-size, var(--xh-control-indicator-md)) / -2);
357
+ }
358
+
359
+ /* 只有手真正拖着时带 data-dragging:放大与光标不会几处一起变。
360
+ 放大用 scale 而不是改尺寸:变换绕自身中心发生,圆心不动,负外边距的算式不用跟着改 */
361
+ .xh-scope-color-picker[data-part='area-thumb'][data-dragging] {
362
+ scale: var(--xh-color-picker-thumb-scale-dragging, var(--xh-motion-scale-drag));
363
+ cursor: grabbing;
364
+ }
365
+
366
+ .xh-scope-color-picker[data-part='area-thumb'][data-readonly]:not([data-disabled]) {
367
+ cursor: default;
368
+ }
369
+
370
+ /* 两条颜色滑块的挂载点,同时充当各自的根节点:color-slider 那份皮的 root 规则落在
371
+ .xh-scope-color-slider[data-part='root'] 上,而这里没有那个节点,所以根上挂的两个私有槽
372
+ (拇指直径、轨道厚度,control / track / thumb 都读它们)与排布得在这儿照抄一遍;
373
+ 滑块内部的皮仍归 color-slider 那一份。尺寸档跟着浮层上的 data-size 走,不必再各写一遍 */
374
+ .xh-scope-color-picker[data-part='hue-slider'],
375
+ .xh-scope-color-picker[data-part='alpha-slider'] {
376
+ --xh-_thumb-size: var(--xh-color-picker-slider-thumb-size, var(--xh-control-indicator-md));
377
+ --xh-_track-thickness: var(--xh-color-picker-slider-track-thickness, var(--xh-space-3));
378
+
379
+ display: flex;
380
+ flex-direction: column;
381
+ }
382
+
383
+ /* 面板里两条滑块的拇指:一枚承载面色的白盘 + 1px 描边,正中一颗 8px 的当前色点。
384
+ 颜色带本身就是一排颜色,拇指整颗填当前色会融进色带里,留白盘才分得出拇指在哪;
385
+ 当前色点读滑块自己按拇指写的那支色 */
386
+ .xh-scope-color-picker:is([data-part='hue-slider'], [data-part='alpha-slider']) .xh-scope-color-slider[data-part='thumb'] {
387
+ border-width: var(--xh-stroke-thin);
388
+ background:
389
+ radial-gradient(circle, var(--xh-_color-slider-thumb-color) 0 var(--xh-space-1), transparent var(--xh-space-1)),
390
+ var(--xh-color-picker-slider-thumb-bg, var(--xh-bg-surface-raised));
391
+ }
392
+
393
+ /* 标题与轨道之间的间隙 */
394
+ .xh-scope-color-picker[data-part='hue-slider'] {
395
+ gap: var(--xh-color-picker-hue-slider-gap, var(--xh-stack-gap-md));
396
+ }
397
+
398
+ .xh-scope-color-picker[data-part='alpha-slider'] {
399
+ gap: var(--xh-color-picker-alpha-slider-gap, var(--xh-stack-gap-md));
400
+ }
401
+
402
+ /* 禁用的整体压暗只做一次,落在最外层;alpha 关掉时透明度那条整条压暗 */
403
+ .xh-scope-color-picker[data-part='hue-slider'][data-disabled],
404
+ .xh-scope-color-picker[data-part='alpha-slider'][data-disabled] {
405
+ opacity: var(--xh-state-disabled-opacity);
406
+ }
407
+
408
+ /* 通道输入照字段外壳:字段淡底 + 控件描边、24px 小号盒、说明档字号;悬停描边升一档,
409
+ 聚焦换承载面底 + 品牌描边、不画环(焦点由描边换色与底色差标出,强制色档补一圈 Highlight 环) */
410
+ .xh-scope-color-picker[data-part='channel-input'] {
411
+ inline-size: 100%;
412
+ min-inline-size: 0;
413
+ block-size: var(--xh-color-picker-input-h, var(--xh-control-action-size));
414
+ padding-inline: var(--xh-color-picker-input-px, var(--xh-control-px-sm));
415
+ border: var(--xh-stroke-thin) solid var(--xh-color-picker-input-border, var(--xh-border-control));
416
+ border-radius: var(--xh-color-picker-input-radius, var(--xh-shape-control));
417
+ background: var(--xh-color-picker-input-bg, var(--xh-bg-field));
418
+ color: inherit;
419
+ /* 表单控件不继承页面字体,只给字号会让输入框用 UA 默认字族,与周围文本对不上 */
420
+ font-family: inherit;
421
+ font-size: var(--xh-color-picker-input-font-size, var(--xh-text-caption-size));
422
+ text-align: center;
423
+ }
424
+
425
+ .xh-scope-color-picker[data-part='channel-input']:hover:not(:disabled, :focus, [data-readonly], [data-invalid]) {
426
+ border-color: var(--xh-color-picker-input-border-hover, var(--xh-border-strong));
427
+ }
428
+
429
+ .xh-scope-color-picker[data-part='channel-input']:focus {
430
+ /* 焦点边一律 --xh-border-control-focus,不随语气 */
431
+ border-color: var(--xh-color-picker-input-border-focus, var(--xh-border-control-focus));
432
+ background: var(--xh-color-picker-input-bg-focus, var(--xh-bg-surface));
433
+ }
434
+
435
+ .xh-scope-color-picker[data-part='channel-input']:focus-visible {
436
+ outline: none;
437
+ }
438
+
439
+ /* 打到一半的串:框里留着草稿,但值没动——描边提示"这串还没被收下" */
440
+ .xh-scope-color-picker[data-part='channel-input'][data-invalid] {
441
+ border-color: var(--xh-color-picker-input-border-invalid, var(--xh-border-invalid));
442
+ }
443
+
444
+ .xh-scope-color-picker[data-part='channel-input'][data-readonly] {
445
+ background: var(--xh-color-picker-input-bg-readonly, var(--xh-bg-subtle));
446
+ }
447
+
448
+ .xh-scope-color-picker[data-part='channel-input']:disabled {
449
+ background: var(--xh-color-picker-input-bg-disabled, var(--xh-bg-subtle));
450
+ color: var(--xh-fg-disabled);
451
+ }
452
+
453
+ .xh-scope-color-picker[data-part='eye-dropper-trigger'] {
454
+ display: inline-flex;
455
+ flex: none;
456
+ align-items: center;
457
+ justify-content: center;
458
+ inline-size: var(--xh-color-picker-action-size, var(--xh-control-action-size));
459
+ block-size: var(--xh-color-picker-action-size, var(--xh-control-action-size));
460
+ padding: 0;
461
+ border: var(--xh-stroke-thin) solid var(--xh-color-picker-action-border, var(--xh-border-control));
462
+ border-radius: var(--xh-color-picker-action-radius, var(--xh-shape-control));
463
+ background: var(--xh-color-picker-action-bg, transparent);
464
+ color: var(--xh-color-picker-action-fg, var(--xh-fg-muted));
465
+ font-family: inherit;
466
+ font-size: var(--xh-color-picker-action-font-size, var(--xh-text-secondary-size));
467
+ line-height: var(--xh-leading-none);
468
+ cursor: pointer;
469
+ user-select: none;
470
+ transition:
471
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
472
+ border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
473
+ scale var(--xh-motion-duration-release) var(--xh-motion-ease-release);
474
+ }
475
+
476
+ .xh-scope-color-picker[data-part='eye-dropper-trigger']:hover:not(:disabled) {
477
+ /* 坐在浮层白底上:白底承载阶梯 hover 100 → pressed 200 */
478
+ background: var(--xh-color-picker-action-bg-hover, var(--xh-bg-subtle));
479
+ color: var(--xh-color-picker-action-fg-hover, var(--xh-fg-default));
480
+ }
481
+
482
+ /* 按下去要有回应:换底之外再压一档。取色是一次「点下去就交给系统」的操作,
483
+ 松手那一刻浮层多半已经被系统的取色镜头盖住,按下的回执只有这一瞬看得见。
484
+ 指针 :active 与 Headless 投影的 data-pressed(Space / Enter 与触屏按住)看见同一副按压面 */
485
+ .xh-scope-color-picker[data-part='eye-dropper-trigger']:not(:disabled):is(:active, [data-pressed]) {
486
+ background: var(--xh-color-picker-action-bg-active, var(--xh-bg-subtle-hover));
487
+ scale: var(--xh-motion-scale-press);
488
+ transition-duration: var(--xh-motion-duration-press);
489
+ transition-timing-function: var(--xh-motion-ease-press);
490
+ }
491
+
492
+ /* 取色途中按钮保持按下的样子:屏幕取色期间浮层多半被系统的取色镜头盖着,
493
+ 这是用户回到页面时唯一能看出"刚才在取色"的痕迹 */
494
+ .xh-scope-color-picker[data-part='eye-dropper-trigger'][data-state='picking'] {
495
+ border-color: var(--xh-color-picker-action-border-active, var(--xh-bg-brand));
496
+ background: var(--xh-color-picker-action-bg-active, var(--xh-bg-subtle-active));
497
+ }
498
+
499
+ .xh-scope-color-picker[data-part='eye-dropper-trigger']:disabled {
500
+ color: var(--xh-fg-disabled);
501
+ }
502
+
503
+ /* 「添加」沉到面板的行尾:它是多选时整块面板的出口,不跟取色面左对齐 */
504
+ .xh-scope-color-picker[data-part='content'] > .xh-scope-color-picker[data-part='confirm-trigger'] {
505
+ flex: none;
506
+ align-self: flex-end;
507
+ }
508
+
509
+ /* 「添加」是面板里唯一的主要动作:品牌实心、悬停 / 按下与 0.97 按压、焦点环全由 Action Control 的
510
+ text solid 档给;槽名统一按部件取 --xh-color-picker-confirm-trigger-*,只映射到家族桥接槽 */
511
+ .xh-scope-color-picker[data-part='confirm-trigger'] {
512
+ --xh-action-visual-size: var(--xh-color-picker-confirm-trigger-h, var(--xh-control-action-size));
513
+ --xh-action-padding-inline: var(--xh-color-picker-confirm-trigger-px, var(--xh-_action-profile-padding-inline));
514
+ --xh-action-radius: var(--xh-color-picker-confirm-trigger-radius, var(--xh-shape-control));
515
+ --xh-action-bg-rest: var(--xh-color-picker-confirm-trigger-bg, var(--xh-_action-variant-bg-rest));
516
+ --xh-action-bg-hover: var(--xh-color-picker-confirm-trigger-bg-hover, var(--xh-_action-variant-bg-hover));
517
+ --xh-action-bg-pressed: var(--xh-color-picker-confirm-trigger-bg-active, var(--xh-_action-variant-bg-pressed));
518
+ --xh-action-fg-rest: var(--xh-color-picker-confirm-trigger-fg, var(--xh-_action-variant-fg-rest));
519
+ --xh-action-fg-hover: var(--xh-color-picker-confirm-trigger-fg, var(--xh-_action-variant-fg-hover));
520
+ --xh-action-fg-pressed: var(--xh-color-picker-confirm-trigger-fg, var(--xh-_action-variant-fg-pressed));
521
+ --xh-action-border-rest: transparent;
522
+ --xh-action-highlight-rest: transparent;
523
+ --xh-action-shadow-rest: var(--xh-color-picker-confirm-trigger-shadow, none);
524
+ --xh-action-shadow-hover: var(--xh-color-picker-confirm-trigger-shadow, none);
525
+ --xh-action-shadow-pressed: var(--xh-color-picker-confirm-trigger-shadow, none);
526
+ --xh-action-font-size: var(--xh-text-secondary-size);
527
+
528
+ border-width: 0;
529
+ }
530
+
531
+ /* 单选时连接层给的是 hidden 属性;家族那条 display 会把 UA 规则盖掉 */
532
+ .xh-scope-color-picker[data-part='confirm-trigger'][hidden] {
533
+ display: none;
534
+ }
535
+
536
+ /* 预设色板的挂载点,同时充当色板的根节点:color-swatch-picker 那份皮的 root 规则落在
537
+ .xh-scope-color-swatch-picker[data-part='root'] 上,而这里没有那个节点,所以根上挂的那几个私有槽
538
+ (格子边长、间距、徽标尺寸、语气色、图标尺)与排布得在这儿照抄一遍;格子的皮仍归色板那一份。
539
+ 浮层里的色板走小号格子:与滑块的拇指、数值框一个量级,整块面板才不会被色板撑开。
540
+ 最近使用色是同一台色块选择器,挂载点同一套 */
541
+ .xh-scope-color-picker:is([data-part='swatch-picker'], [data-part='recent-swatch-picker']) {
542
+ --xh-_color-swatch-picker-cell: var(--xh-color-picker-swatch-cell, var(--xh-glyph-size-sm));
543
+ --xh-_color-swatch-picker-gap: var(--xh-color-picker-swatch-gap, var(--xh-space-2));
544
+ --xh-_color-swatch-picker-indicator: var(--xh-control-indicator-sm);
545
+ --xh-_color-swatch-picker-mark: calc(var(--xh-_color-swatch-picker-indicator) - var(--xh-space-1));
546
+ --xh-_color-swatch-picker-accent: var(--xh-_tone, var(--xh-bg-brand));
547
+ --xh-icon-size: var(--xh-color-picker-swatch-icon-size, var(--xh-_color-swatch-picker-mark));
548
+
549
+ display: flex;
550
+ flex-wrap: wrap;
551
+ align-items: center;
552
+ gap: var(--xh-color-picker-swatch-picker-gap, var(--xh-_color-swatch-picker-gap));
553
+ }
554
+
555
+ .xh-scope-color-picker:is([data-part='swatch-picker'], [data-part='recent-swatch-picker'])[data-disabled] {
556
+ cursor: not-allowed;
557
+ }
558
+
559
+ /* 粗指针:16px 的格子手指压不准,格子回到小号控件高 */
560
+ @media (pointer: coarse) {
561
+ .xh-scope-color-picker:is([data-part='swatch-picker'], [data-part='recent-swatch-picker']) {
562
+ --xh-_color-swatch-picker-cell: var(--xh-color-picker-swatch-cell, var(--xh-control-h-sm));
563
+ }
564
+ }
565
+
566
+ /* 色板区与上面的取色控件之间一条通栏分隔:撑掉两侧内衬铺满面板宽,线取面板材质的描边档;
567
+ 两块色板挨着时只在头一块上画 */
568
+ .xh-scope-color-picker[data-part='content']
569
+ > :is([data-part='swatch-picker'], [data-part='recent-swatch-picker']):where(.xh-scope-color-picker):not(:is([data-part='swatch-picker'], [data-part='recent-swatch-picker']) + *) {
570
+ margin-inline: calc(-1 * var(--xh-_color-picker-content-px));
571
+ padding-block-start: var(--xh-_color-picker-content-py);
572
+ padding-inline: var(--xh-_color-picker-content-px);
573
+ border-block-start: var(--xh-stroke-thin) solid var(--xh-color-picker-separator, var(--xh-material-solid-border));
574
+ }
575
+
576
+ /* 任何 display 都会盖掉 UA 的 [hidden]{display:none}:
577
+ 凡是被赋了 display 的角色节点都要显式让位,漏一处收起态就失效。
578
+ content 的收起交给 presence:退场结束后由适配器写内联 display:none,避免截断动画。 */
579
+ .xh-scope-color-picker[data-part='root'][hidden],
580
+ .xh-scope-color-picker[data-part='trigger'][hidden],
581
+ .xh-scope-color-picker[data-part='saturation-area'][hidden],
582
+ .xh-scope-color-picker[data-part='area-thumb'][hidden],
583
+ .xh-scope-color-picker[data-part='hue-slider'][hidden],
584
+ .xh-scope-color-picker[data-part='alpha-slider'][hidden],
585
+ .xh-scope-color-picker[data-part='eye-dropper-trigger'][hidden],
586
+ .xh-scope-color-picker[data-part='swatch-picker'][hidden],
587
+ .xh-scope-color-picker[data-part='recent-swatch-picker'][hidden] {
588
+ display: none;
589
+ }
590
+
591
+ /* 连接层把它写成 type=hidden,UA 自己就不渲染;这里的视觉隐藏是给元素升级前那一瞬兜底
592
+ (作者手写的是一个普通 input,升级完成前它是可见的文本框)。
593
+ 刻意不写 display:写了反而会盖掉 UA 对 type=hidden 的收起,把它显出来 */
594
+ .xh-scope-color-picker[data-part='hidden-input'] {
595
+ position: absolute;
596
+ inline-size: 1px;
597
+ block-size: 1px;
598
+ padding: 0;
599
+ margin: -1px;
600
+ border: 0;
601
+ overflow: hidden;
602
+ clip-path: inset(50%);
603
+ white-space: nowrap;
604
+ pointer-events: none;
605
+ }
606
+
607
+ @media print {
608
+ /* 打印:定位层与遮罩是交互期才存在的东西,落到纸上只会盖住底下的正文。
609
+ 收起写在这份皮肤里而不是 reset:reset 层排在组件层之前,组件层里任何一条 display 都压得住它。 */
610
+ .xh-scope-color-picker[data-part='positioner'] {
611
+ display: none;
612
+ }
613
+ }
614
+
615
+ /*
616
+ * 高对比档:取色面画的就是颜色本身,被系统换掉之后整个组件不再能取色。这一处退出强制着色,
617
+ * 自己保住原色;退出之后它不再跟着系统底色走,补一圈系统描边把它从背景里框出来。
618
+ * 触发钮里的色块归 Swatch 家族、两条滑块的轨道与色板的格子归各自那份皮,都已各自退出强制着色。
619
+ */
620
+ @media (forced-colors: active) {
621
+ /* 高对比档里底色被系统换掉,取色按钮按下那一档用系统高亮反色画回 */
622
+ .xh-scope-color-picker[data-part='eye-dropper-trigger']:not(:disabled):is(:active, [data-pressed]) {
623
+ background: Highlight;
624
+ color: HighlightText;
625
+ }
626
+
627
+ .xh-scope-color-picker[data-part='saturation-area'],
628
+ .xh-scope-color-picker[data-part='saturation-area']::before {
629
+ forced-color-adjust: none;
630
+ }
631
+
632
+ .xh-scope-color-picker[data-part='saturation-area'] {
633
+ outline: var(--xh-stroke-thin) solid ButtonBorder;
634
+ outline-offset: calc(-1 * var(--xh-stroke-thin));
635
+ }
636
+
637
+ /* 通道输入聚焦不画环,靠描边换色;这一档描边被换成系统色,补一圈 Highlight 环 */
638
+ .xh-scope-color-picker[data-part='channel-input']:focus {
639
+ outline: var(--xh-ring-width) solid Highlight;
640
+ outline-offset: var(--xh-ring-offset);
641
+ }
642
+
643
+ /* 标签前的色点画的也是颜色本身:同样退出强制着色,用系统文字色描一圈 */
644
+ .xh-scope-color-picker[data-part='tag-list'] > .xh-scope-tag[data-part='root'][data-value]::before {
645
+ forced-color-adjust: none;
646
+ border-color: CanvasText;
647
+ }
648
+ }
649
+ }