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