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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +447 -0
  2. package/README.md +1 -1
  3. package/css/accordion.css +56 -5
  4. package/css/alert.css +30 -5
  5. package/css/anchor.css +7 -7
  6. package/css/avatar-group.css +3 -3
  7. package/css/avatar.css +3 -3
  8. package/css/back-top.css +16 -1
  9. package/css/badge.css +16 -2
  10. package/css/breadcrumb.css +24 -4
  11. package/css/button-group.css +14 -13
  12. package/css/button.css +42 -11
  13. package/css/calendar.css +119 -2
  14. package/css/card.css +5 -5
  15. package/css/carousel.css +36 -5
  16. package/css/cascader.css +183 -102
  17. package/css/checkbox-group.css +41 -19
  18. package/css/checkbox.css +54 -8
  19. package/css/clipboard.css +2 -1
  20. package/css/code-block.css +12 -7
  21. package/css/collapsible.css +42 -2
  22. package/css/color-picker.css +111 -45
  23. package/css/combobox.css +114 -53
  24. package/css/composer.css +5 -3
  25. package/css/context-menu.css +97 -69
  26. package/css/date-field.css +91 -14
  27. package/css/date-picker.css +276 -65
  28. package/css/descriptions.css +2 -2
  29. package/css/dialog.css +40 -13
  30. package/css/download-trigger.css +76 -0
  31. package/css/drawer.css +45 -14
  32. package/css/dynamic-input.css +68 -17
  33. package/css/editable.css +12 -10
  34. package/css/ellipsis.css +1 -1
  35. package/css/empty-state.css +7 -7
  36. package/css/field.css +9 -6
  37. package/css/fieldset.css +69 -0
  38. package/css/file-upload.css +45 -7
  39. package/css/float-button.css +16 -1
  40. package/css/floating-panel.css +310 -0
  41. package/css/form.css +4 -4
  42. package/css/heatmap.css +410 -0
  43. package/css/highlight.css +1 -1
  44. package/css/hotkeys.css +90 -0
  45. package/css/hover-card.css +40 -45
  46. package/css/image-cropper.css +231 -0
  47. package/css/image-viewer.css +137 -12
  48. package/css/image.css +2 -2
  49. package/css/infinite-scroll.css +1 -1
  50. package/css/json-viewer.css +241 -0
  51. package/css/layout.css +6 -10
  52. package/css/list.css +8 -8
  53. package/css/listbox.css +20 -4
  54. package/css/loading-bar.css +7 -1
  55. package/css/log.css +1 -1
  56. package/css/marquee.css +9 -0
  57. package/css/masonry.css +63 -0
  58. package/css/mention.css +87 -33
  59. package/css/menu.css +113 -47
  60. package/css/menubar.css +146 -60
  61. package/css/navigation-menu.css +54 -29
  62. package/css/number-animation.css +3 -3
  63. package/css/number-field.css +173 -16
  64. package/css/overlay-arrow.css +51 -0
  65. package/css/page-header.css +5 -5
  66. package/css/pagination.css +13 -13
  67. package/css/password-input.css +356 -0
  68. package/css/pin-input.css +13 -10
  69. package/css/popconfirm.css +46 -10
  70. package/css/popover.css +70 -45
  71. package/css/popselect.css +183 -53
  72. package/css/progress.css +47 -7
  73. package/css/qr-code.css +1 -1
  74. package/css/radio-group.css +14 -8
  75. package/css/rating.css +2 -2
  76. package/css/reset.css +17 -0
  77. package/css/result.css +6 -6
  78. package/css/scroll-area.css +61 -89
  79. package/css/scrollbar.css +167 -0
  80. package/css/segmented.css +215 -0
  81. package/css/select.css +274 -125
  82. package/css/separator.css +2 -2
  83. package/css/side-nav.css +111 -19
  84. package/css/signature-pad.css +144 -0
  85. package/css/skeleton.css +7 -1
  86. package/css/slider.css +10 -10
  87. package/css/space.css +117 -0
  88. package/css/spinner.css +22 -10
  89. package/css/statistic.css +9 -9
  90. package/css/steps.css +25 -8
  91. package/css/switch.css +48 -6
  92. package/css/table.css +131 -37
  93. package/css/tabs.css +4 -4
  94. package/css/tag.css +177 -0
  95. package/css/tags-input.css +78 -40
  96. package/css/text-field.css +149 -36
  97. package/css/thread.css +1 -1
  98. package/css/time-field.css +97 -16
  99. package/css/time-picker.css +259 -69
  100. package/css/timeline.css +10 -10
  101. package/css/timer.css +119 -0
  102. package/css/toast.css +34 -10
  103. package/css/toaster.css +1 -1
  104. package/css/toggle.css +6 -6
  105. package/css/tone.css +10 -5
  106. package/css/toolbar.css +1 -1
  107. package/css/tooltip.css +36 -33
  108. package/css/tour.css +103 -58
  109. package/css/transfer.css +68 -17
  110. package/css/tree-select.css +185 -84
  111. package/css/tree.css +85 -1
  112. package/css/typography.css +4 -4
  113. package/css/undefined.css +11 -1
  114. package/css/virtualizer.css +3 -1
  115. package/css/watermark.css +1 -2
  116. package/index.css +17 -0
  117. package/index.unlayered.css +8659 -2799
  118. package/package.json +19 -3
