@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,107 @@
4
4
  --xh-date-picker-skin: 1;
5
5
  }
6
6
 
7
+ /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
8
+ [data-scope='date-picker'][data-part='positioner'] {
9
+ /* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,内容层继承它限高;
10
+ 引擎没算(尚未落位 / 无引擎 / 贴边归零)时不额外限高 */
11
+ --xh-_date-picker-available-h: 100vh;
12
+
13
+ /* 面板的自绘条浮在内容之上:轨道不上底色,实色轨道会在面板右缘糊出一条竖灰带 */
14
+ --xh-scrollbar-track-bg: transparent;
15
+
16
+ position: fixed;
17
+ z-index: var(--xh-date-picker-layer, var(--xh-layer-popover));
18
+ /* 空壳不吃指针,交互只发生在 content 里 */
19
+ pointer-events: none;
20
+ }
21
+
22
+ /* 锚点被滚出可视区:整个浮层随之收起 */
23
+ [data-scope='date-picker'][data-part='positioner'][data-hidden] {
24
+ visibility: hidden;
25
+ }
26
+
27
+ /* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
28
+ [data-scope='date-picker']:is([data-part='root'], [data-part='positioner']) {
29
+ /* 尺寸档只换这几个私有槽,标题、输入行与浮层里的部件都从这两处继承它们,
30
+ 换档不必给每个部件各写一条选择器 */
31
+ --xh-_date-picker-control-h: var(--xh-control-h-md);
32
+ --xh-_date-picker-control-px: var(--xh-control-px-md);
33
+ --xh-_date-picker-gap: var(--xh-control-gap-md);
34
+ --xh-_date-picker-font-size: var(--xh-control-font-md);
35
+ --xh-_date-picker-label-font-size: var(--xh-control-font-md);
36
+
37
+ /* 形态档只换这三个私有槽:底色与两档描边 */
38
+ --xh-_date-picker-control-bg: var(--xh-bg-canvas);
39
+ --xh-_date-picker-control-border: var(--xh-border-control);
40
+ --xh-_date-picker-control-border-hover: var(--xh-border-control-hover);
41
+
42
+ /* 聚焦环、时间列选中与确认按钮随语气走。没写 data-tone 时这几个 --xh-_tone* 没被声明,
43
+ 退回原来的焦点色与品牌色 */
44
+ --xh-_date-picker-ring: var(--xh-ring-focus);
45
+ --xh-_date-picker-accent: var(--xh-_tone, var(--xh-bg-brand));
46
+ --xh-_date-picker-accent-hover: var(--xh-_tone-hover, var(--xh-bg-brand-hover));
47
+ --xh-_date-picker-accent-fg: var(--xh-_tone-on, var(--xh-fg-on-brand));
48
+ --xh-_date-picker-accent-subtle: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
49
+ /* 淡底上的字与实心底上的字是两档:--xh-_tone-fg 是语气层为淡底配的那一档,
50
+ 没写 data-tone 时退到 fg-brand-strong——fg-brand(600)压在 brand-100 上只有 4.21 */
51
+ --xh-_date-picker-accent-subtle-fg: var(--xh-_tone-fg, var(--xh-fg-brand-strong));
52
+ }
53
+
7
54
  /* 与文本框、分段日期同一套堆叠:标签一行、输入行一行 */
8
55
  [data-scope='date-picker'][data-part='root'] {
56
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
57
+ --xh-icon-size: var(--xh-date-picker-icon-size, var(--xh-glyph-size-md));
58
+
9
59
  display: inline-flex;
10
60
  flex-direction: column;
11
61
  gap: var(--xh-date-picker-gap, var(--xh-space-1));
12
62
  }
13
63
 
