@xihan-ui/styles 1.0.0-alpha.2 → 1.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 (122) hide show
  1. package/CHANGELOG.md +2177 -0
  2. package/README.md +1 -1
  3. package/css/accordion.css +80 -6
  4. package/css/alert.css +43 -14
  5. package/css/anchor.css +8 -8
  6. package/css/avatar-group.css +7 -3
  7. package/css/avatar.css +9 -3
  8. package/css/back-top.css +22 -1
  9. package/css/badge.css +104 -32
  10. package/css/breadcrumb.css +25 -5
  11. package/css/button-group.css +18 -13
  12. package/css/button.css +48 -11
  13. package/css/calendar.css +150 -7
  14. package/css/card.css +20 -11
  15. package/css/carousel.css +36 -5
  16. package/css/cascader.css +211 -124
  17. package/css/checkbox-group.css +72 -22
  18. package/css/checkbox.css +70 -13
  19. package/css/clipboard.css +2 -1
  20. package/css/code-block.css +12 -7
  21. package/css/collapsible.css +49 -3
  22. package/css/color-picker.css +132 -46
  23. package/css/combobox.css +132 -60
  24. package/css/composer.css +5 -3
  25. package/css/context-menu.css +113 -74
  26. package/css/date-field.css +93 -16
  27. package/css/date-picker.css +293 -72
  28. package/css/descriptions.css +11 -5
  29. package/css/dialog.css +47 -14
  30. package/css/download-trigger.css +76 -0
  31. package/css/drawer.css +57 -16
  32. package/css/dynamic-input.css +75 -17
  33. package/css/editable.css +12 -10
  34. package/css/ellipsis.css +7 -1
  35. package/css/empty-state.css +22 -12
  36. package/css/field.css +16 -6
  37. package/css/fieldset.css +69 -0
  38. package/css/file-upload.css +46 -8
  39. package/css/flex.css +13 -7
  40. package/css/float-button.css +23 -1
  41. package/css/floating-panel.css +316 -0
  42. package/css/form.css +4 -4
  43. package/css/grid.css +11 -5
  44. package/css/heatmap.css +411 -0
  45. package/css/highlight.css +2 -2
  46. package/css/hotkeys.css +90 -0
  47. package/css/hover-card.css +43 -45
  48. package/css/image-cropper.css +233 -0
  49. package/css/image-viewer.css +155 -17
  50. package/css/image.css +2 -2
  51. package/css/infinite-scroll.css +1 -1
  52. package/css/json-viewer.css +274 -0
  53. package/css/layout.css +19 -15
  54. package/css/list.css +22 -13
  55. package/css/listbox.css +24 -6
  56. package/css/loading-bar.css +12 -5
  57. package/css/log.css +7 -3
  58. package/css/marquee.css +9 -0
  59. package/css/masonry.css +63 -0
  60. package/css/mention.css +100 -36
  61. package/css/menu.css +127 -50
  62. package/css/menubar.css +155 -61
  63. package/css/navigation-menu.css +56 -31
  64. package/css/notification.css +377 -0
  65. package/css/number-animation.css +3 -3
  66. package/css/number-field.css +182 -19
  67. package/css/overlay-arrow.css +51 -0
  68. package/css/page-header.css +12 -5
  69. package/css/pagination.css +171 -14
  70. package/css/password-input.css +356 -0
  71. package/css/pin-input.css +15 -12
  72. package/css/popconfirm.css +55 -12
  73. package/css/popover.css +73 -45
  74. package/css/popselect.css +207 -57
  75. package/css/progress.css +54 -8
  76. package/css/qr-code.css +1 -1
  77. package/css/radio-group.css +27 -10
  78. package/css/rating.css +4 -4
  79. package/css/reset.css +17 -0
  80. package/css/result.css +21 -11
  81. package/css/scroll-area.css +61 -89
  82. package/css/scrollbar.css +170 -0
  83. package/css/segmented.css +215 -0
  84. package/css/select.css +298 -131
  85. package/css/separator.css +2 -2
  86. package/css/side-nav.css +127 -24
  87. package/css/signature-pad.css +144 -0
  88. package/css/skeleton.css +7 -1
  89. package/css/slider.css +14 -12
  90. package/css/space.css +117 -0
  91. package/css/spinner.css +22 -10
  92. package/css/statistic.css +9 -9
  93. package/css/steps.css +29 -12
  94. package/css/switch.css +57 -8
  95. package/css/table.css +146 -44
  96. package/css/tabs.css +13 -5
  97. package/css/tag.css +179 -0
  98. package/css/tags-input.css +80 -42
  99. package/css/text-field.css +151 -38
  100. package/css/thread.css +11 -3
  101. package/css/time-field.css +99 -18
  102. package/css/time-picker.css +261 -71
  103. package/css/timeline.css +15 -15
  104. package/css/timer.css +119 -0
  105. package/css/toast.css +129 -55
  106. package/css/toggle-group.css +30 -4
  107. package/css/toggle.css +12 -6
  108. package/css/tone.css +57 -22
  109. package/css/toolbar.css +1 -1
  110. package/css/tooltip.css +40 -31
  111. package/css/tour.css +112 -61
  112. package/css/transfer.css +98 -21
  113. package/css/tree-select.css +215 -89
  114. package/css/tree.css +131 -5
  115. package/css/typography.css +5 -5
  116. package/css/undefined.css +12 -1
  117. package/css/virtualizer.css +3 -1
  118. package/css/watermark.css +1 -2
  119. package/index.css +18 -1
  120. package/index.unlayered.css +10356 -3255
  121. package/package.json +20 -4
  122. package/css/toaster.css +0 -74
