@xihan-ui/styles 1.0.0-alpha.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +2177 -0
  2. package/README.md +1 -1
  3. package/css/accordion.css +80 -6
  4. package/css/alert.css +43 -14
  5. package/css/anchor.css +8 -8
  6. package/css/avatar-group.css +7 -3
  7. package/css/avatar.css +9 -3
  8. package/css/back-top.css +22 -1
  9. package/css/badge.css +104 -32
  10. package/css/breadcrumb.css +25 -5
  11. package/css/button-group.css +18 -13
  12. package/css/button.css +48 -11
  13. package/css/calendar.css +150 -7
  14. package/css/card.css +20 -11
  15. package/css/carousel.css +36 -5
  16. package/css/cascader.css +211 -124
  17. package/css/checkbox-group.css +72 -22
  18. package/css/checkbox.css +70 -13
  19. package/css/clipboard.css +2 -1
  20. package/css/code-block.css +12 -7
  21. package/css/collapsible.css +49 -3
  22. package/css/color-picker.css +132 -46
  23. package/css/combobox.css +132 -60
  24. package/css/composer.css +5 -3
  25. package/css/context-menu.css +113 -74
  26. package/css/date-field.css +93 -16
  27. package/css/date-picker.css +293 -72
  28. package/css/descriptions.css +11 -5
  29. package/css/dialog.css +47 -14
  30. package/css/download-trigger.css +76 -0
  31. package/css/drawer.css +57 -16
  32. package/css/dynamic-input.css +75 -17
  33. package/css/editable.css +12 -10
  34. package/css/ellipsis.css +7 -1
  35. package/css/empty-state.css +22 -12
  36. package/css/field.css +16 -6
  37. package/css/fieldset.css +69 -0
  38. package/css/file-upload.css +46 -8
  39. package/css/flex.css +13 -7
  40. package/css/float-button.css +23 -1
  41. package/css/floating-panel.css +316 -0
  42. package/css/form.css +4 -4
  43. package/css/grid.css +11 -5
  44. package/css/heatmap.css +411 -0
  45. package/css/highlight.css +2 -2
  46. package/css/hotkeys.css +90 -0
  47. package/css/hover-card.css +43 -45
  48. package/css/image-cropper.css +233 -0
  49. package/css/image-viewer.css +155 -17
  50. package/css/image.css +2 -2
  51. package/css/infinite-scroll.css +1 -1
  52. package/css/json-viewer.css +274 -0
  53. package/css/layout.css +19 -15
  54. package/css/list.css +22 -13
  55. package/css/listbox.css +24 -6
  56. package/css/loading-bar.css +12 -5
  57. package/css/log.css +7 -3
  58. package/css/marquee.css +9 -0
  59. package/css/masonry.css +63 -0
  60. package/css/mention.css +100 -36
  61. package/css/menu.css +127 -50
  62. package/css/menubar.css +155 -61
  63. package/css/navigation-menu.css +56 -31
  64. package/css/notification.css +377 -0
  65. package/css/number-animation.css +3 -3
  66. package/css/number-field.css +182 -19
  67. package/css/overlay-arrow.css +51 -0
  68. package/css/page-header.css +12 -5
  69. package/css/pagination.css +171 -14
  70. package/css/password-input.css +356 -0
  71. package/css/pin-input.css +15 -12
  72. package/css/popconfirm.css +55 -12
  73. package/css/popover.css +73 -45
  74. package/css/popselect.css +207 -57
  75. package/css/progress.css +54 -8
  76. package/css/qr-code.css +1 -1
  77. package/css/radio-group.css +27 -10
  78. package/css/rating.css +4 -4
  79. package/css/reset.css +17 -0
  80. package/css/result.css +21 -11
  81. package/css/scroll-area.css +61 -89
  82. package/css/scrollbar.css +170 -0
  83. package/css/segmented.css +215 -0
  84. package/css/select.css +298 -131
  85. package/css/separator.css +2 -2
  86. package/css/side-nav.css +127 -24
  87. package/css/signature-pad.css +144 -0
  88. package/css/skeleton.css +7 -1
  89. package/css/slider.css +14 -12
  90. package/css/space.css +117 -0
  91. package/css/spinner.css +22 -10
  92. package/css/statistic.css +9 -9
  93. package/css/steps.css +29 -12
  94. package/css/switch.css +57 -8
  95. package/css/table.css +146 -44
  96. package/css/tabs.css +13 -5
  97. package/css/tag.css +179 -0
  98. package/css/tags-input.css +80 -42
  99. package/css/text-field.css +151 -38
  100. package/css/thread.css +11 -3
  101. package/css/time-field.css +99 -18
  102. package/css/time-picker.css +261 -71
  103. package/css/timeline.css +15 -15
  104. package/css/timer.css +119 -0
  105. package/css/toast.css +129 -55
  106. package/css/toggle-group.css +30 -4
  107. package/css/toggle.css +12 -6
  108. package/css/tone.css +57 -22
  109. package/css/toolbar.css +1 -1
  110. package/css/tooltip.css +40 -31
  111. package/css/tour.css +112 -61
  112. package/css/transfer.css +98 -21
  113. package/css/tree-select.css +215 -89
  114. package/css/tree.css +131 -5
  115. package/css/typography.css +5 -5
  116. package/css/undefined.css +12 -1
  117. package/css/virtualizer.css +3 -1
  118. package/css/watermark.css +1 -2
  119. package/index.css +18 -1
  120. package/index.unlayered.css +10356 -3255
  121. package/package.json +20 -4
  122. package/css/toaster.css +0 -74
