@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
package/css/tree.css CHANGED
@@ -383,26 +383,88 @@
383
383
  }
384
384
 
385
385
  /*
386
- * 缩进参考线:每一层子节点的行首画一道竖线,对齐父节点展开箭头的中线,层级深时一眼看得出谁跟谁同层。
387
- * 线画在子层容器自己的伪元素上:定位在子层里,只贯穿这一层的全部子孙,不越出父节点的范围。
386
+ * 连接线:父节点展开箭头的中线向下引一道竖线,每个子节点从竖线横出一段接到自己行首(├),
387
+ * 最后一个子节点的竖线止于它那一行的中线(└),层级深时一眼看得出谁挂在谁下面。
388
+ * 线由每个子节点自己画:子节点的行画「这一段竖线 + 横出的那一段」,展开着的非末位分支再由它的子层
389
+ * 把竖线接过它整棵子树,交给下一个兄弟。子节点之间、分支行与子层之间的间距由线向上下伸出补齐,竖线不断开。
390
+ * 只画在竖排的子层里:顶层节点没有父节点可连,横排的末端层没有行首可接。
391
+ * 首个与末位子节点按子层里的结构次序认:子层里只放节点,收起的子树整块不显示、不影响次序。
388
392
  * 它是内部分隔的一种,颜色取 border-subtle;行悬停与选中换面时线压在面上照样看得见
389
393
  */
390
394
  [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'] {
391
395
  position: relative;
392
396
  }
393
397
 
394
- [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content']::before {
398
+ /* 竖线落在父节点展开箭头的中线上:父行的行首内边距加半个箭头盒,换算到缩进了一格的子节点坐标里。
399
+ 向上伸出的量补的是上方那段间距(首个子节点补分支行与子层之间的那段),向下补到下一个兄弟 */
400
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='item'],
401
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch'] > [data-scope='tree'][data-part='branch-control'] {
402
+ --xh-_tree-line-x: calc(
403
+ var(--xh-tree-row-px, var(--xh-_tree-row-px)) +
404
+ var(--xh-_tree-indicator-size) / 2 -
405
+ var(--xh-stroke-thin) / 2 -
406
+ var(--xh-tree-indent, var(--xh-_tree-indent))
407
+ );
408
+ --xh-_tree-line-top: 0px;
409
+ --xh-_tree-line-bottom: var(--xh-tree-branch-content-gap, var(--xh-list-option-gap));
410
+
411
+ position: relative;
412
+ }
413
+
414
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='item']:first-child,
415
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch']:first-child > [data-scope='tree'][data-part='branch-control'] {
416
+ --xh-_tree-line-top: var(--xh-tree-branch-gap, var(--xh-list-option-gap));
417
+ }
418
+
419
+ /* 展开着的非末位分支:行下面先是它自己的子层,竖线只伸到子层顶上,余下那段由子层接着画 */
420
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch'] > [data-scope='tree'][data-part='branch-control'][data-state='open'] {
421
+ --xh-_tree-line-bottom: var(--xh-tree-branch-gap, var(--xh-list-option-gap));
422
+ }
423
+
424
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='item']::before,
425
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch'] > [data-scope='tree'][data-part='branch-control']::before {
426
+ content: '';
427
+ position: absolute;
428
+ inset-block: calc(var(--xh-_tree-line-top) * -1) calc(var(--xh-_tree-line-bottom) * -1);
429
+ inset-inline-start: var(--xh-_tree-line-x);
430
+ /* 分支横出到展开箭头盒的起点;叶子没有箭头,横线穿过占位那一格接到正文前 */
431
+ inline-size: calc(var(--xh-tree-row-px, var(--xh-_tree-row-px)) - var(--xh-_tree-line-x));
432
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-tree-line-color, var(--xh-border-subtle));
433
+ /* 横出的那段落在行的中线:线盒上下伸出的量不对称时按差值的一半补回 */
434
+ background: linear-gradient(var(--xh-tree-line-color, var(--xh-border-subtle)), var(--xh-tree-line-color, var(--xh-border-subtle)))
435
+ 0 calc(50% + (var(--xh-_tree-line-top) - var(--xh-_tree-line-bottom)) / 2) / 100% var(--xh-stroke-thin) no-repeat;
436
+ pointer-events: none;
437
+ }
438
+
439
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='item']::before {
440
+ inline-size: calc(
441
+ var(--xh-tree-row-px, var(--xh-_tree-row-px)) +
442
+ var(--xh-_tree-indicator-size) -
443
+ var(--xh-_tree-line-x)
444
+ );
445
+ }
446
+
447
+ /* 最后一个子节点:竖线止于行的中线并在那里拐向行首(└),下面不再有兄弟要接 */
448
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='item']:last-child::before,
449
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch']:last-child > [data-scope='tree'][data-part='branch-control']::before {
450
+ inset-block-end: calc(50% - var(--xh-stroke-thin) / 2);
451
+ border-block-end: var(--xh-stroke-thin) solid var(--xh-tree-line-color, var(--xh-border-subtle));
452
+ background: none;
453
+ }
454
+
455
+ /* 展开着的非末位分支:它的子层把父节点那道竖线接过整棵子树,一直伸到下一个兄弟。
456
+ 子层的盒与分支同起点(缩进是子层自己的内边距),竖线位置与分支行里那一段相同 */
457
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch']:not(:last-child) > [data-scope='tree'][data-part='branch-content']::after {
395
458
  content: '';