@@ -4,13 +4,99 @@
4
4
  --xh-time-picker-skin: 1;
5
5
  }
6
6
 
7
+ /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
8
+ [data-scope='time-picker'][data-part='positioner'] {
9
+ position: fixed;
10
+ z-index: var(--xh-time-picker-layer, var(--xh-layer-popover));
11
+ /* 空壳不吃指针,交互只发生在 content 里 */
12
+ pointer-events: none;
13
+ }
14
+
15
+ /* 锚点被滚出可视区:整个浮层随之收起 */
16
+ [data-scope='time-picker'][data-part='positioner'][data-hidden] {
17
+ visibility: hidden;
18
+ }
19
+
20
+ /* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
21
+ [data-scope='time-picker']:is([data-part='root'], [data-part='positioner']) {
22
+ /* 尺寸档只换这几个私有槽,标题、输入行与浮层里的格子都从这两处继承它们,
23
+ 换档不必给每个部件各写一条选择器 */
24
+ --xh-_time-picker-control-h: var(--xh-control-h-md);
25
+ --xh-_time-picker-control-px: var(--xh-control-px-md);
26
+ --xh-_time-picker-gap: var(--xh-control-gap-md);
27
+ --xh-_time-picker-font-size: var(--xh-control-font-md);
28
+ --xh-_time-picker-label-font-size: var(--xh-control-font-md);
29
+ --xh-_time-picker-item-px: var(--xh-control-px-md);
30
+
31
+ /* 形态档只换这三个私有槽:底色与两档描边 */
32
+ --xh-_time-picker-control-bg: var(--xh-bg-canvas);
33
+ --xh-_time-picker-control-border: var(--xh-border-control);
34
+ --xh-_time-picker-control-border-hover: var(--xh-border-control-hover);
35
+
36
+ /* 聚焦环、段位反白与列里的选中随语气走。没写 data-tone 时这几个 --xh-_tone* 没被声明,
37
+ 退回原来的焦点色与品牌色 */
38
+ --xh-_time-picker-ring: var(--xh-ring-focus);
39
+ --xh-_time-picker-accent: var(--xh-_tone, var(--xh-bg-brand));
40
+ --xh-_time-picker-accent-hover: var(--xh-_tone-hover, var(--xh-bg-brand-hover));
41
+ --xh-_time-picker-accent-fg: var(--xh-_tone-on, var(--xh-fg-on-brand));
42
+ }
43
+
7
44
  /* 与文本框、时间输入同一套堆叠:标签一行、控件一行 */
8
45
  [data-scope='time-picker'][data-part='root'] {
46
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
47
+ --xh-icon-size: var(--xh-time-picker-icon-size, var(--xh-glyph-size-md));
48
+
9
49
  display: inline-flex;
10
50
  flex-direction: column;
11
51
  gap: var(--xh-time-picker-gap, var(--xh-space-1));
12
52
  }
13
53
 
54
+ /* —— 尺寸 —— */
55
+ /* 缺省档写在上面的基础规则里 */
56
+ [data-scope='time-picker']:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
57
+ --xh-icon-size: var(--xh-time-picker-icon-size, var(--xh-glyph-size-sm));
58
+ --xh-_time-picker-control-h: var(--xh-control-h-sm);
59
+ --xh-_time-picker-control-px: var(--xh-control-px-sm);
60
+ --xh-_time-picker-gap: var(--xh-control-gap-sm);
61
+ --xh-_time-picker-font-size: var(--xh-control-font-sm);
62
+ --xh-_time-picker-label-font-size: var(--xh-control-font-sm);
63
+ --xh-_time-picker-item-px: var(--xh-control-px-sm);
64
+ }
65
+
66
+ [data-scope='time-picker']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
67
+ --xh-icon-size: var(--xh-time-picker-icon-size, var(--xh-glyph-size-lg));
68
+ --xh-_time-picker-control-h: var(--xh-control-h-lg);
69
+ --xh-_time-picker-control-px: var(--xh-control-px-lg);
70
+ --xh-_time-picker-gap: var(--xh-control-gap-lg);
71
+ --xh-_time-picker-font-size: var(--xh-control-font-lg);
72
+ --xh-_time-picker-label-font-size: var(--xh-control-font-lg);
73
+ --xh-_time-picker-item-px: var(--xh-control-px-lg);
74
+ }
75
+
76
+ /* —— 形态 —— */
77
+ /* 输入类不做实心档:填满一个要往里打字的框,字与底就没法同时读。
78
+ 形态只决定底与描边怎么画,用哪族颜色由 data-tone 决定 */
79
+ [data-scope='time-picker']:is([data-part='root'], [data-part='positioner'])[data-variant='outline'] {
80
+ --xh-_time-picker-control-bg: var(--xh-bg-canvas);
81
+ --xh-_time-picker-control-border: var(--xh-border-control);
82
+ --xh-_time-picker-control-border-hover: var(--xh-border-control-hover);
83
+ }
84
+
85
+ /* 填充式:底色顶替描边表达边界。描边只退成透明而不去掉,1px 的位置留着,
86
+ 与 outline 档并排时基线对得上、聚焦画描边也不引起跳动 */
87
+ [data-scope='time-picker']:is([data-part='root'], [data-part='positioner'])[data-variant='subtle'] {
88
+ --xh-_time-picker-control-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
89
+ --xh-_time-picker-control-border: transparent;
90
+ --xh-_time-picker-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
91
+ }
92
+
93
+ /* 无框:底与常态描边透明,悬停与聚焦浮出描边 */
94
+ [data-scope='time-picker']:is([data-part='root'], [data-part='positioner'])[data-variant='ghost'] {
95
+ --xh-_time-picker-control-bg: transparent;
96
+ --xh-_time-picker-control-border: transparent;
97
+ --xh-_time-picker-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
98
+ }
99
+
14
100
  /* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
15
101
  [data-scope='time-picker'][data-part='root'][hidden] {
16
102
  display: none;
@@ -18,12 +104,9 @@
18
104
 
19
105
  [data-scope='time-picker'][data-part='label'] {
20
106
  color: var(--xh-time-picker-label-fg, var(--xh-fg-default));
21
- font-size: var(--xh-time-picker-label-font-size, var(--xh-text-label-size));
107
+ font-size: var(--xh-time-picker-label-font-size, var(--xh-_time-picker-label-font-size));
22
108
  font-weight: var(--xh-time-picker-label-font-weight, var(--xh-text-label-weight));
23
109
  line-height: var(--xh-leading-none);
24
- /* 点标题会把焦点送到第一段(段不是能被 for 指向的原生控件,这条由连接层接管),
25
- 指针得如实反映它可点 */
26
- cursor: pointer;
27
110
  }