@@ -8,6 +8,10 @@
8
8
  排布只能读 data-orientation——role=group 不收 aria-orientation,连接层根本不输出它。
9
9
  圆角槽位在容器上先收成 0,组内每段都取得到,两端的圆角再逐段补回来 */
10
10
  [data-scope='button-group'][data-part='root'] {
11
+ /* 组件内那几档层号只在自己人之间排序:建一个层叠上下文把它们关起来,
12
+ 既不让页面上的层号插进来,也不让它们漏出去压住别人 */
13
+ isolation: isolate;
14
+
11
15
  --xh-button-radius: 0;
12
16
 
13
17
  display: inline-flex;
@@ -30,26 +34,27 @@
30
34
 
31
35
  /* —— 尺寸 —— */
32
36
  /* 高度、内边距、间距、字号在容器上写一次,沿继承流给组内每一段。
33
- 三档都写出来:自定义属性会一路继承,组里再套一组时内层不写就会沿用外层的档 */
37
+ 三档都写出来:自定义属性会一路继承,组里再套一组时内层不写就会沿用外层的档。
38
+ 写私有槽而非 --xh-button-*:后者是使用者的入口,组内某一枚自己写了档位时要压得住容器 */
34
39
  [data-scope='button-group'][data-part='root'][data-size='sm'] {
35
- --xh-button-h: var(--xh-control-h-sm);
36
- --xh-button-px: var(--xh-control-px-sm);
37
- --xh-button-gap: var(--xh-control-gap-sm);
38
- --xh-button-font-size: var(--xh-font-size-sm);
40
+ --xh-_button-group-h: var(--xh-control-h-sm);
41
+ --xh-_button-group-px: var(--xh-control-px-sm);
42
+ --xh-_button-group-gap: var(--xh-control-gap-sm);
43
+ --xh-_button-group-font-size: var(--xh-control-font-sm);
39
44
  }
40
45
 
41
46
  [data-scope='button-group'][data-part='root'][data-size='md'] {
42
- --xh-button-h: var(--xh-control-h-md);
43
- --xh-button-px: var(--xh-control-px-md);
44
- --xh-button-gap: var(--xh-control-gap-md);
45
- --xh-button-font-size: var(--xh-font-size-md);
47
+ --xh-_button-group-h: var(--xh-control-h-md);
48
+ --xh-_button-group-px: var(--xh-control-px-md);
49
+ --xh-_button-group-gap: var(--xh-control-gap-md);
50
+ --xh-_button-group-font-size: var(--xh-control-font-md);
46
51
  }
47
52
 
48
53
  [data-scope='button-group'][data-part='root'][data-size='lg'] {
49
- --xh-button-h: var(--xh-control-h-lg);
50
- --xh-button-px: var(--xh-control-px-lg);
51
- --xh-button-gap: var(--xh-control-gap-lg);
52
- --xh-button-font-size: var(--xh-font-size-lg);
54
+ --xh-_button-group-h: var(--xh-control-h-lg);
55
+ --xh-_button-group-px: var(--xh-control-px-lg);
56
+ --xh-_button-group-gap: var(--xh-control-gap-lg);
57
+ --xh-_button-group-font-size: var(--xh-control-font-lg);
53
58
  }
54
59
 
55
60
  /* —— 形态 —— */
package/css/button.css CHANGED
@@ -21,17 +21,21 @@
21
21
  --xh-_bg-active: var(--xh-button-bg-active, var(--xh-bg-subtle-active));
22
22
  --xh-_fg: var(--xh-button-fg, var(--xh-fg-default));
23
23
 
24
+ /* 作者塞进来的图标跟着按钮的尺寸档走:xh-icon 的直径读的就是这个继承槽,
25
+ 它自己显式写了 size 时特异性更高,仍以作者写的为准 */
26
+ --xh-icon-size: var(--xh-button-icon-size, var(--xh-glyph-size-md));
27
+
24
28
  display: inline-flex;
25
29
  align-items: center;
26
30
  justify-content: center;
27
- gap: var(--xh-button-gap, var(--xh-control-gap-md));
28
- block-size: var(--xh-button-h, var(--xh-control-h-md));
29
- padding-inline: var(--xh-button-px, var(--xh-control-px-md));
31
+ gap: var(--xh-button-gap, var(--xh-_button-group-gap, var(--xh-control-gap-md)));
32
+ block-size: var(--xh-button-h, var(--xh-_button-group-h, var(--xh-control-h-md)));
33
+ padding-inline: var(--xh-button-px, var(--xh-_button-group-px, var(--xh-control-px-md)));
30
34
  border: var(--xh-stroke-thin) solid transparent;
31
35
  border-radius: var(--xh-button-radius, var(--xh-shape-control));
32
36
  background: var(--xh-_bg);
33
37
  color: var(--xh-_fg);
34
- font-size: var(--xh-button-font-size, var(--xh-text-label-size));
38
+ font-size: var(--xh-button-font-size, var(--xh-_button-group-font-size, var(--xh-text-label-size)));
35
39
  font-weight: var(--xh-button-font-weight, var(--xh-text-label-weight));
36
40
  line-height: var(--xh-leading-none);
37
41
  white-space: nowrap;
@@ -95,19 +99,52 @@
95
99
 
96
100
  /* —— 尺寸 —— */
97
101
  [data-scope='button'][data-part='root'][data-size='sm'] {
98
- block-size: var(--xh-control-h-sm);
99
- padding-inline: var(--xh-control-px-sm);
100
- font-size: var(--xh-font-size-sm);
102
+ --xh-icon-size: var(--xh-button-icon-size, var(--xh-glyph-size-sm));
103
+
104
+ block-size: var(--xh-button-h, var(--xh-control-h-sm));
105
+ padding-inline: var(--xh-button-px, var(--xh-control-px-sm));
106
+ font-size: var(--xh-button-font-size, var(--xh-control-font-sm));
101
107
  }
102
108
 
103
109
  [data-scope='button'][data-part='root'][data-size='lg'] {
104
- block-size: var(--xh-control-h-lg);
105
- padding-inline: var(--xh-control-px-lg);
106
- font-size: var(--xh-font-size-lg);
110
+ --xh-icon-size: var(--xh-button-icon-size, var(--xh-glyph-size-lg));
111
+
112
+ block-size: var(--xh-button-h, var(--xh-control-h-lg));
113
+ padding-inline: var(--xh-button-px, var(--xh-control-px-lg));
114
+ font-size: var(--xh-button-font-size, var(--xh-control-font-lg));
115
+ }
116
+
117
+ /* 只有图标:左右内距清零,宽度靠比例跟住当前档的高度——换尺寸档时仍是正方形,
118
+ 不必把档位抄进行内样式。写在尺寸档之后,压得住三档各自的 padding-inline */
119
+ [data-scope='button'][data-part='root'][data-icon-only] {
120
+ padding-inline: 0;
121
+ aspect-ratio: 1;
122
+ }
123
+
124
+ [data-scope='button'][data-part='root'][data-full-width] {
125
+ inline-size: 100%;
107
126
  }
108
127
 
109
128
  [data-scope='button'][data-part='indicator'] {
110
129
  display: inline-flex;
111
- animation: xh-spin 0.6s linear infinite;
130
+ animation: xh-spin var(--xh-button-spin-duration, var(--xh-spin-duration)) linear infinite;
131
+ }
132
+
133
+ /* 减少动效:指示器停转,"还在忙"由按钮自身的挂起样式与指示器图标继续表达。
134
+ 两条规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
135
+ @media (prefers-reduced-motion: reduce) {
136
+ [data-scope='button'][data-part='indicator'] {
137
+ animation: none;
138
+ }
139
+ }
140
+
141
+ :where([data-motion='reduce']) [data-scope='button'][data-part='indicator'] {
142
+ animation: none;
143
+ }
144
+
145
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
146
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
147
+ [data-scope='button'][data-part='root'][hidden] {
148
+ display: none;
112
149
  }
113
150
  }
package/css/calendar.css CHANGED
@@ -5,6 +5,9 @@
5
5
  }
6
6
 
7
7
  [data-scope='calendar'][data-part='root'] {
8
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
9
+ --xh-icon-size: var(--xh-calendar-icon-size, var(--xh-glyph-size-text));
10
+
8
11
  display: flex;
9
12
  flex-direction: column;
10
13
  gap: var(--xh-calendar-gap, var(--xh-space-3));
@@ -37,7 +40,49 @@
37
40
  user-select: none;
38
41
  }
39
42
 
43
+ /* 标题里的年与月:点它们逐级钻上去(年 → 十年格、月 → 月格)。
44
+ 长得像标题而不像按钮——它本来就是标题,只是可点 */
45
+ [data-scope='calendar'][data-part='heading-year-trigger']:not([hidden]),
46
+ [data-scope='calendar'][data-part='heading-month-trigger']:not([hidden]) {
47
+ display: inline-flex;
48
+ align-items: center;
49
+ padding-inline: var(--xh-calendar-heading-trigger-px, var(--xh-space-1));
50
+ border: var(--xh-stroke-thin) solid transparent;
51
+ border-radius: var(--xh-calendar-heading-trigger-radius, var(--xh-shape-control));
52
+ background: transparent;
53
+ color: var(--xh-calendar-heading-fg, var(--xh-fg-default));
54
+ font-size: var(--xh-calendar-heading-font-size, var(--xh-text-label-size));
55
+ font-weight: var(--xh-calendar-heading-font-weight, var(--xh-font-weight-semibold));
56
+ line-height: var(--xh-leading-none);
57
+ cursor: pointer;
58
+ transition: color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
59
+ }
60
+
61
+ [data-scope='calendar'][data-part='heading-year-trigger'][hidden],
62
+ [data-scope='calendar'][data-part='heading-month-trigger'][hidden] {
63
+ display: none;
64
+ }
65
+
66
+ [data-scope='calendar'][data-part='heading-year-trigger']:hover:not(:disabled),
67
+ [data-scope='calendar'][data-part='heading-month-trigger']:hover:not(:disabled) {
68
+ color: var(--xh-calendar-heading-trigger-fg-hover, var(--xh-fg-brand));
69
+ }
70
+
71
+ /* 到顶那一层(年视图的年那一截)只作标题显示:不再是可点的东西,光标也别装成能点 */
72
+ [data-scope='calendar'][data-part='heading-year-trigger']:disabled,
73
+ [data-scope='calendar'][data-part='heading-month-trigger']:disabled {
74
+ cursor: default;
75
+ }
76
+
77
+ [data-scope='calendar'][data-part='heading-year-trigger']:focus-visible,
78
+ [data-scope='calendar'][data-part='heading-month-trigger']:focus-visible {
79
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
80
+ outline-offset: var(--xh-ring-offset);
81
+ }
82
+
83
+ [data-scope='calendar'][data-part='prev-year-trigger'],
40
84
  [data-scope='calendar'][data-part='prev-trigger'],
85
+ [data-scope='calendar'][data-part='next-year-trigger'],
41
86
  [data-scope='calendar'][data-part='next-trigger'] {
42
87
  display: inline-flex;
43
88
  flex: none;
@@ -53,25 +98,33 @@
53
98
  transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
54
99
  }
55
100
 
101
+ [data-scope='calendar'][data-part='prev-year-trigger'][hidden],
56
102
  [data-scope='calendar'][data-part='prev-trigger'][hidden],
103
+ [data-scope='calendar'][data-part='next-year-trigger'][hidden],
57
104
  [data-scope='calendar'][data-part='next-trigger'][hidden] {
58
105
  display: none;
59
106
  }
60
107
 
108
+ [data-scope='calendar'][data-part='prev-year-trigger']:hover:not(:disabled),
61
109
  [data-scope='calendar'][data-part='prev-trigger']:hover:not(:disabled),
110
+ [data-scope='calendar'][data-part='next-year-trigger']:hover:not(:disabled),
62
111
  [data-scope='calendar'][data-part='next-trigger']:hover:not(:disabled) {
63
112
  background: var(--xh-calendar-nav-bg-hover, var(--xh-bg-subtle-hover));
64
113
  color: var(--xh-fg-default);
65
114
  }
66
115
 
67
116
  /* 翻月是单体控件,禁用走原生 :disabled(连接层输出的正是原生 disabled) */
117
+ [data-scope='calendar'][data-part='prev-year-trigger']:disabled,
68
118
  [data-scope='calendar'][data-part='prev-trigger']:disabled,
119
+ [data-scope='calendar'][data-part='next-year-trigger']:disabled,
69
120
  [data-scope='calendar'][data-part='next-trigger']:disabled {
70
121
  color: var(--xh-fg-disabled);
71
122
  cursor: not-allowed;
72
123
  }
73
124
 
125
+ [data-scope='calendar'][data-part='prev-year-trigger']:focus-visible,
74
126
  [data-scope='calendar'][data-part='prev-trigger']:focus-visible,
127
+ [data-scope='calendar'][data-part='next-year-trigger']:focus-visible,
75
128
  [data-scope='calendar'][data-part='next-trigger']:focus-visible {
76
129
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
77
130
  outline-offset: var(--xh-ring-offset);
@@ -83,6 +136,27 @@
83
136
  gap: var(--xh-calendar-grid-gap, var(--xh-space-1));
84
137
  }
85
138
 
139
+ /* 粗粒度视图:格子直接铺进网格,不再有周行那一层。
140
+ 月 3 列 × 4 行、季度 4 列一行、年 3 列——与常见日期控件同一套排布 */
141
+ [data-scope='calendar'][data-part='grid'][data-view='month'],
142
+ [data-scope='calendar'][data-part='grid'][data-view='year'] {
143
+ display: grid;
144
+ grid-template-columns: repeat(3, minmax(0, 1fr));
145
+ gap: var(--xh-calendar-period-gap, var(--xh-space-1));
146
+ }
147
+
148
+ [data-scope='calendar'][data-part='grid'][data-view='quarter'] {
149
+ display: grid;
150
+ grid-template-columns: repeat(4, minmax(0, 1fr));
151
+ gap: var(--xh-calendar-period-gap, var(--xh-space-1));
152
+ }
153
+
154
+ /* 粗粒度的格子比日子宽,文字居中、留出上下气口 */
155
+ [data-scope='calendar'][data-part='grid']:is([data-view='month'], [data-view='quarter'], [data-view='year']) [data-part='cell-trigger'] {
156
+ padding-block: var(--xh-calendar-period-py, var(--xh-space-2));
157
+ inline-size: 100%;
158
+ }
159
+
86
160
  [data-scope='calendar'][data-part='grid'][hidden] {
87
161
  display: none;
88
162
  }
@@ -110,6 +184,26 @@
110
184
  grid-template-columns: repeat(7, minmax(0, 1fr));
111
185
  }
