@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,374 @@
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
+ /* 定义 code view 样式。 */
7
+
8
+ /* 独立皮肤同时传递引入折叠条的动作控件配方;full bundle 递归去重。 */
9
+ @import '../family/action-control.css';
10
+
11
+ @layer xihan.components {
12
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
13
+ .xh-scope-code-view {
14
+ --xh-code-view-skin: 1;
15
+ }
16
+
17
+ /* 一张静态内容面:--xh-border-default 描边 + surface 底 + 无影(边界只由描边承担),
18
+ overflow: hidden 让内部 <pre> 的滚动内容沿圆角收边;不设 display,排布由作者决定。
19
+ color 给整段未着色的代码定基线,字号在这里消费一次,缺省即 md 档(与面内按钮同档)。 */
20
+ .xh-scope-code-view[data-part='root'] {
21
+ /* 尺寸缺省档:不写 data-size 时的取值。三档都只写这个私有槽,
22
+ 公开槽留在读处当首选,作者在祖先上设的覆盖才赢得过档位声明 */
23
+ --xh-_code-view-font-size: var(--xh-control-font-md);
24
+
25
+ overflow: hidden;
26
+ border: var(--xh-stroke-thin) solid var(--xh-code-view-border, var(--xh-border-default));
27
+ border-radius: var(--xh-code-view-radius, var(--xh-shape-surface));
28
+ background: var(--xh-code-view-bg, var(--xh-bg-surface));
29
+ box-shadow: var(--xh-code-view-shadow, none);
30
+ color: var(--xh-code-view-fg, var(--xh-fg-muted));
31
+ font-size: var(--xh-code-view-font-size, var(--xh-_code-view-font-size));
32
+ }
33
+
34
+ /* min-block-size 给头部条一个不随内容塌陷的定高:只放文件名时与放进按钮时一样高 */
35
+ .xh-scope-code-view[data-part='header'] {
36
+ display: flex;
37
+ min-block-size: var(--xh-code-view-header-h, var(--xh-control-h-lg));
38
+ align-items: center;
39
+ gap: var(--xh-code-view-header-gap, var(--xh-space-2));
40
+ padding-inline: var(--xh-code-view-header-px, var(--xh-space-4));
41
+ padding-block: var(--xh-code-view-header-py, var(--xh-space-2));
42
+ border-block-end: var(--xh-stroke-thin) solid var(--xh-code-view-header-border, var(--xh-border-subtle));
43
+ color: var(--xh-code-view-header-fg, var(--xh-fg-muted));
44
+ font-size: var(--xh-code-view-header-font-size, var(--xh-text-secondary-size));
45
+ line-height: var(--xh-leading-tight);
46
+ }
47
+
48
+ /* 上面声明的 display 会盖掉 UA 的 [hidden]{display:none},这里补回 */
49
+ .xh-scope-code-view[data-part='header'][hidden] {
50
+ display: none;
51
+ }
52
+
53
+ /* 文件名占满剩余宽度并单行截断:长路径不该把语言角标挤出去 */
54
+ .xh-scope-code-view[data-part='filename'] {
55
+ display: block;
56
+ overflow: hidden;
57
+ flex: 1 1 auto;
58
+ color: var(--xh-code-view-filename-fg, var(--xh-fg-default));
59
+ font-family: var(--xh-code-view-font, var(--xh-font-family-mono));
60
+ text-overflow: ellipsis;
61
+ white-space: nowrap;
62
+ }
63
+
64
+ .xh-scope-code-view[data-part='filename'][hidden] {
65
+ display: none;
66
+ }
67
+
68
+ /* user-select: none 让它不被框选带走 */
69
+ .xh-scope-code-view[data-part='lang-label'] {
70
+ display: block;
71
+ flex: 0 0 auto;
72
+ color: var(--xh-code-view-label-fg, var(--xh-fg-subtle));
73
+ font-size: var(--xh-code-view-label-font-size, var(--xh-text-caption-size));
74
+ line-height: var(--xh-leading-none);
75
+ user-select: none;
76
+ }
77
+
78
+ .xh-scope-code-view[data-part='lang-label'][hidden] {
79
+ display: none;
80
+ }
81
+
82
+ /* margin: 0 去掉 UA 给 <pre> 的默认外边距。
83
+ --xh-code-view-line-height 的兜底须与连接层内联 min-block-size 用的一致,
84
+ 且因参与 calc 乘法必须是长度而非无单位倍数。 */
85
+ .xh-scope-code-view[data-part='pre'] {
86
+ /* 逻辑属性 overflow-inline 尚无可用实现,写物理轴 */
87
+ overflow-x: auto;
88
+ padding-block: var(--xh-code-view-py, var(--xh-space-3));
89
+ margin: 0;
90
+ line-height: var(--xh-code-view-line-height, var(--xh-text-code-leading));
91
+ }
92
+
93
+ /* 折叠时 <pre> 的高度被连接层写死,超出部分沿圆角收边 */
94
+ .xh-scope-code-view[data-part='root'][data-clamped] [data-part='pre']:where(.xh-scope-code-view) {
95
+ overflow-y: hidden;
96
+ }
97
+
98
+ .xh-scope-code-view[data-part='code'] {
99
+ display: block;
100
+ font-family: var(--xh-code-view-font, var(--xh-font-family-mono));
101
+ }
102
+
103
+ .xh-scope-code-view[data-part='code'][hidden] {
104
+ display: none;
105
+ }
106
+
107
+ /* 一行是一个块:行号槽与正文并排,空行也要占满一行高 */
108
+ .xh-scope-code-view[data-part='line'] {
109
+ display: flex;
110
+ min-block-size: var(--xh-code-view-line-height, var(--xh-text-code-leading));
111
+ padding-inline-end: var(--xh-code-view-px, var(--xh-space-3));
112
+ /* 标出来的那几行换的是底色与那条内阴影色条,两样一起过渡才是同一个动作 */
113
+ transition:
114
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
115
+ box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
116
+ }
117
+
118
+ .xh-scope-code-view[data-part='line'][hidden] {
119
+ display: none;
120
+ }
121
+
122
+ /* 高亮行是强调不是选中:中性淡底 + 行首强调条,不用品牌淡底(品牌淡底只表达选中 / 当前) */
123
+ .xh-scope-code-view[data-part='line'][data-highlighted] {
124
+ background: var(--xh-code-view-highlight-bg, var(--xh-bg-subtle));
125
+ box-shadow: inset var(--xh-code-view-highlight-bar, var(--xh-stroke-thick)) 0 0 0 var(--xh-code-view-highlight-fg, var(--xh-border-strong));
126
+ }
127
+
128
+ /* 行号是画上去的不是写上去的:复制代码不带它,读屏也不逐行念数字。
129
+ 节点本身由适配器按 lineNumbers 决定渲不渲,槽宽按 root 上的位数枚举定,见下方 data-digits 各档。
130
+ 行与行之间无间隙,逐行的右边框首尾相接连成一条分隔线;行号比正文小一档、右对齐,多位数才齐。 */
131
+ .xh-scope-code-view[data-part='line-number'] {
132
+ display: block;
133
+ box-sizing: content-box;
134
+ flex: 0 0 auto;
135
+ padding-inline-start: var(--xh-code-view-px, var(--xh-space-3));
136
+ padding-inline-end: var(--xh-code-view-gutter-gap, var(--xh-space-1));
137
+ border-inline-end: var(--xh-stroke-thin) solid var(--xh-code-view-gutter-border, var(--xh-border-subtle));
138
+ color: var(--xh-code-view-number-fg, var(--xh-fg-subtle));
139
+ font-size: var(--xh-code-view-number-font-size, var(--xh-text-caption-size));
140
+ inline-size: var(--xh-_code-view-gutter);
141
+ text-align: end;
142
+ user-select: none;
143
+ }
144
+
145
+ .xh-scope-code-view[data-part='line-number']::before {
146
+ content: attr(data-line-number);
147
+ }
148
+
149
+ .xh-scope-code-view[data-part='line-number'][hidden] {
150
+ display: none;
151
+ }
152
+
153
+ /* white-space: pre 保留缩进不自动换行,长行改为横向滚动 */
154
+ .xh-scope-code-view[data-part='line-content'] {
155
+ display: block;
156
+ flex: 1 1 auto;
157
+ white-space: pre;
158
+ }
159
+
160
+ .xh-scope-code-view[data-part='line-content'][hidden] {
161
+ display: none;
162
+ }
163
+
164
+ /* 开了换行:pre-wrap 仍保留缩进与连续空白,只是允许行尾折下来;
165
+ anywhere 让没有空格的长串(url、base64)也能断,否则照样撑出横向滚动 */
166
+ .xh-scope-code-view[data-part='code'][data-wrap] [data-part='line-content']:where(.xh-scope-code-view) {
167
+ white-space: pre-wrap;
168
+ overflow-wrap: anywhere;
169
+ }
170
+
171
+ /* 没开行号时正文自带左内衬;开了行号则由行号槽的内衬顶开 */
172
+ .xh-scope-code-view[data-part='root']:not([data-line-numbers]) [data-part='line-content']:where(.xh-scope-code-view) {
173
+ padding-inline-start: var(--xh-code-view-px, var(--xh-space-3));
174
+ }
175
+
176
+ /* 行号槽宽按位数分档:连接层写不了 CSS 自定义属性,只能发 data-digits 让这里自己设 */
177
+ .xh-scope-code-view[data-part='root'] {
178
+ --xh-_code-view-gutter: 1ch;
179
+ }
180
+
181
+ .xh-scope-code-view[data-part='root'][data-digits='2'] {
182
+ --xh-_code-view-gutter: 2ch;
183
+ }
184
+
185
+ .xh-scope-code-view[data-part='root'][data-digits='3'] {
186
+ --xh-_code-view-gutter: 3ch;
187
+ }
188
+
189
+ .xh-scope-code-view[data-part='root'][data-digits='4'] {
190
+ --xh-_code-view-gutter: 4ch;
191
+ }
192
+
193
+ .xh-scope-code-view[data-part='root'][data-digits='5'] {
194
+ --xh-_code-view-gutter: 5ch;
195
+ }
196
+
197
+ .xh-scope-code-view[data-part='root'][data-digits='6'] {
198
+ --xh-_code-view-gutter: 6ch;
199
+ }
200
+
201
+ .xh-scope-code-view[data-part='root'][data-digits='7'] {
202
+ --xh-_code-view-gutter: 7ch;
203
+ }
204
+
205
+ /* 折叠条是铺满一行的 disclosure trigger,盒型、悬停与按下面由 Action Control 的 disclosure-trigger 档给
206
+ (ghost 形态:白底承载 hover 100 → pressed 200,按下只换面不缩放);这里只把使用者槽映射到
207
+ 桥接槽:圆角归零贴住卡边,内衬沿用代码区的横向内距与折叠条自己的纵向内距,字号与头部条同档。
208
+ 顶边是与头部条同一支的内部分隔线:配方按状态写 border-color 简写,四个状态的边色槽都映射到
209
+ 这支分隔色,再把四边宽归零、只留顶边一条 */
210
+ .xh-scope-code-view[data-part='fold-trigger'] {
211
+ --xh-action-radius: 0;
212
+ --xh-action-padding-inline: var(--xh-code-view-px, var(--xh-space-3));
213
+ --xh-action-padding-block: var(--xh-code-view-fold-py, var(--xh-space-2));
214
+ --xh-action-font-size: var(--xh-code-view-header-font-size, var(--xh-text-secondary-size));
215
+ --xh-action-fg-rest: var(--xh-code-view-fold-fg, var(--xh-fg-muted));
216
+ --xh-action-bg-hover: var(--xh-code-view-fold-bg-hover, var(--xh-_action-variant-bg-hover));
217
+ --xh-action-border-rest: var(--xh-code-view-header-border, var(--xh-border-subtle));
218
+ --xh-action-border-hover: var(--xh-code-view-header-border, var(--xh-border-subtle));
219
+ --xh-action-border-pressed: var(--xh-code-view-header-border, var(--xh-border-subtle));
220
+ --xh-action-border-focus-visible: var(--xh-code-view-header-border, var(--xh-border-subtle));
221
+
222
+ border-width: 0;
223
+ border-block-start-width: var(--xh-stroke-thin);
224
+ }
225
+
226
+ .xh-scope-code-view[data-part='fold-trigger'][hidden] {
227
+ display: none;
228
+ }
229
+
230
+ /* 按块折叠:每行正文都让出一列(一行高的正方格),块头的折叠钮定位在这一列里;
231
+ 没有钮的行也让,缩进才对得齐 */
232
+ .xh-scope-code-view[data-part='root'][data-block-folding] {
233
+ --xh-_code-view-fold-col: var(--xh-code-view-fold-col, var(--xh-code-view-line-height, var(--xh-text-code-leading)));
234
+ }
235
+
236
+ .xh-scope-code-view[data-part='root'][data-block-folding] [data-part='line-content']:where(.xh-scope-code-view) {
237
+ position: relative;
238
+ padding-inline-start: var(--xh-_code-view-fold-col);
239
+ }
240
+
241
+ .xh-scope-code-view[data-part='root'][data-block-folding]:not([data-line-numbers]) [data-part='line-content']:where(.xh-scope-code-view) {
242
+ padding-inline-start: calc(var(--xh-code-view-px, var(--xh-space-3)) + var(--xh-_code-view-fold-col));
243
+ }
244
+
245
+ /* 行首折叠钮是 disclosure trigger:接 Action Control icon 档、ghost 形态,边长压到一行高,
246
+ 按下只换面不缩放;静息取次级字色,不和正文抢 */
247
+ .xh-scope-code-view[data-part='line-fold-trigger'] {
248
+ --xh-action-visual-size: var(--xh-_code-view-fold-col);
249
+ --xh-action-min-inline-size: var(--xh-_code-view-fold-col);
250
+ --xh-action-radius: var(--xh-code-view-line-fold-trigger-radius, var(--xh-shape-control));
251
+ --xh-action-fg-rest: var(--xh-code-view-line-fold-trigger-fg, var(--xh-fg-subtle));
252
+ --xh-action-scale-pressed: none;
253
+ --xh-icon-size: var(--xh-code-view-icon-size, var(--xh-glyph-size-sm));
254
+
255
+ position: absolute;
256
+ inset-block-start: 0;
257
+ inset-inline-start: 0;
258
+ block-size: var(--xh-_code-view-fold-col);
259
+ }
260
+
261
+ .xh-scope-code-view[data-part='root'][data-block-folding]:not([data-line-numbers]) [data-part='line-fold-trigger']:where(.xh-scope-code-view) {
262
+ inset-inline-start: var(--xh-code-view-px, var(--xh-space-3));
263
+ }
264
+
265
+ .xh-scope-code-view[data-part='line-fold-trigger'][hidden] {
266
+ display: none;
267
+ }
268
+
269
+ /* 展开时朝下;收起时转向行尾那一侧(RTL 跟着换向) */
270
+ .xh-scope-code-view[data-part='line-fold-trigger']::before {
271
+ content: '';
272
+ display: block;
273
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
274
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
275
+ background-color: currentColor;
276
+ -webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
277
+ mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
278
+ transition: rotate var(--xh-motion-duration-expand) var(--xh-motion-ease-enter-strong);
279
+ }
280
+
281
+ .xh-scope-code-view[data-part='line-fold-trigger'][data-state='closed']::before {
282
+ rotate: calc(-90deg * var(--xh-direction-sign));
283
+ transition-duration: var(--xh-motion-duration-collapse);
284
+ }
285
+
286
+ /* 折叠着的块头:正文后面一枚省略号,示意下面收起了几行;画上去的,复制不带它 */
287
+ .xh-scope-code-view[data-part='line-content'][data-folded]::after {
288
+ content: '';
289
+ display: inline-block;
290
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
291
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
292
+ margin-inline-start: var(--xh-code-view-folded-gap, var(--xh-space-1));
293
+ vertical-align: var(--xh-glyph-baseline-shift);
294
+ background-color: var(--xh-code-view-folded-fg, var(--xh-fg-subtle));
295
+ -webkit-mask: var(--xh-glyph-mark-ellipsis) center / contain no-repeat;
296
+ mask: var(--xh-glyph-mark-ellipsis) center / contain no-repeat;
297
+ }
298
+
299
+ /* 尺寸档写私有槽、由 root 基础规则消费一次:缺省与阶梯是同一个口子,
300
+ 作者设的 --xh-code-view-font-size 排在读处首选,不会被这三条盖掉。
301
+ 行号槽宽以 ch 计,随字号一起走 */
302
+ .xh-scope-code-view[data-part='root'][data-size='sm'] {
303
+ --xh-_code-view-font-size: var(--xh-control-font-sm);
304
+ }
305
+
306
+ .xh-scope-code-view[data-part='root'][data-size='md'] {
307
+ --xh-_code-view-font-size: var(--xh-control-font-md);
308
+ }
309
+
310
+ .xh-scope-code-view[data-part='root'][data-size='lg'] {
311
+ --xh-_code-view-font-size: var(--xh-control-font-lg);
312
+ }
313
+
314
+ /* 记号本身不带任何布局,只上色:它是行内片段,多一点盒模型都会破坏对齐 */
315
+ .xh-scope-code-view[data-part='token'][data-kind='comment'] {
316
+ color: var(--xh-code-view-comment-fg, var(--xh-fg-muted));
317
+ font-style: italic;
318
+ }
319
+
320
+ .xh-scope-code-view[data-part='token'][data-kind='string'] {
321
+ color: var(--xh-code-view-string-fg, var(--xh-syntax-string));
322
+ }
323
+
324
+ .xh-scope-code-view[data-part='token'][data-kind='number'] {
325
+ color: var(--xh-code-view-number-token-fg, var(--xh-syntax-number));
326
+ }
327
+
328
+ .xh-scope-code-view[data-part='token'][data-kind='keyword'] {
329
+ color: var(--xh-code-view-keyword-fg, var(--xh-syntax-keyword));
330
+ font-weight: var(--xh-code-view-keyword-weight, var(--xh-font-weight-semibold));
331
+ }
332
+
333
+ .xh-scope-code-view[data-part='token'][data-kind='punctuation'] {
334
+ color: var(--xh-code-view-punctuation-fg, var(--xh-fg-subtle));
335
+ }
336
+
337
+ /*
338
+ * 打印:标出来的那几行只有一层淡底加一条写在 inset 阴影上的实心条,
339
+ * 底多数打印机丢掉、投影本就不该上纸,标了哪几行在纸上完全读不出来。
340
+ * 改画一圈内收的实边把那几行框出来。用 outline 不用 border:
341
+ * 行是横排 flex,加边会把行号与正文一起往里推,没标的行不加边就对不齐了。
342
+ */
343
+ @media print {
344
+ .xh-scope-code-view[data-part='line'][data-highlighted] {
345
+ outline: var(--xh-code-view-highlight-bar, var(--xh-stroke-thick)) solid currentColor;
346
+ outline-offset: calc(-1 * var(--xh-code-view-highlight-bar, var(--xh-stroke-thick)));
347
+ }
348
+ }
349
+
350
+ @media (forced-colors: active) {
351
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
352
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
353
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
354
+ 落在 Canvas 面上的取 CanvasText;
355
+ 禁用取 GrayText */
356
+ .xh-scope-code-view[data-part='line-fold-trigger']::before {
357
+ forced-color-adjust: none;
358
+ background-color: ButtonText;
359
+ }
360
+
361
+ .xh-scope-code-view[data-part='line-content'][data-folded]::after {
362
+ forced-color-adjust: none;
363
+ background-color: CanvasText;
364
+ }
365
+
366
+ .xh-scope-code-view[data-part='line-fold-trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed])::before {
367
+ background-color: HighlightText;
368
+ }
369
+
370
+ .xh-scope-code-view[data-part='line-fold-trigger'][data-disabled]::before {
371
+ background-color: GrayText;
372
+ }
373
+ }
374
+ }
@@ -0,0 +1,185 @@
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
+ /* 定义 collapsible 样式。 */
7
+
8
+ /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立;
9
+ 独立皮肤同时传递引入触发器的动作控件配方,full bundle 递归去重。 */
10
+ @import '../family/motion.css';
11
+ @import '../family/action-control.css';
12
+
13
+ @layer xihan.components {
14
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
15
+ .xh-scope-collapsible {
16
+ --xh-collapsible-skin: 1;
17
+ }
18
+
19
+ /* 根容器自己不排版,这条只声明尺寸档的私有槽:正文与标题行从 root 继承它们,
20
+ 换档不必给部件各写一条选择器;触发器的三档几何由家族 disclosure-trigger 档给 */
21
+ .xh-scope-collapsible[data-part='root'] {
22
+ /* 作者塞进正文里的图标与皮肤画的兜底字形同一把尺:md 档,触发器上另按家族档取值 */
23
+ --xh-icon-size: var(--xh-collapsible-icon-size, var(--xh-glyph-size-md));
24
+
25
+ --xh-_collapsible-trigger-gap: var(--xh-control-gap-md);
26
+ --xh-_collapsible-content-px: var(--xh-space-4);
27
+ --xh-_collapsible-content-pb: var(--xh-space-4);
28
+
29
+ /* 语气落在展开着的触发器上,指示器写在触发器里、跟着继承这个色,不另立规则。
30
+ 没写 data-tone 时 --xh-_tone-fg 没被声明,退回原来的前景色。
31
+ 聚焦环不在其列,它恒是 --xh-ring-focus */
32
+ --xh-_collapsible-open-fg: var(--xh-_tone-fg, var(--xh-fg-default));
33
+ }
34
+
35
+ /* 触发器与其同排内容住的那一行;触发器自己已经是整行宽,这里只负责把两者摆平 */
36
+ .xh-scope-collapsible[data-part='header'] {
37
+ display: flex;
38
+ align-items: center;
39
+ gap: var(--xh-collapsible-header-gap, var(--xh-_collapsible-trigger-gap));
40
+ inline-size: 100%;
41
+ }
42
+
43
+ .xh-scope-collapsible[data-part='header'][hidden] {
44
+ display: none;
45
+ }
46
+
47
+ /* —— 尺寸 —— */
48
+ /* 缺省档写在上面那条里 */
49
+ .xh-scope-collapsible[data-part='root'][data-size='sm'] {
50
+ --xh-_collapsible-trigger-gap: var(--xh-control-gap-sm);
51
+ --xh-_collapsible-content-px: var(--xh-space-3);
52
+ --xh-_collapsible-content-pb: var(--xh-space-3);
53
+ }
54
+
55
+ .xh-scope-collapsible[data-part='root'][data-size='lg'] {
56
+ --xh-_collapsible-trigger-gap: var(--xh-control-gap-lg);
57
+ --xh-_collapsible-content-px: var(--xh-space-5);
58
+ --xh-_collapsible-content-pb: var(--xh-space-5);
59
+ }
60
+
61
+ /* 触发器铺满一行,盒型、三档几何、悬停 / 按下 / 禁用面由 Action Control 的 disclosure-trigger 档给
62
+ (ghost 形态:根无壳,按画布承载 hover 100 → pressed 200;按下只换面不缩放);
63
+ 这里只把使用者槽映射到桥接槽:字色三态同值(家族的 hover / pressed 字色规则比皮肤更特定,不映射会被换回
64
+ 缺省字色),字形按触发器自己的档位取 --xh-_action-profile-glyph-size;边归零贴住标题行,几何与迁移前一致 */
65
+ .xh-scope-collapsible[data-part='trigger'] {
66
+ --xh-action-gap: var(--xh-collapsible-trigger-gap, var(--xh-_action-profile-gap));
67
+ --xh-action-visual-size: var(--xh-collapsible-trigger-h, var(--xh-_action-profile-visual-size));
68
+ --xh-action-padding-block: var(--xh-collapsible-trigger-py, var(--xh-_action-profile-padding-block));
69
+ --xh-action-padding-inline: var(--xh-collapsible-trigger-px, var(--xh-_action-profile-padding-inline));
70
+ --xh-action-radius: var(--xh-collapsible-trigger-radius, var(--xh-_action-profile-radius));
71
+ --xh-action-bg-rest: var(--xh-collapsible-trigger-bg, var(--xh-_action-variant-bg-rest));
72
+ --xh-action-bg-hover: var(--xh-collapsible-trigger-bg-hover, var(--xh-_action-variant-bg-hover));
73
+ --xh-action-fg-rest: var(--xh-collapsible-trigger-fg, var(--xh-_action-variant-fg-rest));
74
+ --xh-action-fg-hover: var(--xh-collapsible-trigger-fg, var(--xh-_action-variant-fg-hover));
75
+ --xh-action-fg-pressed: var(--xh-collapsible-trigger-fg, var(--xh-_action-variant-fg-pressed));
76
+ --xh-action-font-size: var(--xh-collapsible-trigger-font-size, var(--xh-_action-profile-font-size));
77
+ --xh-icon-size: var(--xh-collapsible-icon-size, var(--xh-_action-profile-glyph-size));
78
+
79
+ border-width: 0;
80
+ font-weight: var(--xh-collapsible-trigger-font-weight, var(--xh-text-label-weight));
81
+ }
82
+
83
+ /* 展开着的那一档单开一个槽:与常态共用一个的话,作者一改常态字色就把展开态也改掉了。
84
+ 悬停 / 按下的面与收起态同档(open 与家族 hover 同档中性) */
85
+ .xh-scope-collapsible[data-part='trigger'][data-state='open'] {
86
+ --xh-action-fg-rest: var(--xh-collapsible-trigger-fg-open, var(--xh-_collapsible-open-fg));
87
+ --xh-action-fg-hover: var(--xh-collapsible-trigger-fg-open, var(--xh-_collapsible-open-fg));
88
+ --xh-action-fg-pressed: var(--xh-collapsible-trigger-fg-open, var(--xh-_collapsible-open-fg));
89
+ }
90
+
91
+ /* 禁用前景换成禁用色,不靠 opacity 压暗(家族按 data-disabled 给禁用面与指针,字色槽在这里保留优先) */
92
+ .xh-scope-collapsible[data-part='trigger'][data-disabled] {
93
+ --xh-action-fg-disabled: var(--xh-collapsible-trigger-fg-disabled, var(--xh-_action-variant-fg-disabled));
94
+ }
95
+
96
+ /* 开合方向的标记,排在触发器行尾(触发器是 space-between 两端对齐) */
97
+ .xh-scope-collapsible[data-part='indicator'] {
98
+ display: inline-flex;
99
+ flex: none;
100
+ align-items: center;
101
+ justify-content: center;
102
+ color: var(--xh-collapsible-indicator-fg, var(--xh-fg-muted));
103
+ line-height: var(--xh-leading-none);
104
+ }
105
+
106
+ /* 指示器与正文同档转向:收起时取 collapse 档,展开时(下面的打开态)取 expand 档。
107
+ 首帧就在的朝向直接呈现(data-instant),第一次开合起才转 */
108
+ .xh-scope-collapsible[data-part='indicator']:not([data-instant]) {
109
+ transition: rotate var(--xh-motion-duration-collapse) var(--xh-motion-ease-enter-strong);
110
+ }
111
+
112
+ /* 没写内容就由皮肤画;作者往部件里塞了自己的图形,这条规则即不命中 */
113
+ .xh-scope-collapsible[data-part='indicator']:empty::before {
114
+ content: '';
115
+ display: inline-block;
116
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
117
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
118
+ vertical-align: var(--xh-glyph-baseline-shift);
119
+ background-color: currentColor;
120
+ -webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
121
+ mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
122
+ }
123
+
124
+ .xh-scope-collapsible[data-part='indicator'][data-state='open'] {
125
+ rotate: 180deg;
126
+ }
127
+
128
+ .xh-scope-collapsible[data-part='indicator'][data-state='open']:not([data-instant]) {
129
+ transition: rotate var(--xh-motion-duration-expand) var(--xh-motion-ease-enter-strong);
130
+ }
131
+
132
+ /* 这里刻意没有 [data-part='content'][hidden] { display: none }:补了动画一帧都播不出来。
133
+ 收起由适配器在退场结束后写内联 display 落成,退场窗口内靠 connect 发的 inert 挡住焦点 */
134
+ .xh-scope-collapsible[data-part='content'] {
135
+ /* 行高与内缩同帧动的共享关键帧读这条槽:只有末端有内缩,起端不写、按 0 动 */
136
+ --xh-_disclosure-pb: var(--xh-collapsible-content-pb, var(--xh-_collapsible-content-pb));
137
+
138
+ display: grid;
139
+ grid-template-rows: 1fr;
140
+ overflow: clip;
141
+ padding-block-start: 0;
142
+ padding-block-end: var(--xh-collapsible-content-pb, var(--xh-_collapsible-content-pb));
143
+ padding-inline: var(--xh-collapsible-content-px, var(--xh-_collapsible-content-px));
144
+ color: var(--xh-collapsible-content-fg, var(--xh-fg-muted));
145
+ font-size: var(--xh-collapsible-content-font-size, var(--xh-text-secondary-size));
146
+ line-height: var(--xh-leading-normal);
147
+ }
148
+
149
+ /* 展开与收起只在开合时播:首帧就在的展开 / 收起直接呈现(data-instant) */
150
+ .xh-scope-collapsible[data-part='content'][data-state='open']:not([data-instant]) {
151
+ animation: xh-disclosure-expand var(--xh-motion-duration-expand) var(--xh-motion-ease-enter-strong);
152
+ }
153
+
154
+ .xh-scope-collapsible[data-part='content'][data-state='closed']:not([data-instant]) {
155
+ animation: xh-disclosure-collapse var(--xh-motion-duration-collapse) var(--xh-motion-ease-exit) forwards;
156
+ }
157
+
158
+ @media (forced-colors: active) {
159
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
160
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
161
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
162
+ 禁用取 GrayText */
163
+ .xh-scope-collapsible[data-part='indicator']:empty::before {
164
+ forced-color-adjust: none;
165
+ background-color: ButtonText;
166
+ }
167
+
168
+ .xh-scope-collapsible[data-part='trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]) .xh-scope-collapsible[data-part='indicator']:empty::before {
169
+ background-color: HighlightText;
170
+ }
171
+
172
+ .xh-scope-collapsible[data-part='trigger'][data-disabled] .xh-scope-collapsible[data-part='indicator']:empty::before {
173
+ background-color: GrayText;
174
+ }
175
+ }
176
+ }
177
+
178
+ @layer xihan.motion {
179
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
180
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
181
+ .xh-scope-collapsible[data-part='trigger'][hidden],
182
+ .xh-scope-collapsible[data-part='indicator'][hidden] {
183
+ display: none;
184
+ }
185
+ }