@xihan-ui/styles 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/CHANGELOG.md +5146 -6
  2. package/README.md +22 -2
  3. package/component-tokens.d.ts +4212 -0
  4. package/component-tokens.js +2 -0
  5. package/components.tokens.json +80116 -0
  6. package/css/accordion.css +131 -75
  7. package/css/affix.css +16 -1
  8. package/css/alert.css +114 -67
  9. package/css/anchor.css +99 -27
  10. package/css/approval.css +461 -0
  11. package/css/avatar-group.css +14 -6
  12. package/css/avatar.css +33 -9
  13. package/css/back-top.css +103 -48
  14. package/css/badge.css +42 -14
  15. package/css/bar-code.css +62 -0
  16. package/css/breadcrumb.css +40 -21
  17. package/css/button-group.css +146 -24
  18. package/css/button.css +116 -99
  19. package/css/calendar-picker.css +448 -0
  20. package/css/calendar-range-picker.css +517 -0
  21. package/css/card.css +54 -77
  22. package/css/carousel.css +412 -68
  23. package/css/cascader.css +429 -246
  24. package/css/checkbox-group.css +225 -77
  25. package/css/checkbox.css +174 -37
  26. package/css/clipboard.css +266 -47
  27. package/css/code-view.css +279 -0
  28. package/css/collapsible.css +108 -63
  29. package/css/color-field.css +158 -0
  30. package/css/color-picker.css +172 -184
  31. package/css/color-slider.css +274 -0
  32. package/css/color-swatch-picker.css +243 -0
  33. package/css/color-swatch.css +35 -0
  34. package/css/combobox.css +267 -273
  35. package/css/command.css +399 -0
  36. package/css/context-menu.css +183 -108
  37. package/css/date-field.css +94 -121
  38. package/css/date-picker.css +486 -249
  39. package/css/date-range-picker.css +559 -0
  40. package/css/description.css +51 -0
  41. package/css/descriptions.css +133 -87
  42. package/css/dialog.css +247 -68
  43. package/css/diff-view.css +428 -0
  44. package/css/download-trigger.css +155 -46
  45. package/css/drawer.css +194 -111
  46. package/css/editable.css +172 -152
  47. package/css/empty-state.css +80 -11
  48. package/css/field-array.css +190 -0
  49. package/css/field.css +84 -31
  50. package/css/fieldset.css +51 -18
  51. package/css/file-upload.css +134 -36
  52. package/css/flex.css +20 -1
  53. package/css/float-button.css +238 -57
  54. package/css/floating-panel.css +173 -92
  55. package/css/focus.css +46 -0
  56. package/css/forced-colors.css +93 -0
  57. package/css/form.css +254 -77
  58. package/css/gradient-text.css +34 -10
  59. package/css/grid.css +516 -5
  60. package/css/heatmap.css +87 -29
  61. package/css/highlight.css +20 -5
  62. package/css/hover-card.css +97 -47
  63. package/css/icon-wrapper.css +15 -3
  64. package/css/icon.css +74 -8
  65. package/css/image-cropper.css +143 -29
  66. package/css/image-viewer.css +150 -89
  67. package/css/image.css +30 -1
  68. package/css/infinite-scroll.css +51 -1
  69. package/css/input-group.css +277 -0
  70. package/css/json-viewer.css +102 -45
  71. package/css/kbd.css +72 -0
  72. package/css/label.css +78 -0
  73. package/css/layers.css +5 -0
  74. package/css/layout.css +175 -31
  75. package/css/list.css +24 -3
  76. package/css/listbox.css +208 -67
  77. package/css/loading-bar.css +52 -3
  78. package/css/log.css +144 -9
  79. package/css/markdown-stream.css +149 -0
  80. package/css/marquee.css +27 -1
  81. package/css/masonry.css +7 -0
  82. package/css/matrix-code.css +67 -0
  83. package/css/mention.css +234 -152
  84. package/css/menu.css +180 -83
  85. package/css/menubar.css +204 -136
  86. package/css/message-feed.css +197 -0
  87. package/css/navigation-menu.css +144 -90
  88. package/css/notification.css +178 -100
  89. package/css/number-animation.css +7 -0
  90. package/css/number-field.css +120 -277
  91. package/css/overlay-arrow.css +12 -7
  92. package/css/page-header.css +99 -14
  93. package/css/pagination.css +175 -135
  94. package/css/password-input.css +222 -219
  95. package/css/pin-input.css +101 -67
  96. package/css/pointer.css +36 -0
  97. package/css/popconfirm.css +185 -94
  98. package/css/popover.css +121 -77
  99. package/css/progress.css +60 -12
  100. package/css/prompt-input.css +224 -0
  101. package/css/question-flow.css +513 -0
  102. package/css/radio-group.css +147 -30
  103. package/css/rating.css +193 -43
  104. package/css/reasoning.css +336 -0
  105. package/css/reset.css +84 -6
  106. package/css/resizable.css +237 -0
  107. package/css/scroll-area.css +68 -7
  108. package/css/scrollbar.css +47 -13
  109. package/css/segmented.css +94 -29
  110. package/css/select.css +288 -274
  111. package/css/separator.css +101 -1
  112. package/css/side-nav.css +133 -75
  113. package/css/signature-pad.css +74 -54
  114. package/css/skeleton.css +84 -11
  115. package/css/slider.css +132 -39
  116. package/css/sortable.css +198 -0
  117. package/css/spinner.css +126 -12
  118. package/css/splitter.css +29 -8
  119. package/css/statistic.css +55 -0
  120. package/css/steps.css +206 -72
  121. package/css/switch.css +268 -36
  122. package/css/table.css +695 -118
  123. package/css/tabs.css +604 -42
  124. package/css/tag-group.css +219 -0
  125. package/css/tag.css +118 -28
  126. package/css/tags-input.css +156 -274
  127. package/css/text-field.css +101 -249
  128. package/css/time-field.css +100 -128
  129. package/css/time-picker.css +323 -252
  130. package/css/time-range-picker.css +719 -0
  131. package/css/timeline.css +202 -68
  132. package/css/timer.css +56 -52
  133. package/css/timestamp.css +34 -0
  134. package/css/toast.css +373 -144
  135. package/css/toggle-group.css +309 -76
  136. package/css/toggle.css +116 -85
  137. package/css/tone.css +47 -0
  138. package/css/tool-call.css +421 -0
  139. package/css/toolbar.css +181 -33
  140. package/css/tooltip.css +107 -36
  141. package/css/tour.css +183 -152
  142. package/css/transfer.css +351 -138
  143. package/css/tree-select.css +323 -216
  144. package/css/tree.css +294 -62
  145. package/css/truncate.css +65 -0
  146. package/css/typography.css +228 -5
  147. package/css/undefined.css +10 -1
  148. package/css/virtualizer.css +9 -10
  149. package/css/visually-hidden.css +7 -0
  150. package/css/watermark.css +7 -0
  151. package/family/action-control.css +487 -0
  152. package/family/collection-item.css +721 -0
  153. package/family/field-chrome.css +298 -0
  154. package/family/motion.css +166 -0
  155. package/family/swatch.css +59 -0
  156. package/index.css +41705 -126
  157. package/index.unlayered.css +33692 -17339
  158. package/package.json +51 -17
  159. package/css/calendar.css +0 -367
  160. package/css/code-block.css +0 -91
  161. package/css/composer.css +0 -134
  162. package/css/countdown.css +0 -26
  163. package/css/dynamic-input.css +0 -220
  164. package/css/ellipsis.css +0 -52
  165. package/css/hotkeys.css +0 -90
  166. package/css/popselect.css +0 -391
  167. package/css/qr-code.css +0 -55
  168. package/css/result.css +0 -119
  169. package/css/space.css +0 -117
  170. package/css/thread.css +0 -120
  171. package/css/time.css +0 -25