112
186
 
187
+ /* 摆了周序号格的行多让出行首一列。写 :not([hidden]) 而不是靠顺序压过下面那条兜底——
188
+ 同特指度的规则谁在后面谁赢,收起态会被这条 display 掀开 */
189
+ [data-scope='calendar'][data-part='week-row']:not([hidden]):has(> [data-part='week-number']) {
190
+ display: grid;
191
+ grid-template-columns: var(--xh-calendar-week-number-w, 2.25rem) repeat(7, minmax(0, 1fr));
192
+ }
193
+
194
+ /* 周序号只是行的标号:比日子小一号、颜色压下去,不跟着选中态走 */
195
+ [data-scope='calendar'][data-part='week-number'] {
196
+ display: grid;
197
+ place-items: center;
198
+ color: var(--xh-calendar-week-number-fg, var(--xh-fg-subtle));
199
+ font-size: var(--xh-calendar-week-number-font-size, var(--xh-text-caption-size));
200
+ font-variant-numeric: tabular-nums;
201
+ user-select: none;
202
+ }
203
+
204
+ [data-scope='calendar'][data-part='week-number'][hidden] {
205
+ display: none;
206
+ }
113
207
  [data-scope='calendar'][data-part='week-row'][hidden] {
114
208
  display: none;
115
209
  }
