@xihan-ui/styles 1.0.0-alpha.2 → 1.0.0-alpha.3

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 (118) hide show
  1. package/CHANGELOG.md +447 -0
  2. package/README.md +1 -1
  3. package/css/accordion.css +56 -5
  4. package/css/alert.css +30 -5
  5. package/css/anchor.css +7 -7
  6. package/css/avatar-group.css +3 -3
  7. package/css/avatar.css +3 -3
  8. package/css/back-top.css +16 -1
  9. package/css/badge.css +16 -2
  10. package/css/breadcrumb.css +24 -4
  11. package/css/button-group.css +14 -13
  12. package/css/button.css +42 -11
  13. package/css/calendar.css +119 -2
  14. package/css/card.css +5 -5
  15. package/css/carousel.css +36 -5
  16. package/css/cascader.css +183 -102
  17. package/css/checkbox-group.css +41 -19
  18. package/css/checkbox.css +54 -8
  19. package/css/clipboard.css +2 -1
  20. package/css/code-block.css +12 -7
  21. package/css/collapsible.css +42 -2
  22. package/css/color-picker.css +111 -45
  23. package/css/combobox.css +114 -53
  24. package/css/composer.css +5 -3
  25. package/css/context-menu.css +97 -69
  26. package/css/date-field.css +91 -14
  27. package/css/date-picker.css +276 -65
  28. package/css/descriptions.css +2 -2
  29. package/css/dialog.css +40 -13
  30. package/css/download-trigger.css +76 -0
  31. package/css/drawer.css +45 -14
  32. package/css/dynamic-input.css +68 -17
  33. package/css/editable.css +12 -10
  34. package/css/ellipsis.css +1 -1
  35. package/css/empty-state.css +7 -7
  36. package/css/field.css +9 -6
  37. package/css/fieldset.css +69 -0
  38. package/css/file-upload.css +45 -7
  39. package/css/float-button.css +16 -1
  40. package/css/floating-panel.css +310 -0
  41. package/css/form.css +4 -4
  42. package/css/heatmap.css +410 -0
  43. package/css/highlight.css +1 -1
  44. package/css/hotkeys.css +90 -0
  45. package/css/hover-card.css +40 -45
  46. package/css/image-cropper.css +231 -0
  47. package/css/image-viewer.css +137 -12
  48. package/css/image.css +2 -2
  49. package/css/infinite-scroll.css +1 -1
  50. package/css/json-viewer.css +241 -0
  51. package/css/layout.css +6 -10
  52. package/css/list.css +8 -8
  53. package/css/listbox.css +20 -4
  54. package/css/loading-bar.css +7 -1
  55. package/css/log.css +1 -1
  56. package/css/marquee.css +9 -0
  57. package/css/masonry.css +63 -0
  58. package/css/mention.css +87 -33
  59. package/css/menu.css +113 -47
  60. package/css/menubar.css +146 -60
  61. package/css/navigation-menu.css +54 -29
  62. package/css/number-animation.css +3 -3
  63. package/css/number-field.css +173 -16
  64. package/css/overlay-arrow.css +51 -0
  65. package/css/page-header.css +5 -5
  66. package/css/pagination.css +13 -13
  67. package/css/password-input.css +356 -0
  68. package/css/pin-input.css +13 -10
  69. package/css/popconfirm.css +46 -10
  70. package/css/popover.css +70 -45
  71. package/css/popselect.css +183 -53
  72. package/css/progress.css +47 -7
  73. package/css/qr-code.css +1 -1
  74. package/css/radio-group.css +14 -8
  75. package/css/rating.css +2 -2
  76. package/css/reset.css +17 -0
  77. package/css/result.css +6 -6
  78. package/css/scroll-area.css +61 -89
  79. package/css/scrollbar.css +167 -0
  80. package/css/segmented.css +215 -0
  81. package/css/select.css +274 -125
  82. package/css/separator.css +2 -2
  83. package/css/side-nav.css +111 -19
  84. package/css/signature-pad.css +144 -0
  85. package/css/skeleton.css +7 -1
  86. package/css/slider.css +10 -10
  87. package/css/space.css +117 -0
  88. package/css/spinner.css +22 -10
  89. package/css/statistic.css +9 -9
  90. package/css/steps.css +25 -8
  91. package/css/switch.css +48 -6
  92. package/css/table.css +131 -37
  93. package/css/tabs.css +4 -4
  94. package/css/tag.css +177 -0
  95. package/css/tags-input.css +78 -40
  96. package/css/text-field.css +149 -36
  97. package/css/thread.css +1 -1
  98. package/css/time-field.css +97 -16
  99. package/css/time-picker.css +259 -69
  100. package/css/timeline.css +10 -10
  101. package/css/timer.css +119 -0
  102. package/css/toast.css +34 -10
  103. package/css/toaster.css +1 -1
  104. package/css/toggle.css +6 -6
  105. package/css/tone.css +10 -5
  106. package/css/toolbar.css +1 -1
  107. package/css/tooltip.css +36 -33
  108. package/css/tour.css +103 -58
  109. package/css/transfer.css +68 -17
  110. package/css/tree-select.css +185 -84
  111. package/css/tree.css +85 -1
  112. package/css/typography.css +4 -4
  113. package/css/undefined.css +11 -1
  114. package/css/virtualizer.css +3 -1
  115. package/css/watermark.css +1 -2
  116. package/index.css +17 -0
  117. package/index.unlayered.css +8659 -2799
  118. package/package.json +19 -3
