@xihan-ui/styles 2.1.0 → 3.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 (152) hide show
  1. package/CHANGELOG.md +1227 -0
  2. package/README.md +6 -1
  3. package/component-tokens.d.ts +505 -96
  4. package/components.tokens.json +34636 -25846
  5. package/css/accordion.css +34 -8
  6. package/css/alert.css +59 -1
  7. package/css/anchor.css +46 -8
  8. package/css/approval.css +116 -76
  9. package/css/avatar-group.css +1 -1
  10. package/css/avatar.css +13 -5
  11. package/css/back-top.css +61 -42
  12. package/css/badge.css +62 -12
  13. package/css/bar-code.css +1 -1
  14. package/css/breadcrumb.css +62 -3
  15. package/css/button-group.css +4 -4
  16. package/css/button.css +67 -19
  17. package/css/calendar-picker.css +19 -0
  18. package/css/calendar-range-picker.css +39 -2
  19. package/css/card.css +115 -1
  20. package/css/carousel.css +148 -43
  21. package/css/cartesian-chart.css +830 -0
  22. package/css/cascader.css +181 -65
  23. package/css/checkbox-group.css +59 -89
  24. package/css/checkbox.css +16 -49
  25. package/css/citation.css +470 -0
  26. package/css/clipboard.css +20 -63
  27. package/css/code-view.css +101 -6
  28. package/css/collapsible.css +34 -8
  29. package/css/color-field.css +18 -0
  30. package/css/color-picker.css +55 -58
  31. package/css/color-slider.css +22 -15
  32. package/css/color-swatch-picker.css +3 -1
  33. package/css/combobox.css +80 -33
  34. package/css/command.css +45 -43
  35. package/css/context-menu.css +39 -22
  36. package/css/date-field.css +23 -0
  37. package/css/date-picker.css +57 -22
  38. package/css/date-range-picker.css +301 -12
  39. package/css/description.css +17 -1
  40. package/css/descriptions.css +42 -0
  41. package/css/dialog.css +94 -36
  42. package/css/diff-view.css +97 -12
  43. package/css/download-trigger.css +44 -78
  44. package/css/drawer.css +160 -119
  45. package/css/editable.css +19 -0
  46. package/css/empty-state.css +7 -6
  47. package/css/field-array.css +36 -0
  48. package/css/field.css +16 -18
  49. package/css/file-upload.css +125 -135
  50. package/css/flex.css +324 -8
  51. package/css/float-button.css +165 -38
  52. package/css/floating-panel.css +53 -19
  53. package/css/form.css +23 -17
  54. package/css/funnel-chart.css +106 -0
  55. package/css/graph-chart.css +205 -0
  56. package/css/grid-list.css +235 -0
  57. package/css/grid.css +252 -1
  58. package/css/heatmap.css +119 -36
  59. package/css/hierarchy-chart.css +298 -0
  60. package/css/hover-card.css +31 -14
  61. package/css/icon.css +100 -0
  62. package/css/image-cropper.css +33 -7
  63. package/css/image-viewer.css +167 -22
  64. package/css/image.css +23 -4
  65. package/css/input-group.css +11 -13
  66. package/css/json-viewer.css +50 -2
  67. package/css/layout.css +68 -18
  68. package/css/liquid.css +106 -0
  69. package/css/list.css +1 -1
  70. package/css/listbox.css +46 -6
  71. package/css/loading-bar.css +27 -13
  72. package/css/log.css +129 -33
  73. package/css/markdown-stream.css +1 -1
  74. package/css/marquee.css +163 -7
  75. package/css/matrix-code.css +1 -1
  76. package/css/mention.css +35 -19
  77. package/css/menu.css +35 -21
  78. package/css/menubar.css +36 -20
  79. package/css/message-feed.css +172 -51
  80. package/css/navigation-menu.css +172 -11
  81. package/css/notification.css +429 -108
  82. package/css/number-field.css +22 -0
  83. package/css/page-header.css +3 -1
  84. package/css/pagination.css +126 -24
  85. package/css/password-input.css +40 -8
  86. package/css/pie-chart.css +247 -0
  87. package/css/popconfirm.css +44 -50
  88. package/css/popover.css +50 -14
  89. package/css/progress.css +308 -10
  90. package/css/prompt-input.css +36 -0
  91. package/css/question-flow.css +97 -57
  92. package/css/radar-chart.css +233 -0
  93. package/css/radio-group.css +363 -5
  94. package/css/rating.css +21 -23
  95. package/css/reasoning.css +61 -54
  96. package/css/resizable.css +6 -1
  97. package/css/sankey-chart.css +174 -0
  98. package/css/scroll-area.css +32 -0
  99. package/css/scrollbar.css +1 -1
  100. package/css/select.css +74 -55
  101. package/css/side-nav.css +173 -24
  102. package/css/signature-pad.css +16 -1
  103. package/css/skeleton.css +13 -14
  104. package/css/slider.css +35 -13
  105. package/css/sortable.css +37 -7
  106. package/css/sparkline.css +164 -0
  107. package/css/spinner.css +50 -22
  108. package/css/splitter.css +7 -1
  109. package/css/statistic.css +10 -0
  110. package/css/steps.css +248 -29
  111. package/css/switch.css +23 -48
  112. package/css/table.css +158 -118
  113. package/css/tabs.css +231 -19
  114. package/css/tag-group.css +27 -3
  115. package/css/tag.css +53 -12
  116. package/css/tags-input.css +40 -3
  117. package/css/text-field.css +19 -0
  118. package/css/time-field.css +20 -1
  119. package/css/time-picker.css +44 -15
  120. package/css/time-range-picker.css +45 -16
  121. package/css/timeline.css +1 -1
  122. package/css/toggle-group.css +4 -4
  123. package/css/toggle.css +4 -3
  124. package/css/tool-call.css +59 -51
  125. package/css/toolbar.css +101 -3
  126. package/css/tooltip.css +15 -2
  127. package/css/tour.css +42 -12
  128. package/css/transfer.css +98 -75
  129. package/css/tree-select.css +232 -53
  130. package/css/tree.css +201 -55
  131. package/css/truncate.css +55 -12
  132. package/css/typography.css +93 -0
  133. package/css/virtualizer.css +56 -0
  134. package/css/watermark.css +23 -0
  135. package/family/action-control.css +14 -5
  136. package/family/chart.css +480 -0
  137. package/family/check-mark.css +94 -0
  138. package/family/choice-card.css +97 -0
  139. package/family/collection-item.css +9 -15
  140. package/family/field-chrome.css +1 -12
  141. package/family/loading-ring.css +95 -0
  142. package/family/material.css +72 -0
  143. package/family/menu-choice.css +56 -0
  144. package/family/motion.css +207 -10
  145. package/family/tag-list.css +59 -0
  146. package/index.css +22997 -13678
  147. package/index.unlayered.css +12928 -3605
  148. package/package.json +20 -8
  149. package/css/gradient-text.css +0 -91
  150. package/css/icon-wrapper.css +0 -81
  151. package/css/segmented.css +0 -280
  152. package/css/toast.css +0 -499