@@ -120,7 +214,7 @@
120
214
  justify-content: center;
121
215
  block-size: var(--xh-calendar-week-day-h, var(--xh-control-h-sm));
122
216
  color: var(--xh-calendar-week-day-fg, var(--xh-fg-subtle));
123
- font-size: var(--xh-calendar-week-day-font-size, var(--xh-font-size-xs));
217
+ font-size: var(--xh-calendar-week-day-font-size, var(--xh-text-caption-size));
124
218
  font-weight: var(--xh-calendar-week-day-font-weight, var(--xh-font-weight-medium));
125
219
  line-height: var(--xh-leading-none);
126
220
  user-select: none;
@@ -130,35 +224,60 @@
130
224
  display: none;
131
225
  }
132
226
 
133
- /* 格子是区间底色的画布:连续背景铺在这一层,圆角的选中片留给 trigger。
227
+ /* 格子是区间底色的画布:底色由格子的 ::before 铺出来,圆角的选中片留给 trigger。
134
228
  铺在 trigger 上会被格间空隙切断,区间看起来就是一串断开的圆点 */
135
229
  [data-scope='calendar'][data-part='cell'] {
230
+ position: relative;
136
231
  display: flex;
137
232
  align-items: center;
138
233
  justify-content: center;
139
- padding: var(--xh-calendar-cell-gap, 2px);
234
+ padding: var(--xh-calendar-cell-gap, var(--xh-space-0_5));
140
235
  }