@@ -5,6 +5,9 @@
5
5
  }
6
6
 
7
7
  [data-scope='file-upload'][data-part='root'] {
8
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
9
+ --xh-icon-size: var(--xh-file-upload-icon-size, var(--xh-glyph-size-text));
10
+
8
11
  display: flex;
9
12
  flex-direction: column;
10
13
  gap: var(--xh-file-upload-gap, var(--xh-space-3));
@@ -72,7 +75,7 @@
72
75
  }
73
76
 
74
77
  [data-scope='file-upload'][data-part='dropzone'][data-invalid] {
75
- border-color: var(--xh-file-upload-dropzone-border-invalid, var(--xh-color-danger-500));
78
+ border-color: var(--xh-file-upload-dropzone-border-invalid, var(--xh-border-invalid));
76
79
  }
77
80
 
78
81
  /* 投放区是 div,没有原生 disabled 可用,禁用态只能靠 data-disabled 表达,写 :disabled 永远不命中 */
@@ -215,7 +218,7 @@
215
218
  [data-scope='file-upload'][data-part='item-size-text'] {
216
219
  flex: none;
217
220
  color: var(--xh-file-upload-size-fg, var(--xh-fg-subtle));
218
- font-size: var(--xh-file-upload-size-font-size, var(--xh-font-size-xs));
221
+ font-size: var(--xh-file-upload-size-font-size, var(--xh-text-caption-size));
219
222
  font-variant-numeric: tabular-nums;
220
223
  white-space: nowrap;
221
224
  }
@@ -230,8 +233,8 @@
230
233
  flex: none;
231
234
  align-items: center;
232
235
  justify-content: center;
233
- inline-size: var(--xh-file-upload-delete-size, var(--xh-control-h-sm));
234
- block-size: var(--xh-file-upload-delete-size, var(--xh-control-h-sm));
236
+ inline-size: var(--xh-file-upload-delete-size, var(--xh-control-action-size));
237
+ block-size: var(--xh-file-upload-delete-size, var(--xh-control-action-size));
235
238
  padding: 0;
236
239
  border: 0;
237
240
  border-radius: var(--xh-file-upload-delete-radius, var(--xh-shape-control));
@@ -240,6 +243,9 @@
240
243
  font-family: inherit;
241
244
  line-height: var(--xh-leading-none);
242
245
  cursor: pointer;
246
+ transition:
247
+ background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
248
+ scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
243
249
  }
244
250
 
245
251
  [data-scope='file-upload'][data-part='item-delete-trigger'][hidden] {
@@ -251,6 +257,12 @@
251
257
  color: var(--xh-file-upload-delete-fg-hover, var(--xh-fg-danger-hover));
252
258
  }
253
259
 
260
+ /* 按下:换到按压档底色并轻微下压,松手弹回;禁用钮不压 */
261
+ [data-scope='file-upload'][data-part='item-delete-trigger']:not(:disabled):active {
262
+ background: var(--xh-file-upload-delete-bg-active, var(--xh-bg-subtle-active));
263
+ scale: var(--xh-motion-scale-press);
264
+ }
265
+
254
266
  [data-scope='file-upload'][data-part='item-delete-trigger']:focus-visible {
255
267
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
256
268
  outline-offset: var(--xh-ring-offset);
@@ -261,8 +273,7 @@
261
273
  cursor: not-allowed;
262
274
  }
263
275
 