package/css/timer.css ADDED
@@ -0,0 +1,119 @@
1
+ @layer xihan.components {
2
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
+ [data-scope='timer'] {
4
+ --xh-timer-skin: 1;
5
+ }
6
+
7
+ /* 三个尺寸档只换这几个私有槽,各部件从 root 继承它们,换档不必给每个部件各写一条选择器 */
8
+ [data-scope='timer'][data-part='root'] {
9
+ --xh-_timer-digit-size: var(--xh-text-heading-2-size);
10
+ --xh-_timer-gap: var(--xh-space-3);
11
+ --xh-_timer-control-h: var(--xh-control-h-md);
12
+ --xh-_timer-control-px: var(--xh-control-px-md);
13
+ --xh-_timer-control-gap: var(--xh-control-gap-md);
14
+
15
+ display: inline-flex;
16
+ align-items: center;
17
+ gap: var(--xh-timer-gap, var(--xh-_timer-gap));
18
+ color: var(--xh-timer-fg, var(--xh-fg-default));
19
+ }
20
+
21
+ /* 上面声明了 display,会盖掉 UA 的 [hidden] 规则,收起态要在这里接回来 */
22
+ [data-scope='timer'][data-part='root'][hidden] {
23
+ display: none;
24
+ }
25
+
26
+ /* —— 尺寸 —— */
27
+ [data-scope='timer'][data-part='root'][data-size='sm'] {
28
+ --xh-_timer-digit-size: var(--xh-text-heading-3-size);
29
+ --xh-_timer-gap: var(--xh-space-2);
30
+ --xh-_timer-control-h: var(--xh-control-h-sm);
31
+ --xh-_timer-control-px: var(--xh-control-px-sm);
32
+ --xh-_timer-control-gap: var(--xh-control-gap-sm);
33
+ }
34
+
35
+ [data-scope='timer'][data-part='root'][data-size='lg'] {
36
+ --xh-_timer-digit-size: var(--xh-text-heading-1-size);
37
+ --xh-_timer-gap: var(--xh-space-4);
38
+ --xh-_timer-control-h: var(--xh-control-h-lg);
39
+ --xh-_timer-control-px: var(--xh-control-px-lg);
40
+ --xh-_timer-control-gap: var(--xh-control-gap-lg);
41
+ }
42
+
43
+ /* —— 时间区 —— */
44
+ /* 等宽数字:逐位宽度一致,秒数换位时分隔符与后面的段都不会左右挪动。
45
+ direction 钉成 ltr:每段是一个独立的 flex 项,主轴方向跟着文字方向走,
46
+ 不钉住的话 rtl 页面上时分秒会整体倒过来排——时间串的读序两个方向都一样。 */
47
+ [data-scope='timer'][data-part='area'] {
48
+ display: inline-flex;
49
+ align-items: baseline;
50
+ direction: ltr;
51
+ color: var(--xh-timer-area-fg, var(--xh-fg-default));
52
+ font-size: var(--xh-timer-digit-font-size, var(--xh-_timer-digit-size));
53
+ font-variant-numeric: tabular-nums;
54
+ font-weight: var(--xh-font-weight-semibold);
55
+ line-height: var(--xh-leading-tight);
56
+ }
57
+
58
+ [data-scope='timer'][data-part='area'][hidden] {
59
+ display: none;
60
+ }
61
+
62
+ /* 走完之后这串数字不再是活的信息,退一档;暂停在半路的仍是要盯着看的数,不退 */
63
+ [data-scope='timer'][data-part='area'][data-state='completed'] {
64
+ color: var(--xh-timer-completed-fg, var(--xh-fg-muted));
65
+ }
66
+
67
+ /* 记号只是排版,比数字弱一档、两侧留一点气口 */
68
+ [data-scope='timer'][data-part='separator'] {
69
+ padding-inline: var(--xh-timer-separator-px, var(--xh-space-0_5));
70
+ color: var(--xh-timer-separator-fg, var(--xh-fg-subtle));
71
+ font-weight: var(--xh-font-weight-regular);
72
+ }
73
+
74
+ /* —— 起停按钮 —— */
75
+ [data-scope='timer'][data-part='control'] {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ gap: var(--xh-timer-control-gap, var(--xh-_timer-control-gap));
80
+ block-size: var(--xh-timer-control-h, var(--xh-_timer-control-h));
81
+ padding-inline: var(--xh-timer-control-px, var(--xh-_timer-control-px));
82
+ border: var(--xh-stroke-thin) solid var(--xh-timer-control-border, var(--xh-border-control));
83
+ border-radius: var(--xh-timer-control-radius, var(--xh-shape-control));
84
+ background: var(--xh-timer-control-bg, var(--xh-bg-surface));
85
+ color: var(--xh-timer-control-fg, var(--xh-fg-default));
86
+ font-size: var(--xh-text-label-size);
87
+ font-weight: var(--xh-text-label-weight);
88
+ line-height: var(--xh-leading-none);
89
+ cursor: pointer;
90
+ transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
91
+ }
92
+
93
+ [data-scope='timer'][data-part='control'][hidden] {
94
+ display: none;
95
+ }
96
+
97
+ [data-scope='timer'][data-part='control']:hover {
98
+ border-color: var(--xh-timer-control-border-hover, var(--xh-border-control-hover));
99
+ background: var(--xh-timer-control-bg-hover, var(--xh-bg-subtle-hover));
100
+ }
101
+
102
+ [data-scope='timer'][data-part='control']:active {
103
+ background: var(--xh-timer-control-bg-active, var(--xh-bg-subtle-active));
104
+ }
105
+
106
+ [data-scope='timer'][data-part='control']:focus-visible {
107
+ border-color: var(--xh-timer-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
108
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
109
+ outline-offset: var(--xh-ring-offset);
110
+ }
111
+
112
+ /* 作者把按钮禁掉时的样子。文字改用 fg-disabled 就不再叠 opacity,两条一起上会掉到读不出来 */
113
+ [data-scope='timer'][data-part='control']:disabled {
114
+ border-color: var(--xh-timer-control-border-disabled, var(--xh-border-subtle));
115
+ background: var(--xh-timer-control-bg-disabled, var(--xh-bg-muted));
116
+ color: var(--xh-fg-disabled);
117
+ cursor: not-allowed;
118
+ }
119
+ }
package/css/toast.css CHANGED
@@ -27,7 +27,7 @@
27
27
 
28
28
  to {
29
29
  opacity: 0;
30
- translate: 0 var(--xh-motion-distance-sm);
30
+ translate: 0 var(--xh-motion-distance-md);
31
31
  scale: var(--xh-motion-scale-enter);
32
32
  }
33
33
  }