141
236
 
142
237
  [data-scope='calendar'][data-part='cell'][hidden] {
143
238
  display: none;
144
239
  }
145
240
 
146
- [data-scope='calendar'][data-part='cell'][data-in-range] {
241
+ /* 区间底色:横向铺满格子,相邻两格接成一条;纵向收在格子内衬里,行与行之间留出空当 */
242
+ [data-scope='calendar'][data-part='cell'][data-in-range]::before {
243
+ content: '';
244
+ position: absolute;
245
+ inset-block: var(--xh-calendar-cell-gap, var(--xh-space-0_5));
246
+ inset-inline: 0;
147
247
  background: var(--xh-calendar-range-bg, var(--xh-bg-brand-subtle));
148
248
  }
149
249
 
150
- /* 区间两端各自收圆:中间那些格子保持直角,底色才连成一条 */
151
- [data-scope='calendar'][data-part='cell'][data-range-start] {
250
+ /* 两端那一格只铺半格,另外半格由选中片占满:区间收在圆点上而不是收在格子边上。
251
+ 起止落在同一格时两条一起生效,底色宽度归零,只剩那枚圆点 */
252
+ [data-scope='calendar'][data-part='cell'][data-in-range][data-range-start]::before {
253
+ inset-inline-start: 50%;
254
+ }
255
+
256
+ [data-scope='calendar'][data-part='cell'][data-in-range][data-range-end]::before {
257
+ inset-inline-end: 50%;
258
+ }
259
+
260
+ /* 行首与行尾收圆:区间跨周时每一行各是一条两头圆的横杠。
261
+ 摆了周序号格的行里,行首那一格排在它后面 */
262
+ [data-scope='calendar'][data-part='week-row'] > [data-part='cell'][data-in-range]:first-child::before,
263
+ [data-scope='calendar'][data-part='week-row'] > [data-part='week-number'] + [data-part='cell'][data-in-range]::before {
152
264
  border-start-start-radius: var(--xh-calendar-cell-radius, var(--xh-shape-pill));
153
265
  border-end-start-radius: var(--xh-calendar-cell-radius, var(--xh-shape-pill));
154
266
  }
155
267
 
156
- [data-scope='calendar'][data-part='cell'][data-range-end] {
268
+ [data-scope='calendar'][data-part='week-row'] > [data-part='cell'][data-in-range]:last-child::before {
157
269
  border-start-end-radius: var(--xh-calendar-cell-radius, var(--xh-shape-pill));
158
270
  border-end-end-radius: var(--xh-calendar-cell-radius, var(--xh-shape-pill));
159
271
  }
160
272
 
273
+ /* 粗粒度的格子之间有间隙,底色本就接不成一条,每一格各自收圆 */
274
+ [data-scope='calendar'][data-part='grid']:is([data-view='month'], [data-view='quarter'], [data-view='year']) > [data-part='cell'][data-in-range]::before {
275
+ border-radius: var(--xh-calendar-cell-radius, var(--xh-shape-pill));
276
+ }
277
+
161
278
  [data-scope='calendar'][data-part='cell-trigger'] {
279
+ /* 区间底色是格子上绝对定位的伪元素,选中片得定位才排在它之后 */
280
+ position: relative;
162
281
  display: flex;
163
282
  flex: 1;
164
283
  align-items: center;
@@ -203,6 +322,7 @@
203
322
  font-weight: var(--xh-font-weight-medium);
204
323
  }
205
324
 
325
+
206
326
  /* 不可用走 aria-disabled 而非原生 disabled:格子仍要可聚焦(它还得当方向键的起点),
207
327
  所以只能靠 data-disabled 表达,写 :disabled 永远不命中 */
208
328
  [data-scope='calendar'][data-part='cell-trigger'][data-disabled] {
@@ -221,4 +341,27 @@
221
341
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
222
342
  outline-offset: calc(-1 * var(--xh-ring-width));
223
343
  }
344
+
345
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
346
+ [data-scope='calendar'][data-part='prev-trigger']:empty::before {
347
+ content: '';
348
+ display: inline-block;
349
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
350
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
351
+ vertical-align: var(--xh-glyph-baseline-shift);
352
+ background-color: currentColor;
353
+ -webkit-mask: var(--xh-glyph-mark-chevron-left) center / contain no-repeat;
354
+ mask: var(--xh-glyph-mark-chevron-left) center / contain no-repeat;
355
+ }
356
+
357
+ [data-scope='calendar'][data-part='next-trigger']:empty::before {
358
+ content: '';
359
+ display: inline-block;
360
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
361
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
362
+ vertical-align: var(--xh-glyph-baseline-shift);
363
+ background-color: currentColor;
364
+ -webkit-mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
365
+ mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
366
+ }
224
367
  }
package/css/card.css CHANGED
@@ -27,7 +27,7 @@
27
27
  }
28
28
 
29
29
  [data-scope='card'][data-part='root'][data-variant='elevated'] {
30
- box-shadow: var(--xh-elevation-2);
30
+ box-shadow: var(--xh-card-shadow, var(--xh-elevation-raised));
31
31
  }
32
32
 
33
33
  [data-scope='card'][data-part='root'][data-variant='ghost'] {
@@ -47,7 +47,7 @@
47
47
  @media (hover: hover) {
48
48
  [data-scope='card'][data-part='root'][data-hoverable]:hover {
49
49
  border-color: var(--xh-card-border, var(--xh-border-strong));
50
- box-shadow: var(--xh-elevation-2);
50
+ box-shadow: var(--xh-card-shadow, var(--xh-elevation-raised));
51
51
  }
52
52
  }
53
53
 
@@ -67,25 +67,25 @@
67
67
  [data-scope='card'][data-part='header'] {
68
68
  display: flex;
69
69
  flex-direction: column;
70
- gap: var(--xh-space-1);
70
+ gap: var(--xh-card-header-gap, var(--xh-space-1));
71
71
  padding: var(--xh-_card-pad);
72
72
  /* 头下面若还有别的段,间距由那一段自己的内边距接上,这里不重复留白 */
73
- padding-block-end: var(--xh-space-2);
73
+ padding-block-end: var(--xh-card-header-pb, var(--xh-space-2));
74
74
  }
75
75
 
76
76
  [data-scope='card'][data-part='title'] {
77
- font-size: var(--xh-card-title-font-size, var(--xh-font-size-md));
77
+ font-size: var(--xh-card-title-font-size, var(--xh-text-label-size));
78
78
  font-weight: var(--xh-font-weight-medium);
79
79
  line-height: var(--xh-leading-tight);
80
80
  }
81
81
 
82
82
  [data-scope='card'][data-part='root'][data-size='lg'] [data-part='title'] {
83
- font-size: var(--xh-card-title-font-size, var(--xh-font-size-lg));
83
+ font-size: var(--xh-card-title-font-size, var(--xh-control-font-lg));
84
84
  }
85
85
 
86
86
  [data-scope='card'][data-part='description'] {
87
87
  color: var(--xh-fg-muted);
88
- font-size: var(--xh-font-size-sm);
88
+ font-size: var(--xh-text-secondary-size);
89
89
  line-height: var(--xh-leading-normal);
90
90
  }
91
91
 
@@ -96,26 +96,35 @@
96
96
 
97
97
  /* 头与身相邻时,头已经收窄了下边距,身不必再从顶上留一份 */
98
98
  [data-scope='card'][data-part='header'] + [data-part='body'] {
99
- padding-block-start: var(--xh-space-2);
99
+ padding-block-start: var(--xh-card-body-pt, var(--xh-space-2));
100
100
  }
101
101
 
102
102
  [data-scope='card'][data-part='footer'] {
103
103
  display: flex;
104
104
  align-items: center;
105
- gap: var(--xh-space-2);
105
+ gap: var(--xh-card-footer-gap, var(--xh-space-2));
106
106
  padding: var(--xh-_card-pad);
107
- padding-block-start: var(--xh-space-2);
107
+ padding-block-start: var(--xh-card-footer-pt, var(--xh-space-2));
108
108
  }
109
109
 
110
110
  /* —— 分段 —— */
111
111
  /* 分隔线画在下一段的上边,段与段之间才只有一条 */
112
112
  [data-scope='card'][data-part='root'][data-segmented] [data-part='body'],
113
113
  [data-scope='card'][data-part='root'][data-segmented] [data-part='footer'] {
114
- border-block-start: var(--xh-stroke-thin) solid var(--xh-card-border, var(--xh-border-subtle));
114
+ border-block-start: var(--xh-stroke-thin) solid var(--xh-card-divider, var(--xh-border-subtle));
115
115
  padding-block-start: var(--xh-_card-pad);
116
116
  }
117
117
 
118
118
  [data-scope='card'][data-part='root'][data-segmented] [data-part='header'] {
119
119
  padding-block-end: var(--xh-_card-pad);
120
120
  }
121
+
122
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
123
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
124
+ [data-scope='card'][data-part='root'][hidden],
125
+ [data-scope='card'][data-part='cover'][hidden],
126
+ [data-scope='card'][data-part='header'][hidden],
127
+ [data-scope='card'][data-part='footer'][hidden] {
128
+ display: none;
129
+ }
121
130
  }
package/css/carousel.css CHANGED
@@ -7,6 +7,9 @@
7
7
  /* 根节点是 region 地标:把上一张 / 视口 / 下一张排成一行,指示点另起一行。
8
8
  两端按钮浮在视口上还是排在两侧由作者定,这里只给最朴素的一版排布 */
9
9
  [data-scope='carousel'][data-part='root'] {
10
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
11
+ --xh-icon-size: var(--xh-carousel-icon-size, var(--xh-glyph-size-text));
12
+
10
13
  display: flex;
11
14
  flex-wrap: wrap;
12
15
  align-items: center;
@@ -168,7 +171,7 @@
168
171
  /* 圆点本身没有文字,按钮里的文案(页码)交给作者,默认不显示 */
169
172
  padding: 0;
170
173
  border: 0;
171
- border-radius: var(--xh-carousel-indicator-radius, var(--xh-radius-full));
174
+ border-radius: var(--xh-carousel-indicator-radius, var(--xh-shape-pill));
172
175
  background: var(--xh-carousel-indicator-bg, var(--xh-border-control));
173
176
  font-size: 0;
174
177
  cursor: pointer;
@@ -179,20 +182,48 @@
179
182
  display: none;
180
183
  }
181
184
 
182
- [data-scope='carousel'][data-part='indicator']:hover:not([data-selected]) {
185
+ [data-scope='carousel'][data-part='indicator']:hover:not([data-current]) {
183
186
  background: var(--xh-carousel-indicator-bg-hover, var(--xh-fg-subtle));
184
187
  }
185
188
 
186
- /* 当前页:data-selected 与 aria-current='true' 由连接层成对给出,
189
+ /* 当前页:data-current 与 aria-current='true' 由连接层成对给出,
187
190
  样式挂在 data 钩子上,无障碍语义留给 aria,两边各司其职 */
188
- [data-scope='carousel'][data-part='indicator'][data-selected] {
191
+ [data-scope='carousel'][data-part='indicator'][data-current] {
189
192
  background: var(--xh-carousel-indicator-bg-selected, var(--xh-bg-brand));
190
193
  }
191
194
 
192
- /* 减少动效:位移立刻到位。翻页本身照常发生,只是不再有滑动的过程 */
195
+ /* 减少动效:位移立刻到位。翻页本身照常发生,只是不再有滑动的过程。
196
+ 两条规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
193
197
  @media (prefers-reduced-motion: reduce) {
194
198
  [data-scope='carousel'][data-part='item-group'] {
195
199
  transition: none;
196
200
  }
197
201
  }
202
+
203
+ :where([data-motion='reduce']) [data-scope='carousel'][data-part='item-group'] {
204
+ transition: none;
205
+ }
206
+
207
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
208
+ [data-scope='carousel'][data-part='prev-trigger']:empty::before {
209
+ content: '';
210
+ display: inline-block;
211
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
212
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
213
+ vertical-align: var(--xh-glyph-baseline-shift);
214
+ background-color: currentColor;
215
+ -webkit-mask: var(--xh-glyph-mark-chevron-left) center / contain no-repeat;
216
+ mask: var(--xh-glyph-mark-chevron-left) center / contain no-repeat;
217
+ }
218
+
219
+ [data-scope='carousel'][data-part='next-trigger']:empty::before {
220
+ content: '';
221
+ display: inline-block;
222
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
223
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
224
+ vertical-align: var(--xh-glyph-baseline-shift);
225
+ background-color: currentColor;
226
+ -webkit-mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
227
+ mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
228
+ }
198
229
  }