@xihan-ui/styles 3.0.0 → 3.2.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 (221) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +1 -1
  3. package/component-tokens.d.ts +29 -0
  4. package/components.tokens.json +683 -27
  5. package/css/alert.css +2 -2
  6. package/css/approval.css +4 -4
  7. package/css/button.css +9 -5
  8. package/css/calendar-picker.css +3 -3
  9. package/css/calendar-range-picker.css +7 -7
  10. package/css/carousel.css +45 -13
  11. package/css/cartesian-chart.css +11 -11
  12. package/css/cascader.css +10 -10
  13. package/css/citation.css +2 -2
  14. package/css/code-view.css +6 -6
  15. package/css/color-picker.css +81 -0
  16. package/css/color-swatch-picker.css +9 -4
  17. package/css/combobox.css +12 -4
  18. package/css/command.css +1 -1
  19. package/css/date-field.css +39 -0
  20. package/css/date-picker.css +86 -9
  21. package/css/date-range-picker.css +47 -7
  22. package/css/diff-view.css +8 -8
  23. package/css/field-array.css +1 -1
  24. package/css/field.css +4 -0
  25. package/css/file-upload.css +1 -1
  26. package/css/float-button.css +140 -27
  27. package/css/form.css +14 -6
  28. package/css/graph-chart.css +2 -2
  29. package/css/highlight.css +1 -1
  30. package/css/image.css +1 -1
  31. package/css/mention.css +1 -1
  32. package/css/message-feed.css +1 -1
  33. package/css/notification.css +26 -20
  34. package/css/number-field.css +18 -18
  35. package/css/page-header.css +2 -2
  36. package/css/password-input.css +2 -2
  37. package/css/popconfirm.css +3 -3
  38. package/css/question-flow.css +8 -8
  39. package/css/radar-chart.css +6 -6
  40. package/css/rating.css +1 -1
  41. package/css/select.css +2 -2
  42. package/css/separator.css +2 -2
  43. package/css/side-nav.css +13 -13
  44. package/css/skeleton.css +5 -5
  45. package/css/slider.css +6 -6
  46. package/css/sortable.css +2 -2
  47. package/css/table.css +19 -2
  48. package/css/tags-input.css +1 -1
  49. package/css/time-picker.css +59 -2
  50. package/css/tool-call.css +7 -7
  51. package/css/tooltip.css +1 -1
  52. package/css/tree-select.css +2 -2
  53. package/css/tree.css +81 -11
  54. package/dist/css/accordion.css +269 -0
  55. package/dist/css/affix.css +47 -0
  56. package/dist/css/alert.css +247 -0
  57. package/dist/css/anchor.css +252 -0
  58. package/dist/css/approval.css +501 -0
  59. package/dist/css/avatar-group.css +99 -0
  60. package/dist/css/avatar.css +98 -0
  61. package/dist/css/back-top.css +161 -0
  62. package/dist/css/badge.css +205 -0
  63. package/dist/css/bar-code.css +62 -0
  64. package/dist/css/breadcrumb.css +230 -0
  65. package/dist/css/button-group.css +263 -0
  66. package/dist/css/button.css +219 -0
  67. package/dist/css/calendar-picker.css +467 -0
  68. package/dist/css/calendar-range-picker.css +554 -0
  69. package/dist/css/card.css +221 -0
  70. package/dist/css/carousel.css +710 -0
  71. package/dist/css/cartesian-chart.css +830 -0
  72. package/dist/css/cascader.css +961 -0
  73. package/dist/css/checkbox-group.css +358 -0
  74. package/dist/css/checkbox.css +257 -0
  75. package/dist/css/citation.css +470 -0
  76. package/dist/css/clipboard.css +315 -0
  77. package/dist/css/code-view.css +374 -0
  78. package/dist/css/collapsible.css +185 -0
  79. package/dist/css/color-field.css +176 -0
  80. package/dist/css/color-picker.css +595 -0
  81. package/dist/css/color-slider.css +281 -0
  82. package/dist/css/color-swatch-picker.css +250 -0
  83. package/dist/css/color-swatch.css +35 -0
  84. package/dist/css/combobox.css +574 -0
  85. package/dist/css/command.css +399 -0
  86. package/dist/css/context-menu.css +420 -0
  87. package/dist/css/date-field.css +317 -0
  88. package/dist/css/date-picker.css +868 -0
  89. package/dist/css/date-range-picker.css +886 -0
  90. package/dist/css/description.css +67 -0
  91. package/dist/css/descriptions.css +299 -0
  92. package/dist/css/dialog.css +455 -0
  93. package/dist/css/diff-view.css +513 -0
  94. package/dist/css/download-trigger.css +151 -0
  95. package/dist/css/drawer.css +552 -0
  96. package/dist/css/editable.css +295 -0
  97. package/dist/css/empty-state.css +163 -0
  98. package/dist/css/field-array.css +226 -0
  99. package/dist/css/field.css +166 -0
  100. package/dist/css/fieldset.css +102 -0
  101. package/dist/css/file-upload.css +429 -0
  102. package/dist/css/flex.css +441 -0
  103. package/dist/css/float-button.css +569 -0
  104. package/dist/css/floating-panel.css +429 -0
  105. package/dist/css/focus.css +46 -0
  106. package/dist/css/forced-colors.css +93 -0
  107. package/dist/css/form.css +393 -0
  108. package/dist/css/funnel-chart.css +106 -0
  109. package/dist/css/graph-chart.css +205 -0
  110. package/dist/css/grid-list.css +235 -0
  111. package/dist/css/grid.css +1201 -0
  112. package/dist/css/heatmap.css +552 -0
  113. package/dist/css/hierarchy-chart.css +298 -0
  114. package/dist/css/highlight.css +41 -0
  115. package/dist/css/hover-card.css +226 -0
  116. package/dist/css/icon.css +225 -0
  117. package/dist/css/image-cropper.css +373 -0
  118. package/dist/css/image-viewer.css +538 -0
  119. package/dist/css/image.css +98 -0
  120. package/dist/css/infinite-scroll.css +77 -0
  121. package/dist/css/input-group.css +275 -0
  122. package/dist/css/json-viewer.css +379 -0
  123. package/dist/css/kbd.css +72 -0
  124. package/dist/css/label.css +78 -0
  125. package/dist/css/layers.css +7 -0
  126. package/dist/css/layout.css +372 -0
  127. package/dist/css/liquid.css +106 -0
  128. package/dist/css/list.css +152 -0
  129. package/dist/css/listbox.css +390 -0
  130. package/dist/css/loading-bar.css +141 -0
  131. package/dist/css/log.css +306 -0
  132. package/dist/css/markdown-stream.css +149 -0
  133. package/dist/css/marquee.css +378 -0
  134. package/dist/css/masonry.css +70 -0
  135. package/dist/css/matrix-code.css +67 -0
  136. package/dist/css/mention.css +393 -0
  137. package/dist/css/menu.css +364 -0
  138. package/dist/css/menubar.css +456 -0
  139. package/dist/css/message-feed.css +318 -0
  140. package/dist/css/navigation-menu.css +513 -0
  141. package/dist/css/notification.css +782 -0
  142. package/dist/css/number-animation.css +44 -0
  143. package/dist/css/number-field.css +252 -0
  144. package/dist/css/overlay-arrow.css +56 -0
  145. package/dist/css/page-header.css +184 -0
  146. package/dist/css/pagination.css +450 -0
  147. package/dist/css/password-input.css +391 -0
  148. package/dist/css/pie-chart.css +247 -0
  149. package/dist/css/pin-input.css +199 -0
  150. package/dist/css/pointer.css +36 -0
  151. package/dist/css/popconfirm.css +320 -0
  152. package/dist/css/popover.css +279 -0
  153. package/dist/css/progress.css +501 -0
  154. package/dist/css/prompt-input.css +260 -0
  155. package/dist/css/question-flow.css +553 -0
  156. package/dist/css/radar-chart.css +233 -0
  157. package/dist/css/radio-group.css +598 -0
  158. package/dist/css/rating.css +294 -0
  159. package/dist/css/reasoning.css +343 -0
  160. package/dist/css/reset.css +117 -0
  161. package/dist/css/resizable.css +242 -0
  162. package/dist/css/sankey-chart.css +174 -0
  163. package/dist/css/scroll-area.css +240 -0
  164. package/dist/css/scrollbar.css +204 -0
  165. package/dist/css/select.css +612 -0
  166. package/dist/css/separator.css +122 -0
  167. package/dist/css/side-nav.css +476 -0
  168. package/dist/css/signature-pad.css +179 -0
  169. package/dist/css/skeleton.css +161 -0
  170. package/dist/css/slider.css +374 -0
  171. package/dist/css/sortable.css +228 -0
  172. package/dist/css/sparkline.css +164 -0
  173. package/dist/css/spinner.css +236 -0
  174. package/dist/css/splitter.css +159 -0
  175. package/dist/css/statistic.css +137 -0
  176. package/dist/css/steps.css +627 -0
  177. package/dist/css/switch.css +351 -0
  178. package/dist/css/table.css +1145 -0
  179. package/dist/css/tabs.css +944 -0
  180. package/dist/css/tag-group.css +247 -0
  181. package/dist/css/tag.css +310 -0
  182. package/dist/css/tags-input.css +322 -0
  183. package/dist/css/text-field.css +197 -0
  184. package/dist/css/time-field.css +277 -0
  185. package/dist/css/time-picker.css +707 -0
  186. package/dist/css/time-range-picker.css +746 -0
  187. package/dist/css/timeline.css +423 -0
  188. package/dist/css/timer.css +123 -0
  189. package/dist/css/timestamp.css +34 -0
  190. package/dist/css/toggle-group.css +424 -0
  191. package/dist/css/toggle.css +146 -0
  192. package/dist/css/tone.css +189 -0
  193. package/dist/css/tool-call.css +429 -0
  194. package/dist/css/toolbar.css +365 -0
  195. package/dist/css/tooltip.css +218 -0
  196. package/dist/css/tour.css +439 -0
  197. package/dist/css/transfer.css +638 -0
  198. package/dist/css/tree-select.css +878 -0
  199. package/dist/css/tree.css +733 -0
  200. package/dist/css/truncate.css +108 -0
  201. package/dist/css/typography.css +472 -0
  202. package/dist/css/undefined.css +58 -0
  203. package/dist/css/virtualizer.css +166 -0
  204. package/dist/css/visually-hidden.css +20 -0
  205. package/dist/css/watermark.css +82 -0
  206. package/dist/family/action-control.css +487 -0
  207. package/dist/family/chart.css +480 -0
  208. package/dist/family/check-mark.css +94 -0
  209. package/dist/family/choice-card.css +97 -0
  210. package/dist/family/collection-item.css +764 -0
  211. package/dist/family/field-chrome.css +287 -0
  212. package/dist/family/loading-ring.css +95 -0
  213. package/dist/family/material.css +72 -0
  214. package/dist/family/menu-choice.css +56 -0
  215. package/dist/family/motion.css +363 -0
  216. package/dist/family/swatch.css +59 -0
  217. package/dist/family/tag-list.css +59 -0
  218. package/family/action-control.css +3 -12
  219. package/index.css +7307 -6759
  220. package/index.unlayered.css +7309 -6761
  221. package/package.json +165 -164