28
111
 
29
112
  [data-scope='time-picker'][data-part='label'][data-disabled] {
@@ -34,19 +117,20 @@
34
117
  /* 画成一个框的是 control:几段文字、展开按钮、清空按钮要看起来是一体的,
35
118
  边框长在其中任何一个身上都会把另外几个割在框外 */
36
119
  [data-scope='time-picker'][data-part='control'] {
120
+ min-inline-size: var(--xh-time-picker-control-min-w, var(--xh-control-min-w));
37
121
  display: inline-flex;
38
122
  align-items: center;
39
- gap: var(--xh-time-picker-control-gap, var(--xh-control-gap-md));
40
- block-size: var(--xh-time-picker-control-h, var(--xh-control-h-md));
41
- padding-inline: var(--xh-time-picker-control-px, var(--xh-control-px-md));
123
+ gap: var(--xh-time-picker-control-gap, var(--xh-_time-picker-gap));
124
+ block-size: var(--xh-time-picker-control-h, var(--xh-_time-picker-control-h));
125
+ padding-inline: var(--xh-time-picker-control-px, var(--xh-_time-picker-control-px));
42
126
  padding-block: 0;
43
- border: var(--xh-stroke-thin) solid var(--xh-time-picker-control-border, var(--xh-border-control));
127
+ border: var(--xh-stroke-thin) solid var(--xh-time-picker-control-border, var(--xh-_time-picker-control-border));
44
128
  border-radius: var(--xh-time-picker-control-radius, var(--xh-shape-control));
45
- background: var(--xh-time-picker-control-bg, var(--xh-bg-canvas));
129
+ background: var(--xh-time-picker-control-bg, var(--xh-_time-picker-control-bg));
46
130
  color: var(--xh-time-picker-control-fg, var(--xh-fg-default));
47
131
  /* 表单控件不继承页面字体,只给字号会让它用 UA 默认字族,与周围文本对不上 */
48
132
  font-family: inherit;
49
- font-size: var(--xh-time-picker-font-size, var(--xh-text-body-size));
133
+ font-size: var(--xh-time-picker-font-size, var(--xh-_time-picker-font-size));
50
134
  /* 等宽数字:各位字宽不一时逐段填入会让整行左右跳 */
51
135
  font-variant-numeric: tabular-nums;
52
136
  line-height: var(--xh-leading-normal);
@@ -59,17 +143,22 @@
59
143
 
60
144
  /* hover 只在中性态换描边:invalid 正拿边框颜色说事,被 hover 盖掉那条信息就没了 */
61
145
  [data-scope='time-picker'][data-part='control']:hover:not([data-disabled], [data-invalid]) {
62
- border-color: var(--xh-time-picker-control-border-hover, var(--xh-border-control-hover));
146
+ border-color: var(--xh-time-picker-control-border-hover, var(--xh-_time-picker-control-border-hover));
63
147
  }
64
148
 
65
149
  /* 焦点真正落在段或按钮上,但整块看起来才是一个控件:内部有焦点时整框亮起来。
66
150
  control 自己不占 Tab 位,所以这里写的是 focus-within 而不是 focus-visible */
67
151
  [data-scope='time-picker'][data-part='control']:focus-within:not([data-disabled]) {
68
- border-color: var(--xh-time-picker-control-border-focus, var(--xh-ring-focus));
152
+ border-color: var(--xh-time-picker-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
153
+ outline: var(--xh-ring-width) solid var(--xh-_time-picker-ring);
154
+ outline-offset: var(--xh-ring-offset);
69
155
  }
70
156
 
71
157
  [data-scope='time-picker'][data-part='control'][data-invalid] {
72
- border-color: var(--xh-time-picker-control-border-invalid, var(--xh-color-danger-500));
158
+ border-color: var(--xh-time-picker-control-border-invalid, var(--xh-border-invalid));
159
+
160
+ /* 校验失败时环也跟着变红:两圈等宽相邻却一红一蓝,读的人不知道哪个才是当前状态 */
161
+ --xh-_time-picker-ring: var(--xh-ring-invalid);
73
162
  }
74
163
 
75
164
  /* 只读仍可聚焦、可换段,所以不置灰,只把底色压下去表示"改不动" */
@@ -84,13 +173,25 @@
84
173
  cursor: not-allowed;
85
174
  }
86
175
 
87
- /* 每一段是一小块可聚焦区,紧挨着排;分隔符由作者写在段与段之间的普通节点里,
88
- 不在角色表内,所以间距只能长在段自己身上 */
176
+ /* 段位与作者写在段间的分隔符都在这一层里:它占满盒里剩下的宽度,
177
+ 尾部按钮因此靠在框内末端 */
178
+ [data-scope='time-picker'][data-part='segment-group'] {
179
+ display: inline-flex;
180
+ flex: 1 1 auto;
181
+ align-items: center;
182
+ min-inline-size: 0;
183
+ }
184
+
185
+ [data-scope='time-picker'][data-part='segment-group'][hidden] {
186
+ display: none;
187
+ }
188
+
189
+ /* 每一段是一小块可聚焦区,紧挨着排;间距长在段自己身上 */
89
190
  [data-scope='time-picker'][data-part='input'] {
90
191
  display: inline-block;
91
- padding-inline: var(--xh-time-picker-segment-px, var(--xh-space-0_5));
192
+ padding-inline: var(--xh-time-picker-segment-px, var(--xh-space-1));
92
193
  padding-block: 0;
93
- border-radius: var(--xh-time-picker-segment-radius, var(--xh-radius-sm));
194
+ border-radius: var(--xh-time-picker-segment-radius, var(--xh-shape-inset));
94
195
  color: inherit;
95
196
  font-variant-numeric: inherit;
96
197
  text-align: center;
@@ -109,21 +210,21 @@
109
210
 
110
211
  /* 还没填的段压成弱色:一行里哪几段是占位符,一眼要看得出来 */
111
212
  [data-scope='time-picker'][data-part='input'][data-placeholder] {
112
- color: var(--xh-time-picker-segment-fg-placeholder, var(--xh-fg-subtle));
213
+ color: var(--xh-time-picker-placeholder-fg, var(--xh-fg-subtle));
113
214
  }
114
215
 
115
216
  /* 一行段长得差不多,光有边框亮起来看不出正在改哪一段:当前段必须自己有底色。
116
217
  data-focus 由机器给(它知道谁是当前段),:focus-visible 兜住机器状态还没回流的那一帧 */
117
218
  [data-scope='time-picker'][data-part='input'][data-focus]:not([data-disabled]),
118
219
  [data-scope='time-picker'][data-part='input']:focus-visible {
119
- background: var(--xh-time-picker-segment-bg-focus, var(--xh-bg-brand));
120
- color: var(--xh-time-picker-segment-fg-focus, var(--xh-fg-on-brand));
220
+ background: var(--xh-time-picker-segment-bg-focus, var(--xh-_time-picker-accent));
221
+ color: var(--xh-time-picker-segment-fg-focus, var(--xh-_time-picker-accent-fg));
121
222
  outline: none;
122
223
  }
123
224
 
124
225
  /* 焦点态用了品牌底色之后,占位符那条弱色会被它盖住,这里明确让位给焦点态 */
125
226
  [data-scope='time-picker'][data-part='input'][data-focus][data-placeholder]:not([data-disabled]) {
126
- color: var(--xh-time-picker-segment-fg-focus, var(--xh-fg-on-brand));
227
+ color: var(--xh-time-picker-segment-fg-focus, var(--xh-_time-picker-accent-fg));
127
228
  }
128
229
 
129
230
  [data-scope='time-picker'][data-part='input']:hover:not([data-focus], [data-disabled]) {
@@ -151,82 +252,75 @@
151
252
  background: var(--xh-time-picker-action-bg, transparent);
152
253
  color: var(--xh-time-picker-action-fg, var(--xh-fg-muted));
153
254
  font-family: inherit;
154
- font-size: var(--xh-time-picker-action-font-size, var(--xh-font-size-sm));
255
+ font-size: var(--xh-time-picker-action-font-size, var(--xh-text-secondary-size));
155
256
  line-height: var(--xh-leading-none);
156
257
  cursor: pointer;
157
258
  user-select: none;
158
- transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
259
+ transition:
260
+ background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
261
+ scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
159
262
  }
160
263
 
264
+
161
265
  [data-scope='time-picker'][data-part='trigger'][hidden],
162
266
  [data-scope='time-picker'][data-part='clear-trigger'][hidden] {
163
267
  display: none;
164
268
  }
165
269
 
166
- /* 触发器把整行推到最右:它与清空按钮之间不留缝,两者一起靠框内末端 */
167
- [data-scope='time-picker'][data-part='trigger'] {
168
- margin-inline-start: auto;
169
- }
170
-
171
270
  [data-scope='time-picker'][data-part='trigger']:hover:not(:disabled),
172
- [data-scope='time-picker'][data-part='clear-trigger']:hover:not(:disabled) {
271
+ [data-scope='time-picker'][data-part='clear-trigger']:hover {
173
272
  background: var(--xh-time-picker-action-bg-hover, var(--xh-bg-subtle-hover));
174
273
  color: var(--xh-time-picker-action-fg-hover, var(--xh-fg-default));
175
274
  }
176
275
 
177
- [data-scope='time-picker'][data-part='trigger']:active:not(:disabled),
178
- [data-scope='time-picker'][data-part='clear-trigger']:active:not(:disabled) {
276
+ [data-scope='time-picker'][data-part='trigger']:active:not(:disabled) {
277
+ background: var(--xh-time-picker-action-bg-active, var(--xh-bg-subtle-active));
278
+ }
279
+
280
+ /* 清空钮按下时换底并微缩,给指针一个按到了的反馈 */
281
+ [data-scope='time-picker'][data-part='clear-trigger']:active {
179
282
  background: var(--xh-time-picker-action-bg-active, var(--xh-bg-subtle-active));
283
+ scale: var(--xh-motion-scale-press);
180
284
  }
181
285
 
182
- /* 触发器是常规 Tab 停靠点,落焦必须看得见;清空按钮退出了 Tab 序列,
183
- 这条是给程序化聚焦兜底 */
184
- [data-scope='time-picker'][data-part='trigger']:focus-visible,
286
+ /* 清空按钮退出了 Tab 序列,这条是给程序化聚焦兜底;
287
+ 展开钮是常规 Tab 停靠点,它落焦时环由盒的 :focus-within 画,这里不再套一圈 */
185
288
  [data-scope='time-picker'][data-part='clear-trigger']:focus-visible {
186
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
289
+ outline: var(--xh-ring-width) solid var(--xh-_time-picker-ring);
187
290
  outline-offset: var(--xh-ring-offset);
188
291
  }
189
292
 
190
- /* 两个按钮都是单体控件,禁用走原生 :disabled(列里的格一律 data-disabled) */
191
- [data-scope='time-picker'][data-part='trigger']:disabled,
192
- [data-scope='time-picker'][data-part='clear-trigger']:disabled {
293
+ /* 下拉钮是单体控件,禁用走原生 :disabled(列里的格一律 data-disabled);
294
+ 清空钮没值即收起,不做灰态 */
295
+ [data-scope='time-picker'][data-part='trigger']:disabled {
193
296
  background: var(--xh-time-picker-action-bg, transparent);
194
297
  color: var(--xh-fg-disabled);
195
298
  cursor: not-allowed;
196
299
  }
197
300
 
198
- /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
199
- [data-scope='time-picker'][data-part='positioner'] {
200
- position: fixed;
201
- z-index: var(--xh-layer-popover);
202
- /* 空壳不吃指针,交互只发生在 content 里 */
203
- pointer-events: none;
204
- }
205
-
206
- /* 锚点被滚出可视区:整个浮层随之收起 */
207
- [data-scope='time-picker'][data-part='positioner'][data-hidden] {
208
- visibility: hidden;
209
- }
210
-
211
301
  /* 几列并排:整体高度由列自己撑,滚动发生在列里而不是整个面板上——
212
302
  整面板滚会让时列与分列一起走,挑分的时候时就看不见了 */
213
303
  [data-scope='time-picker'][data-part='content'] {
214
304
  display: flex;
215
305
  align-items: stretch;
216
- padding: var(--xh-time-picker-content-p, var(--xh-space-1));
306
+ padding-block: var(--xh-time-picker-content-py, var(--xh-space-1));
307
+ padding-inline: var(--xh-time-picker-content-px, var(--xh-space-1));
308
+ /* 列自己定高,面板整体不该再长过页内滚动面那一档 */
309
+ max-block-size: var(--xh-time-picker-content-max-h, var(--xh-viewport-h-lg));
217
310
  border: var(--xh-stroke-thin) solid var(--xh-time-picker-content-border, var(--xh-border-default));
218
311
  border-radius: var(--xh-time-picker-content-radius, var(--xh-shape-surface));
219
312
  background: var(--xh-time-picker-content-bg, var(--xh-bg-surface));
220
313
  color: var(--xh-time-picker-content-fg, var(--xh-fg-default));
221
314
  font-variant-numeric: tabular-nums;
222
- box-shadow: var(--xh-time-picker-content-shadow, var(--xh-elevation-2));
315
+ box-shadow: var(--xh-time-picker-content-shadow, var(--xh-elevation-floating));
223
316
  pointer-events: auto;
224
317
  }
225
318
 
226
- /* display 会盖掉 hidden 属性的 UA 规则,收起态显式让位 */
227
- [data-scope='time-picker'][data-part='content'][hidden] {
228
- display: none;
229
- }
319
+ /* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
320
+ 收起态连接层会给 contenthidden,而上面那条 display 正是要盖掉 UA 的
321
+ [hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
322
+ 真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
323
+ 其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
230
324
 
231
325
  /* 面板本身不承载焦点(焦点在某一列的某一格上),落焦时不画环 */
232
326
  [data-scope='time-picker'][data-part='content']:focus-visible {
@@ -234,7 +328,68 @@
234
328
  }
235
329
 
236
330
  [data-scope='time-picker'][data-part='content'][data-state='open'] {
237
- animation: xh-time-picker-panel-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
331
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
332
+ }
333
+
334
+ /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
335
+ 免得动画结束到真收起之间闪一下原样 */
336
+ [data-scope='time-picker'][data-part='content'][data-state='closed'] {
337
+ animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
338
+ }
339
+
340
+ /* 快捷选项也是一列,与时分秒那几列并排,排在行内起始一侧 */
341
+ [data-scope='time-picker'][data-part='presets'] {
342
+ display: flex;
343
+ flex: none;
344
+ flex-direction: column;
345
+ gap: var(--xh-time-picker-presets-gap, var(--xh-list-option-gap));
346
+ max-block-size: var(--xh-time-picker-presets-h, var(--xh-viewport-h-sm));
347
+ padding-inline: var(--xh-time-picker-presets-px, var(--xh-space-1));
348
+ overflow-y: auto;
349
+ border-inline-end: var(--xh-stroke-thin) solid var(--xh-time-picker-column-divider, var(--xh-border-subtle));
350
+ scrollbar-width: thin;
351
+ }
352
+
353
+ [data-scope='time-picker'][data-part='presets'][hidden] {
354
+ display: none;
355
+ }
356
+
357
+ [data-scope='time-picker'][data-part='preset'] {
358
+ padding-block: var(--xh-time-picker-preset-py, var(--xh-space-1));
359
+ padding-inline: var(--xh-time-picker-preset-px, var(--xh-space-3));
360
+ border-radius: var(--xh-time-picker-preset-radius, var(--xh-shape-control));
361
+ font-size: var(--xh-text-secondary-size);
362
+ line-height: var(--xh-leading-normal);
363
+ white-space: nowrap;
364
+ cursor: pointer;
365
+ user-select: none;
366
+ }
367
+
368
+ /* 悬停与键盘锚点共用中性轻档,命中那一条才走品牌底;禁用的不响应悬停 */
369
+ [data-scope='time-picker'][data-part='preset']:hover:not([data-disabled]) {
370
+ background: var(--xh-time-picker-preset-bg-hover, var(--xh-bg-subtle));
371
+ }
372
+
373
+ [data-scope='time-picker'][data-part='preset']:focus-visible,
374
+ [data-scope='time-picker'][data-part='presets']:focus-visible {
375
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
376
+ outline-offset: calc(-1 * var(--xh-ring-width));
377
+ }
378
+
379
+ /* 命中的那一条与选中的格子同一副实心底:同一份浮层里两种「选中」不该长成两个样 */
380
+ [data-scope='time-picker'][data-part='preset'][data-state='checked'] {
381
+ background: var(--xh-time-picker-preset-bg-checked, var(--xh-_time-picker-accent));
382
+ color: var(--xh-time-picker-preset-fg-checked, var(--xh-_time-picker-accent-fg));
383
+ font-weight: var(--xh-font-weight-medium);
384
+ }
385
+
386
+ [data-scope='time-picker'][data-part='preset'][data-state='checked']:hover:not([data-disabled]) {
387
+ background: var(--xh-time-picker-preset-bg-checked-hover, var(--xh-_time-picker-accent-hover));
388
+ }
389
+
390
+ [data-scope='time-picker'][data-part='preset'][data-disabled] {
391
+ color: var(--xh-time-picker-preset-fg-disabled, var(--xh-fg-disabled));
392
+ cursor: not-allowed;
238
393
  }
239
394
 
240
395
  /* 一列一个滚动区:列与列之间用细分隔线,视觉上"时 | 分 | 秒"三栏分明 */
@@ -242,9 +397,10 @@
242
397
  display: flex;
243
398
  flex: none;
244
399
  flex-direction: column;
245
- gap: var(--xh-time-picker-column-gap, var(--xh-space-0_5));
400
+ gap: var(--xh-time-picker-column-gap, var(--xh-list-option-gap));
246
401
  min-inline-size: var(--xh-time-picker-column-min-w, 3.5rem);
247
- max-block-size: var(--xh-time-picker-column-max-h, 12rem);
402
+ /* 几列并排:定高而不是随内容收,否则时列与分列的可选值一多一少就错位 */
403
+ block-size: var(--xh-time-picker-column-h, var(--xh-viewport-h-sm));
248
404
  padding-inline: var(--xh-time-picker-column-px, var(--xh-space-1));
249
405
  overflow-y: auto;
250
406
  /* 滚动容器在某些浏览器里会被自动塞进 Tab 序列,是否画环见下方按 tabindex 分档的两条 */
@@ -263,7 +419,7 @@
263
419
  /* 焦点落在列上有两种情形:指针打开、这一段还空着、还没有任何格当锚点,或整列被界裁空。
264
420
  那一刻它认领着 Tab 位,环画在列内沿;有锚点时环长在格上,列不再画 */
265
421
  [data-scope='time-picker'][data-part='column'][tabindex='0']:focus-visible {
266
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
422
+ outline: var(--xh-ring-width) solid var(--xh-_time-picker-ring);
267
423
  outline-offset: calc(-1 * var(--xh-ring-width));
268
424
  }
269
425
 
@@ -276,11 +432,11 @@
276
432
  flex: none;
277
433
  align-items: center;
278
434
  justify-content: center;
279
- padding-block: var(--xh-time-picker-item-py, var(--xh-space-1_5));
280
- padding-inline: var(--xh-time-picker-item-px, var(--xh-control-px-md));
435
+ padding-block: var(--xh-time-picker-item-py, var(--xh-list-option-py-md));
436
+ padding-inline: var(--xh-time-picker-item-px, var(--xh-_time-picker-item-px));
281
437
  border-radius: var(--xh-time-picker-item-radius, var(--xh-shape-control));
282
438
  color: var(--xh-time-picker-item-fg, var(--xh-fg-default));
283
- font-size: var(--xh-time-picker-item-font-size, var(--xh-text-body-size));
439
+ font-size: var(--xh-time-picker-item-font-size, var(--xh-_time-picker-font-size));
284
440
  /* 居中的单个数字格没有截断层,行高保持紧排,列内多露几格 */
285
441
  line-height: var(--xh-leading-none);
286
442
  white-space: nowrap;
@@ -303,8 +459,8 @@
303
459
  }
304
460
 
305
461
  [data-scope='time-picker'][data-part='item'][data-state='checked'] {
306
- background: var(--xh-time-picker-item-bg-checked, var(--xh-bg-brand));
307
- color: var(--xh-time-picker-item-fg-checked, var(--xh-fg-on-brand));
462
+ background: var(--xh-time-picker-item-bg-checked, var(--xh-_time-picker-accent));
463
+ color: var(--xh-time-picker-item-fg-checked, var(--xh-_time-picker-accent-fg));
308
464
  font-weight: var(--xh-time-picker-item-weight-checked, var(--xh-font-weight-medium));
309
465
  }
310
466
 
@@ -312,11 +468,11 @@
312
468
  不写这条就只有底色被换走、文字仍是品牌底上的反白色 */
313
469
  [data-scope='time-picker'][data-part='item'][data-state='checked'][data-highlighted]:not([data-disabled]),
314
470
  [data-scope='time-picker'][data-part='item'][data-state='checked']:hover:not([data-disabled]) {
315
- background: var(--xh-time-picker-item-bg-checked-hover, var(--xh-bg-brand-hover));
471
+ background: var(--xh-time-picker-item-bg-checked-hover, var(--xh-_time-picker-accent-hover));
316
472
  }
317
473
 
318
474
  [data-scope='time-picker'][data-part='item']:focus-visible {
319
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
475
+ outline: var(--xh-ring-width) solid var(--xh-_time-picker-ring);
320
476
  /* 往内收:选项在滚动列里挨着排,环画在外沿会被列的溢出裁掉 */
321
477
  outline-offset: calc(-1 * var(--xh-ring-offset));
322
478
  }
@@ -343,20 +499,54 @@
343
499
  white-space: nowrap;
344
500
  pointer-events: none;
345
501
  }
502
+
503
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
504
+ [data-scope='time-picker'][data-part='clear-trigger']:empty::before {
505
+ content: '';
506
+ display: inline-block;
507
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
508
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
509
+ vertical-align: var(--xh-glyph-baseline-shift);
510
+ background-color: currentColor;
511
+ -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
512
+ mask: var(--xh-glyph-mark-close) center / contain no-repeat;
513
+ }
514
+
515
+ [data-scope='time-picker'][data-part='trigger']:empty::before {
516
+ content: '';
517
+ display: inline-block;
518
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
519
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
520
+ vertical-align: var(--xh-glyph-baseline-shift);
521
+ background-color: currentColor;
522
+ -webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
523
+ mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
524
+ }
346
525
  }
347
526
 
348
527
  @layer xihan.motion {
349
528
  /* 浮层进场:淡入 + 轻微上浮,方向与它从输入行下方展开一致。
350
529
  关键帧写在自己文件里并带组件前缀,不去动共享的 motion.css */
351
- @keyframes xh-time-picker-panel-in {
530
+ @keyframes xh-pop-in {
352
531
  from {
353
532
  opacity: 0;
354
- translate: 0 calc(-1 * var(--xh-motion-distance-sm));
533
+ scale: var(--xh-motion-scale-enter);
355
534
  }
356
535
 
357
536
  to {
358
537
  opacity: 1;
359
- translate: 0 0;
538
+ scale: 1;
539
+ }
540
+ }
541
+ @keyframes xh-pop-out {
542
+ from {
543
+ opacity: 1;
544
+ scale: 1;
545
+ }
546
+
547
+ to {
548
+ opacity: 0;
549
+ scale: var(--xh-motion-scale-enter);
360
550
  }
361
551
  }
362
552
  }
package/css/timeline.css CHANGED
@@ -7,11 +7,11 @@
7
7
  [data-scope='timeline'][data-part='root'] {
8
8
  /* 尺寸档只换这几个私有槽,条目、圆点与文字都从 root 继承它们,
9
9
  换档不必给每个部件各写一条选择器 */
10
- --xh-_timeline-dot-size: 10px;
10
+ --xh-_timeline-dot-size: var(--xh-space-2_5);
11
11
  --xh-_timeline-gutter: var(--xh-space-3);
12
12
  --xh-_timeline-item-gap: var(--xh-space-5);
13
- --xh-_timeline-title-font-size: var(--xh-text-label-size);
14
- --xh-_timeline-caption-font-size: var(--xh-font-size-xs);
13
+ --xh-_timeline-title-font-size: var(--xh-control-font-md);
14
+ --xh-_timeline-caption-font-size: var(--xh-text-caption-size);
15
15
  /* 标题首行占多高。圆点按它居中下移,圆心才落在标题这一行的中线上 */
16
16
  --xh-_timeline-line-h: calc(
17
17
  var(--xh-timeline-title-font-size, var(--xh-_timeline-title-font-size)) * var(--xh-leading-tight)
@@ -39,21 +39,21 @@
39
39
  }
40
40
 
41
41
  /* —— 尺寸 —— */
42
- /* 缺省档写在上面的基础规则里。圆点直径不在控件高度那把尺上,两侧直接给像素 */
42
+ /* 缺省档写在上面的基础规则里。圆点直径不在控件高度那把尺上,三档走空间尺相邻的三格 */
43
43
  [data-scope='timeline'][data-part='root'][data-size='sm'] {
44
- --xh-_timeline-dot-size: 8px;
44
+ --xh-_timeline-dot-size: var(--xh-space-2);
45
45
  --xh-_timeline-gutter: var(--xh-space-2);
46
46
  --xh-_timeline-item-gap: var(--xh-space-4);
47
- --xh-_timeline-title-font-size: var(--xh-font-size-sm);
47
+ --xh-_timeline-title-font-size: var(--xh-control-font-sm);
48
48
  /* 字号档最小就是 xs,时刻文本不再往下走,故不重声明 caption */
49
49
  }
50
50
 
51
51
  [data-scope='timeline'][data-part='root'][data-size='lg'] {
52
- --xh-_timeline-dot-size: 12px;
52
+ --xh-_timeline-dot-size: var(--xh-space-3);
53
53
  --xh-_timeline-gutter: var(--xh-space-4);
54
54
  --xh-_timeline-item-gap: var(--xh-space-6);
55
- --xh-_timeline-title-font-size: var(--xh-font-size-lg);
56
- --xh-_timeline-caption-font-size: var(--xh-font-size-sm);
55
+ --xh-_timeline-title-font-size: var(--xh-control-font-lg);
56
+ --xh-_timeline-caption-font-size: var(--xh-text-secondary-size);
57
57
  }
58
58
 
59
59
  /* —— 条目 —— */
@@ -92,7 +92,7 @@
92
92
  justify-content: center;
93
93
  inline-size: var(--xh-timeline-indicator-size, var(--xh-_timeline-dot-size));
94
94
  block-size: var(--xh-timeline-indicator-size, var(--xh-_timeline-dot-size));
95
- border-radius: var(--xh-radius-full);
95
+ border-radius: var(--xh-timeline-indicator-radius, var(--xh-shape-pill));
96
96
  /* 使用者令牌排在语气之前;两者都没有时退回一个中性的实心点 */
97
97
  background: var(--xh-timeline-indicator-bg, var(--xh-_tone-soft, var(--xh-fg-muted)));
98
98
  color: var(--xh-timeline-indicator-fg, var(--xh-_tone-on, var(--xh-fg-on-brand)));
@@ -120,7 +120,7 @@
120
120
 
121
121
  /* —— 连线 —— */
122
122
  [data-scope='timeline'][data-part='connector'] {
123
- border-radius: var(--xh-radius-full);
123
+ border-radius: var(--xh-timeline-connector-radius, var(--xh-shape-pill));
124
124
  background: var(--xh-timeline-connector-bg, var(--xh-border-default));
125
125
  }
126
126
 
@@ -158,7 +158,7 @@
158
158
  [data-scope='timeline'][data-part='content'] {
159
159
  display: flex;
160
160
  flex-direction: column;
161
- gap: var(--xh-space-1);
161
+ gap: var(--xh-timeline-content-gap, var(--xh-space-1));
162
162
  min-inline-size: 0;
163
163
  }
164
164
 
@@ -176,7 +176,7 @@
176
176
  [data-scope='timeline'][data-part='item'][data-orientation='horizontal'] [data-scope='timeline'][data-part='content'] {
177
177
  grid-column: 1 / -1;
178
178
  grid-row: 2;
179
- padding-block-start: var(--xh-space-2);
179
+ padding-block-start: var(--xh-timeline-content-pt, var(--xh-space-2));
180
180
  padding-inline-end: var(--xh-timeline-item-gap, var(--xh-_timeline-item-gap));
181
181
  }
182
182
 
@@ -241,7 +241,7 @@
241
241
  grid-row: 1;
242
242
  align-self: end;
243
243
  padding-block-start: 0;
244
- padding-block-end: var(--xh-space-2);
244
+ padding-block-end: var(--xh-timeline-content-pb, var(--xh-space-2));
245
245
  }
246
246
 
247
247
  [data-scope='timeline'][data-part='item'][data-orientation='horizontal'][data-placement='alternate'] {
@@ -262,7 +262,7 @@
262
262
  grid-row: 1;
263
263
  align-self: end;
264
264
  padding-block-start: 0;
265
- padding-block-end: var(--xh-space-2);
265
+ padding-block-end: var(--xh-timeline-content-pb, var(--xh-space-2));
266
266
  }
267
267
 
268
268
  /* —— 文字 —— */