@@ -1,3 +1,10 @@
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
+ /* 定义 avatar group 样式。 */
7
+
1
8
  @layer xihan.components {
2
9
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
10
  [data-scope='avatar-group'] {
@@ -5,7 +12,8 @@
5
12
  }
6
13
 
7
14
  /* 一排叠放的头像:后一枚压在前一枚上。
8
- 组内共用的直径与字号在容器上写一次,沿继承流给每一枚;自己写了档位的那一枚仍按自己的档走 */
15
+ 组内共用的直径与字号在容器上写一次,沿继承流给每一枚——包括自己写了档位的那一枚,
16
+ 它的档位取值也读这两个槽,整排因此始终齐平。单独摆的头像取不到这两个槽,仍按自己的档走 */
9
17
  [data-scope='avatar-group'][data-part='root'] {
10
18
  /* 组件内那几档层号只在自己人之间排序:建一个层叠上下文把它们关起来,
11
19
  既不让页面上的层号插进来,也不让它们漏出去压住别人 */
@@ -69,23 +77,23 @@
69
77
 
70
78
  /* —— 溢出计数 —— */
71
79
  /* 「+N」是这一排里的又一枚:直径、形状与字号跟着组走,里面写什么由作者定 */
72
- [data-scope='avatar-group'][data-part='overflow'] {
80
+ [data-scope='avatar-group'][data-part='overflow-item'] {
73
81
  display: inline-flex;
74
82
  flex: none;
75
83
  align-items: center;
76
84
  justify-content: center;
77
85
  inline-size: var(--xh-_avatar-group-size);
78
86
  block-size: var(--xh-_avatar-group-size);
79
- border-radius: var(--xh-avatar-group-radius, var(--xh-shape-pill));
80
- background: var(--xh-avatar-group-overflow-bg, var(--xh-bg-muted));
81
- color: var(--xh-avatar-group-overflow-fg, var(--xh-fg-muted));
87
+ border-radius: var(--xh-avatar-group-radius, var(--xh-shape-circle));
88
+ background: var(--xh-avatar-group-overflow-item-bg, var(--xh-bg-muted));
89
+ color: var(--xh-avatar-group-overflow-item-fg, var(--xh-fg-muted));
82
90
  font-size: var(--xh-_avatar-group-font-size);
83
91
  font-weight: var(--xh-avatar-group-font-weight, var(--xh-font-weight-medium));
84
92
  line-height: var(--xh-leading-none);
85
93
  user-select: none;
86
94
  }
87
95
 
88
- [data-scope='avatar-group'][data-part='overflow'][hidden] {
96
+ [data-scope='avatar-group'][data-part='overflow-item'][hidden] {
89
97
  display: none;
90
98
  }
91
99
  }
package/css/avatar.css CHANGED
@@ -1,3 +1,13 @@
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
+ /* 定义 avatar 样式。 */
7
+
8
+ /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
9
+ @import '../family/motion.css';
10
+
1
11
  @layer xihan.components {
2
12
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
13
  [data-scope='avatar'] {
@@ -13,7 +23,7 @@
13
23
  overflow: hidden;
14
24
  inline-size: var(--xh-avatar-size, var(--xh-control-h-md));
15
25
  block-size: var(--xh-avatar-size, var(--xh-control-h-md));
16
- border-radius: var(--xh-avatar-radius, var(--xh-shape-pill));
26
+ border-radius: var(--xh-avatar-radius, var(--xh-shape-circle));
17
27
  background: var(--xh-avatar-bg, var(--xh-bg-subtle));
18
28
  color: var(--xh-avatar-fg, var(--xh-fg-muted));
19
29
  font-size: var(--xh-avatar-font-size, var(--xh-text-secondary-size));
@@ -23,25 +33,39 @@
23
33
  }
24
34
 
25
35
  /* 三档尺寸对齐控件档位,缺省档写在上面的基础规则里;
26
- 字号跟着一起缩放,回退字才在小头像里放得下、在大头像里不显小 */
36
+ 字号跟着一起缩放,回退字才在小头像里放得下、在大头像里不显小。
37
+ 每一档都把 --xh-avatar-size / --xh-avatar-font-size 排在自己的档值前面:这两个槽是
38
+ 外层统一整排头像的通道,档值直接写终值的话,写了 data-size 的那一枚就脱离外层控制 */
27
39
  [data-scope='avatar'][data-part='root'][data-size='sm'] {
28
- inline-size: var(--xh-control-h-sm);
29
- block-size: var(--xh-control-h-sm);
30
- font-size: var(--xh-control-caption-sm);
40
+ inline-size: var(--xh-avatar-size, var(--xh-control-h-sm));
41
+ block-size: var(--xh-avatar-size, var(--xh-control-h-sm));
42
+ font-size: var(--xh-avatar-font-size, var(--xh-control-caption-sm));
31
43
  }
32
44
 
33
45
  [data-scope='avatar'][data-part='root'][data-size='lg'] {
34
- inline-size: var(--xh-control-h-lg);
35
- block-size: var(--xh-control-h-lg);
36
- font-size: var(--xh-control-caption-lg);
46
+ inline-size: var(--xh-avatar-size, var(--xh-control-h-lg));
47
+ block-size: var(--xh-avatar-size, var(--xh-control-h-lg));
48
+ font-size: var(--xh-avatar-font-size, var(--xh-control-caption-lg));
49
+ }
50
+
51
+ /* —— 语气 ——
52
+ 头像只有「淡底 + 字/图」一种形态,所以语气只换淡底与字色这一档,不开形态轴。
53
+ 两条声明都把 --xh-avatar-bg / --xh-avatar-fg 排在语气值前面:使用者槽仍是最外那一层,
54
+ 写了 tone 的那一枚照样受外层统一控制。整块带 [data-tone] 限定,没写语气的头像逐值不变 */
55
+ [data-scope='avatar'][data-part='root'][data-tone] {
56
+ background: var(--xh-avatar-bg, var(--xh-_tone-subtle, var(--xh-bg-subtle)));
57
+ color: var(--xh-avatar-fg, var(--xh-_tone-fg, var(--xh-fg-muted)));
37
58
  }
38
59
 
39
- /* 不声明 display,加载完成前的 hidden 直接交给浏览器的 [hidden] 规则收起 */
60
+ /* 不声明 display,加载完成前的 hidden 直接交给浏览器的 [hidden] 规则收起。
61
+ 载完那一刻 hidden 撤掉、这个节点从不显示变为显示,淡入在那一刻起跑,
62
+ 图片不是硬切上来盖掉回退字 */
40
63
  [data-scope='avatar'][data-part='image'] {
41
64
  inline-size: 100%;
42
65
  block-size: 100%;
43
66
  border-radius: inherit;
44
67
  object-fit: cover;
68
+ animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
45
69
  }
46
70
 
47
71
  [data-scope='avatar'][data-part='fallback'] {
package/css/back-top.css CHANGED
@@ -1,3 +1,12 @@
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
+ /* 定义 back top 样式。 */
7
+
8
+ @import '../family/action-control.css';
9
+
1
10
  @layer xihan.components {
2
11
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
12
  [data-scope='back-top'] {
@@ -7,67 +16,106 @@
7
16
  /* 定位壳:钉在视口的尾下角,用逻辑属性,RTL 下自动换到另一侧。
8
17
  不声明 display —— 收起态由连接层写 hidden,UA 的 [hidden]{display:none} 得压得住 */
9
18
  [data-scope='back-top'][data-part='root'] {
10
- /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
11
- --xh-icon-size: var(--xh-back-top-icon-size, var(--xh-glyph-size-text));
12
-
13
- /* 尺寸档只换这一个私有槽,按钮从壳继承,换档不必给每个部件各写一条选择器 */
14
- --xh-_back-top-size: var(--xh-control-h-md);
15
-
16
19
  position: fixed;
17
- inset-block-end: var(--xh-back-top-inset-block, var(--xh-space-8));
18
- inset-inline-end: var(--xh-back-top-inset-inline, var(--xh-space-8));
20
+ /* 贴边与安全区取大的一头:底部横条与圆角压住的那一段由系统给出,贴边比它窄时钮会被切掉一角。
21
+ 桌面上 env() 恒为 0,取值与贴边槽完全一致。安全区只有物理方向的名字,
22
+ 行内轴上两侧同取较宽的那一段,RTL 下不会翻错边。 */
23
+ inset-block-end: max(var(--xh-back-top-inset-block, var(--xh-space-8)), env(safe-area-inset-bottom));
24
+ inset-inline-end: max(
25
+ var(--xh-back-top-inset-inline, var(--xh-space-8)),
26
+ env(safe-area-inset-left),
27
+ env(safe-area-inset-right)
28
+ );
19
29
  z-index: var(--xh-back-top-layer, var(--xh-layer-sticky));
20
30
  }
21
31
 
22
- /* —— 尺寸 —— */
23
- [data-scope='back-top'][data-part='root'][data-size='sm'] {
24
- --xh-_back-top-size: var(--xh-control-h-sm);
25
- }
26
-
27
- [data-scope='back-top'][data-part='root'][data-size='lg'] {
28
- --xh-_back-top-size: var(--xh-control-h-lg);
32
+ /* —— 形态:缺省 outline 的磨砂面 ——
33
+ 触发器接 Action Control floating 档,solid / subtle / ghost 的面由形态矩阵按 data-xh-action-variant 给;
34
+ 缺省 outline(连接层不传 variant 时显式落)与悬浮动作钮同属 M2 磨砂面:背景、边缘、顶光、投影与磨砂
35
+ 从一份配方取,高对比、减少透明度、打印和强制色才能沿同一令牌通道降级。钮浮在正文之上,透空的面在
36
+ 任何内容上都读不出边界,所以 outline 这一档面留着。三支私有槽写在壳上:check-elevation-role 按赋值点
37
+ 认海拔角色,float-button 同款 */
38
+ [data-scope='back-top'][data-part='root'][data-variant='outline'] {
39
+ --xh-_back-top-bg: var(--xh-material-frosted-bg);
40
+ --xh-_back-top-fg: var(--xh-material-frosted-fg);
41
+ --xh-_back-top-border: var(--xh-material-frosted-border);
42
+ --xh-_back-top-shadow: var(--xh-material-frosted-shadow);
29
43
  }
30
44
 
31
- /* 圆形按钮:里面通常只放一个箭头图标,宽高同取一档尺寸 */
45
+ /* —— 触发器 ——
46
+ 浮在内容之上的单图标圆钮,接 Action Control floating 档(§4.1):盒型(md = box-lg 48px,圆形)、
47
+ 四态面、0.97 按压与 44px 命中区由家族配方按 data-xh-action-variant / -size 给出。
48
+ 这里只把公开槽桥接到矩阵之前(使用者槽 → 形态矩阵 → 家族缺省)与几何槽映射。
49
+ 整件只有这一颗按钮,槽名与其余一样不带部件段(照 float-button 的 --xh-float-button-size) */
32
50
  [data-scope='back-top'][data-part='trigger'] {
33
- display: inline-flex;
34
- align-items: center;
35
- justify-content: center;
36
- inline-size: var(--xh-back-top-trigger-size, var(--xh-_back-top-size));
37
- block-size: var(--xh-back-top-trigger-size, var(--xh-_back-top-size));
38
- padding: 0;
39
- border: var(--xh-stroke-thin) solid var(--xh-back-top-border, var(--xh-border-control));
40
- border-radius: var(--xh-back-top-radius, var(--xh-shape-pill));
41
- /* 使用者令牌排在语气之前:写了覆盖钩子就以它为准,没写才退到语气,最后才是中性缺省 */
42
- background: var(--xh-back-top-bg, var(--xh-bg-surface-raised));
43
- color: var(--xh-back-top-fg, var(--xh-_tone-fg, var(--xh-fg-default)));
44
- /* 浮在内容之上,靠投影与页面拉开层次 */
45
- box-shadow: var(--xh-back-top-shadow, var(--xh-elevation-sheet));
46
- cursor: pointer;
47
- transition:
48
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
49
- border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
51
+ --xh-action-bg-rest: var(--xh-back-top-bg, var(--xh-_action-variant-bg-rest));
52
+ --xh-action-bg-hover: var(--xh-back-top-bg-hover, var(--xh-_action-variant-bg-hover));
53
+ --xh-action-bg-pressed: var(--xh-back-top-bg-active, var(--xh-_action-variant-bg-pressed));
54
+ --xh-action-bg-focus-visible: var(--xh-back-top-bg, var(--xh-_action-variant-bg-focus-visible));
55
+ --xh-action-bg-disabled: var(--xh-back-top-bg, var(--xh-_action-variant-bg-disabled));
56
+ --xh-action-fg-rest: var(--xh-back-top-fg, var(--xh-_action-variant-fg-rest));
57
+ --xh-action-fg-hover: var(--xh-back-top-fg, var(--xh-_action-variant-fg-hover));
58
+ --xh-action-fg-pressed: var(--xh-back-top-fg, var(--xh-_action-variant-fg-pressed));
59
+ --xh-action-fg-focus-visible: var(--xh-back-top-fg, var(--xh-_action-variant-fg-focus-visible));
60
+ --xh-action-border-rest: var(--xh-back-top-border, var(--xh-_action-variant-border-rest));
61
+ --xh-action-border-hover: var(--xh-back-top-border-hover, var(--xh-_action-variant-border-hover));
62
+ --xh-action-border-pressed: var(--xh-back-top-border-hover, var(--xh-_action-variant-border-pressed));
63
+ --xh-action-border-focus-visible: var(--xh-back-top-border, var(--xh-_action-variant-border-focus-visible));
64
+ --xh-action-border-disabled: var(--xh-back-top-border, var(--xh-_action-variant-border-disabled));
65
+ /* 矩阵各态无影(§8.3 淡底与阴影互斥);outline 那一档的磨砂投影在下面另桥接 */
66
+ --xh-action-shadow-rest: var(--xh-back-top-shadow, none);
67
+ --xh-action-shadow-hover: var(--xh-back-top-shadow, none);
68
+ --xh-action-shadow-pressed: var(--xh-back-top-shadow, none);
69
+ --xh-action-shadow-focus-visible: var(--xh-back-top-shadow, none);
70
+ --xh-action-shadow-disabled: var(--xh-back-top-shadow, none);
71
+ --xh-action-radius: var(--xh-back-top-radius, var(--xh-_action-profile-radius));
72
+ --xh-action-visual-size: var(--xh-back-top-size, var(--xh-_action-profile-visual-size));
73
+ /* 作者塞进来的图标跟着 floating 档走(md 24px),与皮肤画的兜底字形同一把尺 */
74
+ --xh-icon-size: var(--xh-back-top-icon-size, var(--xh-_action-profile-glyph-size));
50
75
  }
51
76
 
52
- /* 悬停只在能用指针的设备上生效,触摸端不留一个按不掉的悬停态 */
53
- @media (hover: hover) {
54
- [data-scope='back-top'][data-part='trigger']:hover {
55
- border-color: var(--xh-back-top-border-hover, var(--xh-border-control-hover));
56
- background: var(--xh-back-top-bg-hover, var(--xh-bg-subtle-hover));
57
- }
58
- }
77
+ /* 缺省 outline 是 M2 磨砂面:背景、边缘、顶光、投影与磨砂从同一份配方取。
78
+ 悬停 / 按下的底走矩阵 outline 列的画布阶梯(100 → 200),边缘与投影不动;
79
+ 键盘聚焦时铺配方的实体 focus surface——透明面上的内收环不能依赖页面底色;
80
+ 置灰只换字色(矩阵 disabled 列的前景),面仍留着 */
81
+ [data-scope='back-top'][data-part='root'][data-variant='outline']
82
+ [data-scope='back-top'][data-part='trigger'] {
83
+ --xh-action-bg-rest: var(--xh-back-top-bg, var(--xh-_back-top-bg));
84
+ --xh-action-bg-focus-visible: var(--xh-back-top-bg, var(--xh-material-frosted-focus-surface));
85
+ --xh-action-bg-disabled: var(--xh-back-top-bg, var(--xh-_back-top-bg));
86
+ --xh-action-fg-rest: var(--xh-back-top-fg, var(--xh-_back-top-fg));
87
+ --xh-action-fg-hover: var(--xh-back-top-fg, var(--xh-_back-top-fg));
88
+ --xh-action-fg-pressed: var(--xh-back-top-fg, var(--xh-_back-top-fg));
89
+ --xh-action-fg-focus-visible: var(--xh-back-top-fg, var(--xh-_back-top-fg));
90
+ --xh-action-border-rest: var(--xh-back-top-border, var(--xh-_back-top-border));
91
+ --xh-action-border-hover: var(--xh-back-top-border-hover, var(--xh-_back-top-border));
92
+ --xh-action-border-pressed: var(--xh-back-top-border-hover, var(--xh-_back-top-border));
93
+ --xh-action-border-focus-visible: var(--xh-back-top-border, var(--xh-_back-top-border));
94
+ --xh-action-border-disabled: var(--xh-back-top-border, var(--xh-_back-top-border));
95
+ --xh-action-shadow-rest: var(--xh-back-top-shadow, var(--xh-_back-top-shadow));
96
+ --xh-action-shadow-hover: var(--xh-back-top-shadow, var(--xh-_back-top-shadow));
97
+ --xh-action-shadow-pressed: var(--xh-back-top-shadow, var(--xh-_back-top-shadow));
98
+ --xh-action-shadow-focus-visible: var(--xh-back-top-shadow, var(--xh-_back-top-shadow));
99
+ --xh-action-shadow-disabled: var(--xh-back-top-shadow, var(--xh-_back-top-shadow));
100
+ /* M2 顶光走配方的高光通道:实心、淡色与透空形态各有自身表面,不能把磨砂高光误铺上去 */
101
+ --xh-action-highlight-rest: var(--xh-material-frosted-highlight);
102
+ --xh-action-highlight-hover: var(--xh-material-frosted-highlight);
103
+ --xh-action-highlight-pressed: var(--xh-material-frosted-highlight);
104
+ --xh-action-highlight-focus-visible: var(--xh-material-frosted-highlight);
105
+ --xh-action-highlight-disabled: var(--xh-material-frosted-highlight);
59
106
 
60
- [data-scope='back-top'][data-part='trigger']:active {
61
- background: var(--xh-back-top-bg-active, var(--xh-bg-subtle-active));
107
+ -webkit-backdrop-filter: var(--xh-material-frosted-backdrop);
108
+ backdrop-filter: var(--xh-material-frosted-backdrop);
62
109
  }
63
110
 
64
- /* 聚焦环恒是 --xh-ring-focus,不随语气走 */
65
- [data-scope='back-top'][data-part='trigger']:focus-visible {
66
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
67
- outline-offset: var(--xh-ring-offset);
111
+ /* 面是实心的,环色与面同族,画在面里就看不出来;环改取面自己的前景色——
112
+ 那一族色本来就要在这块面上把字读清楚,与面的对比是按可读性定的 */
113
+ [data-scope='back-top'][data-part='trigger'][data-xh-action-variant='solid']:focus-visible {
114
+ --xh-action-ring-color-focus-visible: currentColor;
68
115
  }
69
116
 
70
- /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
117
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中。
118
+ 粗指针的 44px 命中区由配方的 ::after 给,字形占的是 ::before */
71
119
  [data-scope='back-top'][data-part='trigger']:empty::before {
72
120
  content: '';
73
121
  display: inline-block;
@@ -79,9 +127,16 @@
79
127
  mask: var(--xh-glyph-mark-chevron-up) center / contain no-repeat;
80
128
  }
81
129
 
82
- /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
130
+ /* 配方声明过 display,会盖掉 UA 的 [hidden]{display:none},收起态得自己还回去。
83
131
  写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
84
132
  [data-scope='back-top'][data-part='trigger'][hidden] {
85
133
  display: none;
86
134
  }
135
+
136
+ @media print {
137
+ /* 打印:回到顶部这颗钮只有在能滚的地方才成立,落到纸上是一颗按不动的按钮。 */
138
+ [data-scope='back-top'][data-part='root'] {
139
+ display: none;
140
+ }
141
+ }
87
142
  }
package/css/badge.css CHANGED
@@ -1,3 +1,10 @@
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
+ /* 定义 badge 样式。 */
7
+
1
8
  @layer xihan.components {
2
9
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
10
  [data-scope='badge'] {
@@ -25,7 +32,7 @@
25
32
  /* 每一档的盒都要大于字号:两位数在等高的盒里会被撑破。
26
33
  字号刻度最小就是 12px,所以往上抬盒子而不是往下压字 */
27
34
  --xh-_badge-dot: var(--xh-space-2);
28
- --xh-_badge-min: var(--xh-space-5);
35
+ --xh-_badge-min: var(--xh-space-7);
29
36
  --xh-_badge-px: var(--xh-space-1);
30
37
  --xh-_badge-font: var(--xh-text-secondary-size);
31
38
 
@@ -41,8 +48,8 @@
41
48
  border: var(--xh-stroke-thin) solid var(--xh-badge-ring, var(--xh-bg-surface));
42
49
  border-radius: var(--xh-badge-radius, var(--xh-shape-pill));
43
50
  /* 角标默认就是实心的:贴在别的东西上,淡底与描边都看不清 */
44
- background: var(--xh-badge-bg, var(--xh-_tone, var(--xh-bg-brand)));
45
- color: var(--xh-badge-fg, var(--xh-_tone-on, var(--xh-fg-on-brand)));
51
+ background: var(--xh-badge-bg, var(--xh-_tone));
52
+ color: var(--xh-badge-fg, var(--xh-_tone-on));
46
53
  font-size: var(--xh-badge-font-size, var(--xh-_badge-font));
47
54
  font-weight: var(--xh-badge-font-weight, var(--xh-font-weight-medium));
48
55
  line-height: var(--xh-leading-none);
@@ -58,12 +65,17 @@
58
65
  display: none;
59
66
  }
60
67
 
61
- /* 圆点形态:只表示「有」,不表示「有几个」——收掉内边距与文字盒 */
68
+ /* 圆点形态:只表示「有」,不表示「有几个」——收掉内边距与文字盒。
69
+ 宽高同槽的正方盒按身份取 circle(§6.3),不沿用计数档的胶囊冒充圆:
70
+ 胶囊那 9999px 在正方盒上虽也画成圆,形状身份却写错了档,作者按圆点覆盖圆角时无处落手。
71
+ 圆点直径只有六到十像素,一像素的内高光会占去顶上一大截、读成缺了一圈的描边,这里收掉 */
62
72
  [data-scope='badge'][data-part='indicator'][data-dot] {
63
73
  min-inline-size: var(--xh-badge-dot-size, var(--xh-_badge-dot));
64
74
  inline-size: var(--xh-badge-dot-size, var(--xh-_badge-dot));
65
75
  block-size: var(--xh-badge-dot-size, var(--xh-_badge-dot));
76
+ border-radius: var(--xh-badge-dot-radius, var(--xh-shape-circle));
66
77
  padding: 0;
78
+ box-shadow: none;
67
79
  font-size: 0;
68
80
  }
69
81
 
@@ -72,56 +84,72 @@
72
84
  [data-scope='badge'][data-part='indicator'][data-placement='top-end'] {
73
85
  inset-block-start: 0;
74
86
  inset-inline-end: 0;
75
- translate: 50% -50%;
87
+ translate: 25% -25%;
76
88
  }
77
89
 
78
90
  [data-scope='badge'][data-part='indicator'][data-placement='top-start'] {
79
91
  inset-block-start: 0;
80
92
  inset-inline-start: 0;
81
- translate: -50% -50%;
93
+ translate: -25% -25%;
82
94
  }
83
95
 
84
96
  [data-scope='badge'][data-part='indicator'][data-placement='bottom-end'] {
85
97
  inset-block-end: 0;
86
98
  inset-inline-end: 0;
87
- translate: 50% 50%;
99
+ translate: 25% 25%;
88
100
  }
89
101
 
90
102
  [data-scope='badge'][data-part='indicator'][data-placement='bottom-start'] {
91
103
  inset-block-end: 0;
92
104
  inset-inline-start: 0;
93
- translate: -50% 50%;
105
+ translate: -25% 25%;
94
106
  }
95
107
 
96
108
  /* rtl 下 translate 的行内轴要跟着翻,否则角标会往宿主外面跑 */
97
109
  [dir='rtl'] [data-scope='badge'][data-part='indicator'][data-placement='top-end'] {
98
- translate: -50% -50%;
110
+ translate: -25% -25%;
99
111
  }
100
112
 
101
113
  [dir='rtl'] [data-scope='badge'][data-part='indicator'][data-placement='top-start'] {
102
- translate: 50% -50%;
114
+ translate: 25% -25%;
103
115
  }
104
116
 
105
117
  [dir='rtl'] [data-scope='badge'][data-part='indicator'][data-placement='bottom-end'] {
106
- translate: -50% 50%;
118
+ translate: -25% 25%;
107
119
  }
108
120
 
109
121
  [dir='rtl'] [data-scope='badge'][data-part='indicator'][data-placement='bottom-start'] {
110
- translate: 50% 50%;
122
+ translate: 25% 25%;
111
123
  }
112
124
 
113
125
  /* —— 尺寸 —— */
126
+ /* 小号是贴在 16px 图标角上的角标:盒取 12 + 2 的半阶补偿 = 14px,字仍是刻度最小的 12px——
127
+ 数字的字面只占字号的六成,扣掉两道 1px 描边后的 12px 内高装得下两位数,再小就得压字 */
114
128
  [data-scope='badge'][data-part='indicator'][data-size='sm'] {
115
129
  --xh-_badge-dot: var(--xh-space-1_5);
116
- --xh-_badge-min: var(--xh-space-4);
130
+ --xh-_badge-min: calc(var(--xh-space-3) + var(--xh-space-0_5));
117
131
  --xh-_badge-px: var(--xh-space-0_5);
118
132
  --xh-_badge-font: var(--xh-text-caption-size);
119
133
  }
120
134
 
121
135
  [data-scope='badge'][data-part='indicator'][data-size='lg'] {
122
136
  --xh-_badge-dot: var(--xh-space-2_5);
123
- --xh-_badge-min: var(--xh-space-6);
137
+ --xh-_badge-min: var(--xh-space-8);
124
138
  --xh-_badge-px: var(--xh-space-1_5);
125
139
  --xh-_badge-font: var(--xh-text-body-size);
126
140
  }
141
+
142
+ /*
143
+ * 打印:底色被丢掉。计数档配的是实心底上的前景色,底一没那串数字就印不出来;
144
+ * 圆点档整个由底色画成,底一没连位置都看不见。
145
+ * 两档都改由描边承载:常态那圈边是衬在宿主上的隔离环,取的是面色,纸上同样是白的,
146
+ * 这里换成正文色——计数成了一枚描边药丸,圆点成了一个小圈。
147
+ */
148
+ @media print {
149
+ [data-scope='badge'][data-part='indicator'] {
150
+ border-color: currentColor;
151
+ color: var(--xh-fg-default);
152
+ box-shadow: none;
153
+ }
154
+ }
127
155
  }
@@ -0,0 +1,62 @@
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
+ /* 定义 bar code 样式。 */
7
+
8
+ @layer xihan.components {
9
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
+ [data-scope='bar-code'] {
11
+ --xh-bar-code-skin: 1;
12
+ }
13
+
14
+ /*
15
+ * 根 <svg>。深浅两色取固定档而不是语义前景/背景:语义色跟着主题走,深色主题下整张码
16
+ * 会翻成浅底深条的反相图,读码器按"深条浅底"取样,反相码扫不出来。要换配色改下面这两个覆盖槽。
17
+ *
18
+ * 换色只有一条硬约束:条必须比底色深,且两者对比要足。反相与深浅相近都会让读码器扫不出来,
19
+ * 而这件事肉眼看不出来。
20
+ *
21
+ * --xh-bar-code-fg 条色,同时经 currentColor 传给人读文字
22
+ * --xh-bar-code-bg 底色
23
+ */
24
+ [data-scope='bar-code'][data-part='root'] {
25
+ display: block;
26
+ border-radius: var(--xh-bar-code-radius, var(--xh-shape-control));
27
+ background: var(--xh-bar-code-bg, var(--xh-color-neutral-0));
28
+
29
+ /* 条那条 path 不带自己的填充色,从这里继承下去 */
30
+ color: var(--xh-bar-code-fg, var(--xh-color-neutral-950));
31
+ fill: currentColor;
32
+
33
+ /* 占位与码面之间来回时,底色与那圈描边淡变 */
34
+ transition:
35
+ background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
36
+ box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
37
+ }
38
+
39
+ /* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
40
+ [data-scope='bar-code'][data-part='root'][hidden] {
41
+ display: none;
42
+ }
43
+
44
+ /*
45
+ * 人读文字:字号由 connect 按 X 尺寸写在节点上(规范里数字高约 8X),这里只定字体。
46
+ * 等宽字体让每位数字一样宽,EAN 逐位居中落格才整齐;规范要的 OCR-B 一般机器上没有,退到系统等宽。
47
+ */
48
+ [data-scope='bar-code'][data-part='root'] > [data-xh-geom='text'] {
49
+ font-family: var(--xh-bar-code-font-family, var(--xh-font-family-mono));
50
+ fill: var(--xh-bar-code-text-fg, currentColor);
51
+ }
52
+
53
+ /*
54
+ * 没有可编码的内容、以及内容不合规则:两种情形都一根条不铺,留一块带描边的占位。
55
+ * 占位用的是语义色——它是界面元素不是码面,跟着主题走才对。
56
+ */
57
+ [data-scope='bar-code'][data-part='root'][data-state='empty'],
58
+ [data-scope='bar-code'][data-part='root'][data-state='error'] {
59
+ background: var(--xh-bar-code-placeholder-bg, var(--xh-bg-subtle));
60
+ box-shadow: inset 0 0 0 var(--xh-stroke-thin) var(--xh-bar-code-placeholder-border, var(--xh-border-default));
61
+ }
62
+ }
@@ -1,3 +1,14 @@
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
+ /* 定义 breadcrumb 样式。 */
7
+
8
+ /* 链接归 Collection Item 导航当前(nav 语境):面、字色、字重、光标与按压时间线由家族配方按投影的家族角色给,
9
+ 本皮肤只映射桥接槽;当前页由连接层投影 data-xh-collection-terminal,走家族的 terminal 态 */
10
+ @import '../family/collection-item.css';
11
+
1
12
  @layer xihan.components {
2
13
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
14
  [data-scope='breadcrumb'] {
@@ -64,45 +75,53 @@
64
75
  display: none;
65
76
  }
66
77
 
78
+ /* 链接的几何、字号与面全经家族桥接槽:静息 muted / regular,悬停走白底承载 hover 100 + 随语气的字色,
79
+ 按下 pressed 200 只换面(§7.2 / §9.2);当前页那条不再是"可去的地方"(§7.3):连接层投影
80
+ data-xh-collection-terminal,家族给透明面 + 随语气的 fg-default + medium + cursor default,不响应悬停与按下,
81
+ 并压过它同时带的 aria-disabled 禁用面。本条 (0,2,0) 压过家族基础块 (0,1,0),不能再写 color / background */
67
82
  [data-scope='breadcrumb'][data-part='link'] {
83
+ --xh-collection-block-padding: var(--xh-space-0);
84
+ --xh-collection-inline-padding: var(--xh-breadcrumb-link-px, var(--xh-space-1));
85
+ --xh-collection-radius: var(--xh-breadcrumb-link-radius, var(--xh-shape-control));
86
+ --xh-collection-font-size: var(--xh-breadcrumb-font-size, var(--xh-_breadcrumb-font-size));
87
+ /* 家族会把 --xh-icon-size 写在条目上;不映射,root 上随文字形档的那支会被家族的 md 档盖掉 */
88
+ --xh-collection-glyph-size: var(--xh-breadcrumb-icon-size, var(--xh-glyph-size-text));
89
+ --xh-collection-fg-rest: var(--xh-breadcrumb-fg, var(--xh-fg-muted));
90
+ --xh-collection-bg-hover: var(--xh-breadcrumb-link-bg-hover, var(--xh-bg-subtle));
91
+ --xh-collection-fg-hover: var(--xh-breadcrumb-link-fg-hover, var(--xh-_breadcrumb-accent-text));
92
+ --xh-collection-bg-pressed: var(--xh-breadcrumb-link-bg-pressed, var(--xh-bg-subtle-hover));
93
+ --xh-collection-fg-terminal: var(--xh-breadcrumb-link-fg-current, var(--xh-_breadcrumb-accent-text));
94
+ --xh-collection-font-weight-terminal: var(--xh-breadcrumb-link-font-weight-current, var(--xh-font-weight-medium));
95
+
68
96
  display: inline-flex;
69
97
  align-items: center;
70
98
  gap: var(--xh-breadcrumb-link-gap, var(--xh-space-1));
71
99
  /* 一层的名字可能很长(文档标题、订单号),压不住会把整条路径撑开 */
72
100
  max-inline-size: var(--xh-breadcrumb-link-max-w, var(--xh-nav-link-max-w));
73
- padding-inline: var(--xh-breadcrumb-link-px, var(--xh-space-1));
74
- border-radius: var(--xh-breadcrumb-link-radius, var(--xh-shape-control));
75
- color: inherit;
101
+ /* 行高随 root 的行距槽:家族基础块给条目写了 leading-normal,这里接回 root 那一支 */
102
+ line-height: var(--xh-breadcrumb-leading, var(--xh-leading-tight));
76
103
  text-decoration: none;
77
104
  white-space: nowrap;
78
105
  overflow: hidden;
79
106
  text-overflow: ellipsis;
80
- transition:
81
- color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
82
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
83
107
  }
84
108
 
85
109
  [data-scope='breadcrumb'][data-part='link'][hidden] {
86
110
  display: none;
87
111
  }
88
112
 
89
- /* 当前页那条不再是"可去的地方":不给悬停反馈,指针也不摆出可点的样子。
90
- 连接层同时拦下了它的点击并把它移出了 Tab 序列,这里只负责说清楚这件事 */
91
- [data-scope='breadcrumb'][data-part='link']:not([data-current]):hover {
92
- background: var(--xh-breadcrumb-link-bg-hover, var(--xh-bg-subtle-hover));
93
- color: var(--xh-breadcrumb-link-fg-hover, var(--xh-_breadcrumb-accent-text));
94
- }
95
-
96
- [data-scope='breadcrumb'][data-part='link']:focus-visible {
97
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
98
- outline-offset: var(--xh-ring-offset);
113
+ /* 图标位跟着字号走,与文字并排;不参与省略,压缩时先压文字 */
114
+ [data-scope='breadcrumb'][data-part='link-icon'] {
115
+ display: inline-flex;
116
+ flex: none;
117
+ align-items: center;
118
+ justify-content: center;
119
+ inline-size: var(--xh-breadcrumb-link-icon-size, var(--xh-glyph-size-text));
120
+ block-size: var(--xh-breadcrumb-link-icon-size, var(--xh-glyph-size-text));
99
121
  }
100
122
 
101
- /* 当前页用字重与前景色区分,不加下划线:下划线是"可点"的信号,而它点不动 */
102
- [data-scope='breadcrumb'][data-part='link'][data-current] {
103
- color: var(--xh-breadcrumb-current-fg, var(--xh-_breadcrumb-accent-text));
104
- font-weight: var(--xh-breadcrumb-current-font-weight, var(--xh-font-weight-medium));
105
- cursor: default;
123
+ [data-scope='breadcrumb'][data-part='link-icon'][hidden] {
124
+ display: none;
106
125
  }
107
126
 
108
127
  /* 分隔符与省略号都是纯视觉占位,读屏那边已被 aria-hidden 摘掉 */