@@ -40,27 +40,30 @@
40
40
  }
41
41
 
42
42
  [data-scope='toast'][data-part='root'] {
43
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
44
+ --xh-icon-size: var(--xh-toast-icon-size, var(--xh-glyph-size-text));
45
+
43
46
  display: flex;
44
47
  flex-direction: column;
45
48
  gap: var(--xh-toast-gap, var(--xh-space-1));
46
- inline-size: var(--xh-toast-w, 20rem);
49
+ inline-size: var(--xh-toast-w, var(--xh-overlay-max-w));
47
50
  /* 摞是整面视口宽的定位面且带内边距,取 100% 就等于自动让出两侧留白,
48
51
  窄屏上不必再算一遍 viewport 减法 */
49
52
  max-inline-size: 100%;
50
- padding-block: var(--xh-toast-py, var(--xh-space-3));
51
- padding-inline: var(--xh-toast-px, var(--xh-space-4));
53
+ padding-block: var(--xh-toast-py, var(--xh-surface-py-sm));
54
+ padding-inline: var(--xh-toast-px, var(--xh-surface-px-sm));
52
55
  border: var(--xh-stroke-thin) solid var(--xh-toast-border, var(--xh-border-default));
53
56
  /* 语气色条做成起始侧的粗边,而不是伪元素:圆角与阴影都不用再对第二遍。
54
57
  两条必须排在 border 简写之后,否则被简写重置回细边与常规描边色。
55
58
  颜色由 connect 从 type 派生的 data-tone 经语气层给出,作者写 --xh-toast-accent
56
59
  就能把某一条整体改色;两者都没有时退回原来的 info 蓝 */
57
- border-inline-start-width: var(--xh-toast-accent-width, 4px);
60
+ border-inline-start-width: var(--xh-toast-accent-width, var(--xh-space-1));
58
61
  border-inline-start-color: var(--xh-toast-accent, var(--xh-_tone-soft, var(--xh-color-info-500)));
59
62
  border-radius: var(--xh-toast-radius, var(--xh-shape-surface));
60
63
  background: var(--xh-toast-bg, var(--xh-bg-surface-raised));
61
64
  color: var(--xh-toast-fg, var(--xh-fg-default));
62
- box-shadow: var(--xh-toast-shadow, var(--xh-elevation-3));
63
- font-size: var(--xh-toast-font-size, var(--xh-font-size-sm));
65
+ box-shadow: var(--xh-toast-shadow, var(--xh-elevation-sheet));
66
+ font-size: var(--xh-toast-font-size, var(--xh-text-secondary-size));
64
67
  line-height: var(--xh-toast-leading, var(--xh-leading-normal));
65
68
  /* 摞的定位面整面铺开且不吃指针,卡片必须自己吃回来:
66
69
  悬停按住计时、按钮可点、焦点进出,全指着这一条 */
@@ -94,7 +97,7 @@
94
97
  /* 作者可能把它写成 h2/p,外边距得先归零,否则卡片内的行距对不上 */
95
98
  margin: 0;
96
99
  color: var(--xh-toast-title-fg, var(--xh-fg-default));
97
- font-size: var(--xh-toast-title-font-size, var(--xh-font-size-md));
100
+ font-size: var(--xh-toast-title-font-size, var(--xh-text-label-size));
98
101
  font-weight: var(--xh-toast-title-font-weight, var(--xh-font-weight-semibold));
99
102
  line-height: var(--xh-toast-title-leading, var(--xh-leading-tight));
100
103
  }