396
459
  position: absolute;
397
- inset-block: 0;
398
- /* 父行的行首内边距加半个箭头盒:竖线正好落在父节点展开箭头的中线上 */
460
+ inset-block: 0 calc(var(--xh-tree-branch-content-gap, var(--xh-list-option-gap)) * -1);
399
461
  inset-inline-start: calc(
400
462
  var(--xh-tree-row-px, var(--xh-_tree-row-px)) +
401
463
  var(--xh-tree-indicator-size, var(--xh-_tree-indicator)) / 2 -
402
- var(--xh-stroke-thin) / 2
464
+ var(--xh-stroke-thin) / 2 -
465
+ var(--xh-tree-indent, var(--xh-_tree-indent))
403
466
  );
404
- inline-size: var(--xh-stroke-thin);
405
- background: var(--xh-tree-line-color, var(--xh-border-subtle));
467
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-tree-line-color, var(--xh-border-subtle));
406
468
  pointer-events: none;
407
469
  }
408
470
 
@@ -631,10 +693,18 @@
631
693
  }
632
694
  }
633
695
 
634
- /* 强制色:参考线是一块底色,系统色下会被抹成 Canvas;换成 GrayText 并只让这条线不参与强制换色 */
696
+ /* 强制色:连接线的横段是一块渐变底色、竖段是描边,系统色下一个被抹掉、一个被换成文字色;
697
+ 两段都写 GrayText,并只让连接线不参与强制换色 */
635
698
  @media (forced-colors: active) {
636
- [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content']::before {
637
- background: GrayText;
699
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='item']::before,
700
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch'] > [data-scope='tree'][data-part='branch-control']::before {
701
+ border-color: GrayText;
702
+ background-image: linear-gradient(GrayText, GrayText);
703
+ forced-color-adjust: none;
704
+ }
705
+
706
+ [data-scope='tree'][data-part='tree'][data-lines] [data-scope='tree'][data-part='branch-content'][data-orientation='vertical'] > [data-scope='tree'][data-part='branch'] > [data-scope='tree'][data-part='branch-content']::after {
707
+ border-color: GrayText;
638
708
  forced-color-adjust: none;
639
709
  }
640
710
  }