@@ -73,6 +73,7 @@
73
73
  --xh-_date-range-picker-control-px: var(--xh-control-px-md);
74
74
  --xh-_date-range-picker-gap: var(--xh-control-gap-md);
75
75
  --xh-_date-range-picker-font-size: var(--xh-control-font-md);
76
+ --xh-_date-range-picker-item-py: var(--xh-list-option-py-md);
76
77
 
77
78
  /* 选中对号随语气走。没写 data-tone 时这几个 --xh-_tone* 没被声明,退回品牌色 */
78
79
  /* 内嵌日期段沿用日期输入的轻强调焦点:当前段是「当前项」,淡底 + 淡底前景,不另画一套实心选择态。 */
@@ -80,6 +81,15 @@
80
81
  --xh-_date-field-segment-fg: var(--xh-_tone-fg, var(--xh-fg-on-brand-subtle));
81
82
  /* 对号画在普通面上,取语气前景角色,不拿实心强调底色充当前景。 */
82
83
  --xh-_date-range-picker-check-fg: var(--xh-_tone, var(--xh-fg-brand));
84
+ /* 时间列与预设的对号与 Select 等列表的对号同一把尺:指示符档,随密度收放 */
85
+ --xh-_date-range-picker-time-item-check-size: var(--xh-control-indicator-size);
86
+ }
87
+
88
+ /* 375px 复合面板要同时容下日历与两组时间列;手机档用正式小指示符,平板起恢复 16px。 */
89
+ @media not all and (min-width: 768px) {
90
+ [data-scope='date-range-picker']:is([data-part='root'], [data-part='positioner']) {
91
+ --xh-_date-range-picker-time-item-check-size: var(--xh-control-indicator-sm);
92
+ }
83
93
  }
84
94
 
85
95
  /* 与文本框、分段日期同一套堆叠:标签一行、输入行一行 */
@@ -108,6 +118,7 @@
108
118
  --xh-_date-range-picker-control-px: var(--xh-control-px-sm);
109
119
  --xh-_date-range-picker-gap: var(--xh-control-gap-sm);
110
120
  --xh-_date-range-picker-font-size: var(--xh-control-font-sm);
121
+ --xh-_date-range-picker-item-py: var(--xh-list-option-py-sm);
111
122
  }
112
123
 
113
124
  [data-scope='date-range-picker']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
@@ -116,6 +127,7 @@
116
127
  --xh-_date-range-picker-control-px: var(--xh-control-px-lg);
117
128
  --xh-_date-range-picker-gap: var(--xh-control-gap-lg);
118
129
  --xh-_date-range-picker-font-size: var(--xh-control-font-lg);
130
+ --xh-_date-range-picker-item-py: var(--xh-list-option-py-lg);
119
131
  }
120
132
 
121
133
  /* 只要声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
@@ -312,7 +324,8 @@
312
324
  outline: none;
313
325
  }
314
326
 
315
- [data-scope='date-range-picker'][data-part='content'][data-state='open'] {
327
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
328
+ [data-scope='date-range-picker'][data-part='content'][data-state='open']:not([data-instant]) {
316
329
  animation: xh-overlay-slide-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
317
330
  }
318
331
 
@@ -350,7 +363,7 @@
350
363
  手机档两张月历折行堆叠,线画在块起始边 */
351
364
  [data-scope='date-range-picker'][data-part='calendar'] + [data-scope='date-range-picker'][data-part='calendar'] {
352
365
  padding-block-start: var(--xh-date-range-picker-panel-gap, var(--xh-space-3));
353
- border-block-start: var(--xh-stroke-thin) solid var(--xh-date-range-picker-panel-divider, var(--xh-material-frosted-separator));
366
+ border-block-start: var(--xh-stroke-thin) solid var(--xh-date-range-picker-panel-divider, var(--xh-material-solid-separator));
354
367
  }
355
368
 
356
369
  /* 平板起两张月历并排放得下,线改画在行内起始边 */
@@ -359,7 +372,7 @@
359
372
  padding-block-start: 0;
360
373
  padding-inline-start: var(--xh-date-range-picker-panel-gap, var(--xh-space-3));