264
- /* 清空是收尾动作,画成不带底色的文字按钮:它比"选择文件"次要,
265
- 且列表为空时连接层会给原生 disabled,那时它本就该看着点不动 */
276
+ /* 清空是收尾动作,画成不带底色的文字按钮:它比"选择文件"次要 */
266
277
  [data-scope='file-upload'][data-part='clear-trigger'] {
267
278
  display: inline-flex;
268
279
  flex: none;
@@ -277,9 +288,12 @@
277
288
  background: transparent;
278
289
  color: var(--xh-file-upload-clear-fg, var(--xh-fg-muted));
279
290
  font-family: inherit;
280
- font-size: var(--xh-file-upload-clear-font-size, var(--xh-font-size-xs));
291
+ font-size: var(--xh-file-upload-clear-font-size, var(--xh-text-caption-size));
281
292
  line-height: var(--xh-leading-none);
282
293
  cursor: pointer;
294
+ transition:
295
+ background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
296
+ scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
283
297
  }
284
298
 
285
299
  [data-scope='file-upload'][data-part='clear-trigger'][hidden] {
@@ -291,13 +305,37 @@
291
305
  color: var(--xh-file-upload-clear-fg-hover, var(--xh-fg-default));
292
306
  }
293
307
 
308
+ /* 按下:换到按压档底色并轻微下压,松手弹回;禁用钮不压 */
309
+ [data-scope='file-upload'][data-part='clear-trigger']:not(:disabled):active {
310
+ background: var(--xh-file-upload-clear-bg-active, var(--xh-bg-subtle-active));
311
+ scale: var(--xh-motion-scale-press);
312
+ }
313
+
294
314
  [data-scope='file-upload'][data-part='clear-trigger']:focus-visible {
295
315
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
296
316
  outline-offset: var(--xh-ring-offset);
297
317
  }
298
318
 
319
+ /* 空列表时按钮照常可按(收起它会让焦点掉回 body),只把前景压淡一档 */
320
+ [data-scope='file-upload'][data-part='clear-trigger'][data-empty] {
321
+ color: var(--xh-fg-subtle);
322
+ }
323
+
299
324
  [data-scope='file-upload'][data-part='clear-trigger']:disabled {
300
325
  color: var(--xh-fg-disabled);
301
326
  cursor: not-allowed;
302
327
  }
328
+
329
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
330
+ [data-scope='file-upload'][data-part='item-delete-trigger']:empty::before,
331
+ [data-scope='file-upload'][data-part='clear-trigger']:empty::before {
332
+ content: '';
333
+ display: inline-block;
334
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
335
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
336
+ vertical-align: var(--xh-glyph-baseline-shift);
337
+ background-color: currentColor;
338
+ -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
339
+ mask: var(--xh-glyph-mark-close) center / contain no-repeat;
340
+ }
303
341
  }
@@ -10,6 +10,9 @@
10
10
  transform / filter / backdrop-filter / contain,包含块就被抢走,整组立刻贴错位置——
11
11
  所以别往覆盖钩子里加这几个属性。 */
12
12
  [data-scope='float-button'][data-part='root'] {
13
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
14
+ --xh-icon-size: var(--xh-float-button-icon-size, var(--xh-glyph-size-text));
15
+
13
16
  --xh-_float-button-offset: var(--xh-space-6);
14
17
  /* 触发器与展开的每一条动作共用这两个私有槽,换档只改这里 */
15
18
  --xh-_float-button-size: var(--xh-float-button-size, var(--xh-control-h-lg));
@@ -67,7 +70,7 @@
67
70
  background: var(--xh-float-button-bg, var(--xh-bg-surface-raised));
68
71
  color: var(--xh-float-button-fg, var(--xh-fg-default));
69
72
  /* 浮在内容之上,靠投影与页面拉开层次 */
70
- box-shadow: var(--xh-elevation-3);
73
+ box-shadow: var(--xh-float-button-shadow, var(--xh-elevation-sheet));
71
74
  cursor: pointer;
72
75
  transition:
73
76
  background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
@@ -123,4 +126,16 @@
123
126
  block-size: var(--xh-_float-button-size);
124
127
  border-radius: var(--xh-_float-button-radius);
125
128
  }
129
+
130
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
131
+ [data-scope='float-button'][data-part='trigger']:empty::before {
132
+ content: '';
133
+ display: inline-block;
134
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
135
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
136
+ vertical-align: var(--xh-glyph-baseline-shift);
137
+ background-color: currentColor;
138
+ -webkit-mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
139
+ mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
140
+ }
126
141
  }