@@ -102,7 +105,7 @@
102
105
  [data-scope='toast'][data-part='description'] {
103
106
  margin: 0;
104
107
  color: var(--xh-toast-description-fg, var(--xh-fg-muted));
105
- font-size: var(--xh-toast-description-font-size, var(--xh-font-size-sm));
108
+ font-size: var(--xh-toast-description-font-size, var(--xh-text-secondary-size));
106
109
  }
107
110
 
108
111
  /* 没给文案的那一个仍然要留在 DOM 里(aria-labelledby / aria-describedby 指着它),
@@ -169,6 +172,10 @@
169
172
  font: inherit;
170
173
  line-height: var(--xh-leading-none);
171
174
  cursor: pointer;
175
+ transition:
176
+ background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
177
+ color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
178
+ scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
172
179
  }
173
180
 
174
181
  /* closable=false 时连接层同时给了 hidden 与 disabled,这条是它真正收起的那一半:
@@ -178,10 +185,15 @@
178
185
  }
179
186
 
180
187
  [data-scope='toast'][data-part='close-trigger']:hover:not(:disabled) {
181
- background: var(--xh-toast-close-bg-hover, var(--xh-bg-subtle));
188
+ background: var(--xh-toast-close-bg-hover, var(--xh-bg-subtle-hover));
182
189
  color: var(--xh-toast-close-fg-hover, var(--xh-fg-default));
183
190
  }
184
191
 
192
+ [data-scope='toast'][data-part='close-trigger']:active {
193
+ background: var(--xh-toast-close-bg-active, var(--xh-bg-subtle-active));
194
+ scale: var(--xh-motion-scale-press);
195
+ }
196
+
185
197
  /* 单体控件用原生 disabled。常规路径下它与 hidden 同时出现看不见,
186
198
  但作者若在覆盖层把收起改了回来,至少还能看出这颗叉是按不动的 */