361
374
  border-block-start: none;
362
- border-inline-start: var(--xh-stroke-thin) solid var(--xh-date-range-picker-panel-divider, var(--xh-material-frosted-separator));
375
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-date-range-picker-panel-divider, var(--xh-material-solid-separator));
363
376
  }
364
377
  }
365
378
 
@@ -410,7 +423,7 @@
410
423
  overflow-y: hidden;
411
424
  /* 浮层滚动面:滚到头不把页面一起带走 */
412
425
  overscroll-behavior: contain;
413
- border-block-end: var(--xh-stroke-thin) solid var(--xh-date-range-picker-column-divider, var(--xh-material-frosted-separator));
426
+ border-block-end: var(--xh-stroke-thin) solid var(--xh-date-range-picker-column-divider, var(--xh-material-solid-separator));
414
427
  }
415
428
 
416
429
  /* 平板起:换成贴在日历行内起始一侧的竖列,滚动轴与分隔线一起转过来 */
@@ -420,7 +433,7 @@
420
433
  flex-direction: column;
421
434
  overflow: auto;
422
435
  border-block-end: none;
423
- border-inline-end: var(--xh-stroke-thin) solid var(--xh-date-range-picker-column-divider, var(--xh-material-frosted-separator));
436
+ border-inline-end: var(--xh-stroke-thin) solid var(--xh-date-range-picker-column-divider, var(--xh-material-solid-separator));
424
437
  }
425
438
  }
426
439
 
@@ -435,7 +448,7 @@
435
448
  --xh-collection-block-padding: var(--xh-date-range-picker-preset-py, var(--xh-space-1));
436
449
  --xh-collection-inline-padding: var(--xh-date-range-picker-preset-px, var(--xh-space-3));
437
450
  --xh-collection-font-size: var(--xh-text-secondary-size);
438
- --xh-collection-radius: var(--xh-date-range-picker-preset-radius, var(--xh-shape-control));
451
+ --xh-collection-radius: var(--xh-date-range-picker-preset-radius, var(--xh-shape-inset));
439
452
  /* 面板是实体面(floating),正文取页面前景 */
440
453
  --xh-collection-fg-rest: var(--xh-fg-default);
441
454
  --xh-collection-fg-hover: var(--xh-fg-default);
@@ -462,7 +475,7 @@
462
475
  /* 对号的末端轨始终留着,切换选中时文字与整列宽度都不移动。 */
463
476
  padding-inline-end: calc(
464
477
  var(--xh-date-range-picker-preset-px, var(--xh-space-3)) +
465
- var(--xh-date-range-picker-preset-check-size, var(--xh-glyph-size-sm)) +
478
+ var(--xh-date-range-picker-preset-check-size, var(--xh-control-indicator-size)) +
466
479
  var(--xh-space-1)
467
480
  );
468
481
  white-space: nowrap;
@@ -487,8 +500,8 @@
487
500
  position: absolute;
488
501
  inset-block-start: 50%;
489
502
  inset-inline-end: var(--xh-date-range-picker-preset-px, var(--xh-space-3));
490
- inline-size: var(--xh-date-range-picker-preset-check-size, var(--xh-glyph-size-sm));
491
- block-size: var(--xh-date-range-picker-preset-check-size, var(--xh-glyph-size-sm));
503
+ inline-size: var(--xh-date-range-picker-preset-check-size, var(--xh-control-indicator-size));
504
+ block-size: var(--xh-date-range-picker-preset-check-size, var(--xh-control-indicator-size));
492
505
  translate: 0 -50%;
493
506
  background-color: var(--xh-date-range-picker-preset-check-fg, var(--xh-_date-range-picker-check-fg));
494
507
  opacity: 0;
@@ -506,6 +519,247 @@
506
519
  background-color: var(--xh-date-range-picker-preset-fg-disabled, var(--xh-fg-disabled));
507
520
  }
508
521
 