@@ -0,0 +1,310 @@
1
+ @layer xihan.components {
2
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
+ [data-scope='floating-panel'] {
4
+ --xh-floating-panel-skin: 1;
5
+ }
6
+
7
+ /* 分工:**面板的落位与尺寸**由连接层每帧写进 positioner 的内联样式
8
+ (position / left / top / width / height)。这份皮肤一条都不碰那五个属性——
9
+ 内联优先级高于样式表,写了不但是死声明,还会在切换形态的那一帧跟连接层抢位置。
10
+ 皮肤只管层级、配色、圆角、阴影、把手的摆放与状态表现。 */
11
+
12
+ [data-scope='floating-panel'][data-part='root'] {
13
+ /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
14
+ --xh-icon-size: var(--xh-floating-panel-icon-size, var(--xh-glyph-size-text));
15
+
16
+ /* 面板本身是 fixed 定位,root 只是作者那棵树里的容器,不参与排布 */
17
+ display: contents;
18
+ }
19
+
20
+ [data-scope='floating-panel'][data-part='root'][hidden] {
21
+ display: none;
22
+ }
23
+
24
+ [data-scope='floating-panel'][data-part='trigger'] {
25
+ display: inline-flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ block-size: var(--xh-floating-panel-trigger-h, var(--xh-control-h-md));
29
+ padding-inline: var(--xh-floating-panel-trigger-px, var(--xh-control-px-md));
30
+ border: var(--xh-stroke-thin) solid var(--xh-floating-panel-trigger-border, var(--xh-border-control));
31
+ border-radius: var(--xh-floating-panel-trigger-radius, var(--xh-shape-control));
32
+ background: var(--xh-floating-panel-trigger-bg, var(--xh-bg-surface));
33
+ color: var(--xh-floating-panel-trigger-fg, var(--xh-fg-default));
34
+ font-size: var(--xh-text-label-size);
35
+ cursor: pointer;
36
+ }
37
+
38
+ [data-scope='floating-panel'][data-part='trigger'][hidden] {
39
+ display: none;
40
+ }
41
+
42
+ [data-scope='floating-panel'][data-part='trigger']:focus-visible {
43
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
44
+ outline-offset: var(--xh-ring-offset);
45
+ }
46
+
47
+ /* 把手的粗细:八个把手共用这两档,声明在这里往下继承。 */
48
+ [data-scope='floating-panel'][data-part='positioner'] {
49
+ --xh-_floating-panel-handle: var(--xh-floating-panel-handle-size, var(--xh-space-2));
50
+ --xh-_floating-panel-corner: var(--xh-floating-panel-corner-size, var(--xh-space-4));
51
+
52
+ position: fixed;
53
+ /* 与抽屉同一档:面板要盖住吸顶栏,又该被随后打开的弹窗与浮层压住 */
54
+ z-index: var(--xh-floating-panel-layer, var(--xh-layer-drawer));
55
+ display: block;
56
+ }
57
+
58
+ [data-scope='floating-panel'][data-part='positioner'][hidden] {
59
+ display: none;
60
+ }
61
+
62
+ [data-scope='floating-panel'][data-part='content'] {
63
+ position: relative;
64
+ block-size: 100%;
65
+ display: flex;
66
+ flex-direction: column;
67
+ overflow: hidden;
68
+ /* 面板底下没有遮罩,压着的是任意页面内容:这条描边是它与背景之间唯一的边界,
69
+ 取 border-default 与同样无遮罩的气泡卡片一档,别退到更淡的 border-subtle */
70
+ border: var(--xh-stroke-thin) solid var(--xh-floating-panel-border, var(--xh-border-default));
71
+ border-radius: var(--xh-floating-panel-radius, var(--xh-shape-surface));
72
+ background: var(--xh-floating-panel-bg, var(--xh-bg-surface));
73
+ color: var(--xh-floating-panel-fg, var(--xh-fg-default));
74
+ box-shadow: var(--xh-floating-panel-shadow, var(--xh-elevation-sheet));
75
+ }
76
+
77
+ [data-scope='floating-panel'][data-part='content'][hidden] {
78
+ display: none;
79
+ }
80
+
81
+ /* 面板本体不接收焦点,只是键盘事件的收口点,画环反而像是选中了整块 */
82
+ [data-scope='floating-panel'][data-part='content']:focus-visible {
83
+ outline: none;
84
+ }
85
+
86
+ /* 跟手期间整块不许选中文字:手在标题栏上来回蹭时会顺带把正文刷成高亮 */
87
+ [data-scope='floating-panel'][data-part='content'][data-dragging],
88
+ [data-scope='floating-panel'][data-part='content'][data-resizing] {
89
+ user-select: none;
90
+ }
91
+
92
+ [data-scope='floating-panel'][data-part='header'] {
93
+ display: flex;
94
+ align-items: center;
95
+ gap: var(--xh-floating-panel-header-gap, var(--xh-control-gap-sm));
96
+ padding-block: var(--xh-floating-panel-header-py, var(--xh-space-2));
97
+ padding-inline: var(--xh-floating-panel-header-px, var(--xh-space-3));
98
+ border-block-end: var(--xh-stroke-thin) solid var(--xh-floating-panel-header-border, var(--xh-border-subtle));
99
+ background: var(--xh-floating-panel-header-bg, var(--xh-bg-subtle));
100
+ }
101
+
102
+ [data-scope='floating-panel'][data-part='header'][hidden] {
103
+ display: none;
104
+ }
105
+
106
+ [data-scope='floating-panel'][data-part='title'] {
107
+ margin: 0;
108
+ flex: 1 1 auto;
109
+ overflow: hidden;
110
+ font-size: var(--xh-floating-panel-title-font-size, var(--xh-text-label-size));
111
+ font-weight: var(--xh-floating-panel-title-font-weight, var(--xh-text-label-weight));
112
+ line-height: var(--xh-leading-tight);
113
+ white-space: nowrap;
114
+ text-overflow: ellipsis;
115
+ color: var(--xh-floating-panel-title-fg, var(--xh-fg-default));
116
+ }
117
+
118
+ /* 拖拽把手铺满标题栏剩下的横向空间:只给一小块纹理的话很难抓住 */
119
+ [data-scope='floating-panel'][data-part='drag-trigger'] {
120
+ flex: 1 1 auto;
121
+ align-self: stretch;
122
+ min-inline-size: var(--xh-space-6);
123
+ border: 0;
124
+ padding: 0;
125
+ background: transparent;
126
+ cursor: grab;
127
+ }
128
+
129
+ [data-scope='floating-panel'][data-part='drag-trigger'][data-dragging] {
130
+ cursor: grabbing;
131
+ }
132
+
133
+ [data-scope='floating-panel'][data-part='drag-trigger'][data-disabled] {
134
+ cursor: default;
135
+ }
136
+
137
+ [data-scope='floating-panel'][data-part='drag-trigger']:focus-visible {
138
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
139
+ outline-offset: calc(-1 * var(--xh-ring-offset));
140
+ }
141
+
142
+ /* —— 改尺把手 ——
143
+ 这一段刻意用物理的 inset / width / height:面板的坐标是屏幕坐标(连接层写的是
144
+ left/top),指针位移与方向键推动的也是屏幕方向。改成逻辑属性后,RTL 下 inset-inline-start
145
+ 会翻到另一侧,守着「西边」的把手会长在东边,手往右拖却从左边收——把手与它推的那条边脱钩。 */
146
+ [data-scope='floating-panel'][data-part='resize-trigger'] {
147
+ position: absolute;
148
+ border: 0;
149
+ padding: 0;
150
+ /* 把手是透明的命中区:看不见但要摸得着,嫌小就调 --xh-floating-panel-handle-size */
151
+ background: transparent;
152
+ }
153
+
154
+ /* 只换指针形状,不摘 pointer-events:点击守卫在连接层,摘掉会让"键盘还在、指针没了"
155
+ 这两套禁用语义对不上 */
156
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-disabled] {
157
+ cursor: default;
158
+ }
159
+
160
+ [data-scope='floating-panel'][data-part='resize-trigger']:focus-visible {
161
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
162
+ outline-offset: calc(-1 * var(--xh-ring-offset));
163
+ }
164
+
165
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='n'] {
166
+ inset: 0 0 auto 0;
167
+ height: var(--xh-_floating-panel-handle);
168
+ cursor: ns-resize;
169
+ }
170
+
171
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='s'] {
172
+ inset: auto 0 0 0;
173
+ height: var(--xh-_floating-panel-handle);
174
+ cursor: ns-resize;
175
+ }
176
+
177
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='w'] {
178
+ inset: 0 auto 0 0;
179
+ width: var(--xh-_floating-panel-handle);
180
+ cursor: ew-resize;
181
+ }
182
+
183
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='e'] {
184
+ inset: 0 0 0 auto;
185
+ width: var(--xh-_floating-panel-handle);
186
+ cursor: ew-resize;
187
+ }
188
+
189
+ /* 四个角排在四条边之后,命中区大一圈:角上要同时抓住两条边 */
190
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='nw'] {
191
+ inset: 0 auto auto 0;
192
+ width: var(--xh-_floating-panel-corner);
193
+ height: var(--xh-_floating-panel-corner);
194
+ cursor: nwse-resize;
195
+ }
196
+
197
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='ne'] {
198
+ inset: 0 0 auto auto;
199
+ width: var(--xh-_floating-panel-corner);
200
+ height: var(--xh-_floating-panel-corner);
201
+ cursor: nesw-resize;
202
+ }
203
+
204
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='se'] {
205
+ inset: auto 0 0 auto;
206
+ width: var(--xh-_floating-panel-corner);
207
+ height: var(--xh-_floating-panel-corner);
208
+ cursor: nwse-resize;
209
+ }
210
+
211
+ [data-scope='floating-panel'][data-part='resize-trigger'][data-edge='sw'] {
212
+ inset: auto auto 0 0;
213
+ width: var(--xh-_floating-panel-corner);
214
+ height: var(--xh-_floating-panel-corner);
215
+ cursor: nesw-resize;
216
+ }
217
+
218
+ /* —— 标题栏上的按钮 —— */
219
+ [data-scope='floating-panel'][data-part='stage-trigger'],
220
+ [data-scope='floating-panel'][data-part='close-trigger'] {
221
+ flex: 0 0 auto;
222
+ display: inline-flex;
223
+ align-items: center;
224
+ justify-content: center;
225
+ border: 0;
226
+ background: transparent;
227
+ color: var(--xh-floating-panel-action-fg, var(--xh-fg-muted));
228
+ cursor: pointer;
229
+ transition:
230
+ background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
231
+ color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
232
+ scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
233
+ }
234
+
235
+ /* 两颗钮同高同圆角,尺寸与圆角槽按各自角色命名 */
236
+ [data-scope='floating-panel'][data-part='stage-trigger'] {
237
+ inline-size: var(--xh-floating-panel-action-size, var(--xh-control-h-sm));
238
+ block-size: var(--xh-floating-panel-action-size, var(--xh-control-h-sm));
239
+ border-radius: var(--xh-floating-panel-action-radius, var(--xh-shape-control));
240
+ }
241
+
242
+ [data-scope='floating-panel'][data-part='close-trigger'] {
243
+ inline-size: var(--xh-floating-panel-close-size, var(--xh-control-h-sm));
244
+ block-size: var(--xh-floating-panel-close-size, var(--xh-control-h-sm));
245
+ border-radius: var(--xh-floating-panel-close-radius, var(--xh-shape-control));
246
+ }
247
+
248
+ [data-scope='floating-panel'][data-part='stage-trigger'][hidden],
249
+ [data-scope='floating-panel'][data-part='close-trigger'][hidden] {
250
+ display: none;
251
+ }
252
+
253
+ [data-scope='floating-panel'][data-part='stage-trigger']:hover,
254
+ [data-scope='floating-panel'][data-part='close-trigger']:hover {
255
+ background: var(--xh-floating-panel-action-bg-hover, var(--xh-bg-subtle-hover));
256
+ color: var(--xh-floating-panel-action-fg-hover, var(--xh-fg-default));
257
+ }
258
+
259
+ [data-scope='floating-panel'][data-part='stage-trigger']:active,
260
+ [data-scope='floating-panel'][data-part='close-trigger']:active {
261
+ background: var(--xh-floating-panel-action-bg-active, var(--xh-bg-subtle-active));
262
+ scale: var(--xh-motion-scale-press);
263
+ }
264
+
265
+ /* 当前形态的那个按钮压着不放,用户一眼看得出面板正处于哪一档。
266
+ 按下态的前景取 fg-default 而不是品牌色:品牌色压在这块底上只有 3.4:1(深色皮肤 2.9:1),
267
+ 按钮里通常就一个字形,够不着文字该有的对比度。 */
268
+ [data-scope='floating-panel'][data-part='stage-trigger'][data-state='on'] {
269
+ background: var(--xh-floating-panel-action-bg-active, var(--xh-bg-subtle-active));
270
+ color: var(--xh-floating-panel-action-fg-active, var(--xh-fg-default));
271
+ }
272
+
273
+ /* 只换前景不叠 opacity:叠了之后禁用文字的对比度会掉到读不出来 */
274
+ [data-scope='floating-panel'][data-part='stage-trigger'][data-disabled] {
275
+ background: transparent;
276
+ color: var(--xh-fg-disabled);
277
+ cursor: not-allowed;
278
+ }
279
+
280
+ [data-scope='floating-panel'][data-part='stage-trigger']:focus-visible,
281
+ [data-scope='floating-panel'][data-part='close-trigger']:focus-visible {
282
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
283
+ outline-offset: var(--xh-ring-offset);
284
+ }
285
+
286
+ [data-scope='floating-panel'][data-part='body'] {
287
+ flex: 1 1 auto;
288
+ display: block;
289
+ overflow: auto;
290
+ padding-block: var(--xh-floating-panel-body-py, var(--xh-surface-py-sm));
291
+ padding-inline: var(--xh-floating-panel-body-px, var(--xh-surface-px-sm));
292
+ }
293
+
294
+ /* 收拢时连接层给正文打 hidden,这里把 UA 的 [hidden] 还回来(上面那条 display 盖掉了它) */
295
+ [data-scope='floating-panel'][data-part='body'][hidden] {
296
+ display: none;
297
+ }
298
+
299
+ /* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
300
+ [data-scope='floating-panel'][data-part='close-trigger']:empty::before {
301
+ content: '';
302
+ display: inline-block;
303
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
304
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
305
+ vertical-align: var(--xh-glyph-baseline-shift);
306
+ background-color: currentColor;
307
+ -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
308
+ mask: var(--xh-glyph-mark-close) center / contain no-repeat;
309
+ }
310
+ }
package/css/form.css CHANGED
@@ -44,7 +44,7 @@
44
44
  用逻辑属性,RTL 下自动换到右侧 */