187
199
  [data-scope='toast'][data-part='close-trigger']:disabled {
@@ -193,4 +205,16 @@
193
205
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
194
206
  outline-offset: var(--xh-ring-offset);
195
207
  }
208
+
209
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
210
+ [data-scope='toast'][data-part='close-trigger']:empty::before {
211
+ content: '';
212
+ display: inline-block;
213
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
214
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
215
+ vertical-align: var(--xh-glyph-baseline-shift);
216
+ background-color: currentColor;
217
+ -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
218
+ mask: var(--xh-glyph-mark-close) center / contain no-repeat;
219
+ }
196
220
  }
package/css/toaster.css CHANGED
@@ -30,7 +30,7 @@
30
30
  position: fixed;
31
31
  inset-block: 0;
32
32
  inset-inline: 0;
33
- z-index: var(--xh-layer-toast);
33
+ z-index: var(--xh-toaster-layer, var(--xh-layer-toast));
34
34
  display: flex;
35
35
  flex-direction: column;
36
36
  /* 基线按默认落位 bottom-end 写,下面只覆盖跟它不同的那几个位 */
package/css/toggle.css CHANGED
@@ -95,14 +95,14 @@
95
95
 
96
96
  /* —— 尺寸 —— */
97
97
  [data-scope='toggle'][data-part='root'][data-size='sm'] {
98
- block-size: var(--xh-control-h-sm);
99
- padding-inline: var(--xh-control-px-sm);
100
- font-size: var(--xh-font-size-sm);
98
+ block-size: var(--xh-toggle-h, var(--xh-control-h-sm));
99
+ padding-inline: var(--xh-toggle-px, var(--xh-control-px-sm));
100
+ font-size: var(--xh-toggle-font-size, var(--xh-control-font-sm));
101
101
  }
102
102
 