522
+ /* —— showTime:起止各一组时间列贴在日历旁边、逐列滚动,确认按钮收口 ——
523
+ 与日历同处一条可折行的行内流:放得下就并排,放不下时两组时间列折到日历下面,组内几列仍横着排 */
524
+ [data-scope='date-range-picker'][data-part='content']:has(> [data-part='column-group']) {
525
+ display: flex;
526
+ flex-wrap: wrap;
527
+ align-items: flex-start;
528
+ }
529
+
530
+ /* 确认按钮沉到所在那一行的底边:它是整块面板的出口,不跟日历顶边对齐 */
531
+ [data-scope='date-range-picker'][data-part='content']:has(> [data-part='column-group']) > [data-part='confirm-trigger'] {
532
+ align-self: flex-end;
533
+ }
534
+
535
+ /* 一端的几列成组并排,小标题落在与日历标题栏等高的顶带里;两组之间多留一档空当,眼睛先分起止、再分时分 */
536
+ [data-scope='date-range-picker'][data-part='column-group'] {
537
+ position: relative;
538
+ display: flex;
539
+ flex: none;
540
+ flex-wrap: nowrap;
541
+ align-items: stretch;
542
+ min-inline-size: 0;
543
+ /* 让出与日历标题栏等高的一带放小标题,列的顶边因此与日历网格对齐 */
544
+ padding-block-start: var(
545
+ --xh-date-range-picker-column-group-offset,
546
+ calc(var(--xh-control-h-sm) + var(--xh-date-range-picker-calendar-gap, var(--xh-space-2)))
547
+ );
548
+ }
549
+
550
+ [data-scope='date-range-picker'][data-part='column-group'][hidden] {
551
+ display: none;
552
+ }
553
+
554
+ [data-scope='date-range-picker'][data-part='column-group'] + [data-scope='date-range-picker'][data-part='column-group'] {
555
+ margin-inline-start: var(--xh-date-range-picker-column-group-gap, var(--xh-space-2));
556
+ }
557
+
558
+ /* 组的小标题:辅助文本档、次要前景;正在编辑的那一端换成正文前景与中等字重,看得出日历下一次点选改哪一端 */
559
+ [data-scope='date-range-picker'][data-part='column-group-label'] {
560
+ position: absolute;
561
+ inset-block-start: 0;
562
+ inset-inline: 0;
563
+ display: flex;
564
+ box-sizing: border-box;
565
+ align-items: center;
566
+ justify-content: center;
567
+ block-size: var(--xh-control-h-sm);
568
+ padding-inline: var(--xh-date-range-picker-column-group-label-px, var(--xh-space-1));
569
+ color: var(--xh-date-range-picker-column-group-label-fg, var(--xh-fg-subtle));
570
+ font-size: var(--xh-text-caption-size);
571
+ line-height: var(--xh-leading-normal);
572
+ text-align: center;
573
+ user-select: none;
574
+ }
575
+
576
+ [data-scope='date-range-picker'][data-part='column-group-label'][data-editing] {
577
+ color: var(--xh-date-range-picker-column-group-label-fg-active, var(--xh-fg-default));
578
+ font-weight: var(--xh-date-range-picker-column-group-label-font-weight-active, var(--xh-font-weight-medium));
579
+ }
580
+
581
+ [data-scope='date-range-picker'][data-part='column-group-label'][hidden] {
582
+ display: none;
583
+ }
584
+
585
+ [data-scope='date-range-picker'][data-part='time-column'] {
586
+ display: flex;
587
+ flex: none;
588
+ flex-direction: column;
589
+ gap: var(--xh-date-range-picker-time-column-gap, 0);
590
+ min-inline-size: var(--xh-date-range-picker-time-column-min-w, var(--xh-overlay-column-min-w));
591
+ /* 几列并排:定高而不是随内容收,否则时列与分列的可选值一多一少就错位 */
592
+ block-size: var(--xh-date-range-picker-time-column-h, var(--xh-overlay-calendar-column-h));
593
+ padding-block: var(--xh-date-range-picker-time-column-padding, var(--xh-space-1));
594
+ padding-inline: var(--xh-date-range-picker-time-column-px, 0);
595
+ overflow-x: hidden;
596
+ overflow-y: auto;
597
+ /* 浮层滚动面:滚到头不把页面一起带走 */
598
+ overscroll-behavior: contain;
599
+ border-inline-start: var(--xh-stroke-thin) solid var(--xh-date-range-picker-column-divider, var(--xh-material-solid-separator));
600
+ }
601
+
602
+ [data-scope='date-range-picker'][data-part='time-column'][hidden] {
603
+ display: none;
604
+ }
605
+
606
+ /* 时间格:悬停 / 高亮 100、按下 200 由 Collection Item 家族按 overlay 语境给,选中只留末端对号——
607
+ 浮层瞬态集合的选中不上品牌淡底、不加粗、不变字色。格里只有数字、没有正文部件,保持自己的
608
+ 居中排版与等宽标记轨,家族只给状态面 */
609
+ [data-scope='date-range-picker'][data-part='time-item'] {
610
+ --xh-_date-range-picker-time-item-rail: max(
611
+ var(--xh-date-range-picker-time-item-px, var(--xh-space-0_5)),
612
+ calc(var(--xh-date-range-picker-time-item-check-size, var(--xh-_date-range-picker-time-item-check-size)) + var(--xh-space-0_5))
613
+ );
614
+ --xh-collection-block-padding: var(--xh-date-range-picker-time-item-py, var(--xh-_date-range-picker-item-py));
615
+ --xh-collection-inline-padding: var(--xh-_date-range-picker-time-item-rail);
616
+ --xh-collection-font-size: var(--xh-date-range-picker-time-item-font-size, var(--xh-_date-range-picker-font-size));
617
+ --xh-collection-radius: var(--xh-date-range-picker-time-item-radius, var(--xh-shape-inset));
618
+ --xh-collection-fg-rest: var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg));
619
+ --xh-collection-fg-hover: var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg));
620
+ --xh-collection-fg-keyboard-highlight: var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg));
621
+ --xh-collection-fg-pressed: var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg));
622
+ --xh-collection-fg-selected: var(--xh-date-range-picker-time-item-fg-selected, var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg)));
623
+ --xh-collection-fg-selected-highlight: var(--xh-date-range-picker-time-item-fg-selected, var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg)));
624
+ --xh-collection-fg-selected-hover: var(--xh-date-range-picker-time-item-fg-selected, var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg)));
625
+ --xh-collection-fg-selected-pressed: var(--xh-date-range-picker-time-item-fg-selected, var(--xh-date-range-picker-time-item-fg, var(--xh-material-frosted-fg)));
626
+ --xh-collection-font-weight-selected: var(--xh-date-range-picker-time-item-font-weight-selected, var(--xh-font-weight-regular));
627
+ --xh-collection-font-weight-selected-highlight: var(--xh-date-range-picker-time-item-font-weight-selected, var(--xh-font-weight-regular));
628
+ --xh-collection-font-weight-selected-hover: var(--xh-date-range-picker-time-item-font-weight-selected, var(--xh-font-weight-regular));
629
+ --xh-collection-font-weight-selected-pressed: var(--xh-date-range-picker-time-item-font-weight-selected, var(--xh-font-weight-regular));
630
+ --xh-collection-bg-hover: var(--xh-date-range-picker-time-item-bg-hover, var(--xh-bg-subtle));
631
+ --xh-collection-bg-keyboard-highlight: var(--xh-date-range-picker-time-item-bg-hover, var(--xh-bg-subtle));
632
+ --xh-collection-bg-selected-highlight: var(--xh-date-range-picker-time-item-bg-hover, var(--xh-bg-subtle));
633
+ --xh-collection-bg-selected-hover: var(--xh-date-range-picker-time-item-bg-hover, var(--xh-bg-subtle));
634
+ --xh-collection-bg-pressed: var(--xh-date-range-picker-time-item-bg-pressed, var(--xh-bg-subtle-hover));
635
+ --xh-collection-bg-selected-pressed: var(--xh-date-range-picker-time-item-bg-pressed, var(--xh-bg-subtle-hover));
636
+ --xh-collection-outline-keyboard-highlight: transparent;
637
+ --xh-collection-outline-selected-highlight: transparent;
638
+
639
+ position: relative;
640
+ display: flex;
641
+ flex: none;
642
+ align-items: center;
643
+ justify-content: center;
644
+ block-size: var(--xh-date-range-picker-time-item-h, auto);
645
+ font-variant-numeric: tabular-nums;
646
+ line-height: var(--xh-leading-normal);
647
+ text-align: center;
648
+ white-space: nowrap;
649
+ user-select: none;
650
+ }
651
+
652
+ [data-scope='date-range-picker'][data-part='time-item'][hidden] {
653
+ display: none;
654
+ }
655
+
656
+ /* 键盘焦点出现时环才接回并立即到位,不压在背景过渡的中间帧上 */
657
+ [data-scope='date-range-picker'][data-part='time-item']:focus-visible:not(:hover) {
658
+ --xh-collection-outline-keyboard-highlight: var(--xh-ring-focus);
659
+ --xh-collection-outline-selected-highlight: var(--xh-ring-focus);
660
+
661
+ transition: none;
662
+ }
663
+
664
+ [data-scope='date-range-picker'][data-part='time-item']::after {
665
+ content: '';
666
+ position: absolute;
667
+ inset-block-start: 50%;
668
+ /* 标记占轨道末端,内缘与正文之间恒留一档间隙;与 padding 读同一个 rail,避免重叠。 */
669
+ inset-inline-end: calc(
670
+ var(--xh-_date-range-picker-time-item-rail) -
671
+ var(--xh-date-range-picker-time-item-check-size, var(--xh-_date-range-picker-time-item-check-size)) -
672
+ var(--xh-space-1)
673
+ );
674
+ inline-size: var(--xh-date-range-picker-time-item-check-size, var(--xh-_date-range-picker-time-item-check-size));
675
+ block-size: var(--xh-date-range-picker-time-item-check-size, var(--xh-_date-range-picker-time-item-check-size));
676
+ translate: 0 -50%;
677
+ background-color: var(--xh-date-range-picker-time-item-check-fg, var(--xh-_date-range-picker-check-fg));
678
+ opacity: 0;
679
+ pointer-events: none;
680
+ transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
681
+ -webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
682
+ mask: var(--xh-glyph-mark-check) center / contain no-repeat;
683
+ }
684
+
685
+ [data-scope='date-range-picker'][data-part='time-item'][data-state='checked']::after {
686
+ opacity: 1;
687
+ }
688
+
689
+ /* 界外、早于同一天的起点与被判为不可用的格走 aria-disabled,家族按它给禁用面;选中标记跟着降级 */
690
+ [data-scope='date-range-picker'][data-part='time-item'][data-disabled]::after {
691
+ background-color: var(--xh-fg-disabled);
692
+ }
693
+
694
+ @media not all and (min-width: 768px) {
695
+ [data-scope='date-range-picker'][data-part='time-column'] {
696
+ min-inline-size: var(--xh-date-range-picker-time-column-min-w-mobile, var(--xh-overlay-column-min-w));
697
+ }
698
+
699
+ [data-scope='date-range-picker'][data-part='time-item'] {
700
+ --xh-_date-range-picker-time-item-rail: var(
701
+ --xh-date-range-picker-time-item-check-size,
702
+ var(--xh-_date-range-picker-time-item-check-size)
703
+ );
704
+ }
705
+
706
+ [data-scope='date-range-picker'][data-part='time-item']::after {
707
+ inset-inline-end: 0;
708
+ }
709
+ }
710
+
711
+ /* 列整体禁用时格没有自己的 aria-disabled,禁用面按列的 aria-disabled 映射到家族槽:
712
+ 字色降级、悬停 / 高亮 / 按下不换面、光标 not-allowed */
713
+ [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item'] {
714
+ --xh-collection-fg-rest: var(--xh-fg-disabled);
715
+ --xh-collection-fg-hover: var(--xh-fg-disabled);
716
+ --xh-collection-fg-keyboard-highlight: var(--xh-fg-disabled);
717
+ --xh-collection-fg-pressed: var(--xh-fg-disabled);
718
+ --xh-collection-fg-selected: var(--xh-fg-disabled);
719
+ --xh-collection-bg-hover: transparent;
720
+ --xh-collection-bg-keyboard-highlight: transparent;
721
+ --xh-collection-bg-pressed: transparent;
722
+ --xh-collection-bg-selected-hover: transparent;
723
+ --xh-collection-bg-selected-highlight: transparent;
724
+ --xh-collection-bg-selected-pressed: transparent;
725
+ --xh-collection-cursor-rest: not-allowed;
726
+ --xh-collection-cursor-hover: not-allowed;
727
+ --xh-collection-cursor-keyboard-highlight: not-allowed;
728
+ --xh-collection-cursor-pressed: not-allowed;
729
+ --xh-collection-cursor-selected: not-allowed;
730
+ }
731
+
732
+ [data-scope='date-range-picker'][data-part='time-column'][aria-disabled='true'] [data-part='time-item']::after {
733
+ background-color: var(--xh-fg-disabled);
734
+ }
735
+
736
+ /* 确认钮是面板里唯一的主要动作:品牌实心、悬停 / 按下与 0.97 按压、焦点环全由 Action Control 的
737
+ text solid 档给;槽名统一按部件取 --xh-date-range-picker-confirm-trigger-*,只映射到家族桥接槽 */
738
+ [data-scope='date-range-picker'][data-part='confirm-trigger'] {
739
+ --xh-action-visual-size: var(--xh-date-range-picker-confirm-trigger-h, var(--xh-_action-profile-visual-size));
740
+ --xh-action-padding-inline: var(--xh-date-range-picker-confirm-trigger-px, var(--xh-_action-profile-padding-inline));
741
+ --xh-action-radius: var(--xh-date-range-picker-confirm-trigger-radius, var(--xh-shape-control));
742
+ --xh-action-bg-rest: var(--xh-date-range-picker-confirm-trigger-bg, var(--xh-_action-variant-bg-rest));
743
+ --xh-action-bg-hover: var(--xh-date-range-picker-confirm-trigger-bg-hover, var(--xh-_action-variant-bg-hover));
744
+ --xh-action-bg-pressed: var(--xh-date-range-picker-confirm-trigger-bg-active, var(--xh-_action-variant-bg-pressed));
745
+ --xh-action-fg-rest: var(--xh-date-range-picker-confirm-trigger-fg, var(--xh-_action-variant-fg-rest));
746
+ --xh-action-fg-hover: var(--xh-date-range-picker-confirm-trigger-fg, var(--xh-_action-variant-fg-hover));
747
+ --xh-action-fg-pressed: var(--xh-date-range-picker-confirm-trigger-fg, var(--xh-_action-variant-fg-pressed));
748
+ --xh-action-border-rest: transparent;
749
+ --xh-action-highlight-rest: transparent;
750
+ --xh-action-shadow-rest: var(--xh-date-range-picker-confirm-trigger-shadow, none);
751
+ --xh-action-shadow-hover: var(--xh-date-range-picker-confirm-trigger-shadow, none);
752
+ --xh-action-shadow-pressed: var(--xh-date-range-picker-confirm-trigger-shadow, none);
753
+ --xh-action-font-size: var(--xh-text-secondary-size);
754
+
755
+ border-width: 0;
756
+ }
757
+
758
+ /* 收起时连接层给的是 hidden 属性;家族那条 display 会把 UA 规则盖掉 */
759
+ [data-scope='date-range-picker'][data-part='confirm-trigger'][hidden] {
760
+ display: none;
761
+ }
762
+
509
763
  /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
