@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,15 @@
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
+ /* 定义 float button 样式。 */
7
+
8
+ @import '../family/action-control.css';
9
+
10
+ /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
11
+ @import '../family/motion.css';
12
+
1
13
  @layer xihan.components {
2
14
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
15
  [data-scope='float-button'] {
@@ -10,16 +22,18 @@
10
22
  transform / filter / backdrop-filter / contain,包含块就被抢走,整组立刻贴错位置——
11
23
  所以别往覆盖钩子里加这几个属性。 */
12
24
  [data-scope='float-button'][data-part='root'] {
13
- /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
14
- --xh-icon-size: var(--xh-float-button-icon-size, var(--xh-glyph-size-text));
15
-
16
25
  --xh-_float-button-offset: var(--xh-space-6);
17
- /* 触发器与展开的每一条动作共用这两个私有槽,换档只改这里 */
18
- --xh-_float-button-size: var(--xh-float-button-size, var(--xh-control-h-lg));
19
- --xh-_float-button-radius: var(--xh-float-button-radius, var(--xh-shape-pill));
26
+ /* 展开列表里原生动作项的身量与字形尺:触发器自己走 Action Control floating 档
27
+ (sm = box-md / md = box-lg / lg = box-lg + space-2,字形 md / lg / xl),
28
+ 原生动作项不是 Headless 部件、配方打不到它,这两支私有槽按同一张表镜像,换档只改这里 */
29
+ --xh-_float-button-size: var(--xh-control-box-lg);
30
+ --xh-_float-button-glyph-size: var(--xh-glyph-size-lg);
31
+ /* 作者塞进指示符槽的图标跟着尺寸档走,与皮肤画的兜底字形同一把尺 */
32
+ --xh-icon-size: var(--xh-float-button-icon-size, var(--xh-_float-button-glyph-size));
20
33
 
21
34
  position: fixed;
22
- z-index: var(--xh-float-button-layer, var(--xh-layer-sticky));
35
+ /* 展开时消费 LayerRegistry 的实时层序;收起后没有逻辑层,仍回到普通 sticky 槽。 */
36
+ z-index: var(--xh-float-button-layer, var(--xh-_layer, var(--xh-layer-sticky)));
23
37
  display: flex;
24
38
  /* 摞的方向由落位定,下面四条各自覆盖;这里给的是没写落位时的落点 */
25
39
  flex-direction: column;
@@ -29,76 +43,160 @@
29
43
 
30
44
  /* —— 四角 ——
31
45
  start / end 用逻辑属性,RTL 下自动换到另一侧。
32
- 摞的方向按贴的是上沿还是下沿定:离屏幕边最近的恒是触发器,展开的那一组往页面中间长 */
46
+ 摞的方向按贴的是上沿还是下沿定:离屏幕边最近的恒是触发器,展开的那一组往页面中间长。
47
+ 四条贴边都与安全区取大的一头:刘海、圆角与底部横条压住的那一段由系统给出,
48
+ 贴边比它窄时钮会被切掉一角;桌面上 env() 恒为 0,取值与贴边槽完全一致。
49
+ 安全区只有物理方向的四个名字,行内轴上两侧同取较宽的那一段,RTL 下不会翻错边。 */
33
50
  [data-scope='float-button'][data-part='root'][data-placement^='top'] {
34
- inset-block-start: var(--xh-_float-button-offset);
51
+ inset-block-start: max(var(--xh-_float-button-offset), env(safe-area-inset-top));
35
52
  flex-direction: column;
36
53
  }
37
54
 
38
55
  [data-scope='float-button'][data-part='root'][data-placement^='bottom'] {
39
- inset-block-end: var(--xh-_float-button-offset);
56
+ inset-block-end: max(var(--xh-_float-button-offset), env(safe-area-inset-bottom));
40
57
  flex-direction: column-reverse;
41
58
  }
42
59
 
43
60
  [data-scope='float-button'][data-part='root'][data-placement$='-start'] {
44
- inset-inline-start: var(--xh-_float-button-offset);
61
+ inset-inline-start: max(var(--xh-_float-button-offset), env(safe-area-inset-left), env(safe-area-inset-right));
45
62
  }
46
63
 
47
64
  [data-scope='float-button'][data-part='root'][data-placement$='-end'] {
48
- inset-inline-end: var(--xh-_float-button-offset);
65
+ inset-inline-end: max(var(--xh-_float-button-offset), env(safe-area-inset-left), env(safe-area-inset-right));
49
66
  }
50
67
 
51
- /* —— 外形 —— */
52
- /* 使用者令牌排在形态之前:写了 --xh-float-button-radius 就以它为准,没写才按 shape 换档 */
53
- [data-scope='float-button'][data-part='root'][data-shape='square'] {
54
- --xh-_float-button-radius: var(--xh-float-button-radius, var(--xh-shape-control));
68
+ /* —— 尺寸:原生动作项与触发器的 floating 档逐档同表 —— */
69
+ [data-scope='float-button'][data-part='root'][data-size='sm'] {
70
+ --xh-_float-button-size: var(--xh-control-box-md);
71
+ --xh-_float-button-glyph-size: var(--xh-glyph-size-md);
55
72
  }
56
73
 
57
- /* —— 触发器 —— */
58
- /* 里面通常只放一个图标,宽高同取一档尺寸 */
59
- [data-scope='float-button'][data-part='trigger'] {
60
- display: inline-flex;
61
- flex: none;
62
- align-items: center;
63
- justify-content: center;
64
- inline-size: var(--xh-_float-button-size);
65
- block-size: var(--xh-_float-button-size);
66
- padding: 0;
67
- border: var(--xh-stroke-thin) solid var(--xh-float-button-border, var(--xh-border-control));
68
- border-radius: var(--xh-_float-button-radius);
69
- /* 使用者令牌排在缺省之前:写了覆盖钩子就以它为准,没写才退到中性缺省 */
70
- background: var(--xh-float-button-bg, var(--xh-bg-surface-raised));
71
- color: var(--xh-float-button-fg, var(--xh-fg-default));
72
- /* 浮在内容之上,靠投影与页面拉开层次 */
73
- box-shadow: var(--xh-float-button-shadow, var(--xh-elevation-sheet));
74
- cursor: pointer;
75
- transition:
76
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
77
- border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
74
+ [data-scope='float-button'][data-part='root'][data-size='md'] {
75
+ --xh-_float-button-size: var(--xh-control-box-lg);
76
+ --xh-_float-button-glyph-size: var(--xh-glyph-size-lg);
78
77
  }
79
78
 
80
- /* 悬停只在能用指针的设备上生效,触摸端不留一个按不掉的悬停态 */
81
- @media (hover: hover) {
82
- [data-scope='float-button'][data-part='trigger']:not([data-disabled]):hover {
83
- border-color: var(--xh-float-button-border-hover, var(--xh-border-control-hover));
84
- background: var(--xh-float-button-bg-hover, var(--xh-bg-subtle-hover));
85
- }
79
+ [data-scope='float-button'][data-part='root'][data-size='lg'] {
80
+ --xh-_float-button-size: calc(var(--xh-control-box-lg) + var(--xh-space-2));
81
+ --xh-_float-button-glyph-size: var(--xh-glyph-size-xl);
86
82
  }
87
83
 
88
- [data-scope='float-button'][data-part='trigger']:not([data-disabled]):active {
89
- background: var(--xh-float-button-bg-active, var(--xh-bg-subtle-active));
84
+ /* —— 形态:给展开列表里原生动作项用的面 ——
85
+ 触发器的面由 Action Control 形态矩阵按 data-xh-action-variant 给(solid / subtle / ghost),
86
+ 原生动作项读不到矩阵,这几块私有槽按矩阵同一张表镜像;ghost 与 outline 的悬停 / 按下走画布承载的
87
+ 阶梯(100 → 200,§7.2 第 3 条)。缺省 outline(连接层不传 variant 时显式落)是磨砂面:背景、边缘、
88
+ 顶光、投影与磨砂从同一份 M2 配方取,高对比、减少透明度、打印和强制色便能一起降级——钮浮在正文
89
+ 之上,透空的面在任何内容上都读不出边界,所以 outline 这一档面留着 */
90
+ [data-scope='float-button'][data-part='root'][data-variant='solid'] {
91
+ --xh-_float-button-bg: var(--xh-_tone, var(--xh-bg-brand));
92
+ --xh-_float-button-bg-hover: var(--xh-_tone-hover, var(--xh-bg-brand-hover));
93
+ --xh-_float-button-bg-active: var(--xh-_tone-active, var(--xh-bg-brand-active));
94
+ --xh-_float-button-fg: var(--xh-_tone-on, var(--xh-fg-on-brand));
95
+ --xh-_float-button-border: transparent;
96
+ --xh-_float-button-border-hover: transparent;
97
+ --xh-_float-button-shadow: none;
90
98
  }
91
99
 
92
- /* 禁用只换颜色,不叠不透明度:两者同时用只会互相抵消,把字压到读不出来 */
93
- [data-scope='float-button'][data-part='trigger'][data-disabled] {
94
- color: var(--xh-fg-disabled);
95
- cursor: not-allowed;
100
+ [data-scope='float-button'][data-part='root'][data-variant='subtle'] {
101
+ --xh-_float-button-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
102
+ --xh-_float-button-bg-hover: var(--xh-_tone-subtle-hover, var(--xh-bg-subtle-hover));
103
+ --xh-_float-button-bg-active: var(--xh-_tone-subtle-active, var(--xh-bg-subtle-active));
104
+ --xh-_float-button-fg: var(--xh-_tone-fg, var(--xh-fg-default));
105
+ --xh-_float-button-border: transparent;
106
+ --xh-_float-button-border-hover: transparent;
107
+ --xh-_float-button-shadow: none;
96
108
  }
97
109
 
98
- /* 聚焦环恒是 --xh-ring-focus,不随外形与落位走 */
99
- [data-scope='float-button'][data-part='trigger']:focus-visible {
100
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
101
- outline-offset: var(--xh-ring-offset);
110
+ [data-scope='float-button'][data-part='root'][data-variant='outline'] {
111
+ --xh-_float-button-bg: var(--xh-material-frosted-bg);
112
+ --xh-_float-button-bg-hover: var(--xh-_tone-subtle, var(--xh-bg-subtle));
113
+ --xh-_float-button-bg-active: var(--xh-_tone-subtle-hover, var(--xh-bg-subtle-hover));
114
+ --xh-_float-button-fg: var(--xh-material-frosted-fg);
115
+ --xh-_float-button-border: var(--xh-material-frosted-border);
116
+ --xh-_float-button-border-hover: var(--xh-material-frosted-border);
117
+ --xh-_float-button-shadow: var(--xh-material-frosted-shadow);
118
+ }
119
+
120
+ [data-scope='float-button'][data-part='root'][data-variant='ghost'] {
121
+ --xh-_float-button-bg: transparent;
122
+ --xh-_float-button-bg-hover: var(--xh-_tone-subtle, var(--xh-bg-subtle));
123
+ --xh-_float-button-bg-active: var(--xh-_tone-subtle-hover, var(--xh-bg-subtle-hover));
124
+ --xh-_float-button-fg: var(--xh-_tone-fg, var(--xh-fg-default));
125
+ --xh-_float-button-border: transparent;
126
+ --xh-_float-button-border-hover: transparent;
127
+ --xh-_float-button-shadow: none;
128
+ }
129
+
130
+ /* —— 触发器 ——
131
+ 浮在内容之上的单图标圆钮,接 Action Control floating 档(§4.1):盒型(md = box-lg 48px,圆形)、
132
+ 四态面、0.97 按压与 44px 命中区由家族配方按 data-xh-action-variant / -size 给出。
133
+ 这里只把公开槽桥接到矩阵之前(使用者槽 → 形态矩阵 → 家族缺省)与几何槽映射 */
134
+ [data-scope='float-button'][data-part='trigger'] {
135
+ --xh-action-bg-rest: var(--xh-float-button-bg, var(--xh-_action-variant-bg-rest));
136
+ --xh-action-bg-hover: var(--xh-float-button-bg-hover, var(--xh-_action-variant-bg-hover));
137
+ --xh-action-bg-pressed: var(--xh-float-button-bg-active, var(--xh-_action-variant-bg-pressed));
138
+ --xh-action-bg-focus-visible: var(--xh-float-button-bg, var(--xh-_action-variant-bg-focus-visible));
139
+ --xh-action-bg-disabled: var(--xh-float-button-bg, var(--xh-_action-variant-bg-disabled));
140
+ --xh-action-fg-rest: var(--xh-float-button-fg, var(--xh-_action-variant-fg-rest));
141
+ --xh-action-fg-hover: var(--xh-float-button-fg, var(--xh-_action-variant-fg-hover));
142
+ --xh-action-fg-pressed: var(--xh-float-button-fg, var(--xh-_action-variant-fg-pressed));
143
+ --xh-action-fg-focus-visible: var(--xh-float-button-fg, var(--xh-_action-variant-fg-focus-visible));
144
+ --xh-action-border-rest: var(--xh-float-button-border, var(--xh-_action-variant-border-rest));
145
+ --xh-action-border-hover: var(--xh-float-button-border-hover, var(--xh-_action-variant-border-hover));
146
+ --xh-action-border-pressed: var(--xh-float-button-border-hover, var(--xh-_action-variant-border-pressed));
147
+ --xh-action-border-focus-visible: var(--xh-float-button-border, var(--xh-_action-variant-border-focus-visible));
148
+ --xh-action-border-disabled: var(--xh-float-button-border, var(--xh-_action-variant-border-disabled));
149
+ /* 矩阵各态无影(§8.3 淡底与阴影互斥);outline 那一档的磨砂投影在下面另桥接 */
150
+ --xh-action-shadow-rest: var(--xh-float-button-shadow, none);
151
+ --xh-action-shadow-hover: var(--xh-float-button-shadow, none);
152
+ --xh-action-shadow-pressed: var(--xh-float-button-shadow, none);
153
+ --xh-action-shadow-focus-visible: var(--xh-float-button-shadow, none);
154
+ --xh-action-shadow-disabled: var(--xh-float-button-shadow, none);
155
+ --xh-action-radius: var(--xh-float-button-radius, var(--xh-_action-profile-radius));
156
+ --xh-action-visual-size: var(--xh-float-button-size, var(--xh-_action-profile-visual-size));
157
+ /* 作者塞进来的图标跟着 floating 档走(md 24px),与皮肤画的兜底字形同一把尺 */
158
+ --xh-icon-size: var(--xh-float-button-icon-size, var(--xh-_action-profile-glyph-size));
159
+ }
160
+
161
+ /* 缺省 outline 是 M2 磨砂面:背景、边缘、顶光、投影与磨砂从同一份配方取。
162
+ 悬停 / 按下的底走矩阵 outline 列的画布阶梯(100 → 200),边缘与投影不动;
163
+ 键盘聚焦时铺配方的实体 focus surface——透明面上的内收环没有稳定的底可量对比;
164
+ 置灰只换字色(矩阵 disabled 列的前景),面仍留着,透空的面在任何内容上都读不出边界 */
165
+ [data-scope='float-button'][data-part='root'][data-variant='outline']
166
+ [data-scope='float-button'][data-part='trigger'] {
167
+ --xh-action-bg-rest: var(--xh-float-button-bg, var(--xh-_float-button-bg));
168
+ --xh-action-bg-focus-visible: var(--xh-float-button-bg, var(--xh-material-frosted-focus-surface));
169
+ --xh-action-bg-disabled: var(--xh-float-button-bg, var(--xh-_float-button-bg));
170
+ --xh-action-fg-rest: var(--xh-float-button-fg, var(--xh-_float-button-fg));
171
+ --xh-action-fg-hover: var(--xh-float-button-fg, var(--xh-_float-button-fg));
172
+ --xh-action-fg-pressed: var(--xh-float-button-fg, var(--xh-_float-button-fg));
173
+ --xh-action-fg-focus-visible: var(--xh-float-button-fg, var(--xh-_float-button-fg));
174
+ --xh-action-border-rest: var(--xh-float-button-border, var(--xh-_float-button-border));
175
+ --xh-action-border-hover: var(--xh-float-button-border-hover, var(--xh-_float-button-border-hover));
176
+ --xh-action-border-pressed: var(--xh-float-button-border-hover, var(--xh-_float-button-border-hover));
177
+ --xh-action-border-focus-visible: var(--xh-float-button-border, var(--xh-_float-button-border));
178
+ --xh-action-border-disabled: var(--xh-float-button-border, var(--xh-_float-button-border));
179
+ --xh-action-shadow-rest: var(--xh-float-button-shadow, var(--xh-_float-button-shadow));
180
+ --xh-action-shadow-hover: var(--xh-float-button-shadow, var(--xh-_float-button-shadow));
181
+ --xh-action-shadow-pressed: var(--xh-float-button-shadow, var(--xh-_float-button-shadow));
182
+ --xh-action-shadow-focus-visible: var(--xh-float-button-shadow, var(--xh-_float-button-shadow));
183
+ --xh-action-shadow-disabled: var(--xh-float-button-shadow, var(--xh-_float-button-shadow));
184
+ /* M2 顶光走配方的高光通道:实心、淡色与透空形态各有自身表面,不能把磨砂高光误铺上去 */
185
+ --xh-action-highlight-rest: var(--xh-material-frosted-highlight);
186
+ --xh-action-highlight-hover: var(--xh-material-frosted-highlight);
187
+ --xh-action-highlight-pressed: var(--xh-material-frosted-highlight);
188
+ --xh-action-highlight-focus-visible: var(--xh-material-frosted-highlight);
189
+ --xh-action-highlight-disabled: var(--xh-material-frosted-highlight);
190
+
191
+ -webkit-backdrop-filter: var(--xh-material-frosted-backdrop);
192
+ backdrop-filter: var(--xh-material-frosted-backdrop);
193
+ }
194
+
195
+ /* 面是实心的,环色与面同族,画在面里就看不出来;环改取面自己的前景色——
196
+ 那一族色本来就要在这块面上把字读清楚,与面的对比是按可读性定的。
197
+ 置灰后矩阵把面换成中性淡底,公共环压上去足够对比,不再另灌 */
198
+ [data-scope='float-button'][data-part='trigger'][data-xh-action-variant='solid']:not([data-disabled]):focus-visible {
199
+ --xh-action-ring-color-focus-visible: currentColor;
102
200
  }
103
201
 
104
202
  /* —— 展开的那一组 —— */
@@ -122,12 +220,88 @@
122
220
  /* 展开的每一条动作与触发器同一副身量:它们是一排里的同类,作者只管往里放按钮 */
123
221
  [data-scope='float-button'][data-part='list'] > * {
124
222
  flex: none;
125
- inline-size: var(--xh-_float-button-size);
126
- block-size: var(--xh-_float-button-size);
127
- border-radius: var(--xh-_float-button-radius);
223
+ inline-size: var(--xh-float-button-size, var(--xh-_float-button-size));
224
+ block-size: var(--xh-float-button-size, var(--xh-_float-button-size));
225
+ border-radius: var(--xh-float-button-radius, var(--xh-shape-circle));
226
+ /* 逐条依次冒出来,离触发器最近的那条先到。backwards 让每条在自己那份延迟里保持起始帧 */
227
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
128
228
  }
129
229
 
130
- /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
230
+ /* 原生按钮直接作为动作项时,沿用触发器的视觉面(同一组公开槽、同一张形态表);XhButton 保留自己的皮肤。 */
231
+ [data-scope='float-button'][data-part='list'] > button:not([data-scope]) {
232
+ padding: 0;
233
+ border: var(--xh-stroke-thin) solid var(--xh-float-button-border, var(--xh-_float-button-border));
234
+ background-color: var(--xh-float-button-bg, var(--xh-_float-button-bg));
235
+ color: var(--xh-float-button-fg, var(--xh-_float-button-fg));
236
+ box-shadow: var(--xh-float-button-shadow, var(--xh-_float-button-shadow));
237
+ font: inherit;
238
+ cursor: pointer;
239
+ transition:
240
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
241
+ border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
242
+ scale var(--xh-motion-duration-release) var(--xh-motion-ease-release);
243
+ }
244
+
245
+ [data-scope='float-button'][data-part='root'][data-variant='outline']
246
+ [data-scope='float-button'][data-part='list']
247
+ > button:not([data-scope]) {
248
+ background-image: linear-gradient(
249
+ to bottom,
250
+ var(--xh-material-frosted-highlight) 0 var(--xh-stroke-thin),
251
+ transparent var(--xh-stroke-thin)
252
+ );
253
+ -webkit-backdrop-filter: var(--xh-material-frosted-backdrop);
254
+ backdrop-filter: var(--xh-material-frosted-backdrop);
255
+ }
256
+
257
+ [data-scope='float-button'][data-part='list'] > button:not([data-scope]):focus-visible {
258
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
259
+ outline-offset: var(--xh-ring-offset);
260
+ }
261
+
262
+ @media (hover: hover) {
263
+ [data-scope='float-button'][data-part='list'] > button:not([data-scope]):not(:disabled):hover {
264
+ border-color: var(--xh-float-button-border-hover, var(--xh-_float-button-border-hover));
265
+ background-color: var(--xh-float-button-bg-hover, var(--xh-_float-button-bg-hover));
266
+ }
267
+ }
268
+
269
+ [data-scope='float-button'][data-part='list'] > button:not([data-scope]):not(:disabled):active {
270
+ background-color: var(--xh-float-button-bg-active, var(--xh-_float-button-bg-active));
271
+ scale: var(--xh-motion-scale-press);
272
+ transition-duration: var(--xh-motion-duration-press);
273
+ transition-timing-function: var(--xh-motion-ease-press);
274
+ }
275
+
276
+ [data-scope='float-button'][data-part='list'] > button:not([data-scope]):disabled {
277
+ color: var(--xh-fg-disabled);
278
+ cursor: not-allowed;
279
+ }
280
+
281
+ /* 交错的间隔:第二条起逐级往后推,第六条起统一钉在第五级,
282
+ 动作再多也不会拖出一条越来越慢的尾巴 */
283
+ [data-scope='float-button'][data-part='list'] > *:nth-child(2) {
284
+ animation-delay: var(--xh-motion-stagger-step);
285
+ }
286
+
287
+ [data-scope='float-button'][data-part='list'] > *:nth-child(3) {
288
+ animation-delay: calc(2 * var(--xh-motion-stagger-step));
289
+ }
290
+
291
+ [data-scope='float-button'][data-part='list'] > *:nth-child(4) {
292
+ animation-delay: calc(3 * var(--xh-motion-stagger-step));
293
+ }
294
+
295
+ [data-scope='float-button'][data-part='list'] > *:nth-child(5) {
296
+ animation-delay: calc(4 * var(--xh-motion-stagger-step));
297
+ }
298
+
299
+ [data-scope='float-button'][data-part='list'] > *:nth-child(n + 6) {
300
+ animation-delay: calc(5 * var(--xh-motion-stagger-step));
301
+ }
302
+
303
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中。
304
+ 粗指针的 44px 命中区由配方的 ::after 给,字形占的是 ::before */
131
305
  [data-scope='float-button'][data-part='trigger']:empty::before {
132
306
  content: '';
133
307
  display: inline-block;
@@ -145,4 +319,11 @@
145
319
  [data-scope='float-button'][data-part='trigger'][hidden] {
146
320
  display: none;
147
321
  }
322
+
323
+ @media print {
324
+ /* 打印:悬浮动作钮固定在视口上,纸上没有视口——它会印在页面某处盖住正文,而且按不动。 */
325
+ [data-scope='float-button'][data-part='root'] {
326
+ display: none;
327
+ }
328
+ }
148
329
  }