103
103
  [data-scope='toggle'][data-part='root'][data-size='lg'] {
104
- block-size: var(--xh-control-h-lg);
105
- padding-inline: var(--xh-control-px-lg);
106
- font-size: var(--xh-font-size-lg);
104
+ block-size: var(--xh-toggle-h, var(--xh-control-h-lg));
105
+ padding-inline: var(--xh-toggle-px, var(--xh-control-px-lg));
106
+ font-size: var(--xh-toggle-font-size, var(--xh-control-font-lg));
107
107
  }
108
108
  }
package/css/tone.css CHANGED
@@ -18,6 +18,10 @@
18
18
  *
19
19
  * 这两个槽用的都是固定原语而不是 --xh-fg-default:实心底本身是原语色、不随主题翻,
20
20
  * 配色若跟着主题翻,暗色下就会变成白字压在浅黄底上(实测对比度 2.70)。
21
+ *
22
+ * brand 是例外:那一族的色相归使用者,所以它的底与前景走 --xh-bg-brand / --xh-fg-on-brand
23
+ * 这两个语义令牌。缺省主题下它们就解析成 brand-600 与 neutral-0,与其余五族同值;
24
+ * 改写过品牌色的使用者只改这两个令牌,实心底与它上面的字就一起跟着走。
21
25
  */