@@ -186,10 +186,12 @@
186
186
  }
187
187
 
188
188
  /* 作者塞进来的图形跟着勾同一套显隐 */
189
+ /* 显隐写在 indicator 自己的私有槽上、图形只读槽:作者的图形没有可认的特征,
190
+ 规则主体不能挂在 data-state 后面(翻转时会让全页同名属性的变化整棵子树重算) */
189
191
  [data-scope='color-swatch-picker'][data-part='indicator'] > * {
190
192
  position: relative;
191
193
  color: var(--xh-color-swatch-picker-indicator-fg, var(--xh-_tone-on, var(--xh-fg-on-brand)));
192
- opacity: 0;
194
+ opacity: var(--xh-_color-swatch-picker-glyph-opacity, 0);
193
195
  transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
194
196
  }
195
197
 
@@ -199,8 +201,11 @@
199
201
  scale: 1;
200
202
  }
201
203
 
202
- [data-scope='color-swatch-picker'][data-part='indicator'][data-state='checked']:empty::after,
203
- [data-scope='color-swatch-picker'][data-part='indicator'][data-state='checked'] > * {
204
+ [data-scope='color-swatch-picker'][data-part='indicator'][data-state='checked'] {
205
+ --xh-_color-swatch-picker-glyph-opacity: 1;
206
+ }
207
+
208
+ [data-scope='color-swatch-picker'][data-part='indicator'][data-state='checked']:empty::after {
204
209
  opacity: 1;
205
210
  }
206
211
 
@@ -227,7 +232,7 @@
227
232
  */
228
233
  @media (forced-colors: active) {
229
234
  /* 家族在这一档把色块描边统一钉成 CanvasText,选中的那一格要在它之上换成高亮色 */
230
- [data-scope='color-swatch-picker'][data-part='item'][data-state='checked'] > [data-part='swatch'] {
235
+ [data-scope='color-swatch-picker'][data-part='item'][data-state='checked'] > [data-part='swatch']:where([data-scope='color-swatch-picker']) {
231
236
  border-color: Highlight;
232
237
  }
233
238
 
package/css/combobox.css CHANGED
@@ -236,14 +236,19 @@
236
236
  /* 有值时清空钮顶上来,展开钮让位:两颗并排堆着用户分不清点哪个,换来换去还会让盒的宽度跳一下。
237
237
  判据是盒里此刻有一颗没收起的清空钮——没写清空钮的结构里展开钮照常留着;
238
238
  输入框仍是展开的入口(打字、方向键、openOnClick) */
239
- [data-scope='combobox'][data-part='control']:has([data-part='clear-trigger']:not([hidden])) [data-part='trigger'] {
239
+ [data-scope='combobox'][data-part='control']:has([data-part='clear-trigger']:not([hidden])) [data-part='trigger']:where([data-scope='combobox']) {
240
240
  display: none;
241
241
  }
242
242
 
243
243
  /* 展开时箭头翻个面,指向与列表的去向一致。转的是字形或作者塞的图形,不转按钮本体:
244
244
  按钮自带悬停底色,整个按钮转会带着底色一起转;家族按压缩放的是整钮,不影响这里的转向 */
245
- [data-scope='combobox'][data-part='trigger']:empty::before,
245
+ [data-scope='combobox'][data-part='trigger']:empty::before {
246
+ transition: rotate var(--xh-motion-duration-nudge) var(--xh-motion-ease-enter-strong);
247
+ }
248
+
249
+ /* 作者的箭头是任意节点:转向写在 trigger 自己的私有槽上,箭头只读槽(规则主体无特征时不挂在 data-state 后面) */
246
250
  [data-scope='combobox'][data-part='trigger'] > * {
251
+ rotate: var(--xh-_combobox-trigger-turn, none);
247
252
  transition: rotate var(--xh-motion-duration-nudge) var(--xh-motion-ease-enter-strong);
248
253
  }
249
254
 
@@ -272,11 +277,14 @@
272
277
  }
273
278
 
274
279
  /* 打开中与悬停同档:展开钮不另上底,方向由箭头转向承担 */
275
- [data-scope='combobox'][data-part='trigger'][data-state='open']:empty::before,
276
- [data-scope='combobox'][data-part='trigger'][data-state='open'] > * {
280
+ [data-scope='combobox'][data-part='trigger'][data-state='open']:empty::before {
277
281
  rotate: 180deg;
278
282
  }
279
283
 
284
+ [data-scope='combobox'][data-part='trigger'][data-state='open'] {
285
+ --xh-_combobox-trigger-turn: 180deg;
286
+ }
287
+
280
288
  [data-scope='combobox'][data-part='content'] {
281
289
  /* 材质由家族配方画(family/material.css 的 frosted 面:描边、底、1px 顶光、前景、投影与背景滤镜),
282
290
  这里只把使用者槽接进来 */
package/css/command.css CHANGED
@@ -298,7 +298,7 @@
298
298
  不会拖出一条越来越慢的尾巴)。打开时已有的结果直接呈现:自己或本列表带 data-instant。
299
299
  检索过滤筛掉的条目带 hidden 不生成盒子,重新露面只是换一批已有结果,机器给它打上 data-instant 直接呈现。
300
300
  backwards 让每条在自己那份延迟里保持起始帧 */
301
- [data-scope='command'][data-part='list'] [data-part='item']:not([data-instant], [data-scope='command'][data-part='list'][data-instant] *) {
301
+ [data-scope='command'][data-part='list'] [data-part='item']:where([data-scope='command']):not([data-instant], [data-scope='command'][data-part='list'][data-instant] :where([data-scope='command'])) {
302
302
  animation: xh-rise-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
303
303
  animation-delay: calc(var(--xh-_stagger-index, 0) * var(--xh-motion-stagger-step));
304
304
  }
@@ -123,6 +123,36 @@
123
123
  display: none;
124
124
  }
125
125
 
126
+ /* 整条占位:一段都没填、焦点也不在段上时,段位与分隔符让位给一句占位文字,焦点一进到段上就换回段位。
127
+ 段位只是淡出(仍可聚焦、仍在读屏树里),文字以生成内容压在同一行上、不吃指针,点下去落到底下的段位 */
128
+ [data-scope='date-field'][data-part='segment-group'][data-placeholder-shown] {
129
+ position: relative;
130
+ color: transparent;
131
+ }
132
+
133
+ /* 段位与分隔符(后者是不带解剖的文字节点)一起淡出:显隐写在 segment-group 自己的私有槽上,
134
+ 子节点只读槽——主体无特征的规则不挂在 data-placeholder-shown 后面,输入时翻转只让这一组失效 */
135
+ [data-scope='date-field'][data-part='segment-group'][data-placeholder-shown] {
136
+ --xh-_date-field-segment-opacity: 0;
137
+ }
138
+
139
+ [data-scope='date-field'][data-part='segment-group'] > * {
140
+ opacity: var(--xh-_date-field-segment-opacity, 1);
141
+ }
142
+
143
+ [data-scope='date-field'][data-part='segment-group'][data-placeholder-shown]::before {
144
+ content: attr(data-placeholder-text);
145
+ position: absolute;
146
+ inset-inline: 0;
147
+ inset-block-start: 50%;
148
+ overflow: hidden;
149
+ color: var(--xh-date-field-placeholder-fg, var(--xh-fg-subtle));
150
+ white-space: nowrap;
151
+ text-overflow: ellipsis;
152
+ pointer-events: none;
153
+ translate: 0 -50%;
154
+ }
155
+
126
156
  [data-scope='date-field'][data-part='segment-group'] > :not([data-scope]) {
127
157
  color: var(--xh-date-field-literal-fg, var(--xh-fg-subtle));
128
158
  }
@@ -235,6 +265,15 @@
235
265
  }
236
266
 
237
267
  @media (forced-colors: active) {
268
+ /* 整条占位的文字照系统的弱色画;段位让位时的透明字不被强制换色顶回来 */
269
+ [data-scope='date-field'][data-part='segment-group'][data-placeholder-shown] {
270
+ forced-color-adjust: none;
271
+ }
272
+
273
+ [data-scope='date-field'][data-part='segment-group'][data-placeholder-shown]::before {
274
+ color: GrayText;
275
+ }
276
+
238
277
  [data-scope='date-field'][data-part='segment'][data-invalid]:is([data-focus], :focus-visible) {
239
278
  outline: var(--xh-ring-width) solid Highlight;
240
279
  outline-offset: var(--xh-ring-offset);
@@ -12,6 +12,7 @@
12
12
 
13
13
  /* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
14
14
  @import '../family/motion.css';
15
+ @import '../family/tag-list.css';
15
16
 
16
17
  @layer xihan.components {
17
18
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
@@ -203,11 +204,75 @@
203
204
  color: var(--xh-date-picker-literal-fg, var(--xh-fg-subtle));
204
205
  }
205
206
 
207
+ /* 整条占位:一段都没填、焦点也不在段上时,段位与分隔符让位给一句占位文字,焦点一进到段上就换回段位。
208
+ 段位只是淡出(仍可聚焦、仍在读屏树里),文字以生成内容压在同一行上、不吃指针,点下去落到底下的段位 */
209
+ [data-scope='date-picker'][data-part='segment-group'][data-placeholder-shown] {
210
+ position: relative;
211
+ color: transparent;
212
+ }
213
+
214
+ /* 段位与分隔符(后者是不带解剖的文字节点)一起淡出:显隐写在 segment-group 自己的私有槽上,
215
+ 子节点只读槽——主体无特征的规则不挂在 data-placeholder-shown 后面,输入时翻转只让这一组失效 */
216
+ [data-scope='date-picker'][data-part='segment-group'][data-placeholder-shown] {
217
+ --xh-_date-picker-segment-opacity: 0;
218
+ }
219
+
220
+ [data-scope='date-picker'][data-part='segment-group'] > * {
221
+ opacity: var(--xh-_date-picker-segment-opacity, 1);
222
+ }
223
+
224
+ [data-scope='date-picker'][data-part='segment-group'][data-placeholder-shown]::before {
225
+ content: attr(data-placeholder-text);
226
+ position: absolute;
227
+ inset-inline: 0;
228
+ inset-block-start: 50%;
229
+ overflow: hidden;
230
+ color: var(--xh-date-picker-placeholder-fg, var(--xh-fg-subtle));
231
+ white-space: nowrap;
232
+ text-overflow: ellipsis;
233
+ pointer-events: none;
234
+ translate: 0 -50%;
235
+ }
236
+
206
237
  /* 容器自己不占 Tab 位、也不承载焦点,环由 control 画,这里不再套一圈 */
207
238
  [data-scope='date-picker'][data-part='segment-group']:focus-visible {
208
239
  outline: none;
209
240
  }
210
241
 
242
+ /* 多选的标签行:段位让位,选中的日期在盒里排成标签,超过 maxTagCount 的折进 +N。
243
+ 行里每一枚都是 tag(data-scope="tag"),样子归 tag.css;行怎么排、标签怎么进出归标签行家族配方,
244
+ 这里只接使用者的间距槽,并让它像段位那样占满输入行剩下的宽度 */
245
+ [data-scope='date-picker'][data-part='tag-list'] {
246
+ --xh-tag-list-gap: var(--xh-date-picker-tag-list-gap, var(--xh-space-1));
247
+
248
+ /* 基准取 0:只吃两颗钮剩下的宽度、在自己里面折行;按内容宽算基准的话,盒子会先在钮前面折行,把钮挤到最后一行 */
249
+ flex: 1 1 0;
250
+ flex-wrap: wrap;
251
+ font-size: var(--xh-date-picker-font-size, var(--xh-_date-picker-font-size));
252
+ }
253
+
254
+ /* 日期标签是定长文字,截短了就读不出是哪天:不收缩,排不下就折到下一行(与标签输入同一种排法),
255
+ 盒随行数长高(字段家族的 multi-tag 布局给),到上限后在盒内滚动 */
256
+ [data-scope='date-picker'][data-part='tag-list'] > [data-scope='tag'][data-part='root'] {
257
+ flex: none;
258
+ }
259
+
260
+ [data-scope='date-picker'][data-part='control'][data-xh-field-layout='multi-tag'] {
261
+ max-block-size: var(--xh-date-picker-control-max-h, var(--xh-viewport-h-sm));
262
+ overflow-y: auto;
263
+ }
264
+
265
+ /* 没有选中时这一行承载整条占位:与单选那条占位同一句文字、同一个颜色槽 */
266
+ [data-scope='date-picker'][data-part='tag-list'][data-placeholder-shown]::before {
267
+ content: attr(data-placeholder-text);
268
+ min-inline-size: 0;
269
+ overflow: hidden;
270
+ color: var(--xh-date-picker-placeholder-fg, var(--xh-fg-subtle));
271
+ white-space: nowrap;
272
+ text-overflow: ellipsis;
273
+ pointer-events: none;
274
+ }
275
+
211
276
  /* 两个按钮同一副长相:贴在框内末端的小方钮,不占宽度也不撑高 control。正方视觉盒、inset 圆角、
212
277
  悬停 100 / 按下 200 与 0.97 按压、粗指针热区、禁用面与 :focus-visible 关环(盒的 :focus-within
213
278
  已画了一圈)全由 Action Control 的 field-inset ghost 档给,组件只映射既有覆盖槽。
@@ -247,10 +312,11 @@
247
312
  --xh-action-fg-rest: var(--xh-date-picker-action-fg-hover, var(--xh-fg-default));
248
313
  }
249
314
 
250
- /* 有值时清空钮顶上来,日历钮让位:两颗并排堆着用户分不清点哪个 */
315
+ /* 有值时清空钮顶上来,日历钮让位:两颗并排堆着用户分不清点哪个。
316
+ 多选不让位:段位收起后日历钮是唯一的键盘入口(退格摘标签也在它身上),藏了键盘就进不来 */
251
317
  [data-scope='date-picker'][data-part='control']:has(
252
318
  > [data-scope='date-picker'][data-part='clear-trigger']:not([hidden])
253
- )
319
+ ):not(:has(> [data-scope='date-picker'][data-part='tag-list']:not([hidden])))
254
320
  > [data-scope='date-picker'][data-part='trigger'] {
255
321
  display: none;
256
322
  }
@@ -269,9 +335,10 @@
269
335
  border-radius: var(--xh-date-picker-content-radius, var(--xh-shape-overlay));
270
336
  background: var(--xh-date-picker-content-bg, var(--xh-bg-surface));
271
337
  color: var(--xh-date-picker-content-fg, var(--xh-fg-default));
272
- /* 日历是定高结构:六行日期加表头本来就有固定高度,上限走页内滚动面那一档;
338
+ /* 日历是定高结构:网格、时间列与确认行都按 px 排,天然高度就是它们的和,缺省不另设上限
339
+ (按 rem 的滚动面档会随根字号缩小,根字号低于 16px 时确认行就被挤到滚动里);
273
340
  可用高度是定位引擎算出的视口余量,视口真放不下时再收一截 */
274
- max-block-size: min(var(--xh-date-picker-max-h, var(--xh-viewport-h-lg)), var(--xh-_date-picker-available-h));
341
+ max-block-size: min(var(--xh-date-picker-max-h, var(--xh-_date-picker-available-h)), var(--xh-_date-picker-available-h));
275
342
  /* 两轴都滚:块轴放不下时面板内自己竖滚,行内轴放不下时面板内自己横滚,
276
343
  日历那几块保持各自的天然宽度,不被压 */
277
344
  overflow: auto;
@@ -340,7 +407,7 @@
340
407
  }
341
408
 
342
409
  /* 确认按钮沉到所在那一行的底边:它是整块面板的出口,不跟日历顶边对齐 */
343
- [data-scope='date-picker'][data-part='content']:has(> [data-part='time-column']) > [data-part='confirm-trigger'] {
410
+ [data-scope='date-picker'][data-part='content']:has(> [data-part='time-column']) > [data-part='confirm-trigger']:where([data-scope='date-picker']) {
344
411
  align-self: flex-end;
345
412
  }
346
413
 
@@ -660,7 +727,7 @@
660
727
 
661
728
  /* 列整体禁用时格没有自己的 aria-disabled,禁用面按列的 aria-disabled 映射到家族槽:
662
729
  字色降级、悬停 / 高亮 / 按下不换面、光标 not-allowed */
663
- [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item'] {
730
+ [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-picker']) {
664
731
  --xh-collection-fg-rest: var(--xh-fg-disabled);
665
732
  --xh-collection-fg-hover: var(--xh-fg-disabled);
666
733
  --xh-collection-fg-keyboard-highlight: var(--xh-fg-disabled);
@@ -679,7 +746,7 @@
679
746
  --xh-collection-cursor-selected: not-allowed;
680
747
  }
681
748
 
682
- [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']::after {
749
+ [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-picker'])::after {
683
750
  background-color: var(--xh-fg-disabled);
684
751
  }
685
752
 
@@ -734,6 +801,16 @@
734
801
  }
735
802
 
736
803
  @media (forced-colors: active) {
804
+ /* 整条占位的文字照系统的弱色画;段位让位时的透明字不被强制换色顶回来 */
805
+ [data-scope='date-picker'][data-part='segment-group'][data-placeholder-shown] {
806
+ forced-color-adjust: none;
807
+ }
808
+
809
+ [data-scope='date-picker'][data-part='segment-group'][data-placeholder-shown]::before,
810
+ [data-scope='date-picker'][data-part='tag-list'][data-placeholder-shown]::before {
811
+ color: GrayText;
812
+ }
813
+
737
814
  /* 系统接管底色后仍保住末端对号;禁用标记改用系统失效色。 */
738
815
  [data-scope='date-picker'][data-part='preset']::after,
739
816
  [data-scope='date-picker'][data-part='time-item']::after {
@@ -749,13 +826,13 @@
749
826
 
750
827
  [data-scope='date-picker'][data-part='preset'][data-disabled]::after,
751
828
  [data-scope='date-picker'][data-part='time-item'][data-disabled]::after,
752
- [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']::after {
829
+ [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-picker'])::after {
753
830
  background-color: GrayText;
754
831
  }
755
832
 
756
833
  [data-scope='date-picker'][data-part='preset'][data-disabled],
757
834
  [data-scope='date-picker'][data-part='time-item'][data-disabled],
758
- [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item'] {
835
+ [data-scope='date-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-picker']) {
759
836
  color: GrayText;
760
837
  }
761
838
  }
@@ -232,6 +232,36 @@
232
232
  color: var(--xh-date-range-picker-literal-fg, var(--xh-fg-subtle));
233
233
  }
234
234
 
235
+ /* 整条占位:一段都没填、焦点也不在段上时,段位与分隔符让位给一句占位文字,焦点一进到段上就换回段位。
236
+ 段位只是淡出(仍可聚焦、仍在读屏树里),文字以生成内容压在同一行上、不吃指针,点下去落到底下的段位 */
237
+ [data-scope='date-range-picker'][data-part='segment-group'][data-placeholder-shown] {
238
+ position: relative;
239
+ color: transparent;
240
+ }
241
+
242
+ /* 段位与分隔符(后者是不带解剖的文字节点)一起淡出:显隐写在 segment-group 自己的私有槽上,
243
+ 子节点只读槽——主体无特征的规则不挂在 data-placeholder-shown 后面,输入时翻转只让这一组失效 */
244
+ [data-scope='date-range-picker'][data-part='segment-group'][data-placeholder-shown] {
245
+ --xh-_date-range-picker-segment-opacity: 0;
246
+ }
247
+
248
+ [data-scope='date-range-picker'][data-part='segment-group'] > * {
249
+ opacity: var(--xh-_date-range-picker-segment-opacity, 1);
250
+ }
251
+
252
+ [data-scope='date-range-picker'][data-part='segment-group'][data-placeholder-shown]::before {
253
+ content: attr(data-placeholder-text);
254
+ position: absolute;
255
+ inset-inline: 0;
256
+ inset-block-start: 50%;
257
+ overflow: hidden;
258
+ color: var(--xh-date-range-picker-placeholder-fg, var(--xh-fg-subtle));
259
+ white-space: nowrap;
260
+ text-overflow: ellipsis;
261
+ pointer-events: none;
262
+ translate: 0 -50%;
263
+ }
264
+
235
265
  /* 容器自己不占 Tab 位、也不承载焦点,环由 control 画,这里不再套一圈 */
236
266
  [data-scope='date-range-picker'][data-part='segment-group']:focus-visible {
237
267
  outline: none;
@@ -298,9 +328,10 @@
298
328
  border-radius: var(--xh-date-range-picker-content-radius, var(--xh-shape-overlay));
299
329
  background: var(--xh-date-range-picker-content-bg, var(--xh-bg-surface));
300
330
  color: var(--xh-date-range-picker-content-fg, var(--xh-fg-default));
301
- /* 日历是定高结构:六行日期加表头本来就有固定高度,上限走页内滚动面那一档;
331
+ /* 日历是定高结构:网格、时间列与确认行都按 px 排,天然高度就是它们的和,缺省不另设上限
332
+ (按 rem 的滚动面档会随根字号缩小,根字号低于 16px 时确认行就被挤到滚动里);
302
333
  可用高度是定位引擎算出的视口余量,视口真放不下时再收一截 */
303
- max-block-size: min(var(--xh-date-range-picker-max-h, var(--xh-viewport-h-lg)), var(--xh-_date-range-picker-available-h));
334
+ max-block-size: min(var(--xh-date-range-picker-max-h, var(--xh-_date-range-picker-available-h)), var(--xh-_date-range-picker-available-h));
304
335
  /* 两轴都滚:块轴放不下时面板内自己竖滚,行内轴放不下时面板内自己横滚,
305
336
  日历那几块保持各自的天然宽度,不被压 */
306
337
  overflow: auto;
@@ -528,7 +559,7 @@
528
559
  }
529
560
 
530
561
  /* 确认按钮沉到所在那一行的底边:它是整块面板的出口,不跟日历顶边对齐 */
531
- [data-scope='date-range-picker'][data-part='content']:has(> [data-part='column-group']) > [data-part='confirm-trigger'] {
562
+ [data-scope='date-range-picker'][data-part='content']:has(> [data-part='column-group']) > [data-part='confirm-trigger']:where([data-scope='date-range-picker']) {
532
563
  align-self: flex-end;
533
564
  }
534
565
 
@@ -710,7 +741,7 @@
710
741
 
711
742
  /* 列整体禁用时格没有自己的 aria-disabled,禁用面按列的 aria-disabled 映射到家族槽:
712
743
  字色降级、悬停 / 高亮 / 按下不换面、光标 not-allowed */
713
- [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item'] {
744
+ [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-range-picker']) {
714
745
  --xh-collection-fg-rest: var(--xh-fg-disabled);
715
746
  --xh-collection-fg-hover: var(--xh-fg-disabled);
716
747
  --xh-collection-fg-keyboard-highlight: var(--xh-fg-disabled);
@@ -729,7 +760,7 @@
729
760
  --xh-collection-cursor-selected: not-allowed;
730
761
  }
731
762
 
732
- [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']::after {
763
+ [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-range-picker'])::after {
733
764
  background-color: var(--xh-fg-disabled);
734
765
  }
735
766
 
@@ -784,6 +815,15 @@
784
815
  }
785
816
 
786
817
  @media (forced-colors: active) {
818
+ /* 整条占位的文字照系统的弱色画;段位让位时的透明字不被强制换色顶回来 */
819
+ [data-scope='date-range-picker'][data-part='segment-group'][data-placeholder-shown] {
820
+ forced-color-adjust: none;
821
+ }
822
+
823
+ [data-scope='date-range-picker'][data-part='segment-group'][data-placeholder-shown]::before {
824
+ color: GrayText;
825
+ }
826
+
787
827
  /* 系统接管底色后仍保住末端对号;禁用标记改用系统失效色。 */
788
828
  [data-scope='date-range-picker'][data-part='preset']::after,
789
829
  [data-scope='date-range-picker'][data-part='time-item']::after {
@@ -799,13 +839,13 @@
799
839
 
800
840
  [data-scope='date-range-picker'][data-part='preset'][data-disabled]::after,
801
841
  [data-scope='date-range-picker'][data-part='time-item'][data-disabled]::after,
802
- [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']::after {
842
+ [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-range-picker'])::after {
803
843
  background-color: GrayText;
804
844
  }
805
845
 
806
846
  [data-scope='date-range-picker'][data-part='preset'][data-disabled],
807
847
  [data-scope='date-range-picker'][data-part='time-item'][data-disabled],
808
- [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item'] {
848
+ [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']:where([data-scope='date-range-picker']) {
809
849
  color: GrayText;
810
850
  }
811
851
 
package/css/diff-view.css CHANGED
@@ -164,7 +164,7 @@
164
164
  /* 窄档的并排视图:一行的两侧改成上下两段,旧行在上、新行在下。
165
165
  行由横排 flex 换成两列栅格——行号一列、正文一列,一行里的四个格按 DOM 次序
166
166
  自然落成两行,正文列因此只按单侧的最长行撑宽,不再是两侧之和 */
167
- [data-scope='diff-view'][data-part='root'][data-view='split'] [data-part='row']:not([hidden]) {
167
+ [data-scope='diff-view'][data-part='root'][data-view='split'] [data-part='row']:where([data-scope='diff-view']):not([hidden]) {
168
168
  display: grid;
169
169
  grid-template-columns: auto minmax(0, 1fr);
170
170
  }
@@ -197,13 +197,13 @@
197
197
 
198
198
  /* 开了换行:pre-wrap 仍保留缩进与连续空白,只是允许行尾折下来;
199
199
  anywhere 让没有空格的长串(url、base64)也能断 */
200
- [data-scope='diff-view'][data-part='root'][data-wrap] [data-part='line-content'] {
200
+ [data-scope='diff-view'][data-part='root'][data-wrap] [data-part='line-content']:where([data-scope='diff-view']) {
201
201
  white-space: pre-wrap;
202
202
  overflow-wrap: anywhere;
203
203
  }
204
204
 
205
205
  /* 正文原本按最长行撑宽,不解除就折不下来 */
206
- [data-scope='diff-view'][data-part='root'][data-wrap] [data-part='body'] {
206
+ [data-scope='diff-view'][data-part='root'][data-wrap] [data-part='body']:where([data-scope='diff-view']) {
207
207
  min-inline-size: 0;
208
208
  }
209
209
 
@@ -348,7 +348,7 @@
348
348
  --xh-_diff-view-comment-col: var(--xh-diff-view-comment-col, var(--xh-diff-view-line-height, var(--xh-text-code-leading)));
349
349
  }
350
350
 
351
- [data-scope='diff-view'][data-part='root'][data-commentable] [data-part='line-content'] {
351
+ [data-scope='diff-view'][data-part='root'][data-commentable] [data-part='line-content']:where([data-scope='diff-view']) {
352
352
  position: relative;
353
353
  padding-inline-start: var(--xh-_diff-view-comment-col);
354
354
  }
@@ -387,8 +387,8 @@
387
387
  --xh-action-opacity-rest: 0;
388
388
  }
389
389
 
390
- [data-scope='diff-view'][data-part='row']:hover [data-part='comment-trigger'],
391
- [data-scope='diff-view'][data-part='viewport']:focus-within [data-part='comment-trigger'] {
390
+ [data-scope='diff-view'][data-part='row']:hover [data-part='comment-trigger']:where([data-scope='diff-view']),
391
+ [data-scope='diff-view'][data-part='viewport']:focus-within [data-part='comment-trigger']:where([data-scope='diff-view']) {
392
392
  --xh-action-opacity-rest: 1;
393
393
  }
394
394
  }
@@ -434,13 +434,13 @@
434
434
 
435
435
  /* 宽档:视口放得下两列,并排视图回到一行两侧 */
436
436
  @media (min-width: 1024px) {
437
- [data-scope='diff-view'][data-part='root'][data-view='split'] [data-part='row']:not([hidden]) {
437
+ [data-scope='diff-view'][data-part='root'][data-view='split'] [data-part='row']:where([data-scope='diff-view']):not([hidden]) {
438
438
  display: flex;
439
439
  }
440
440
 
441
441
  /* 两列之间的接缝:新侧的行号槽再补一条左边线。只在并排时是接缝,
442
442
  堆叠时它落在段首,成了一条与任何东西都不相接的竖线 */
443
- [data-scope='diff-view'][data-part='root'][data-view='split'] [data-part='line-number'][data-side='new'] {
443
+ [data-scope='diff-view'][data-part='root'][data-view='split'] [data-part='line-number'][data-side='new']:where([data-scope='diff-view']) {
444
444
  border-inline-start: var(--xh-stroke-thin) solid var(--xh-diff-view-divider, var(--xh-border-subtle));
445
445
  }
446
446
  }
@@ -42,7 +42,7 @@
42
42
  }
43
43
 
44
44
  /* 新增的行进场,同一批按到达顺序错开;首帧就在的直接呈现(自己或根节点带 data-instant) */
45
- [data-scope='field-array'][data-part='item']:not([data-instant], [data-instant] > *) {
45
+ [data-scope='field-array'][data-part='item']:not([data-instant], [data-instant] > :where([data-scope='field-array'])) {
46
46
  animation: xh-item-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
47
47
  animation-delay: calc(var(--xh-_stagger-index, 0) * var(--xh-motion-stagger-step));
48
48
  }
package/css/field.css CHANGED
@@ -18,6 +18,10 @@
18
18
  display: flex;
19
19
  flex-direction: column;
20
20
  gap: var(--xh-field-gap, var(--xh-space-1));
21
+ /* 字段族控件放进字段即铺满字段宽:字段的宽由表单的列给,控件跟着列走,
22
+ 不必逐个组件在根上写 inline-size: 100%。单独摆放的控件仍是 16rem 缺省宽;
23
+ 单类钉宽(--xh-<组件>-control-w)照旧压过这一条 */
24
+ --xh-control-w: 100%;
21
25
  }
22
26
 
23
27
  /* 表单横排(标签左置):字段转两列网格,标签列宽由表单的 --xh-form-label-w 统一给,
@@ -184,7 +184,7 @@
184
184
  transition: translate var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
185
185
  }
186
186
 
187
- [data-scope='file-upload'][data-part='item']:not([data-instant], [data-instant] > *) {
187
+ [data-scope='file-upload'][data-part='item']:not([data-instant], [data-instant] > :where([data-scope='file-upload'])) {
188
188
  animation: xh-item-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
189
189
  animation-delay: calc(var(--xh-_stagger-index, 0) * var(--xh-motion-stagger-step));
190
190
  }