510
764
  [data-scope='date-range-picker'][data-part='clear-trigger']:empty::before {
511
765
  content: '';
@@ -531,18 +785,53 @@
531
785
 
532
786
  @media (forced-colors: active) {
533
787
  /* 系统接管底色后仍保住末端对号;禁用标记改用系统失效色。 */
534
- [data-scope='date-range-picker'][data-part='preset']::after {
788
+ [data-scope='date-range-picker'][data-part='preset']::after,
789
+ [data-scope='date-range-picker'][data-part='time-item']::after {
535
790
  forced-color-adjust: none;
536
791
  background-color: CanvasText;
537
792
  }
538
793
 
539
- [data-scope='date-range-picker'][data-part='preset'][data-disabled]::after {
794
+ /* 按下与没被高亮时的悬停,家族把条目涂成 Highlight,对号跟着换 HighlightText */
795
+ [data-scope='date-range-picker'][data-part='preset']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted]))::after,
796
+ [data-scope='date-range-picker'][data-part='time-item']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted]))::after {
797
+ background-color: HighlightText;
798
+ }
799
+
800
+ [data-scope='date-range-picker'][data-part='preset'][data-disabled]::after,
801
+ [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 {
540
803
  background-color: GrayText;
541
804
  }
542
805
 
543
- [data-scope='date-range-picker'][data-part='preset'][data-disabled] {
806
+ [data-scope='date-range-picker'][data-part='preset'][data-disabled],
807
+ [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'] {
544
809
  color: GrayText;
545
810
  }
811
+
812
+ /* 正在编辑的那一端靠字重与系统前景区分,不靠颜色 */
813
+ [data-scope='date-range-picker'][data-part='column-group-label'][data-editing] {
814
+ color: CanvasText;
815
+ }
816
+ }
817
+
818
+ @media (forced-colors: active) {
819
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
820
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
821
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
822
+ 禁用取 GrayText */
823
+ [data-scope='date-range-picker']:is([data-part='clear-trigger'], [data-part='trigger']):empty::before {
824
+ forced-color-adjust: none;
825
+ background-color: ButtonText;
826
+ }
827
+
828
+ [data-scope='date-range-picker']:is([data-part='clear-trigger'], [data-part='trigger']):not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
829
+ background-color: HighlightText;
830
+ }
831
+
832
+ [data-scope='date-range-picker']:is([data-part='clear-trigger'], [data-part='trigger'])[data-disabled]:empty::before {
833
+ background-color: GrayText;
834
+ }
546
835
  }