22
26
  @layer xihan.components {
23
27
  [data-tone] {
@@ -46,9 +50,9 @@
46
50
  }
47
51
 
48
52
  [data-tone='brand'] {
49
- --xh-_tone: var(--xh-color-brand-600);
53
+ --xh-_tone: var(--xh-bg-brand);
50
54
  --xh-_tone-soft: var(--xh-color-brand-500);
51
- --xh-_tone-on: var(--xh-color-neutral-0);
55
+ --xh-_tone-on: var(--xh-fg-on-brand);
52
56
  --xh-_tone-shift: var(--xh-color-neutral-950);
53
57
  }
54
58
 
@@ -88,12 +92,13 @@
88
92
 
89
93
  /* 主色本体在各自的底上有两族够不到 3:1:黄在白底上只有 2.70,中性在深色底上只有 2.54。
90
94
  语气色是固定原语、不随主题翻,所以这两族只能按主题各兜一次。
91
- 浅色是缺省态(不写 data-theme 也算浅色),深色靠属性选择器压过它 */
95
+ 浅色是缺省态(不写 data-theme 也算浅色),深色靠属性选择器压过它。
96
+ data-theme 写在语气容器自己身上还是写在祖先上都算,两种用法都成立 */
92
97
  [data-tone='warning'] {
93
98
  --xh-_tone-border-control: var(--xh-color-warning-700);
94
99
  }
95
100
 
96
- [data-theme='dark'] [data-tone='warning'] {
101
+ :is([data-theme='dark'] *, [data-theme='dark'])[data-tone='warning'] {
97
102
  --xh-_tone-border-control: var(--xh-color-warning-600);
98
103
  }
99
104
 
@@ -101,7 +106,7 @@
101
106
  --xh-_tone-border-control: var(--xh-color-neutral-600);
102
107
  }
103
108
 
104
- [data-theme='dark'] [data-tone='neutral'] {
109
+ :is([data-theme='dark'] *, [data-theme='dark'])[data-tone='neutral'] {
105
110
  --xh-_tone-border-control: var(--xh-color-neutral-550);
106
111
  }
107
112
  }
package/css/toolbar.css CHANGED
@@ -101,7 +101,7 @@
101
101
  [data-scope='toolbar'][data-part='separator'] {
102
102
  flex: none;
103
103
  align-self: stretch;
104
- border-radius: var(--xh-toolbar-separator-radius, var(--xh-radius-full));
104
+ border-radius: var(--xh-toolbar-separator-radius, var(--xh-shape-pill));
105
105
  background: var(--xh-toolbar-separator-color, var(--xh-border-default));
106
106
  }
107
107
 
package/css/tooltip.css CHANGED
@@ -1,13 +1,27 @@
1
1
  @layer xihan.motion {
2
2
  /* 动画名的查找只认「文档里有没有这个名字」:引用别处文件里的名字,那份文件不一定在场,
3
3
  动画会静默地整个不跑。每份皮肤都能单独引入,所以它用到的关键帧都写在自己身上。 */
4
- @keyframes xh-fade-in {
4
+ @keyframes xh-pop-in {
5
5
  from {
6
6
  opacity: 0;
7
+ scale: var(--xh-motion-scale-enter);
7
8
  }
8
9
 
9
10
  to {
10
11
  opacity: 1;
12
+ scale: 1;
13
+ }
14
+ }
15
+
16
+ @keyframes xh-pop-out {
17
+ from {
18
+ opacity: 1;
19
+ scale: 1;
20
+ }
21
+
22
+ to {
23
+ opacity: 0;
24
+ scale: var(--xh-motion-scale-enter);
11
25
  }
12
26
  }
13
27
  }
@@ -40,7 +54,7 @@
40
54
  position: fixed;
41
55
  inset-block-start: 0;
42
56
  inset-inline-start: 0;
43
- z-index: var(--xh-layer-tooltip);
57
+ z-index: var(--xh-tooltip-layer, var(--xh-layer-tooltip));
44
58
  /* 浮层不承载交互:指针必须能穿过去点到底下的东西 */
45
59
  pointer-events: none;
46
60
  }
@@ -55,25 +69,36 @@
55
69
  箭头是它的后代,语气槽一并继承 */
56
70
  --xh-_tooltip-py: var(--xh-space-1);
57
71
  --xh-_tooltip-px: var(--xh-space-2);
58
- --xh-_tooltip-font-size: var(--xh-font-size-sm);
72
+ --xh-_tooltip-font-size: var(--xh-text-secondary-size);
59
73
 
60
74
  /* 与 positioner 相反:浮层本体要能接指针,指针停在提示上就不该收起
61
75
  (长文案需要停留细看)。positioner 仍是 none,空白区域照样点得穿。 */
76
+ /* 显式声明 display 是为了盖掉 UA 的 [hidden]{display:none}:收起那一帧 content 仍带 hidden,
77
+ 盒子得先在,退场动画才播得出来。真正的收起由宿主在退场结束后落成内联 display */
78
+ display: block;
62
79
  pointer-events: auto;
63
80
  max-inline-size: var(--xh-tooltip-max-w, var(--xh-overlay-max-w));
64
81
  padding-block: var(--xh-tooltip-py, var(--xh-_tooltip-py));
65
82
  padding-inline: var(--xh-tooltip-px, var(--xh-_tooltip-px));
83
+ /* 这里刻意用 control 而不是浮层那档 surface:提示气泡通常只有一行字、高度接近控件,
84
+ 8px 圆角在这个尺寸上占比过大,看着会发胖。档位定义里为此单列了一条 */
66
85
  border-radius: var(--xh-tooltip-radius, var(--xh-shape-control));
67
86
  /* 实心底与其上的文字色随语气走。没写 data-tone 时两个槽都没被声明,退回原来的取值 */
68
87
  background: var(--xh-tooltip-bg, var(--xh-_tone, var(--xh-fg-default)));
69
88
  color: var(--xh-tooltip-fg, var(--xh-_tone-on, var(--xh-bg-surface)));
70
89
  font-size: var(--xh-tooltip-font-size, var(--xh-_tooltip-font-size));
71
90
  line-height: var(--xh-leading-normal);
72
- box-shadow: var(--xh-tooltip-shadow, var(--xh-elevation-2));
91
+ box-shadow: var(--xh-tooltip-shadow, var(--xh-elevation-floating));
73
92
  }
74
93
 