45
45
  [data-scope='form'][data-part='field-group'][data-invalid] {
46
46
  padding-inline-start: var(--xh-form-field-invalid-px, var(--xh-space-2));
47
- border-inline-start: var(--xh-stroke-thick) solid var(--xh-form-field-invalid-border, var(--xh-color-danger-500));
47
+ border-inline-start: var(--xh-stroke-thick) solid var(--xh-form-field-invalid-border, var(--xh-border-invalid));
48
48
  }
49
49
 
50
50
  /* 容器带着 tabindex=-1:控件全禁用时焦点会落在它自己身上,
@@ -61,13 +61,13 @@
61
61
  gap: var(--xh-form-summary-gap, var(--xh-space-1_5));
62
62
  padding-block: var(--xh-form-summary-py, var(--xh-space-3));
63
63
  padding-inline: var(--xh-form-summary-px, var(--xh-control-px-md));
64
- border: var(--xh-stroke-thin) solid var(--xh-form-summary-border, var(--xh-color-danger-500));
64
+ border: var(--xh-stroke-thin) solid var(--xh-form-summary-border, var(--xh-border-invalid));
65
65
  border-radius: var(--xh-form-summary-radius, var(--xh-shape-surface));
66
66
  background: var(--xh-form-summary-bg, var(--xh-bg-surface));
67
67
  color: var(--xh-form-summary-fg, var(--xh-fg-danger));
68
68
  font-size: var(--xh-form-summary-font-size, var(--xh-text-body-size));
69
69
  line-height: var(--xh-leading-normal);
70
- box-shadow: var(--xh-form-summary-shadow, var(--xh-elevation-1));
70
+ box-shadow: var(--xh-form-summary-shadow, var(--xh-elevation-raised));
71
71
  }
72
72
 
73
73
  /* 漏了这条,摘要一旦出现过就再也撤不下去(上面那条 display 盖掉了 UA 的 [hidden] 规则) */
@@ -90,7 +90,7 @@
90
90
  [data-scope='form'][data-part='error-summary-item'] {
91
91
  display: block;
92
92
  color: inherit;
93
- font-size: var(--xh-form-summary-item-font-size, var(--xh-font-size-sm));
93
+ font-size: var(--xh-form-summary-item-font-size, var(--xh-text-secondary-size));
94
94
  text-decoration: underline;
95
95
  text-underline-offset: 2px;
96
96
  cursor: pointer;