@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,44 @@
1
+ /*
2
+ * Copyright (c) 2021-Present XiHanFun and contributors.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ */
5
+
6
+ /* 定义 number animation 样式。 */
7
+
8
+ @layer xihan.components {
9
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
+ .xh-scope-number-animation {
11
+ --xh-number-animation-skin: 1;
12
+ }
13
+
14
+ .xh-scope-number-animation[data-part='root'] {
15
+ /* 不写尺寸就跟着上下文的字号走:这个数常常摆在别人的标题、卡片标题或统计数值槽里,
16
+ 自带一个字号只会跟摆放它的地方打架。三个档位各自换掉这个私有槽 */
17
+ --xh-_number-animation-size: inherit;
18
+
19
+ display: inline-block;
20
+ color: var(--xh-number-animation-fg, var(--xh-_tone-fg, var(--xh-fg-default)));
21
+ font-size: var(--xh-number-animation-font-size, var(--xh-_number-animation-size));
22
+ /* 等宽数字:逐位宽度一致,逐帧换数时后面的字符不会左右挪动,整块也不会一跳一跳地变宽 */
23
+ font-variant-numeric: tabular-nums;
24
+ line-height: var(--xh-leading-tight);
25
+ }
26
+
27
+ /* 上面声明了 display,会盖掉 UA 的 [hidden] 规则,收起态要在这里接回来 */
28
+ .xh-scope-number-animation[data-part='root'][hidden] {
29
+ display: none;
30
+ }
31
+
32
+ /* —— 尺寸 —— */
33
+ .xh-scope-number-animation[data-part='root'][data-size='sm'] {
34
+ --xh-_number-animation-size: var(--xh-control-font-lg);
35
+ }
36
+
37
+ .xh-scope-number-animation[data-part='root'][data-size='md'] {
38
+ --xh-_number-animation-size: var(--xh-text-heading-2-size);
39
+ }
40
+
41
+ .xh-scope-number-animation[data-part='root'][data-size='lg'] {
42
+ --xh-_number-animation-size: var(--xh-text-heading-1-size);
43
+ }
44
+ }
@@ -0,0 +1,252 @@
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
+ /* NumberField 独立皮肤同时传递引入字段视觉盒与字段内动作;full bundle 递归去重。 */
7
+ @import '../family/field-chrome.css';
8
+ @import '../family/action-control.css';
9
+
10
+ @layer xihan.components {
11
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
12
+ .xh-scope-number-field {
13
+ --xh-number-field-skin: 1;
14
+ }
15
+
16
+ /* 与文本框同一套堆叠:标签一行、输入行一行。
17
+ control 是必需的唯一视觉盒,输入框、加减钮与前后缀都放在里面;
18
+ 输入与前后缀在左,减、加两颗动作依次收在逻辑末端。
19
+ 组件层只把既有公开槽映射到家族合同;形态三档由家族按 control 上的 data-variant 生成,皮肤不再声明。 */
20
+ .xh-scope-number-field[data-part='root'] {
21
+ /* 作者塞进来的图标跟着控件的尺寸档走;它自己写了 size 时仍以作者的为准 */
22
+ --xh-icon-size: var(--xh-number-field-icon-size, var(--xh-glyph-size-md));
23
+
24
+ /* 尺寸档只换这几个私有槽,输入框与加减钮都从 root 继承它们,
25
+ 换档不必给每个部件各写一条选择器 */
26
+ --xh-_number-field-h: var(--xh-control-h-md);
27
+ --xh-_number-field-px: var(--xh-control-px-md);
28
+ --xh-_number-field-gap: 0;
29
+ --xh-_number-field-font-size: var(--xh-control-font-md);
30
+ --xh-_number-field-trigger-font-size: var(--xh-control-font-md);
31
+
32
+ /* 盒内那道分隔线的长度:取钮高的一半,线的上下各留一截空白,不与钮等高 */
33
+ --xh-_number-field-divider-h: 50%;
34
+
35
+ display: inline-flex;
36
+ flex-direction: column;
37
+ gap: var(--xh-number-field-gap, var(--xh-space-1));
38
+
39
+ /* 不传尺寸时一律这么宽,宽度不随内容走;父容器给不出这么宽时整件跟着收,地板同步让步,不越出父容器。
40
+ 地板不高过缺省宽:使用者把缺省宽钉到底线以下时不必再放开底线 */
41
+ inline-size: var(--xh-number-field-control-w, var(--xh-control-w));
42
+ min-inline-size: min(var(--xh-number-field-control-w, var(--xh-control-w)), var(--xh-number-field-control-min-w, var(--xh-control-min-w)), 100%);
43
+ max-inline-size: 100%;
44
+ }
45
+
46
+ /* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
47
+ .xh-scope-number-field[data-part='root'][hidden] {
48
+ display: none;
49
+ }
50
+
51
+ /* —— 尺寸 —— */
52
+ /* 缺省档写在上面的基础规则里 */
53
+ .xh-scope-number-field[data-part='root'][data-size='sm'] {
54
+ --xh-icon-size: var(--xh-number-field-icon-size, var(--xh-glyph-size-sm));
55
+ --xh-_number-field-h: var(--xh-control-h-sm);
56
+ --xh-_number-field-px: var(--xh-control-px-sm);
57
+ --xh-_number-field-font-size: var(--xh-control-font-sm);
58
+ --xh-_number-field-trigger-font-size: var(--xh-control-font-sm);
59
+ }
60
+
61
+ .xh-scope-number-field[data-part='root'][data-size='lg'] {
62
+ --xh-icon-size: var(--xh-number-field-icon-size, var(--xh-glyph-size-lg));
63
+ --xh-_number-field-h: var(--xh-control-h-lg);
64
+ --xh-_number-field-px: var(--xh-control-px-lg);
65
+ --xh-_number-field-font-size: var(--xh-control-font-lg);
66
+ --xh-_number-field-trigger-font-size: var(--xh-control-font-lg);
67
+ }
68
+
69
+ .xh-scope-number-field[data-part='label'] {
70
+ color: var(--xh-number-field-label-fg, var(--xh-fg-default));
71
+ font-size: var(--xh-number-field-label-font-size, var(--xh-text-label-size));
72
+ font-weight: var(--xh-number-field-label-font-weight, var(--xh-text-label-weight));
73
+ }
74
+
75
+ .xh-scope-number-field[data-part='label'][data-disabled] {
76
+ color: var(--xh-number-field-label-fg-disabled, var(--xh-fg-subtle));
77
+ }
78
+
79
+ /* —— 一体式 control:输入框与加减钮同框 —— */
80
+ /* control 是唯一的视觉盒:描边、底色、圆角、聚焦环、五态与悬停由 Field Chrome 家族画,
81
+ 盒内三件都退成透明分段,整枚控件从头到尾只有这一道描边。
82
+ 外观槽按所在部件取名 --xh-number-field-control-*;--xh-number-field-input-* 只管
83
+ input 自己的字色与内衬。控件不给内衬:内衬走 input 与钮各自的盒。 */
84
+ .xh-scope-number-field[data-part='control'] {
85
+ --xh-field-control-height: var(--xh-number-field-control-h, var(--xh-_number-field-h));
86
+ --xh-field-control-padding-inline: var(--xh-number-field-control-px, 0);
87
+ --xh-field-control-gap: var(--xh-number-field-control-gap, var(--xh-_number-field-gap));
88
+ --xh-field-control-min-inline-size: var(--xh-number-field-control-min-w, var(--xh-control-min-w));
89
+ --xh-field-control-radius: var(--xh-number-field-control-radius, var(--xh-shape-control));
90
+ --xh-field-bg-rest: var(--xh-number-field-control-bg, var(--xh-_field-variant-bg-rest));
91
+ --xh-field-bg-hover: var(--xh-number-field-control-bg-hover, var(--xh-_field-variant-bg-hover));
92
+ --xh-field-bg-read-only: var(--xh-number-field-control-bg-readonly, var(--xh-_field-variant-bg-read-only));
93
+ --xh-field-bg-disabled: var(--xh-number-field-control-bg-disabled, var(--xh-_field-variant-bg-disabled));
94
+ --xh-field-fg-rest: var(--xh-number-field-control-fg, var(--xh-fg-default));
95
+ --xh-field-border-rest: var(--xh-number-field-control-border, var(--xh-_field-variant-border-rest));
96
+ --xh-field-border-hover: var(--xh-number-field-control-border-hover, var(--xh-_field-variant-border-hover));
97
+ --xh-field-border-focus: var(--xh-number-field-control-border-focus, var(--xh-_field-variant-border-focus));
98
+ --xh-field-border-invalid: var(--xh-number-field-control-border-invalid, var(--xh-_field-variant-border-invalid));
99
+ --xh-field-ring-focus: var(--xh-ring-focus);
100
+ --xh-field-ring-invalid: var(--xh-ring-invalid);
101
+ --xh-field-shadow-rest: var(--xh-number-field-control-shadow, none);
102
+ /* 家族 chrome 会重写 --xh-icon-size,使用者图标槽必须经桥接槽下发才能在盒内生效 */
103
+ --xh-field-glyph-size: var(--xh-number-field-icon-size, var(--xh-_field-size-glyph-size));
104
+
105
+ position: relative;
106
+ }
107
+
108
+ /* 装饰段:货币符、单位、图标。与输入框同框,不参与分宽,弱一档前景把它与数字分开 */
109
+ .xh-scope-number-field[data-part='prefix'],
110
+ .xh-scope-number-field[data-part='suffix'] {
111
+ --xh-field-affix-fg: var(--xh-number-field-affix-fg, var(--xh-fg-muted));
112
+ --xh-field-affix-fg-disabled: var(--xh-number-field-affix-fg-disabled, var(--xh-fg-disabled));
113
+ --xh-field-affix-font-size: var(--xh-number-field-affix-font-size, var(--xh-_number-field-font-size));
114
+ }
115
+
116
+ .xh-scope-number-field[data-part='prefix'][hidden],
117
+ .xh-scope-number-field[data-part='suffix'][hidden] {
118
+ display: none;
119
+ }
120
+
121
+ /* 盒内 input:无边框无底无圆角无落影由家族重置,观感全归 control。
122
+ 数字居中排在两个按钮之间,行内内衬留给它自己(control 不给内衬);
123
+ 前后缀图标/文字直接流式排在 input 两侧,不用再绝对定位 */
124
+ .xh-scope-number-field[data-part='control'] [data-part='input']:where(.xh-scope-number-field) {
125
+ --xh-field-input-fg: var(--xh-number-field-input-fg, var(--xh-fg-default));
126
+ --xh-field-input-font-size: var(--xh-number-field-input-font-size, var(--xh-_number-field-font-size));
127
+ --xh-field-placeholder-fg: var(--xh-number-field-placeholder-fg, var(--xh-fg-subtle));
128
+ --xh-field-autofill-bg: var(--xh-number-field-input-autofill-bg, var(--xh-bg-canvas));
129
+ --xh-field-autofill-fg: var(--xh-number-field-input-autofill-fg, var(--xh-fg-default));
130
+
131
+ inline-size: var(--xh-number-field-input-w, 5em);
132
+ padding-inline: var(--xh-number-field-input-px, var(--xh-_number-field-px));
133
+ font-variant-numeric: tabular-nums;
134
+ text-align: var(--xh-number-field-input-align, center);
135
+ }
136
+
137
+ /* 盒内按钮:正方视觉盒、inset 圆角、悬停 100 / 按下 200 与 0.97 按压、粗指针热区与
138
+ :focus-visible 关环全由 Action Control 的 field-inset ghost 档给,组件只映射既有覆盖槽。
139
+ 常态只剩符号,符号取默认前景,悬停与按下才浮出底色 */
140
+ .xh-scope-number-field[data-part='control'] [data-part='increment-trigger']:where(.xh-scope-number-field),
141
+ .xh-scope-number-field[data-part='control'] [data-part='decrement-trigger']:where(.xh-scope-number-field) {
142
+ --xh-action-visual-size: var(--xh-number-field-trigger-size, var(--xh-_action-profile-visual-size));
143
+ --xh-action-min-inline-size: var(--xh-number-field-trigger-size, var(--xh-_action-profile-visual-size));
144
+ --xh-action-radius: var(--xh-number-field-trigger-radius, var(--xh-shape-inset));
145
+ /* 底色阶梯由 ghost 档给(透明 → 100 → 200),使用者槽只作覆盖入口 */
146
+ --xh-action-bg-pressed: var(--xh-number-field-trigger-bg-active, var(--xh-_action-variant-bg-pressed));
147
+ --xh-action-fg-rest: var(--xh-number-field-trigger-fg, var(--xh-fg-default));
148
+ --xh-action-fg-hover: var(--xh-number-field-trigger-fg-hover, var(--xh-fg-default));
149
+ --xh-action-border-rest: transparent;
150
+ --xh-action-highlight-rest: transparent;
151
+ --xh-action-shadow-rest: none;
152
+ --xh-action-shadow-hover: none;
153
+ --xh-action-shadow-pressed: none;
154
+ --xh-action-font-size: var(--xh-number-field-trigger-font-size, var(--xh-_number-field-trigger-font-size));
155
+ /* 配方尚未把 profile 字形档灌进 --xh-icon-size,钮内字形先按 field-inset 档逐钮取值 */
156
+ --xh-icon-size: var(--xh-_action-profile-glyph-size);
157
+
158
+ border-width: 0;
159
+ }
160
+
161
+ /* DOM 顺序不承担视觉位置:既有用法即使把减钮写在 input 前面,默认仍统一收进右侧动作组。 */
162
+ .xh-scope-number-field[data-part='control'] [data-part='decrement-trigger']:where(.xh-scope-number-field) {
163
+ order: 1;
164
+ }
165
+
166
+ .xh-scope-number-field[data-part='control'] [data-part='increment-trigger']:where(.xh-scope-number-field) {
167
+ order: 2;
168
+ }
169
+
170
+ .xh-scope-number-field[data-part='control'] [data-part='increment-trigger'][hidden]:where(.xh-scope-number-field),
171
+ .xh-scope-number-field[data-part='control'] [data-part='decrement-trigger'][hidden]:where(.xh-scope-number-field) {
172
+ display: none;
173
+ }
174
+
175
+ /* 右侧动作组与输入之间的细线:把「按的」与「填的」分成两块。
176
+ 线不画在钮的边框上:边框会跟着钮的圆角与悬停底走,而这道线要独立于钮的各态,长度也短于钮自己。
177
+ ::before 已被兜底字形占着,::after 在粗指针下是家族给的 44px 热区,几何只能落在
178
+ background-image 上:一条 1px × 半高的渐变贴在逻辑起始侧,底色换态时它仍叠在上层。
179
+ 线只画在动作组第一颗减钮的逻辑起始侧;background-position 是物理轴,RTL 另给一条换边。 */
180
+ .xh-scope-number-field[data-part='control']:has([data-part='input']) [data-part='decrement-trigger']:where(.xh-scope-number-field) {
181
+ background-image: linear-gradient(
182
+ var(--xh-number-field-trigger-divider, var(--xh-material-soft-separator)),
183
+ var(--xh-number-field-trigger-divider, var(--xh-material-soft-separator))
184
+ );
185
+ background-repeat: no-repeat;
186
+ background-position: 0 50%;
187
+ background-size: var(--xh-stroke-thin) var(--xh-number-field-trigger-divider-h, var(--xh-_number-field-divider-h));
188
+ }
189
+
190
+ [dir='rtl'] .xh-scope-number-field[data-part='control']:has([data-part='input']) [data-part='decrement-trigger']:where(.xh-scope-number-field) {
191
+ background-position: 100% 50%;
192
+ }
193
+
194
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
195
+ .xh-scope-number-field[data-part='control'] [data-part='increment-trigger']:where(.xh-scope-number-field):empty::before {
196
+ content: '';
197
+ display: inline-block;
198
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
199
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
200
+ vertical-align: var(--xh-glyph-baseline-shift);
201
+ background-color: currentColor;
202
+ -webkit-mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
203
+ mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
204
+ }
205
+
206
+ .xh-scope-number-field[data-part='control'] [data-part='decrement-trigger']:where(.xh-scope-number-field):empty::before {
207
+ content: '';
208
+ display: inline-block;
209
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
210
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
211
+ vertical-align: var(--xh-glyph-baseline-shift);
212
+ background-color: currentColor;
213
+ -webkit-mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
214
+ mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
215
+ }
216
+
217
+ /* 高对比档整层丢弃 background-image,分隔线改用系统色重画,并关掉这一颗钮的强制换色 */
218
+ @media (forced-colors: active) {
219
+ .xh-scope-number-field[data-part='control']:has([data-part='input']) [data-part='decrement-trigger']:where(.xh-scope-number-field) {
220
+ background-image: linear-gradient(ButtonText, ButtonText);
221
+ forced-color-adjust: none;
222
+ }
223
+ }
224
+
225
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
226
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
227
+ .xh-scope-number-field[data-part='control'][hidden] {
228
+ display: none;
229
+ }
230
+
231
+ @media (forced-colors: active) {
232
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
233
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
234
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
235
+ 禁用取 GrayText */
236
+ .xh-scope-number-field[data-part='control'] [data-part='increment-trigger']:where(.xh-scope-number-field):empty::before,
237
+ .xh-scope-number-field[data-part='control'] [data-part='decrement-trigger']:where(.xh-scope-number-field):empty::before {
238
+ forced-color-adjust: none;
239
+ background-color: ButtonText;
240
+ }
241
+
242
+ .xh-scope-number-field[data-part='control'] [data-part='increment-trigger']:where(.xh-scope-number-field):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before,
243
+ .xh-scope-number-field[data-part='control'] [data-part='decrement-trigger']:where(.xh-scope-number-field):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
244
+ background-color: HighlightText;
245
+ }
246
+
247
+ .xh-scope-number-field[data-part='control'] [data-part='increment-trigger'][data-disabled]:where(.xh-scope-number-field):empty::before,
248
+ .xh-scope-number-field[data-part='control'] [data-part='decrement-trigger'][data-disabled]:where(.xh-scope-number-field):empty::before {
249
+ background-color: GrayText;
250
+ }
251
+ }
252
+ }
@@ -0,0 +1,56 @@
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
+ /*
7
+ * 浮层箭头的几何,八类浮层共用一份,只匹配这些组件自身的 arrow 部件。
8
+ *
9
+ * 箭头是正方形转 45°,构成尖角的是哪两条物理边,所以贴边与摘边框都写物理属性。
10
+ * 行内轴上的中心点仍写逻辑属性:定位引擎在 RTL 下已把 arrow-x 镜像成逻辑量。
11
+ *
12
+ * 底色与描边色留在各组件皮肤,它们同时把自己的内联落点槽接到这里的统一名字上。
13
+ * 引入顺序排在消费方皮肤之后;作用域使用 :where,维持原有特异性和摘边优先级。
14
+ */
15
+ @layer xihan.components {
16
+ :where(.xh-scope-context-menu, .xh-scope-hover-card, .xh-scope-menu, .xh-scope-menubar, .xh-scope-popconfirm, .xh-scope-popover, .xh-scope-tour, .xh-scope-tooltip)[data-part='arrow'] {
17
+ position: absolute;
18
+ inline-size: var(--xh-_overlay-arrow-size);
19
+ block-size: var(--xh-_overlay-arrow-size);
20
+ rotate: 45deg;
21
+ }
22
+
23
+ /* 浮层落在锚点下方:箭头贴 content 上缘,摘掉埋进 content 的下、右两条边 */
24
+ :where(.xh-scope-context-menu, .xh-scope-hover-card, .xh-scope-menu, .xh-scope-menubar, .xh-scope-popconfirm, .xh-scope-popover, .xh-scope-tour, .xh-scope-tooltip)[data-part='arrow'][data-placement^='bottom'] {
25
+ top: calc(var(--xh-_overlay-arrow-size) / -2);
26
+ inset-inline-start: calc(var(--xh-_overlay-arrow-x) - var(--xh-_overlay-arrow-size) / 2);
27
+ border-right: 0;
28
+ border-bottom: 0;
29
+ }
30
+
31
+ /* 浮层落在锚点上方:箭头贴 content 下缘,摘掉上、左两条边 */
32
+ :where(.xh-scope-context-menu, .xh-scope-hover-card, .xh-scope-menu, .xh-scope-menubar, .xh-scope-popconfirm, .xh-scope-popover, .xh-scope-tour, .xh-scope-tooltip)[data-part='arrow'][data-placement^='top'] {
33
+ bottom: calc(var(--xh-_overlay-arrow-size) / -2);
34
+ inset-inline-start: calc(var(--xh-_overlay-arrow-x) - var(--xh-_overlay-arrow-size) / 2);
35
+ border-top: 0;
36
+ border-left: 0;
37
+ }
38
+
39
+ /* 浮层落在锚点右侧:箭头贴 content 左缘,摘掉上、右两条边 */
40
+ :where(.xh-scope-context-menu, .xh-scope-hover-card, .xh-scope-menu, .xh-scope-menubar, .xh-scope-popconfirm, .xh-scope-popover, .xh-scope-tour, .xh-scope-tooltip)[data-part='arrow'][data-placement^='right'] {
41
+ top: calc(var(--xh-_overlay-arrow-y) - var(--xh-_overlay-arrow-size) / 2);
42
+ /* stylelint-disable-next-line property-disallowed-list -- 旋转是物理的,贴边跟着物理走 */
43
+ left: calc(var(--xh-_overlay-arrow-size) / -2);
44
+ border-top: 0;
45
+ border-right: 0;
46
+ }
47
+
48
+ /* 浮层落在锚点左侧:箭头贴 content 右缘,摘掉下、左两条边 */
49
+ :where(.xh-scope-context-menu, .xh-scope-hover-card, .xh-scope-menu, .xh-scope-menubar, .xh-scope-popconfirm, .xh-scope-popover, .xh-scope-tour, .xh-scope-tooltip)[data-part='arrow'][data-placement^='left'] {
50
+ top: calc(var(--xh-_overlay-arrow-y) - var(--xh-_overlay-arrow-size) / 2);
51
+ /* stylelint-disable-next-line property-disallowed-list -- 旋转是物理的,贴边跟着物理走 */
52
+ right: calc(var(--xh-_overlay-arrow-size) / -2);
53
+ border-bottom: 0;
54
+ border-left: 0;
55
+ }
56
+ }
@@ -0,0 +1,184 @@
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
+ /* 定义 page header 样式。 */
7
+
8
+ @layer xihan.components {
9
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
+ .xh-scope-page-header {
11
+ --xh-page-header-skin: 1;
12
+ }
13
+
14
+ .xh-scope-page-header[data-part='root'] {
15
+ /* 尺寸档只换这三个私有槽,各段从根上继承它们,换档不必给每个部件各写一条选择器 */
16
+ --xh-_page-header-py: var(--xh-space-4);
17
+ --xh-_page-header-row-gap: var(--xh-space-2);
18
+ --xh-_page-header-title-size: var(--xh-text-heading-3-size);
19
+ /* 形态档只换这两个:不画面的那一档左右不留内衬、也不切圆角 */
20
+ --xh-_page-header-px: 0;
21
+ --xh-_page-header-radius: 0;
22
+
23
+ /* 返回、媒体、标题区与操作区分列;标题与说明上下排列。 */
24
+ display: grid;
25
+ grid-auto-flow: dense;
26
+ grid-template-columns: auto auto minmax(0, 1fr) auto;
27
+ align-items: center;
28
+ row-gap: var(--xh-page-header-row-gap, var(--xh-_page-header-row-gap));
29
+ padding-block: var(--xh-page-header-py, var(--xh-_page-header-py));
30
+ padding-inline: var(--xh-page-header-px, var(--xh-_page-header-px));
31
+ border-radius: var(--xh-page-header-radius, var(--xh-_page-header-radius));
32
+ color: var(--xh-page-header-fg, var(--xh-fg-default));
33
+ }
34
+
35
+ /* 上面声明了 display,会盖掉 UA 的 [hidden] 规则,收起态要在这里接回来 */
36
+ .xh-scope-page-header[data-part='root'][hidden] {
37
+ display: none;
38
+ }
39
+
40
+ /* —— 尺寸 —— */
41
+ .xh-scope-page-header[data-part='root'][data-size='sm'] {
42
+ --xh-_page-header-py: var(--xh-space-3);
43
+ --xh-_page-header-row-gap: var(--xh-space-1);
44
+ --xh-_page-header-title-size: var(--xh-control-font-lg);
45
+ }
46
+
47
+ .xh-scope-page-header[data-part='root'][data-size='lg'] {
48
+ --xh-_page-header-py: var(--xh-space-6);
49
+ --xh-_page-header-row-gap: var(--xh-space-3);
50
+ --xh-_page-header-title-size: var(--xh-text-heading-2-size);
51
+ }
52
+
53
+ /* —— 分隔线 —— */
54
+ /* 只有贴底的 ghost 画这条下边线:一块切了圆角的面底下横一条直线,两头会露在圆角外面,
55
+ 有面的两档由自己的边界接手同一件事——把页头与下面的内容分开 */
56
+ .xh-scope-page-header[data-part='root'][data-variant='ghost'][data-split] {
57
+ border-block-end: var(--xh-stroke-thin) solid var(--xh-page-header-border, var(--xh-border-subtle));
58
+ }
59
+
60
+ /* —— 形态 —— */
61
+ /* ghost 不在这儿:它就是上面那套基础取值,贴在页面底色上不画面。
62
+ 画了面的两档左右补上与上下同档的内衬,否则内容会贴着那块面的边 */
63
+ .xh-scope-page-header[data-part='root']:is([data-variant='outline'], [data-variant='subtle']) {
64
+ --xh-_page-header-px: var(--xh-_page-header-py);
65
+ --xh-_page-header-radius: var(--xh-shape-surface);
66
+ }
67
+
68
+ /* outline 是一张静态内容面:--xh-border-default 描边撑住这块面的边界 + surface 底,不叠投影;
69
+ --xh-border-subtle 只作 ghost 贴底那条分隔线用,不当根面外边 */
70
+ .xh-scope-page-header[data-part='root'][data-variant='outline'] {
71
+ border: var(--xh-stroke-thin) solid var(--xh-page-header-border, var(--xh-border-default));
72
+ background: var(--xh-page-header-bg, var(--xh-bg-surface));
73
+ }
74
+
75
+ /* subtle 用淡底当边界:描边让位给底色但留住 1px 边位(与 outline 同一几何)、无影 */
76
+ .xh-scope-page-header[data-part='root'][data-variant='subtle'] {
77
+ border: var(--xh-stroke-thin) solid transparent;
78
+ background: var(--xh-page-header-bg, var(--xh-bg-subtle));
79
+ }
80
+
81
+ /* —— 各段 —— */
82
+ /* 面包屑占满一整行排在标题之上:它写在标记的最前面,整行铺开就把标题挤到了下一行 */
83
+ .xh-scope-page-header[data-part='breadcrumb'] {
84
+ grid-column: 1 / -1;
85
+ color: var(--xh-page-header-breadcrumb-fg, var(--xh-fg-muted));
86
+ font-size: var(--xh-page-header-breadcrumb-font-size, var(--xh-text-secondary-size));
87
+ line-height: var(--xh-leading-normal);
88
+ }
89
+
90
+ /* 头像 / 图标位:不参与伸缩,图形本身多大由作者定 */
91
+ .xh-scope-page-header[data-part='media'] {
92
+ grid-column: 2;
93
+ margin-inline-end: var(--xh-page-header-column-gap, var(--xh-space-3));
94
+ display: inline-flex;
95
+ align-items: center;
96
+ justify-content: center;
97
+ }
98
+
99
+ /* 返回位只摆位置与对齐,外观归作者自己的按钮 */
100
+ .xh-scope-page-header[data-part='back-trigger'] {
101
+ grid-column: 1;
102
+ margin-inline-end: var(--xh-page-header-column-gap, var(--xh-space-3));
103
+ display: inline-flex;
104
+ align-items: center;
105
+ justify-content: center;
106
+ }
107
+
108
+ .xh-scope-page-header[data-part='title'] {
109
+ grid-column: 3;
110
+ margin: 0;
111
+ /* 标题不参与伸缩,长过整行时收到行宽为止,中间没有断点的长串在行尾断开,
112
+ 不把整条页头撑出容器 */
113
+ max-inline-size: 100%;
114
+ overflow-wrap: anywhere;
115
+ color: var(--xh-page-header-title-fg, var(--xh-fg-default));
116
+ font-size: var(--xh-page-header-title-font-size, var(--xh-_page-header-title-size));
117
+ /* 页面级标题:字重走标题档令牌,不直接下探字重原语 */
118
+ font-weight: var(--xh-page-header-title-font-weight, var(--xh-text-heading-3-weight));
119
+ line-height: var(--xh-leading-tight);
120
+ }
121
+
122
+ /* 副标题吃掉标题与操作之间的剩余宽度,长文本在这里收窄换行 */
123
+ .xh-scope-page-header[data-part='description'] {
124
+ grid-column: 3;
125
+ margin: 0;
126
+ min-inline-size: 0;
127
+ color: var(--xh-page-header-description-fg, var(--xh-fg-muted));
128
+ font-size: var(--xh-page-header-description-font-size, var(--xh-text-secondary-size));
129
+ line-height: var(--xh-leading-normal);
130
+ }
131
+
132
+ /* 操作区贴到行尾,没有副标题占位时也一样靠边 */
133
+ .xh-scope-page-header[data-part='extra'] {
134
+ grid-column: 4;
135
+ display: flex;
136
+ flex-wrap: wrap;
137
+ align-items: center;
138
+ gap: var(--xh-page-header-extra-gap, var(--xh-space-2));
139
+ margin-inline-start: var(--xh-page-header-column-gap, var(--xh-space-3));
140
+ justify-self: end;
141
+ }
142
+
143
+ /* 页脚占满一整行,前面有内容时自然被挤到下一行 */
144
+ .xh-scope-page-header[data-part='footer'] {
145
+ grid-column: 1 / -1;
146
+ color: var(--xh-page-header-footer-fg, var(--xh-fg-muted));
147
+ font-size: var(--xh-page-header-footer-font-size, var(--xh-text-secondary-size));
148
+ line-height: var(--xh-leading-normal);
149
+ }
150
+
151
+ .xh-scope-page-header[data-part='root']:has(> [data-part='description'])
152
+ > :is([data-part='back-trigger'], [data-part='media'], [data-part='extra']):where(.xh-scope-page-header) {
153
+ grid-row: span 2;
154
+ }
155
+
156
+ /* 窄于 sm 断点时标题区占满第二列、操作区换到下一行。写成 min-width 的补集:640px 本身归宽档,
157
+ 与其余皮肤在同一宽度切换 */
158
+ @media not all and (min-width: 640px) {
159
+ .xh-scope-page-header[data-part='root'] {
160
+ grid-template-columns: auto minmax(0, 1fr);
161
+ }
162
+
163
+ .xh-scope-page-header[data-part='media'],
164
+ .xh-scope-page-header[data-part='title'],
165
+ .xh-scope-page-header[data-part='description'] {
166
+ grid-column: 2;
167
+ }
168
+
169
+ .xh-scope-page-header[data-part='root'] > [data-part='extra']:where(.xh-scope-page-header) {
170
+ grid-column: 1 / -1;
171
+ grid-row: auto;
172
+ margin-inline-start: 0;
173
+ justify-self: start;
174
+ }
175
+ }
176
+
177
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
178
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
179
+ .xh-scope-page-header[data-part='back-trigger'][hidden],
180
+ .xh-scope-page-header[data-part='media'][hidden],
181
+ .xh-scope-page-header[data-part='extra'][hidden] {
182
+ display: none;
183
+ }
184
+ }