547
836
  }
548
837
 
@@ -35,13 +35,29 @@
35
35
  color: var(--xh-fg-muted);
36
36
  }
37
37
 
38
- /* 不 invalid 时节点带 hidden:此处不声明 display,交给浏览器的 [hidden] 规则收起 */
38
+ /* 错误文案出现时淡入。不 invalid 时节点带 hidden,但不交给浏览器的 [hidden] 规则收成 display: none:
39
+ 从不生成盒到生成盒没有过渡的起点,淡入播不出来。收起态改成不占位(绝对定位、零高、裁切)、
40
+ 不可见也不进可及树(visibility: hidden)的盒,露面时回到流里淡入;首帧就在的错误文案没有过渡起点,
41
+ 直接呈现。收起那一下不占位的盒当场让位,不留淡出——同一行随即交还说明或整行收起,淡出只会叠在
42
+ 别的内容上;Field 下方为错误文案预留了一行时,退场在那一行里淡出(见 field.css) */
39
43
  [data-scope='field'][data-part='error-text'],
40
44
  [data-scope='fieldset'][data-part='error-text'] {
41
45
  margin: 0;
42
46
  font-size: var(--xh-text-secondary-size);
43
47
  line-height: var(--xh-leading-normal);
44
48
  color: var(--xh-fg-danger);
49
+ transition: opacity var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
50
+ }
51
+
52
+ [data-scope='field'][data-part='error-text'][hidden],
53
+ [data-scope='fieldset'][data-part='error-text'][hidden] {
54
+ display: block;
55
+ position: absolute;
56
+ block-size: 0;
57
+ overflow: clip;
58
+ visibility: hidden;
59
+ opacity: 0;
60
+ transition: none;
45
61
  }