75
94
  [data-scope='tooltip'][data-part='content'][data-state='open'] {
76
- animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
95
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
96
+ }
97
+
98
+ /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
99
+ 免得动画结束到真收起之间闪一下原样 */
100
+ [data-scope='tooltip'][data-part='content'][data-state='closed'] {
101
+ animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
77
102
  }
78
103
 
79
104
  /* —— 尺寸 —— */
@@ -82,46 +107,24 @@
82
107
  [data-scope='tooltip'][data-part='content'][data-size='sm'] {
83
108
  --xh-_tooltip-py: var(--xh-space-0_5);
84
109
  --xh-_tooltip-px: var(--xh-space-1_5);
85
- --xh-_tooltip-font-size: var(--xh-font-size-xs);
110
+ --xh-_tooltip-font-size: var(--xh-control-caption-sm);
86
111
  }
87
112
 
88
113
  [data-scope='tooltip'][data-part='content'][data-size='lg'] {
89
114
  --xh-_tooltip-py: var(--xh-space-1_5);
90
115
  --xh-_tooltip-px: var(--xh-space-2_5);
91
- --xh-_tooltip-font-size: var(--xh-font-size-md);
116
+ --xh-_tooltip-font-size: var(--xh-control-caption-lg);
92
117
  }
93
118
 
94
- /* 箭头是旋转 45° 的方块,按自报的落定朝向贴在 content 对侧边上;
119
+ /* 箭头的底色与描边色,几何在 overlay-arrow.css。
95
120
  交叉轴落点由定位引擎经内联自定义属性写进来,没给时退回居中 */
96
121
  [data-scope='tooltip'][data-part='arrow'] {
97
- --xh-_tooltip-arrow-size: var(--xh-tooltip-arrow-size, var(--xh-overlay-arrow-size));
98
122
  --xh-_tooltip-arrow-x: 50%;
99
123
  --xh-_tooltip-arrow-y: 50%;
124
+ --xh-_overlay-arrow-size: var(--xh-tooltip-arrow-size, var(--xh-overlay-arrow-size));
125
+ --xh-_overlay-arrow-x: var(--xh-_tooltip-arrow-x);
126
+ --xh-_overlay-arrow-y: var(--xh-_tooltip-arrow-y);
100
127
 
101
- position: absolute;
102
- inline-size: var(--xh-_tooltip-arrow-size);
103
- block-size: var(--xh-_tooltip-arrow-size);
104
128
  background: var(--xh-tooltip-bg, var(--xh-_tone, var(--xh-fg-default)));
105
- transform: rotate(45deg);
106
- }
107
-
108
- [data-scope='tooltip'][data-part='arrow'][data-placement^='bottom'] {
109
- inset-block-start: calc(var(--xh-_tooltip-arrow-size) / -2);
110
- inset-inline-start: calc(var(--xh-_tooltip-arrow-x) - var(--xh-_tooltip-arrow-size) / 2);
111
- }
112
-
113
- [data-scope='tooltip'][data-part='arrow'][data-placement^='top'] {
114
- inset-block-end: calc(var(--xh-_tooltip-arrow-size) / -2);
115
- inset-inline-start: calc(var(--xh-_tooltip-arrow-x) - var(--xh-_tooltip-arrow-size) / 2);
116
- }
117
-
118
- [data-scope='tooltip'][data-part='arrow'][data-placement^='left'] {
119
- inset-block-start: calc(var(--xh-_tooltip-arrow-y) - var(--xh-_tooltip-arrow-size) / 2);
120
- inset-inline-end: calc(var(--xh-_tooltip-arrow-size) / -2);
121
- }
122
-
123
- [data-scope='tooltip'][data-part='arrow'][data-placement^='right'] {
124
- inset-block-start: calc(var(--xh-_tooltip-arrow-y) - var(--xh-_tooltip-arrow-size) / 2);
125
- inset-inline-start: calc(var(--xh-_tooltip-arrow-size) / -2);
126
129
  }
127
130
  }