64
+ /* —— 尺寸 —— */
65
+ /* 缺省档写在上面的基础规则里 */
66
+ [data-scope='date-picker']:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
67
+ --xh-icon-size: var(--xh-date-picker-icon-size, var(--xh-glyph-size-sm));
68
+ --xh-_date-picker-control-h: var(--xh-control-h-sm);
69
+ --xh-_date-picker-control-px: var(--xh-control-px-sm);
70
+ --xh-_date-picker-gap: var(--xh-control-gap-sm);
71
+ --xh-_date-picker-font-size: var(--xh-control-font-sm);
72
+ --xh-_date-picker-label-font-size: var(--xh-control-font-sm);
73
+ }
74
+
75
+ [data-scope='date-picker']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
76
+ --xh-icon-size: var(--xh-date-picker-icon-size, var(--xh-glyph-size-lg));
77
+ --xh-_date-picker-control-h: var(--xh-control-h-lg);
78
+ --xh-_date-picker-control-px: var(--xh-control-px-lg);
79
+ --xh-_date-picker-gap: var(--xh-control-gap-lg);
80
+ --xh-_date-picker-font-size: var(--xh-control-font-lg);
81
+ --xh-_date-picker-label-font-size: var(--xh-control-font-lg);
82
+ }
83
+
84
+ /* —— 形态 —— */
85
+ /* 输入类不做实心档:填满一个要往里打字的框,字与底就没法同时读。
86
+ 形态只决定底与描边怎么画,用哪族颜色由 data-tone 决定 */
87
+ [data-scope='date-picker']:is([data-part='root'], [data-part='positioner'])[data-variant='outline'] {
88
+ --xh-_date-picker-control-bg: var(--xh-bg-canvas);
89
+ --xh-_date-picker-control-border: var(--xh-border-control);
90
+ --xh-_date-picker-control-border-hover: var(--xh-border-control-hover);
91
+ }
92
+
93
+ /* 填充式:底色顶替描边表达边界。描边只退成透明而不去掉,1px 的位置留着,
94
+ 与 outline 档并排时基线对得上、聚焦画描边也不引起跳动 */
95
+ [data-scope='date-picker']:is([data-part='root'], [data-part='positioner'])[data-variant='subtle'] {
96
+ --xh-_date-picker-control-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
97
+ --xh-_date-picker-control-border: transparent;
98
+ --xh-_date-picker-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
99
+ }
100
+
101
+ /* 无框:底与常态描边透明,悬停与聚焦浮出描边 */
102
+ [data-scope='date-picker']:is([data-part='root'], [data-part='positioner'])[data-variant='ghost'] {
103
+ --xh-_date-picker-control-bg: transparent;
104
+ --xh-_date-picker-control-border: transparent;
105
+ --xh-_date-picker-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
106
+ }
107
+
14
108
  /* 只要声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
15
109
  [data-scope='date-picker'][data-part='root'][hidden] {
16
110
  display: none;
@@ -18,11 +112,9 @@
18
112
 
19
113
  [data-scope='date-picker'][data-part='label'] {
20
114
  color: var(--xh-date-picker-label-fg, var(--xh-fg-default));
21
- font-size: var(--xh-date-picker-label-font-size, var(--xh-text-label-size));
115
+ font-size: var(--xh-date-picker-label-font-size, var(--xh-_date-picker-label-font-size));
22
116
  font-weight: var(--xh-date-picker-label-font-weight, var(--xh-text-label-weight));
23
117
  line-height: var(--xh-leading-none);
24
- /* 点标题会把焦点送进首段,指针得说明这件事 */
25
- cursor: default;
26
118
  }
27
119
 