46
62
 
47
63
  [data-scope='field'][data-part='root'][data-invalid] > [data-scope='field'][data-part='description'],
@@ -78,6 +78,46 @@
78
78
  --xh-_descriptions-font-size: var(--xh-control-font-lg);
79
79
  }
80
80
 
81
+ /* —— 头部 ——
82
+ 列表之前的一行:左标题、右附加内容。它是根的兄弟,继承不到根上的私有槽,尺寸档自己再换一次 */
83
+ [data-scope='descriptions'][data-part='header'] {
84
+ --xh-_descriptions-header-mb: var(--xh-space-3);
85
+
86
+ display: flex;
87
+ flex-wrap: wrap;
88
+ align-items: center;
89
+ gap: var(--xh-descriptions-header-gap, var(--xh-space-3));
90
+ margin-block-end: var(--xh-descriptions-header-mb, var(--xh-_descriptions-header-mb));
91
+ }
92
+
93
+ [data-scope='descriptions'][data-part='header'][data-size='sm'] {
94
+ --xh-_descriptions-header-mb: var(--xh-space-2);
95
+ }
96
+
97
+ [data-scope='descriptions'][data-part='header'][data-size='lg'] {
98
+ --xh-_descriptions-header-mb: var(--xh-space-4);
99
+ }
100
+
101
+ /* 标题是 Surface 内标题:正文字号 + 半粗;作者写成 h2 / h3 时 UA 的外边距与字号在这里清掉 */
102
+ [data-scope='descriptions'][data-part='title'] {
103
+ flex: 1 1 auto;
104
+ min-inline-size: 0;
105
+ margin: 0;
106
+ color: var(--xh-descriptions-title-fg, var(--xh-fg-default));
107
+ font-size: var(--xh-descriptions-title-font-size, var(--xh-text-label-size));
108
+ font-weight: var(--xh-descriptions-title-font-weight, var(--xh-font-weight-semibold));
109
+ line-height: var(--xh-leading-relaxed);
110
+ }
111
+
112
+ /* 附加内容贴在行尾:操作钮或状态标签,一行放不下时整块换到下一行 */
113
+ [data-scope='descriptions'][data-part='extra'] {
114
+ display: flex;
115
+ flex: none;
116
+ align-items: center;
117
+ gap: var(--xh-descriptions-extra-gap, var(--xh-space-2));
118
+ margin-inline-start: auto;
119
+ }
120
+
81
121
  /* —— 每一格 —— */
82
122
  /* 一格自己也是网格:不写 placement 即标签一行、取值一行叠着排。
83
123
  窄档每格横跨根上排定的所有列,一行只摆一组,作者写在格上的 span 这一档不认 */
@@ -251,6 +291,8 @@
251
291
 
252
292
  /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
253
293
  写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
294
+ [data-scope='descriptions'][data-part='header'][hidden],
295
+ [data-scope='descriptions'][data-part='extra'][hidden],
254
296
  [data-scope='descriptions'][data-part='item'][hidden] {
255
297
  display: none;
256
298
  }
package/css/dialog.css CHANGED
@@ -9,38 +9,6 @@
9
9
  @import '../family/motion.css';
10
10
  @import '../family/action-control.css';
11
11
 