@@ -0,0 +1,269 @@
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
+ /* 定义 accordion 样式。 */
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-accordion {
16
+ --xh-accordion-skin: 1;
17
+ }
18
+
19
+ .xh-scope-accordion[data-part='root'] {
20
+ /* 作者塞进正文里的图标与皮肤画的兜底字形同一把尺:md 档,标题栏上另按家族档取值 */
21
+ --xh-icon-size: var(--xh-accordion-icon-size, var(--xh-glyph-size-md));
22
+
23
+ /* 尺寸档只换正文这两个私有槽,正文从 root 继承它们;标题栏的三档几何由家族 disclosure-trigger 档给 */
24
+ --xh-_accordion-content-px: var(--xh-space-4);
25
+ --xh-_accordion-content-pb: var(--xh-space-4);
26
+
27
+ /* 语气落在展开着的标题上,指示器写在标题里、跟着继承这个色,不另立规则。
28
+ 没写 data-tone 时 --xh-_tone-fg 没被声明,退回原来的前景色。
29
+ 聚焦环不在其列,它恒是 --xh-ring-focus */
30
+ --xh-_accordion-open-fg: var(--xh-_tone-fg, var(--xh-fg-default));
31
+
32
+ display: flex;
33
+ flex-direction: column;
34
+ inline-size: 100%;
35
+ contain: layout style;
36
+ }
37
+
38
+ .xh-scope-accordion[data-part='root'][data-orientation='horizontal'] {
39
+ flex-direction: row;
40
+ }
41
+
42
+ /* —— 尺寸 —— */
43
+ /* 缺省档写在上面的基础规则里 */
44
+ .xh-scope-accordion[data-part='root'][data-size='sm'] {
45
+ --xh-_accordion-content-px: var(--xh-space-3);
46
+ --xh-_accordion-content-pb: var(--xh-space-3);
47
+ }
48
+
49
+ .xh-scope-accordion[data-part='root'][data-size='lg'] {
50
+ --xh-_accordion-content-px: var(--xh-space-5);
51
+ --xh-_accordion-content-pb: var(--xh-space-5);
52
+ }
53
+
54
+ .xh-scope-accordion[data-part='item'] {
55
+ position: relative;
56
+ min-inline-size: 0;
57
+ }
58
+
59
+ /* 分隔线画在后一条的起始边,条与条之间才只有一条,末条也不会留一条悬空线
60
+ (根没有外框接住它)。只认自己的直接子条目:套在条目里的另一份手风琴由它自己的根管。
61
+ 横排时换成行内轴那一侧 */
62
+ .xh-scope-accordion[data-part='root']
63
+ > .xh-scope-accordion[data-part='item']
64
+ + .xh-scope-accordion[data-part='item'] {
65
+ border-block-start: var(--xh-stroke-thin) solid var(--xh-accordion-item-border, var(--xh-border-subtle));
66
+ }
67
+
68
+ .xh-scope-accordion[data-part='root'][data-orientation='horizontal']
69
+ > .xh-scope-accordion[data-part='item']
70
+ + .xh-scope-accordion[data-part='item'] {
71
+ border-block-start: 0;
72
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-accordion-item-border, var(--xh-border-subtle));
73
+ }
74
+
75
+ /* 作者显式渲染的分隔线。渲染了它,上面那条 item + item 的相邻规则就不再命中,
76
+ 两条线不会同时出现 */
77
+ .xh-scope-accordion[data-part='item-separator'] {
78
+ flex: none;
79
+ block-size: var(--xh-stroke-thin);
80
+ border: 0;
81
+ margin: 0;
82
+ background: var(--xh-accordion-item-border, var(--xh-border-subtle));
83
+ }
84
+
85
+ .xh-scope-accordion[data-part='item-separator'][hidden] {
86
+ display: none;
87
+ }
88
+
89
+ .xh-scope-accordion[data-part='root'][data-orientation='horizontal']
90
+ > .xh-scope-accordion[data-part='item-separator'] {
91
+ block-size: auto;
92
+ inline-size: var(--xh-stroke-thin);
93
+ }
94
+
95
+ /* —— 形态 —— */
96
+ /* ghost 档不在这儿:它就是上面那套基础取值,写不写 data-variant 都长一个样 */
97
+ /* 整份有了一块面,条与条之间就不再靠那条相邻边分开 */
98
+ .xh-scope-accordion[data-part='root']:is([data-variant='outline'], [data-variant='subtle'])
99
+ > .xh-scope-accordion[data-part='item']
100
+ + .xh-scope-accordion[data-part='item'] {
101
+ border-block-start: 0;
102
+ border-inline-start: 0;
103
+ }
104
+
105
+ /* outline:一张静态内容面,--xh-border-default 描边 + surface 底 + 无影(边界只由描边承担);
106
+ 根的外边走 --xh-accordion-border,与条与条之间的分隔线槽 --xh-accordion-item-border 各管各的 */
107
+ .xh-scope-accordion[data-part='root'][data-variant='outline'] {
108
+ border: var(--xh-stroke-thin) solid var(--xh-accordion-border, var(--xh-border-default));
109
+ border-radius: var(--xh-accordion-item-radius, var(--xh-shape-surface));
110
+ background: var(--xh-accordion-item-bg, var(--xh-bg-surface));
111
+ box-shadow: var(--xh-accordion-item-shadow, none);
112
+ overflow: clip;
113
+ }
114
+
115
+ /* subtle:同一块连续表面,底换成淡底,描边让位给底色但留住 1px 边位(三档几何一致);
116
+ 淡底承载面向标题栏下发 hover 200 → pressed 300 */
117
+ .xh-scope-accordion[data-part='root'][data-variant='subtle'] {
118
+ --xh-action-host-bg-hover: var(--xh-bg-subtle-hover);
119
+ --xh-action-host-bg-pressed: var(--xh-bg-subtle-active);
120
+
121
+ border: var(--xh-stroke-thin) solid transparent;
122
+ border-radius: var(--xh-accordion-item-radius, var(--xh-shape-surface));
123
+ background: var(--xh-accordion-item-bg, var(--xh-bg-subtle));
124
+ box-shadow: var(--xh-accordion-item-shadow, none);
125
+ overflow: clip;
126
+ }
127
+
128
+ .xh-scope-accordion[data-part='root']:is([data-variant='outline'], [data-variant='subtle'])
129
+ > .xh-scope-accordion[data-part='item']:not(:last-child)::after {
130
+ content: '';
131
+ position: absolute;
132
+ inset-inline: 3%;
133
+ inset-block-end: 0;
134
+ block-size: var(--xh-stroke-thin);
135
+ background: var(--xh-accordion-item-border, var(--xh-border-subtle));
136
+ pointer-events: none;
137
+ }
138
+
139
+ .xh-scope-accordion[data-part='header'] {
140
+ margin: 0;
141
+ font: inherit;
142
+ }
143
+
144
+ /* 标题栏铺满一行,盒型、三档几何、悬停 / 按下 / 禁用面由 Action Control 的 disclosure-trigger 档给
145
+ (ghost 形态:白底承载 hover 100 → pressed 200,淡底容器由根下发 host 槽;按下只换面不缩放);
146
+ 这里只把使用者槽映射到桥接槽:字色三态同值(家族的 hover / pressed 字色规则比皮肤更特定,不映射会被换回
147
+ 缺省字色),字形按标题栏自己的档位取 --xh-_action-profile-glyph-size;边归零贴住条目,几何与迁移前一致 */
148
+ .xh-scope-accordion[data-part='trigger'] {
149
+ --xh-action-gap: var(--xh-accordion-trigger-gap, var(--xh-_action-profile-gap));
150
+ --xh-action-visual-size: var(--xh-accordion-trigger-h, var(--xh-_action-profile-visual-size));
151
+ --xh-action-padding-block: var(--xh-accordion-trigger-py, var(--xh-_action-profile-padding-block));
152
+ --xh-action-padding-inline: var(--xh-accordion-trigger-px, var(--xh-_action-profile-padding-inline));
153
+ --xh-action-radius: var(--xh-accordion-trigger-radius, var(--xh-_action-profile-radius));
154
+ --xh-action-bg-rest: var(--xh-accordion-trigger-bg, var(--xh-_action-variant-bg-rest));
155
+ --xh-action-bg-hover: var(--xh-accordion-trigger-bg-hover, var(--xh-_action-variant-bg-hover));
156
+ --xh-action-fg-rest: var(--xh-accordion-trigger-fg, var(--xh-_action-variant-fg-rest));
157
+ --xh-action-fg-hover: var(--xh-accordion-trigger-fg, var(--xh-_action-variant-fg-hover));
158
+ --xh-action-fg-pressed: var(--xh-accordion-trigger-fg, var(--xh-_action-variant-fg-pressed));
159
+ --xh-action-font-size: var(--xh-accordion-trigger-font-size, var(--xh-_action-profile-font-size));
160
+ --xh-icon-size: var(--xh-accordion-icon-size, var(--xh-_action-profile-glyph-size));
161
+
162
+ border-width: 0;
163
+ font-weight: var(--xh-accordion-trigger-font-weight, var(--xh-text-label-weight));
164
+ }
165
+
166
+ /* 展开态自带一个槽:与常态共用一个的话,作者一改常态字色,
167
+ 展开那一档的语气高亮就跟着被抹平,再也分不开。悬停 / 按下的面与收起态同档(open 与家族 hover 同档中性) */
168
+ .xh-scope-accordion[data-part='trigger'][data-state='open'] {
169
+ --xh-action-fg-rest: var(--xh-accordion-trigger-fg-open, var(--xh-_accordion-open-fg));
170
+ --xh-action-fg-hover: var(--xh-accordion-trigger-fg-open, var(--xh-_accordion-open-fg));
171
+ --xh-action-fg-pressed: var(--xh-accordion-trigger-fg-open, var(--xh-_accordion-open-fg));
172
+ }
173
+
174
+ /* 禁用条目走 aria-disabled,仍留在 Tab 序里,只是不可操作;前景换成禁用色,不靠 opacity 压暗
175
+ (家族按 data-disabled 给禁用面与指针,字色槽在这里保留优先) */
176
+ .xh-scope-accordion[data-part='trigger'][data-disabled] {
177
+ --xh-action-fg-disabled: var(--xh-accordion-trigger-fg-disabled, var(--xh-_action-variant-fg-disabled));
178
+ }
179
+
180
+ .xh-scope-accordion[data-part='indicator'] {
181
+ display: inline-flex;
182
+ align-items: center;
183
+ justify-content: center;
184
+ flex: none;
185
+ color: var(--xh-accordion-indicator-fg, var(--xh-fg-muted));
186
+ line-height: var(--xh-leading-none);
187
+ }
188
+
189
+ /* 指示器与正文同档转向:收起时取 collapse 档,展开时(下面的打开态)取 expand 档。
190
+ 首帧就在的朝向直接呈现(data-instant),第一次开合起才转 */
191
+ .xh-scope-accordion[data-part='indicator']:not([data-instant]) {
192
+ transition: rotate var(--xh-motion-duration-collapse) var(--xh-motion-ease-enter-strong);
193
+ }
194
+
195
+ /* 没写内容就由皮肤画;作者往部件里塞了自己的图形,这条规则即不命中 */
196
+ .xh-scope-accordion[data-part='indicator']:empty::before {
197
+ content: '';
198
+ display: inline-block;
199
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
200
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
201
+ vertical-align: var(--xh-glyph-baseline-shift);
202
+ background-color: currentColor;
203
+ -webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
204
+ mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
205
+ }
206
+
207
+ .xh-scope-accordion[data-part='indicator'][data-state='open'] {
208
+ rotate: 180deg;
209
+ }
210
+
211
+ .xh-scope-accordion[data-part='indicator'][data-state='open']:not([data-instant]) {
212
+ transition: rotate var(--xh-motion-duration-expand) var(--xh-motion-ease-enter-strong);
213
+ }
214
+
215
+ /* 这里刻意没有 [data-part='content'][hidden] { display: none }:补了动画一帧都播不出来。
216
+ 收起由适配器在退场结束后写内联 display 落成,退场窗口内靠 connect 发的 inert 挡住焦点 */
217
+ .xh-scope-accordion[data-part='content'] {
218
+ /* 行高与内缩同帧动的共享关键帧读这条槽:只有末端有内缩,起端不写、按 0 动 */
219
+ --xh-_disclosure-pb: var(--xh-accordion-content-pb, var(--xh-_accordion-content-pb));
220
+
221
+ display: grid;
222
+ grid-template-rows: 1fr;
223
+ overflow: clip;
224
+ padding-block-start: 0;
225
+ padding-block-end: var(--xh-accordion-content-pb, var(--xh-_accordion-content-pb));
226
+ padding-inline: var(--xh-accordion-content-px, var(--xh-_accordion-content-px));
227
+ color: var(--xh-accordion-content-fg, var(--xh-fg-muted));
228
+ font-size: var(--xh-accordion-content-font-size, var(--xh-text-secondary-size));
229
+ line-height: var(--xh-leading-normal);
230
+ }
231
+
232
+ /* 展开与收起只在开合时播:首帧就在的展开 / 收起直接呈现(data-instant) */
233
+ .xh-scope-accordion[data-part='content'][data-state='open']:not([data-instant]) {
234
+ animation: xh-disclosure-expand var(--xh-motion-duration-expand) var(--xh-motion-ease-enter-strong);
235
+ }
236
+
237
+ .xh-scope-accordion[data-part='content'][data-state='closed']:not([data-instant]) {
238
+ animation: xh-disclosure-collapse var(--xh-motion-duration-collapse) var(--xh-motion-ease-exit) forwards;
239
+ }
240
+
241
+ @media (forced-colors: active) {
242
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
243
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
244
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
245
+ 禁用取 GrayText */
246
+ .xh-scope-accordion[data-part='indicator']:empty::before {
247
+ forced-color-adjust: none;
248
+ background-color: ButtonText;
249
+ }
250
+
251
+ .xh-scope-accordion[data-part='trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]) .xh-scope-accordion[data-part='indicator']:empty::before {
252
+ background-color: HighlightText;
253
+ }
254
+
255
+ .xh-scope-accordion[data-part='trigger'][data-disabled] .xh-scope-accordion[data-part='indicator']:empty::before {
256
+ background-color: GrayText;
257
+ }
258
+ }
259
+ }
260
+
261
+ @layer xihan.motion {
262
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
263
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
264
+ .xh-scope-accordion[data-part='root'][hidden],
265
+ .xh-scope-accordion[data-part='trigger'][hidden],
266
+ .xh-scope-accordion[data-part='indicator'][hidden] {
267
+ display: none;
268
+ }
269
+ }
@@ -0,0 +1,47 @@
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
+ /* 定义 affix 样式。 */
7
+
8
+ @layer xihan.components {
9
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
+ .xh-scope-affix {
11
+ --xh-affix-skin: 1;
12
+ }
13
+
14
+ /* 占位盒就是 content 在常规流里占的那块地方。
15
+ 这里不声明 display,也不写高度:吸住时冻结的高度由连接层量好写进内联样式(它量得到,样式表量不到),
16
+ 没吸住时高度就该跟着内容走。不给 display,UA 的 [hidden]{display:none} 也仍然压得住 */
17
+ .xh-scope-affix[data-part='root'] {
18
+ /* 脱流后 content 不再撑开占位盒,宽度改从父级取 */
19
+ inline-size: 100%;
20
+ }
21
+
22
+ /* 没吸住时是常规流里普通的一块,不做任何定位 */
23
+ .xh-scope-affix[data-part='content'] {
24
+ inline-size: 100%;
25
+ }
26
+
27
+ /*
28
+ * 吸住:脱离常规流钉在视口上。
29
+ * 四个落位数(top / bottom / left / width)由连接层写成内联样式——它们是照占位盒的矩形实测出来的
30
+ * 物理量,换成逻辑属性会在 RTL 下贴反。这里只管「用哪种定位、压在第几层」。
31
+ * 另一件必须提防的事:fixed 认的是视口,祖先上一旦出现
32
+ * transform / filter / backdrop-filter / contain,包含块就被抢走,钉住的内容立刻贴错位置——
33
+ * 所以别往覆盖钩子里加这几个属性。
34
+ */
35
+ .xh-scope-affix[data-part='content'][data-fixed] {
36
+ position: fixed;
37
+ z-index: var(--xh-affix-layer, var(--xh-layer-sticky));
38
+ }
39
+
40
+ @media print {
41
+ /* 打印:钉住的是作者自己的内容,不能收起;但保持 fixed 会让部分打印引擎每页重复一次,
42
+ 所以只把它放回正常流。 */
43
+ .xh-scope-affix[data-part='content'][data-fixed] {
44
+ position: static;
45
+ }
46
+ }
47
+ }