28
120
  [data-scope='date-picker'][data-part='label'][hidden] {
@@ -39,14 +131,14 @@
39
131
  [data-scope='date-picker'][data-part='control'] {
40
132
  display: inline-flex;
41
133
  align-items: center;
42
- gap: var(--xh-date-picker-control-gap, var(--xh-control-gap-md));
43
- min-inline-size: var(--xh-date-picker-control-min-w, var(--xh-overlay-min-w));
44
- block-size: var(--xh-date-picker-control-h, var(--xh-control-h-md));
45
- padding-inline: var(--xh-date-picker-control-px, var(--xh-control-px-md));
134
+ gap: var(--xh-date-picker-control-gap, var(--xh-_date-picker-gap));
135
+ min-inline-size: var(--xh-date-picker-control-min-w, var(--xh-control-min-w));
136
+ block-size: var(--xh-date-picker-control-h, var(--xh-_date-picker-control-h));
137
+ padding-inline: var(--xh-date-picker-control-px, var(--xh-_date-picker-control-px));
46
138
  padding-block: 0;
47
- border: var(--xh-stroke-thin) solid var(--xh-date-picker-control-border, var(--xh-border-control));
139
+ border: var(--xh-stroke-thin) solid var(--xh-date-picker-control-border, var(--xh-_date-picker-control-border));
48
140
  border-radius: var(--xh-date-picker-control-radius, var(--xh-shape-control));
49
- background: var(--xh-date-picker-control-bg, var(--xh-bg-canvas));
141
+ background: var(--xh-date-picker-control-bg, var(--xh-_date-picker-control-bg));
50
142
  color: var(--xh-date-picker-control-fg, var(--xh-fg-default));
51
143
  transition: border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
52
144
  }
@@ -57,19 +149,22 @@
57
149
 
58
150
  /* hover 只在中性态换描边:invalid 正拿边框颜色说事,被 hover 盖掉那条信息就没了 */
59
151
  [data-scope='date-picker'][data-part='control']:hover:not([data-disabled], [data-invalid]) {
60
- border-color: var(--xh-date-picker-control-border-hover, var(--xh-border-control-hover));
152
+ border-color: var(--xh-date-picker-control-border-hover, var(--xh-_date-picker-control-border-hover));
61
153
  }
62
154
 
63
155
  /* 焦点落在某一段或某个按钮上,而边框长在 control 上:焦点环得由内向外借一层。
64
156
  control 自己不占 Tab 位,:focus-within 是它唯一能感知组内焦点的方式 */
65
- [data-scope='date-picker'][data-part='control']:focus-within {
66
- border-color: var(--xh-date-picker-control-border-focus, var(--xh-ring-focus));
67
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
157
+ [data-scope='date-picker'][data-part='control']:focus-within:not([data-disabled]) {
158
+ border-color: var(--xh-date-picker-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
159
+ outline: var(--xh-ring-width) solid var(--xh-_date-picker-ring);
68
160
  outline-offset: var(--xh-ring-offset);
69
161
  }
70
162
 
71
163
  [data-scope='date-picker'][data-part='control'][data-invalid] {
72
- border-color: var(--xh-date-picker-control-border-invalid, var(--xh-color-danger-500));
164
+ border-color: var(--xh-date-picker-control-border-invalid, var(--xh-border-invalid));
165
+
166
+ /* 校验失败时环也跟着变红:两圈等宽相邻却一红一蓝,读的人不知道哪个才是当前状态 */
167
+ --xh-_date-picker-ring: var(--xh-ring-invalid);
73
168
  }
74
169
 
75
170
  /* 只读仍可聚焦、日历仍能展开来看,不置灰,只把底色压下去表示"改不动" */
@@ -83,27 +178,27 @@
83
178
  cursor: not-allowed;
84
179
  }
85
180
 
86
- /* 分段容器:段位自己那身皮由 date-field 那份样式负责(它们戴的是那一份解剖的标记),
87
- 这里只管把一排段位横过来、占满输入行剩下的宽度 */
88
- [data-scope='date-picker'][data-part='input'] {
181
+ /* 段位与作者写在段间的分隔符都在这一层里:段位自己那身皮由 date-field 那份样式负责
182
+ (它们戴的是那一份解剖的标记),这里只管把一排段位横过来、占满输入行剩下的宽度 */
183
+ [data-scope='date-picker'][data-part='segment-group'] {
89
184
  display: inline-flex;
90
- flex: 1;
185
+ flex: 1 1 auto;
91
186
  align-items: center;
92
187
  min-inline-size: 0;
93
188
  block-size: 100%;
94
189
  color: inherit;
95
190
  /* 表单控件不继承页面字体,只给字号会让段位用 UA 默认字族,与周围文本对不上 */
96
191
  font-family: inherit;
97
- font-size: var(--xh-date-picker-font-size, var(--xh-text-body-size));
192
+ font-size: var(--xh-date-picker-font-size, var(--xh-_date-picker-font-size));
98
193
  line-height: var(--xh-leading-none);
99
194
  }
100
195
 
101
- [data-scope='date-picker'][data-part='input'][hidden] {
196
+ [data-scope='date-picker'][data-part='segment-group'][hidden] {
102
197
  display: none;
103
198
  }
104
199
 
105
200
  /* 容器自己不占 Tab 位、也不承载焦点,环由 control 画,这里不再套一圈 */
106
- [data-scope='date-picker'][data-part='input']:focus-visible {
201
+ [data-scope='date-picker'][data-part='segment-group']:focus-visible {
107
202
  outline: none;
108
203
  }
109
204
 
@@ -122,77 +217,74 @@
122
217
  background: var(--xh-date-picker-action-bg, transparent);
123
218
  color: var(--xh-date-picker-action-fg, var(--xh-fg-muted));
124
219
  font-family: inherit;
125
- font-size: var(--xh-date-picker-action-font-size, var(--xh-font-size-sm));
220
+ font-size: var(--xh-date-picker-action-font-size, var(--xh-text-secondary-size));
126
221
  line-height: var(--xh-leading-none);
127
222
  cursor: pointer;
128
223
  user-select: none;
129
- transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
224
+ transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter), scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
130
225
  }
131
226
 
227
+
132
228
  [data-scope='date-picker'][data-part='trigger'][hidden],
133
229
  [data-scope='date-picker'][data-part='clear-trigger'][hidden] {
134
230
  display: none;
135
231
  }
136
232
 
137
233
  [data-scope='date-picker'][data-part='trigger']:hover:not(:disabled),
138
- [data-scope='date-picker'][data-part='clear-trigger']:hover:not(:disabled) {
234
+ [data-scope='date-picker'][data-part='clear-trigger']:hover {
139
235
  background: var(--xh-date-picker-action-bg-hover, var(--xh-bg-subtle-hover));
140
236
  color: var(--xh-date-picker-action-fg-hover, var(--xh-fg-default));
141
237
  }
142
238
 
143
- [data-scope='date-picker'][data-part='trigger']:active:not(:disabled),
144
- [data-scope='date-picker'][data-part='clear-trigger']:active:not(:disabled) {
239
+ [data-scope='date-picker'][data-part='trigger']:active:not(:disabled) {
145
240
  background: var(--xh-date-picker-action-bg-active, var(--xh-bg-subtle-active));
146
241
  }
147
242
 
243
+ [data-scope='date-picker'][data-part='clear-trigger']:active {
244
+ background: var(--xh-date-picker-action-bg-active, var(--xh-bg-subtle-active));
245
+ scale: var(--xh-motion-scale-press);
246
+ }
247
+
148
248
  /* 展开时按钮压一层底色,与浮层的存在互相印证 */
149
249
  [data-scope='date-picker'][data-part='trigger'][data-state='open'] {
150
250
  background: var(--xh-date-picker-action-bg-active, var(--xh-bg-subtle-active));
151
251
  color: var(--xh-date-picker-action-fg-hover, var(--xh-fg-default));
152
252
  }
153
253
 
154
- /* trigger Tab 序列里(清空按钮不在,它是 tabindex=-1 的兜底),落焦时必须看得见 */
155
- [data-scope='date-picker'][data-part='trigger']:focus-visible,
254
+ /* 清空按钮不占 Tab 位(tabindex=-1),这条是给程序化聚焦兜底:落焦时得看得见。
255
+ 展开钮是常规 Tab 停靠点,它落焦时环由盒的 :focus-within 画,这里不再套一圈 */
156
256
  [data-scope='date-picker'][data-part='clear-trigger']:focus-visible {
157
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
257
+ outline: var(--xh-ring-width) solid var(--xh-_date-picker-ring);
158
258
  outline-offset: var(--xh-ring-offset);
159
259
  }
160
260
 
161
- [data-scope='date-picker'][data-part='trigger']:disabled,
162
- [data-scope='date-picker'][data-part='clear-trigger']:disabled {
261
+ [data-scope='date-picker'][data-part='trigger']:disabled {
163
262
  background: var(--xh-date-picker-action-bg, transparent);
164
263
  color: var(--xh-fg-disabled);
165
264
  cursor: not-allowed;
166
265
  }
167
266
 
168
- /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
169
- [data-scope='date-picker'][data-part='positioner'] {
170
- position: fixed;
171
- z-index: var(--xh-layer-popover);
172
- /* 空壳不吃指针,交互只发生在 content 里 */
173
- pointer-events: none;
174
- }
175
-
176
- /* 锚点被滚出可视区:整个浮层随之收起 */
177
- [data-scope='date-picker'][data-part='positioner'][data-hidden] {
178
- visibility: hidden;
179
- }
180
-
181
267
  [data-scope='date-picker'][data-part='content'] {
182
268
  display: block;
183
- padding: var(--xh-date-picker-content-p, var(--xh-space-3));
269
+ padding-block: var(--xh-date-picker-content-py, var(--xh-space-3));
270
+ padding-inline: var(--xh-date-picker-content-px, var(--xh-space-3));
184
271
  border: var(--xh-stroke-thin) solid var(--xh-date-picker-content-border, var(--xh-border-default));
185
272
  border-radius: var(--xh-date-picker-content-radius, var(--xh-shape-surface));
186
273
  background: var(--xh-date-picker-content-bg, var(--xh-bg-surface));
187
274
  color: var(--xh-date-picker-content-fg, var(--xh-fg-default));
188
- box-shadow: var(--xh-date-picker-content-shadow, var(--xh-elevation-2));
275
+ /* 日历是定高结构:六行日期加表头本来就有固定高度,上限走页内滚动面那一档;
276
+ 可用高度是定位引擎算出的视口余量,视口真放不下时再收一截 */
277
+ max-block-size: min(var(--xh-date-picker-max-h, var(--xh-viewport-h-lg)), var(--xh-_date-picker-available-h));
278
+ overflow-y: auto;
279
+ box-shadow: var(--xh-date-picker-content-shadow, var(--xh-elevation-floating));
189
280
  pointer-events: auto;
190
281
  }
191
282
 
192
- /* display 会盖掉 hidden 属性的 UA 规则,收起态显式让位 */
193
- [data-scope='date-picker'][data-part='content'][hidden] {
194
- display: none;
195
- }
283
+ /* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
284
+ 收起态连接层会给 contenthidden,而上面那条 display 正是要盖掉 UA 的
285
+ [hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
286
+ 真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
287
+ 其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
196
288
 
197
289
  /* 浮层壳不承载焦点(焦点直接落到聚焦日那一格),但它写着 tabindex=-1,
198
290
  程序化落焦时不该再画一圈环 */
@@ -201,12 +293,47 @@
201
293
  }
202
294
 
203
295
  [data-scope='date-picker'][data-part='content'][data-state='open'] {
204
- animation: xh-date-picker-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
296
+ animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
297
+ }
298
+
299
+ /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
300
+ 免得动画结束到真收起之间闪一下原样 */
301
+ [data-scope='date-picker'][data-part='content'][data-state='closed'] {
302
+ animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
205
303
  }
206
304
 
207
305
  /* 内嵌日历的挂载点同时充当日历的根节点:日历那份样式的 root 规则落在
208
306
  [data-scope='calendar'][data-part='root'] 上,而这里没有那个节点,
209
307
  所以网格外层该有的排布得在这儿补齐(网格内部的皮仍归 calendar 那一份) */
308
+ /* 真的摆了两张日历才横过来。写成 :has 而不是无条件 flex 行:
309
+ showTime 那套结构里 content 直属子节点是作者自己的包裹块与确认行,
310
+ 无条件横排会把它们并到日历旁边去。
311
+ 不加 :not([hidden]):content 收起态带 hidden 但仍在播退场动画,
312
+ 排除掉会让它在那几帧退回 block、两张日历竖着堆一下 */
313
+ [data-scope='date-picker'][data-part='content']:has(> [data-part='calendar'] + [data-part='calendar']) {
314
+ display: flex;
315
+ align-items: flex-start;
316
+ }
317
+
318
+ /* 快捷选项列摆在日历的行内起始一侧,同样只在它真在场时才横过来。
319
+ 与上一条同理:不加 :not([hidden]),退场那几帧塌回 block 会让两块竖着堆一下 */
320
+ [data-scope='date-picker'][data-part='content']:has(> [data-part='presets']) {
321
+ display: flex;
322
+ align-items: stretch;
323
+ }
324
+
325
+ /* 第二个起的面板画一道左分隔线:两张网格挨着排时要有条界,
326
+ 否则 8 月末与 9 月初那两列看着像同一张表 */
327
+ [data-scope='date-picker'][data-part='calendar'] + [data-scope='date-picker'][data-part='calendar'] {
328
+ padding-inline-start: var(--xh-date-picker-panel-gap, var(--xh-space-3));
329
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-date-picker-panel-divider, var(--xh-border-subtle));
330
+ }
331
+
332
+ /* 快捷选项列与它旁边那张日历之间留出同样的空当,两道分隔线左右对称 */
333
+ [data-scope='date-picker'][data-part='presets'] + [data-scope='date-picker'][data-part='calendar'] {
334
+ padding-inline-start: var(--xh-date-picker-panel-gap, var(--xh-space-3));
335
+ }
336
+
210
337
  [data-scope='date-picker'][data-part='calendar'] {
211
338
  display: flex;
212
339
  flex-direction: column;
@@ -219,16 +346,69 @@
219
346
  display: none;
220
347
  }
221
348
 
349
+ /* —— 快捷选项:一列按钮式条目,贴在日历的行内起始一侧 —— */
350
+ [data-scope='date-picker'][data-part='presets'] {
351
+ display: flex;
352
+ flex: none;
353
+ /* 这一列的高度由并排的日历给:不写就按内容收,右侧那道分隔线只画到最后一条选项 */
354
+ align-self: stretch;
355
+ flex-direction: column;
356
+ gap: var(--xh-date-picker-presets-gap, var(--xh-list-option-gap));
357
+ /* 选项多起来时这一列自己滚,不把整张面板撑高 */
358
+ max-block-size: var(--xh-date-picker-presets-h, var(--xh-viewport-h-lg));
359
+ padding: var(--xh-date-picker-presets-padding, var(--xh-space-1));
360
+ overflow-y: auto;
361
+ border-inline-end: var(--xh-stroke-thin) solid var(--xh-date-picker-column-divider, var(--xh-border-subtle));
362
+ }
363
+
364
+ [data-scope='date-picker'][data-part='presets'][hidden] {
365
+ display: none;
366
+ }
367
+
368
+ [data-scope='date-picker'][data-part='preset'] {
369
+ padding-block: var(--xh-date-picker-preset-py, var(--xh-space-1));
370
+ padding-inline: var(--xh-date-picker-preset-px, var(--xh-space-3));
371
+ border-radius: var(--xh-date-picker-preset-radius, var(--xh-shape-control));
372
+ font-size: var(--xh-text-secondary-size);
373
+ line-height: var(--xh-leading-normal);
374
+ white-space: nowrap;
375
+ cursor: pointer;
376
+ user-select: none;
377
+ }
378
+
379
+ /* 悬停与键盘锚点共用中性轻档,命中那一条才走品牌淡底——两档靠色相分家;禁用的不响应悬停 */
380
+ [data-scope='date-picker'][data-part='preset']:hover:not([data-disabled]) {
381
+ background: var(--xh-date-picker-preset-bg-hover, var(--xh-bg-subtle));
382
+ }
383
+
384
+ [data-scope='date-picker'][data-part='preset']:focus-visible,
385
+ [data-scope='date-picker'][data-part='presets']:focus-visible {
386
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
387
+ outline-offset: calc(-1 * var(--xh-ring-width));
388
+ }
389
+
390
+ [data-scope='date-picker'][data-part='preset'][data-state='checked'] {
391
+ background: var(--xh-date-picker-preset-bg-selected, var(--xh-_date-picker-accent-subtle));
392
+ color: var(--xh-date-picker-preset-fg-selected, var(--xh-_date-picker-accent-subtle-fg));
393
+ font-weight: var(--xh-font-weight-medium);
394
+ }
395
+
396
+ [data-scope='date-picker'][data-part='preset'][data-disabled] {
397
+ color: var(--xh-date-picker-preset-fg-disabled, var(--xh-fg-disabled));
398
+ cursor: not-allowed;
399
+ }
400
+
222
401
  /* —— showTime:时间列贴在日历右侧、逐列滚动,确认按钮收口 ——
223
402
  content 是 block,作者把日历与时间列包进一行排布;列自身只管滚与选项画法 */
224
403
  [data-scope='date-picker'][data-part='time-column'] {
225
404
  display: flex;
226
405
  flex-direction: column;
227
- gap: 2px;
228
- max-block-size: var(--xh-date-picker-time-column-h, 14rem);
229
- padding: var(--xh-space-1);
406
+ gap: var(--xh-date-picker-time-column-gap, var(--xh-list-option-gap));
407
+ /* 几列并排:定高而不是随内容收,否则时列与分列的可选值一多一少就错位 */
408
+ block-size: var(--xh-date-picker-time-column-h, var(--xh-viewport-h-sm));
409
+ padding: var(--xh-date-picker-time-column-padding, var(--xh-space-1));
230
410
  overflow-y: auto;
231
- border-inline-start: var(--xh-stroke-thin) solid var(--xh-date-picker-content-border, var(--xh-border-default));
411
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-date-picker-column-divider, var(--xh-border-subtle));
232
412
  }
233
413
 
234
414
  [data-scope='date-picker'][data-part='time-column'][hidden] {
@@ -236,10 +416,10 @@
236
416
  }
237
417
 
238
418
  [data-scope='date-picker'][data-part='time-item'] {
239
- padding-block: var(--xh-space-1);
240
- padding-inline: var(--xh-space-3);
241
- border-radius: var(--xh-shape-control);
242
- font-size: var(--xh-font-size-sm);
419
+ padding-block: var(--xh-date-picker-time-item-py, var(--xh-space-1));
420
+ padding-inline: var(--xh-date-picker-time-item-px, var(--xh-space-3));
421
+ border-radius: var(--xh-date-picker-time-item-radius, var(--xh-shape-control));
422
+ font-size: var(--xh-text-secondary-size);
243
423
  line-height: var(--xh-leading-normal);
244
424
  text-align: center;
245
425
  cursor: pointer;
@@ -250,9 +430,16 @@
250
430
  background: var(--xh-date-picker-time-item-bg-hover, var(--xh-bg-subtle));
251
431
  }
252
432
 
253
- [data-scope='date-picker'][data-part='time-item'][data-selected] {
254
- background: var(--xh-date-picker-time-item-bg-selected, var(--xh-bg-brand-subtle));
255
- color: var(--xh-date-picker-time-item-fg-selected, var(--xh-fg-brand));
433
+ /* 键盘走到哪一格要看得见:这几列靠方向键逐格走,没有这一条就等于闭着眼挑 */
434
+ [data-scope='date-picker'][data-part='time-item']:focus-visible,
435
+ [data-scope='date-picker'][data-part='time-column']:focus-visible {
436
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
437
+ outline-offset: calc(-1 * var(--xh-ring-width));
438
+ }
439
+
440
+ [data-scope='date-picker'][data-part='time-item'][data-state='checked'] {
441
+ background: var(--xh-date-picker-time-item-bg-selected, var(--xh-_date-picker-accent-subtle));
442
+ color: var(--xh-date-picker-time-item-fg-selected, var(--xh-_date-picker-accent-subtle-fg));
256
443
  font-weight: var(--xh-font-weight-medium);
257
444
  }
258
445
 
@@ -261,40 +448,74 @@
261
448
  align-items: center;
262
449
  justify-content: center;
263
450
  block-size: var(--xh-control-h-sm);
264
- padding-inline: var(--xh-control-px-sm);
451
+ padding-inline: var(--xh-date-picker-confirm-trigger-px, var(--xh-control-px-sm));
265
452
  border: none;
266
- border-radius: var(--xh-shape-control);
267
- background: var(--xh-date-picker-confirm-bg, var(--xh-bg-brand));
268
- color: var(--xh-date-picker-confirm-fg, var(--xh-fg-on-brand));
269
- font-size: var(--xh-font-size-sm);
453
+ border-radius: var(--xh-date-picker-confirm-trigger-radius, var(--xh-shape-control));
454
+ background: var(--xh-date-picker-confirm-bg, var(--xh-_date-picker-accent));
455
+ color: var(--xh-date-picker-confirm-fg, var(--xh-_date-picker-accent-fg));
456
+ font-size: var(--xh-text-secondary-size);
270
457
  cursor: pointer;
271
458
  }
272
459
 
273
460
  [data-scope='date-picker'][data-part='confirm-trigger']:hover {
274
- background: var(--xh-date-picker-confirm-bg-hover, var(--xh-bg-brand-hover));
461
+ background: var(--xh-date-picker-confirm-bg-hover, var(--xh-_date-picker-accent-hover));
275
462
  }
276
463
 
277
464
  [data-scope='date-picker'][data-part='confirm-trigger']:focus-visible {
278
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
465
+ outline: var(--xh-ring-width) solid var(--xh-_date-picker-ring);
279
466
  outline-offset: var(--xh-ring-offset);
280
467
  }
281
468
 
282
469
  [data-scope='date-picker'][data-part='confirm-trigger'][hidden] {
283
470
  display: none;
284
471
  }
472
+
473
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
474
+ [data-scope='date-picker'][data-part='clear-trigger']:empty::before {
475
+ content: '';
476
+ display: inline-block;
477
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
478
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
479
+ vertical-align: var(--xh-glyph-baseline-shift);
480
+ background-color: currentColor;
481
+ -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
482
+ mask: var(--xh-glyph-mark-close) center / contain no-repeat;
483
+ }
484
+
485
+ [data-scope='date-picker'][data-part='trigger']:empty::before {
486
+ content: '';
487
+ display: inline-block;
488
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
489
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
490
+ vertical-align: var(--xh-glyph-baseline-shift);
491
+ background-color: currentColor;
492
+ -webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
493
+ mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
494
+ }
285
495
  }
286
496
 
287
497
  @layer xihan.motion {
288
498
  /* 浮层进场:淡入 + 轻微上浮。名字带组件前缀,不与公共关键帧抢名 */
289
- @keyframes xh-date-picker-in {
499
+ @keyframes xh-pop-in {
290
500
  from {
291
501
  opacity: 0;
292
- translate: 0 calc(-1 * var(--xh-motion-distance-sm));
502
+ scale: var(--xh-motion-scale-enter);
293
503
  }
294
504
 
295
505
  to {
296
506
  opacity: 1;
297
- translate: 0 0;
507
+ scale: 1;
508
+ }
509
+ }
510
+ @keyframes xh-pop-out {
511
+ from {
512
+ opacity: 1;
513
+ scale: 1;
514
+ }
515
+
516
+ to {
517
+ opacity: 0;
518
+ scale: var(--xh-motion-scale-enter);
298
519
  }
299
520
  }
300
521
  }
@@ -12,7 +12,7 @@
12
12
  --xh-_descriptions-label-gap: var(--xh-space-2);
13
13
  --xh-_descriptions-py: var(--xh-space-2);
14
14
  --xh-_descriptions-px: var(--xh-space-3);
15
- --xh-_descriptions-font-size: var(--xh-text-body-size);
15
+ --xh-_descriptions-font-size: var(--xh-control-font-md);
16
16
  /* 标签在左时那一列的宽度:收到最长的那个标签 */
17
17
  --xh-_descriptions-label-w: max-content;
18
18
 
@@ -58,7 +58,7 @@
58
58
  --xh-_descriptions-gap: var(--xh-space-2);
59
59
  --xh-_descriptions-py: var(--xh-space-1);
60
60
  --xh-_descriptions-px: var(--xh-space-2);
61
- --xh-_descriptions-font-size: var(--xh-font-size-sm);
61
+ --xh-_descriptions-font-size: var(--xh-control-font-sm);
62
62
  }
63
63
 
64
64
  [data-scope='descriptions'][data-part='root'][data-size='lg'] {
@@ -67,7 +67,7 @@
67
67
  --xh-_descriptions-label-gap: var(--xh-space-3);
68
68
  --xh-_descriptions-py: var(--xh-space-3);
69
69
  --xh-_descriptions-px: var(--xh-space-4);
70
- --xh-_descriptions-font-size: var(--xh-font-size-lg);
70
+ --xh-_descriptions-font-size: var(--xh-control-font-lg);
71
71
  }
72
72
 
73
73
  /* —— 每一格 —— */
@@ -117,9 +117,9 @@
117
117
  > [data-scope='descriptions'][data-part='item'] {
118
118
  padding-block: var(--xh-descriptions-item-py, var(--xh-_descriptions-py));
119
119
  padding-inline: var(--xh-descriptions-item-px, var(--xh-_descriptions-px));
120
- border-block-start: var(--xh-stroke-thin) solid var(--xh-descriptions-border, var(--xh-border-subtle));
120
+ border-block-start: var(--xh-stroke-thin) solid var(--xh-descriptions-divider, var(--xh-border-subtle));
121
121
  /* 每行一组时左边没有邻居,宽度按列数补回来 */
122
- border-inline-start: 0 solid var(--xh-descriptions-border, var(--xh-border-subtle));
122
+ border-inline-start: 0 solid var(--xh-descriptions-divider, var(--xh-border-subtle));
123
123
  }
124
124
 
125
125
  [data-scope='descriptions'][data-part='root'][data-bordered]
@@ -202,4 +202,10 @@
202
202
  > [data-scope='descriptions'][data-part='item']:nth-child(-n + 6) {
203
203
  border-block-start-width: 0;
204
204
  }
205
+
206
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
207
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
208
+ [data-scope='descriptions'][data-part='item'][hidden] {
209
+ display: none;
210
+ }
205
211
  }