12
- @layer xihan.motion {
13
- /* 幅度走令牌,减弱动效时由令牌层归零;位移与缩放用独立属性而非 transform 简写,
14
- 两者互不覆盖,手势期间写 translate 也不会把 scale 抹掉 */
15
- @keyframes xh-dialog-in {
16
- from {
17
- opacity: 0;
18
- translate: 0 var(--xh-motion-distance-md);
19
- scale: var(--xh-motion-scale-enter);
20
- }
21
-
22
- to {
23
- opacity: 1;
24
- translate: 0 0;
25
- scale: 1;
26
- }
27
- }
28
-
29
- @keyframes xh-dialog-out {
30
- from {
31
- opacity: 1;
32
- translate: 0 0;
33
- scale: 1;
34
- }
35
-
36
- to {
37
- opacity: 0;
38
- translate: 0 var(--xh-motion-distance-md);
39
- scale: var(--xh-motion-scale-exit);
40
- }
41
- }
42
- }
43
-
44
12
  @layer xihan.components {
45
13
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
46
14
  [data-scope='dialog'] {
@@ -80,7 +48,7 @@
80
48
  background: transparent;
81
49
  }
82
50
 
83
- [data-scope='dialog'][data-part='backdrop'][data-state='open'] {
51
+ [data-scope='dialog'][data-part='backdrop'][data-state='open']:not([data-instant]) {
84
52
  animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
85
53
  }
86
54
 
@@ -178,12 +146,77 @@
178
146
  outline: none;
179
147
  }
180
148
 
181
- [data-scope='dialog'][data-part='content'][data-state='open'] {
182
- animation: xh-dialog-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
149
+ /* 挂载时就开着的那一段(data-instant)属于首帧,直接呈现 */
150
+ [data-scope='dialog'][data-part='content'][data-state='open']:not([data-instant]) {
151
+ animation: xh-sheet-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
183
152
  }
184
153
 
185
154
  [data-scope='dialog'][data-part='content'][data-state='closed'] {
186
- animation: xh-dialog-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
155
+ animation: xh-sheet-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
156
+ }
157
+
158
+ /* —— 拖动 ——
159
+ 位移由连接层写进两个私有槽,是屏幕坐标:跟着指针与方向键走,RTL 下不翻。
160
+ 进出场关键帧占着 translate 与 scale 两个独立属性,位移只能走 transform:它排在独立属性之后合成,
161
+ 与进出场叠在一起。写进 translate 的话,拖过的面板一收起就先被关键帧拽回居中再退场。
162
+ 位移跟手,不挂过渡 */
163
+ [data-scope='dialog'][data-part='content'][data-draggable] {
164
+ transform: translate(var(--xh-_dialog-drag-x, 0px), var(--xh-_dialog-drag-y, 0px));
165
+ }
166
+
167
+ /* 跟手期间才备合成层;拖动中不选中文字 */
168
+ [data-scope='dialog'][data-part='content'][data-dragging] {
169
+ will-change: transform;
170
+ user-select: none;
171
+ }
172
+
173
+ /* 标题栏是拖动区(没写 header 时是标题):指针按下即跟手,触屏不让浏览器抢走这段手势 */
174
+ [data-scope='dialog'][data-part='header'][data-draggable],
175
+ [data-scope='dialog'][data-part='title'][data-draggable] {
176
+ cursor: grab;
177
+ touch-action: none;
178
+ user-select: none;
179
+ }
180
+
181
+ [data-scope='dialog'][data-part='content'][data-dragging] [data-scope='dialog'][data-part='header'],
182
+ [data-scope='dialog'][data-part='content'][data-dragging] [data-scope='dialog'][data-part='title'] {
183
+ cursor: grabbing;
184
+ }
185
+
186
+ /* 拖动把手:一块透明的命中区,给键盘一个挪动面板的落脚点。放在标题栏里时铺满标题栏,
187
+ 焦点环沿标题栏画;单独摆放时是一条满宽的细条 */
188
+ [data-scope='dialog'][data-part='drag-trigger'] {
189
+ display: block;
190
+ inline-size: 100%;
191
+ min-block-size: var(--xh-dialog-drag-trigger-min-h, var(--xh-space-6));
192
+ border: 0;
193
+ border-radius: var(--xh-dialog-drag-trigger-radius, var(--xh-shape-control));
194
+ padding: 0;
195
+ background: transparent;
196
+ cursor: grab;
197
+ touch-action: none;
198
+ }
199
+
200
+ [data-scope='dialog'][data-part='header']:has(> [data-scope='dialog'][data-part='drag-trigger']) {
201
+ position: relative;
202
+ }
203
+
204
+ [data-scope='dialog'][data-part='header'] > [data-scope='dialog'][data-part='drag-trigger'] {
205
+ position: absolute;
206
+ inset: 0;
207
+ min-block-size: 0;
208
+ }
209
+
210
+ [data-scope='dialog'][data-part='drag-trigger'][data-dragging] {
211
+ cursor: grabbing;
212
+ }
213
+
214
+ [data-scope='dialog'][data-part='drag-trigger'][data-disabled] {
215
+ cursor: default;
216
+ }
217
+
218
+ [data-scope='dialog'][data-part='drag-trigger'][hidden] {
219
+ display: none;
187
220
  }
188
221
 
189
222
  /* —— 面板三段 —— */
@@ -394,4 +427,29 @@
394
427
  display: none;
395
428
  }
396
429
  }
430
+
431
+ @media (forced-colors: active) {
432
+ /* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
433
+ 字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
434
+ 按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
435
+ 落在 Canvas 面上的取 CanvasText;
436
+ 禁用取 GrayText */
437
+ [data-scope='dialog'][data-part='indicator']:empty::before {
438
+ forced-color-adjust: none;
439
+ background-color: CanvasText;
440
+ }
441
+
442
+ [data-scope='dialog'][data-part='close-trigger']:empty::before {
443
+ forced-color-adjust: none;
444
+ background-color: ButtonText;
445
+ }
446
+
447
+ [data-scope='dialog'][data-part='close-trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
448
+ background-color: HighlightText;
449
+ }
450
+
451
+ [data-scope='dialog'][data-part='close-trigger'][data-disabled]:empty::before {
452
+ background-color: GrayText;
453
+ }
454
+ }
397
455
  }