@xihan-ui/styles 2.1.0 → 3.1.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.
- package/CHANGELOG.md +1261 -0
- package/README.md +6 -1
- package/component-tokens.d.ts +533 -96
- package/components.tokens.json +35461 -26045
- package/css/accordion.css +34 -8
- package/css/alert.css +59 -1
- package/css/anchor.css +46 -8
- package/css/approval.css +116 -76
- package/css/avatar-group.css +1 -1
- package/css/avatar.css +13 -5
- package/css/back-top.css +61 -42
- package/css/badge.css +62 -12
- package/css/bar-code.css +1 -1
- package/css/breadcrumb.css +62 -3
- package/css/button-group.css +4 -4
- package/css/button.css +67 -19
- package/css/calendar-picker.css +19 -0
- package/css/calendar-range-picker.css +39 -2
- package/css/card.css +115 -1
- package/css/carousel.css +148 -43
- package/css/cartesian-chart.css +830 -0
- package/css/cascader.css +181 -65
- package/css/checkbox-group.css +59 -89
- package/css/checkbox.css +16 -49
- package/css/citation.css +470 -0
- package/css/clipboard.css +20 -63
- package/css/code-view.css +101 -6
- package/css/collapsible.css +34 -8
- package/css/color-field.css +18 -0
- package/css/color-picker.css +128 -50
- package/css/color-slider.css +22 -15
- package/css/color-swatch-picker.css +3 -1
- package/css/combobox.css +80 -33
- package/css/command.css +45 -43
- package/css/context-menu.css +39 -22
- package/css/date-field.css +56 -0
- package/css/date-picker.css +132 -26
- package/css/date-range-picker.css +337 -14
- package/css/description.css +17 -1
- package/css/descriptions.css +42 -0
- package/css/dialog.css +94 -36
- package/css/diff-view.css +97 -12
- package/css/download-trigger.css +44 -78
- package/css/drawer.css +160 -119
- package/css/editable.css +19 -0
- package/css/empty-state.css +7 -6
- package/css/field-array.css +36 -0
- package/css/field.css +20 -18
- package/css/file-upload.css +125 -135
- package/css/flex.css +324 -8
- package/css/float-button.css +263 -38
- package/css/floating-panel.css +53 -19
- package/css/form.css +31 -17
- package/css/funnel-chart.css +106 -0
- package/css/graph-chart.css +205 -0
- package/css/grid-list.css +235 -0
- package/css/grid.css +252 -1
- package/css/heatmap.css +119 -36
- package/css/hierarchy-chart.css +298 -0
- package/css/hover-card.css +31 -14
- package/css/icon.css +100 -0
- package/css/image-cropper.css +33 -7
- package/css/image-viewer.css +167 -22
- package/css/image.css +23 -4
- package/css/input-group.css +11 -13
- package/css/json-viewer.css +50 -2
- package/css/layout.css +68 -18
- package/css/liquid.css +106 -0
- package/css/list.css +1 -1
- package/css/listbox.css +46 -6
- package/css/loading-bar.css +27 -13
- package/css/log.css +129 -33
- package/css/markdown-stream.css +1 -1
- package/css/marquee.css +163 -7
- package/css/matrix-code.css +1 -1
- package/css/mention.css +35 -19
- package/css/menu.css +35 -21
- package/css/menubar.css +36 -20
- package/css/message-feed.css +172 -51
- package/css/navigation-menu.css +172 -11
- package/css/notification.css +435 -108
- package/css/number-field.css +22 -0
- package/css/page-header.css +3 -1
- package/css/pagination.css +126 -24
- package/css/password-input.css +40 -8
- package/css/pie-chart.css +247 -0
- package/css/popconfirm.css +44 -50
- package/css/popover.css +50 -14
- package/css/progress.css +308 -10
- package/css/prompt-input.css +36 -0
- package/css/question-flow.css +97 -57
- package/css/radar-chart.css +233 -0
- package/css/radio-group.css +363 -5
- package/css/rating.css +21 -23
- package/css/reasoning.css +61 -54
- package/css/resizable.css +6 -1
- package/css/sankey-chart.css +174 -0
- package/css/scroll-area.css +32 -0
- package/css/scrollbar.css +1 -1
- package/css/select.css +74 -55
- package/css/side-nav.css +173 -24
- package/css/signature-pad.css +16 -1
- package/css/skeleton.css +13 -14
- package/css/slider.css +35 -13
- package/css/sortable.css +37 -7
- package/css/sparkline.css +164 -0
- package/css/spinner.css +50 -22
- package/css/splitter.css +7 -1
- package/css/statistic.css +10 -0
- package/css/steps.css +248 -29
- package/css/switch.css +23 -48
- package/css/table.css +175 -118
- package/css/tabs.css +231 -19
- package/css/tag-group.css +27 -3
- package/css/tag.css +53 -12
- package/css/tags-input.css +40 -3
- package/css/text-field.css +19 -0
- package/css/time-field.css +20 -1
- package/css/time-picker.css +103 -17
- package/css/time-range-picker.css +45 -16
- package/css/timeline.css +1 -1
- package/css/toggle-group.css +4 -4
- package/css/toggle.css +4 -3
- package/css/tool-call.css +59 -51
- package/css/toolbar.css +101 -3
- package/css/tooltip.css +15 -2
- package/css/tour.css +42 -12
- package/css/transfer.css +98 -75
- package/css/tree-select.css +232 -53
- package/css/tree.css +271 -55
- package/css/truncate.css +55 -12
- package/css/typography.css +93 -0
- package/css/virtualizer.css +56 -0
- package/css/watermark.css +23 -0
- package/family/action-control.css +14 -5
- package/family/chart.css +480 -0
- package/family/check-mark.css +94 -0
- package/family/choice-card.css +97 -0
- package/family/collection-item.css +9 -15
- package/family/field-chrome.css +1 -12
- package/family/loading-ring.css +95 -0
- package/family/material.css +72 -0
- package/family/menu-choice.css +56 -0
- package/family/motion.css +207 -10
- package/family/tag-list.css +59 -0
- package/index.css +13824 -4030
- package/index.unlayered.css +13403 -3605
- package/package.json +20 -8
- package/css/gradient-text.css +0 -91
- package/css/icon-wrapper.css +0 -81
- package/css/segmented.css +0 -280
- package/css/toast.css +0 -499
package/css/layout.css
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
缺哪一段,对应的行/列就没有条目,宽高自动收成 0,不必为"少写一段"另立规则。
|
|
19
19
|
|
|
20
20
|
侧栏两档宽度与头的高度声明在根上:各段自己读这些槽,换档只改这里。
|
|
21
|
-
宽度槽用 -w 缩写,与同处的 --xh-layout-header-h
|
|
21
|
+
宽度槽用 -w 缩写,与同处的 --xh-layout-header-h 一致;两档宽度的缺省取侧栏令牌 --xh-sider-w / --xh-sider-collapsed-w。
|
|
22
22
|
头的高度之所以也归到根上:头吸顶时头这一行的轨道要按同一个值定高,两处必须同源。 */
|
|
23
23
|
[data-scope='layout'][data-part='root'] {
|
|
24
24
|
display: grid;
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
31
31
|
background: var(--xh-layout-bg, var(--xh-bg-page));
|
|
32
32
|
color: var(--xh-layout-fg, var(--xh-fg-default));
|
|
33
|
-
--xh-_layout-sider-expanded-w: var(--xh-layout-sider-w,
|
|
33
|
+
--xh-_layout-sider-expanded-w: var(--xh-layout-sider-w, var(--xh-sider-w));
|
|
34
34
|
--xh-_layout-sider-w: var(--xh-_layout-sider-expanded-w);
|
|
35
|
-
--xh-_layout-sider-collapsed-w: var(--xh-layout-sider-collapsed-w,
|
|
35
|
+
--xh-_layout-sider-collapsed-w: var(--xh-layout-sider-collapsed-w, var(--xh-sider-collapsed-w));
|
|
36
36
|
--xh-_layout-header-h: var(--xh-layout-header-h, 3.5rem);
|
|
37
37
|
/* 侧栏吸附时钉在哪条线上:缺省贴滚动容器上沿,头也吸顶时改成让开头的高度 */
|
|
38
38
|
--xh-_layout-sider-offset: 0px;
|
|
@@ -97,13 +97,15 @@
|
|
|
97
97
|
[data-scope='layout'][data-part='sider'] {
|
|
98
98
|
--xh-action-host-bg-hover: var(--xh-bg-subtle-hover);
|
|
99
99
|
--xh-action-host-bg-pressed: var(--xh-bg-subtle-active);
|
|
100
|
+
/* 内衬缺省一档,装了 SideNav 的侧栏在下面归零;覆盖档与安全区取大时读的也是这一支 */
|
|
101
|
+
--xh-_layout-sider-padding: var(--xh-space-3);
|
|
100
102
|
|
|
101
103
|
grid-area: sider;
|
|
102
104
|
inline-size: var(--xh-_layout-sider-w);
|
|
103
105
|
overflow: hidden;
|
|
104
|
-
padding: var(--xh-layout-sider-padding, var(--xh-
|
|
106
|
+
padding: var(--xh-layout-sider-padding, var(--xh-_layout-sider-padding));
|
|
105
107
|
background: var(--xh-layout-sider-bg, var(--xh-bg-subtle));
|
|
106
|
-
transition: inline-size var(--xh-motion-duration-
|
|
108
|
+
transition: inline-size var(--xh-motion-duration-move) var(--xh-motion-ease-continuous);
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
/* 折起来时不换行:窄到放不下的那几个字直接被 overflow 裁掉,不会挤成一列竖排 */
|
|
@@ -112,6 +114,19 @@
|
|
|
112
114
|
white-space: nowrap;
|
|
113
115
|
}
|
|
114
116
|
|
|
117
|
+
/* 侧栏里装着 SideNav 时内衬缺省归零:SideNav 自带一圈内衬,宽度又与侧栏同取侧栏令牌,
|
|
118
|
+
再叠一圈侧栏内衬,导航就比侧栏的内容盒宽出两侧内衬、右缘被裁掉。
|
|
119
|
+
认后代而不是子代:Web Components 在侧栏与导航根之间隔着 <xh-side-nav> 宿主。
|
|
120
|
+
不认 :has() 的引擎(Firefox 121 以前)照旧留内衬,导航右缘被裁,与改动前一致 */
|
|
121
|
+
[data-scope='layout'][data-part='sider']:has([data-scope='side-nav'][data-part='root']) {
|
|
122
|
+
--xh-_layout-sider-padding: 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* 侧栏里的 SideNav 跟着侧栏收放:侧栏这一次开合直接落位(首帧、跨过断点)时,导航的宽度同样直接落位 */
|
|
126
|
+
[data-scope='layout'][data-part='sider'][data-instant] [data-scope='side-nav'][data-part='root'] {
|
|
127
|
+
transition: none;
|
|
128
|
+
}
|
|
129
|
+
|
|
115
130
|
[data-scope='layout'][data-part='content'] {
|
|
116
131
|
grid-area: content;
|
|
117
132
|
/* 内容列已是 minmax(0, 1fr),这里再声明一次,宽表格与长串文本才撑不破列 */
|
|
@@ -189,6 +204,23 @@
|
|
|
189
204
|
inset-block-start: 0;
|
|
190
205
|
}
|
|
191
206
|
|
|
207
|
+
/* liquid 档:吸顶的顶栏是内容从下面滚过的导航层,换成液态面。贴边铺满的栏不取圆角,
|
|
208
|
+
边界由下沿那条墨色细线承担。液态面是墨色域,前景在这里按域重取,子孙跟着继承。
|
|
209
|
+
滚过深浅分界时色调翻转:底色、字色、细线与投影一起淡变,不在同一帧跳 */
|
|
210
|
+
:where([data-material='liquid']) [data-scope='layout'][data-part='header'][data-fixed][data-xh-liquid] {
|
|
211
|
+
border-block-end: var(--xh-stroke-thin) solid var(--xh-layout-border, var(--xh-material-liquid-border));
|
|
212
|
+
background: var(--xh-layout-header-bg, var(--xh-_liquid-bg));
|
|
213
|
+
color: var(--xh-material-liquid-fg);
|
|
214
|
+
box-shadow: var(--xh-_liquid-shadow);
|
|
215
|
+
-webkit-backdrop-filter: var(--xh-material-liquid-backdrop);
|
|
216
|
+
backdrop-filter: var(--xh-material-liquid-backdrop);
|
|
217
|
+
transition:
|
|
218
|
+
background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
219
|
+
border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
220
|
+
color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
221
|
+
box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
222
|
+
}
|
|
223
|
+
|
|
192
224
|
/* 头也吸顶时侧栏钉在头的下沿,两段不叠在一起 */
|
|
193
225
|
[data-scope='layout'][data-part='root'][data-header-fixed][data-sider-fixed] {
|
|
194
226
|
--xh-_layout-sider-offset: var(--xh-_layout-header-h);
|
|
@@ -215,10 +247,10 @@
|
|
|
215
247
|
参照的是视口,与上面 sticky 那条同一个注意事项:整副骨架装进带 transform / filter 的祖先里时,
|
|
216
248
|
固定定位的包含块会换成那个祖先,面板跟着一起滚。 */
|
|
217
249
|
[data-scope='layout'][data-part='sider'][data-presentation='sheet'] {
|
|
218
|
-
/* 位移方向的私有槽位:默认按行首 + LTR,行尾与 RTL
|
|
219
|
-
|
|
250
|
+
/* 位移方向的私有槽位:默认按行首 + LTR,行尾与 RTL 在下面翻符号。幅度取整幅位移令牌,
|
|
251
|
+
减弱动效下归零。写成槽位而不是写死物理方向:贴边用的是逻辑 inset,RTL 下行首落在物理右边,
|
|
220
252
|
位移若写死物理方向就会出现「贴在右边、却从左边滑进来」 */
|
|
221
|
-
--xh-_layout-sheet-shift: -
|
|
253
|
+
--xh-_layout-sheet-shift: calc(-1 * var(--xh-motion-travel));
|
|
222
254
|
/* 这一档的底是 elevated 白底:交互阶梯按承载面走,把上面占位档下发的 200 → 300 写回
|
|
223
255
|
白底的 hover 100 → pressed 200 */
|
|
224
256
|
--xh-action-host-bg-hover: var(--xh-bg-subtle);
|
|
@@ -238,10 +270,10 @@
|
|
|
238
270
|
/* 贴死视口的那一档,内衬与安全区取大的一头:刘海、圆角与底部横条压住的那一段由系统给出。
|
|
239
271
|
桌面上 env() 恒为 0,取值与内衬槽完全一致。安全区只有物理方向的四个名字,
|
|
240
272
|
行内轴上两侧同取较宽的那一段,RTL 下不会翻错边 */
|
|
241
|
-
padding-block-start: max(var(--xh-layout-sider-padding, var(--xh-
|
|
242
|
-
padding-block-end: max(var(--xh-layout-sider-padding, var(--xh-
|
|
273
|
+
padding-block-start: max(var(--xh-layout-sider-padding, var(--xh-_layout-sider-padding)), env(safe-area-inset-top));
|
|
274
|
+
padding-block-end: max(var(--xh-layout-sider-padding, var(--xh-_layout-sider-padding)), env(safe-area-inset-bottom));
|
|
243
275
|
padding-inline: max(
|
|
244
|
-
var(--xh-layout-sider-padding, var(--xh-
|
|
276
|
+
var(--xh-layout-sider-padding, var(--xh-_layout-sider-padding)),
|
|
245
277
|
env(safe-area-inset-left),
|
|
246
278
|
env(safe-area-inset-right)
|
|
247
279
|
);
|
|
@@ -256,16 +288,19 @@
|
|
|
256
288
|
overscroll 不在这里写 contain:这一面与占位档共用同一个部件,scroll-surface-registry 把侧栏整体登记为
|
|
257
289
|
页内结构容器(overscroll=false),门禁按整个部件核,不按档分 */
|
|
258
290
|
overflow-y: auto;
|
|
259
|
-
/*
|
|
260
|
-
|
|
291
|
+
/* 推出来走 slide 档:视口尺度的位移。并列的不透明度取淡变档:
|
|
292
|
+
缺省两端都是不透明、看不出来,减弱动效下整幅位移归零、由它表达进出。
|
|
293
|
+
visibility 展开那一路立刻露出来 */
|
|
294
|
+
opacity: 1;
|
|
261
295
|
transition:
|
|
262
296
|
translate var(--xh-motion-duration-slide) var(--xh-motion-ease-slide),
|
|
297
|
+
opacity var(--xh-motion-duration-enter) var(--xh-motion-ease-enter),
|
|
263
298
|
visibility var(--xh-motion-duration-slide) var(--xh-motion-ease-slide);
|
|
264
299
|
}
|
|
265
300
|
|
|
266
301
|
/* 挂在行尾:贴另一条边,位移随之反向,描边也换到贴着内容的那一侧 */
|
|
267
302
|
[data-scope='layout'][data-part='sider'][data-presentation='sheet'][data-placement='end'] {
|
|
268
|
-
--xh-_layout-sheet-shift:
|
|
303
|
+
--xh-_layout-sheet-shift: var(--xh-motion-travel);
|
|
269
304
|
|
|
270
305
|
inset-inline-start: auto;
|
|
271
306
|
inset-inline-end: 0;
|
|
@@ -274,18 +309,24 @@
|
|
|
274
309
|
}
|
|
275
310
|
|
|
276
311
|
[data-scope='layout'][data-part='sider'][data-presentation='sheet']:dir(rtl) {
|
|
277
|
-
--xh-_layout-sheet-shift:
|
|
312
|
+
--xh-_layout-sheet-shift: var(--xh-motion-travel);
|
|
278
313
|
}
|
|
279
314
|
|
|
280
315
|
[data-scope='layout'][data-part='sider'][data-presentation='sheet'][data-placement='end']:dir(rtl) {
|
|
281
|
-
--xh-_layout-sheet-shift: -
|
|
316
|
+
--xh-_layout-sheet-shift: calc(-1 * var(--xh-motion-travel));
|
|
282
317
|
}
|
|
283
318
|
|
|
284
319
|
/* 收起:推出画外并让出无障碍树与 Tab 序列。位移量按面板自身宽度的百分比算,
|
|
285
|
-
|
|
320
|
+
宽度换成任何一档都正好推到画外。收进去是退场,位移与淡出同走退场档,
|
|
321
|
+
visibility 等这一段播完才真正藏起来;减弱动效下位移归零,只剩淡出 */
|
|
286
322
|
[data-scope='layout'][data-part='sider'][data-presentation='sheet'][data-collapsed] {
|
|
287
323
|
translate: var(--xh-_layout-sheet-shift) 0;
|
|
324
|
+
opacity: var(--xh-motion-travel-opacity);
|
|
288
325
|
visibility: hidden;
|
|
326
|
+
transition:
|
|
327
|
+
translate var(--xh-motion-duration-exit) var(--xh-motion-ease-exit),
|
|
328
|
+
opacity var(--xh-motion-duration-exit) var(--xh-motion-ease-exit),
|
|
329
|
+
visibility var(--xh-motion-duration-exit) var(--xh-motion-ease-exit);
|
|
289
330
|
}
|
|
290
331
|
|
|
291
332
|
/* 覆盖档的遮罩:与面板同一个层号,谁盖谁看文档序——遮罩写在侧栏之前。
|
|
@@ -299,10 +340,19 @@
|
|
|
299
340
|
transition: opacity var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
300
341
|
}
|
|
301
342
|
|
|
302
|
-
/*
|
|
343
|
+
/* 收起态:淡出并让开指针,底下的内容照常点得到;淡出走退场档 */
|
|
303
344
|
[data-scope='layout'][data-part='sider-backdrop'][data-collapsed] {
|
|
304
345
|
opacity: 0;
|
|
305
346
|
pointer-events: none;
|
|
347
|
+
transition: opacity var(--xh-motion-duration-exit) var(--xh-motion-ease-exit);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/* 侧栏与遮罩的过渡只给用户的开合:首帧与跨过断点这类环境引起的开合,连接层投影 data-instant,
|
|
351
|
+
直接落位。三条各压过同一部件上带过渡的那一档(占位 / 覆盖展开、覆盖收起、遮罩收起) */
|
|
352
|
+
[data-scope='layout']:is([data-part='sider'], [data-part='sider-backdrop'])[data-instant],
|
|
353
|
+
[data-scope='layout'][data-part='sider'][data-presentation='sheet'][data-collapsed][data-instant],
|
|
354
|
+
[data-scope='layout'][data-part='sider-backdrop'][data-collapsed][data-instant] {
|
|
355
|
+
transition: none;
|
|
306
356
|
}
|
|
307
357
|
|
|
308
358
|
/* 纸上没有覆盖这回事:遮罩印出来就是盖住正文的一片灰 */
|
package/css/liquid.css
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2021-Present XiHanFun and contributors.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE in the project root for license information.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* 液态材质层:与组件无关,全库共用一份。
|
|
8
|
+
*
|
|
9
|
+
* data-material="liquid" 下,连接层投影了 data-xh-liquid 的导航层部件(浮动钮、回到顶部等浮在内容之上的控制面)
|
|
10
|
+
* 换成液态面。这里只声明私有槽,各组件皮肤在自己的部件上把 Action Control 的桥接槽指过来;standard 档下
|
|
11
|
+
* 这些槽没人读,部件保持原材质。
|
|
12
|
+
*
|
|
13
|
+
* 静态形态(服务端、挂载前,或液态面还没判定下层):色调随主题极性,不透明度取可读下限,这一档对任何
|
|
14
|
+
* 下层都保证标签 4.5:1。组件的状态机把部件挂进 core 的液态面,由它按下层在部件上写:
|
|
15
|
+
* data-xh-ink dark / light:部件成为黑墨或白墨域。墨色域本身是浅色 / 深色主题边界,
|
|
16
|
+
* 按主题取值的液态通道随之落到那一种色调
|
|
17
|
+
* data-xh-liquid-clarity clear:下层均匀且色调已知,换通透档
|
|
18
|
+
* --xh-_liquid-light-x / -y 光源方向的单位向量,决定 1px 亮边落在哪一侧
|
|
19
|
+
* --xh-_liquid-deform 按住时的形变(transform 串),松手弹回后撤掉
|
|
20
|
+
*
|
|
21
|
+
* 同一宿主里的几块可以结成液态组(core 的 trackLiquidGoo):宿主带 data-xh-liquid-goo,最前面多一层
|
|
22
|
+
* [data-xh-liquid-goo-layer] 色块层,沿整组的外形画底色、墨色细线、亮边与投影;组件皮肤在这一档把块自己的
|
|
23
|
+
* 面、细线、亮边与投影撤掉,只留磨砂。
|
|
24
|
+
*/
|
|
25
|
+
@layer xihan.components {
|
|
26
|
+
:where([data-material='liquid']) [data-xh-liquid] {
|
|
27
|
+
/* 光源缺省在左上方 */
|
|
28
|
+
--xh-_liquid-light-x: -0.71;
|
|
29
|
+
--xh-_liquid-light-y: -0.71;
|
|
30
|
+
--xh-_liquid-bg: var(--xh-material-liquid-bg);
|
|
31
|
+
/* 1px 亮边是两层零模糊内阴影:阴影形状朝背光方向偏移,露出的一弯落在朝光源的一侧,
|
|
32
|
+
另一层反过来偏移,在背光一侧留一道弱亮边。面内不加高光 */
|
|
33
|
+
--xh-_liquid-rim:
|
|
34
|
+
inset calc(var(--xh-_liquid-light-x) * var(--xh-stroke-thin) * -1) calc(var(--xh-_liquid-light-y) * var(--xh-stroke-thin) * -1) 0 0 var(--xh-material-liquid-highlight),
|
|
35
|
+
inset calc(var(--xh-_liquid-light-x) * var(--xh-stroke-thin)) calc(var(--xh-_liquid-light-y) * var(--xh-stroke-thin)) 0 0 var(--xh-material-liquid-rim-far);
|
|
36
|
+
--xh-_liquid-shadow: var(--xh-_liquid-rim), var(--xh-material-liquid-shadow);
|
|
37
|
+
/* 交互阶梯往部件自己的前景色兑:浅色调变深、深色调变浅 */
|
|
38
|
+
--xh-_liquid-bg-hover: color-mix(in oklab, var(--xh-_liquid-bg), var(--xh-material-liquid-fg) 8%);
|
|
39
|
+
--xh-_liquid-bg-pressed: color-mix(in oklab, var(--xh-_liquid-bg), var(--xh-material-liquid-fg) 14%);
|
|
40
|
+
/* 按住时的黏滞形变:液态面在手指按住期间逐帧写进来(朝手指鼓出、沿指向拉长、另一个方向压扁),
|
|
41
|
+
松手由弹簧带回后撤掉;组件皮肤拿它当 transform。没按住时为 none */
|
|
42
|
+
--xh-_liquid-deform: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* 通透档:下层均匀且色调已知时由液态面写上,着色按主题取值,已随墨色域落到对应色调 */
|
|
46
|
+
:where([data-material='liquid']) [data-xh-liquid][data-xh-liquid-clarity='clear'] {
|
|
47
|
+
--xh-_liquid-bg: color-mix(in oklab, var(--xh-material-liquid-tint) calc(var(--xh-material-liquid-alpha-clear) * 100%), transparent);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* 液态组的色块层:core 在宿主最前面生成(aria-hidden、不接指针),压在各块之下,每块一个色块,
|
|
51
|
+
跟着块的盒子、圆角与变换走。色块层套 core 放在它旁边的粘连滤镜(行内 filter),滤镜只取色块的轮廓,
|
|
52
|
+
把靠得够近的连成一片,再沿整体外形画液态面:投影、底色、墨色细线、朝光亮边与背光弱亮边,颜色都在下面
|
|
53
|
+
按段取液态令牌,投影由色块自己带着、滤镜只留外形之外的那部分。色调(墨色域)与通透档由 core 按源块的
|
|
54
|
+
读数同步到色块层与装滤镜的 <svg> 上。
|
|
55
|
+
色块层不设层号,靠排在宿主最前压在各块之下:宿主须是定位元素,组里的块须是定位元素(或装在定位容器里)。
|
|
56
|
+
层往外多铺一圈,给模糊与投影留出余地。组件可以在自己的宿主上改写投影槽,把使用者的投影槽接进来 */
|
|
57
|
+
[data-xh-liquid-goo-layer] {
|
|
58
|
+
--xh-_liquid-goo-shadow: var(--xh-material-liquid-shadow);
|
|
59
|
+
|
|
60
|
+
position: absolute;
|
|
61
|
+
inset: calc(-1 * var(--xh-space-8));
|
|
62
|
+
pointer-events: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* 色块提供轮廓与投影,底色由滤镜铺 */
|
|
66
|
+
[data-xh-liquid-goo-layer] > span {
|
|
67
|
+
position: absolute;
|
|
68
|
+
box-sizing: border-box;
|
|
69
|
+
background-color: var(--xh-material-liquid-tint);
|
|
70
|
+
box-shadow: var(--xh-_liquid-goo-shadow);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
[data-xh-liquid-goo-filter] [data-xh-goo-paint='fill'] {
|
|
74
|
+
flood-color: var(--xh-material-liquid-tint);
|
|
75
|
+
flood-opacity: var(--xh-material-liquid-alpha-floor);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[data-xh-liquid-goo-filter][data-xh-liquid-clarity='clear'] [data-xh-goo-paint='fill'] {
|
|
79
|
+
flood-opacity: var(--xh-material-liquid-alpha-clear);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
[data-xh-liquid-goo-filter] [data-xh-goo-paint='edge'] {
|
|
83
|
+
flood-color: var(--xh-material-liquid-border);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
[data-xh-liquid-goo-filter] [data-xh-goo-paint='near'] {
|
|
87
|
+
flood-color: var(--xh-material-liquid-highlight);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
[data-xh-liquid-goo-filter] [data-xh-goo-paint='far'] {
|
|
91
|
+
flood-color: var(--xh-material-liquid-rim-far);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* 强制色:系统配色下只留块自己的边,装饰色块撤掉 */
|
|
95
|
+
@media (forced-colors: active) {
|
|
96
|
+
[data-xh-liquid-goo-layer] {
|
|
97
|
+
display: none;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* 从右往左排版时光源缺省在右上方 */
|
|
102
|
+
:where([dir='rtl']) :where([data-material='liquid']) [data-xh-liquid],
|
|
103
|
+
:where([data-material='liquid']) :where([dir='rtl']) [data-xh-liquid] {
|
|
104
|
+
--xh-_liquid-light-x: 0.71;
|
|
105
|
+
}
|
|
106
|
+
}
|
package/css/list.css
CHANGED
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
[data-scope='list'][data-part='root'][data-hoverable] > [data-scope='list'][data-part='item'] {
|
|
94
|
-
transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
94
|
+
transition: background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/* 悬停换底色:只在能用指针的设备上生效,触摸端不留一个按不掉的悬停态 */
|
package/css/listbox.css
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
@import '../family/action-control.css';
|
|
9
9
|
@import '../family/collection-item.css';
|
|
10
|
+
@import '../family/loading-ring.css';
|
|
11
|
+
@import '../family/motion.css';
|
|
10
12
|
|
|
11
13
|
@layer xihan.components {
|
|
12
14
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
@@ -117,7 +119,7 @@
|
|
|
117
119
|
/* 手写结构按真正的条目判断,空白文本与分组标题都不算候选。
|
|
118
120
|
只排除 content 内部的 hidden 祖先;外层浮层退场时不改变本列表的几何。
|
|
119
121
|
禁用条目仍是有效内容,不参与此处排除。 */
|
|
120
|
-
[data-scope='listbox'][data-part='content']:not(:has(
|
|
122
|
+
[data-scope='listbox'][data-part='content']:not([data-xh-virtualized]):not(:has(
|
|
121
123
|
[data-scope='listbox'][data-part='item']:not([hidden]):not([data-scope='listbox'][data-part='content'] [hidden] *)
|
|
122
124
|
)),
|
|
123
125
|
[data-scope='listbox'][data-part='group']:not(:has(
|
|
@@ -164,11 +166,18 @@
|
|
|
164
166
|
display: block;
|
|
165
167
|
padding-block: var(--xh-listbox-group-label-py, var(--xh-space-1));
|
|
166
168
|
padding-inline: var(--xh-listbox-group-label-px, var(--xh-_listbox-item-px));
|
|
167
|
-
color: var(--xh-listbox-group-label-fg, var(--xh-fg-
|
|
169
|
+
color: var(--xh-listbox-group-label-fg, var(--xh-fg-muted));
|
|
168
170
|
font-size: var(--xh-listbox-group-label-font-size, var(--xh-text-caption-size));
|
|
169
171
|
font-weight: var(--xh-listbox-group-label-font-weight, var(--xh-font-weight-medium));
|
|
170
172
|
line-height: var(--xh-leading-none);
|
|
171
173
|
user-select: none;
|
|
174
|
+
transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* 刷新:已有选项时后台在取,保留上一帧,条目与分组标题按 micro 淡下,数据到了再淡回;在途占位此时让位。
|
|
178
|
+
淡的是内容不是面:content 自己是描边面,整块淡下去边也跟着淡 */
|
|
179
|
+
[data-scope='listbox'][data-part='content'][aria-busy='true'] [data-scope='listbox']:is([data-part='item'], [data-part='group-label']) {
|
|
180
|
+
opacity: var(--xh-state-disabled-opacity);
|
|
172
181
|
}
|
|
173
182
|
|
|
174
183
|
[data-scope='listbox'][data-part='group-label'][hidden] {
|
|
@@ -185,7 +194,7 @@
|
|
|
185
194
|
display: block;
|
|
186
195
|
padding-block: var(--xh-listbox-empty-py, var(--xh-space-3));
|
|
187
196
|
padding-inline: var(--xh-listbox-empty-px, var(--xh-_listbox-item-px));
|
|
188
|
-
color: var(--xh-listbox-empty-fg, var(--xh-fg-
|
|
197
|
+
color: var(--xh-listbox-empty-fg, var(--xh-fg-muted));
|
|
189
198
|
font-size: var(--xh-listbox-empty-font-size, var(--xh-_listbox-font-size));
|
|
190
199
|
line-height: var(--xh-leading-none);
|
|
191
200
|
text-align: center;
|
|
@@ -202,10 +211,13 @@
|
|
|
202
211
|
|
|
203
212
|
/* 在途占位:与空态占位同一个位置、同一副观感,两者不同屏 */
|
|
204
213
|
[data-scope='listbox'][data-part='loading'] {
|
|
205
|
-
display:
|
|
214
|
+
display: flex;
|
|
215
|
+
align-items: center;
|
|
216
|
+
justify-content: center;
|
|
217
|
+
gap: var(--xh-_listbox-gap);
|
|
206
218
|
padding-block: var(--xh-listbox-loading-py, var(--xh-space-3));
|
|
207
219
|
padding-inline: var(--xh-listbox-loading-px, var(--xh-_listbox-item-px));
|
|
208
|
-
color: var(--xh-listbox-loading-fg, var(--xh-fg-
|
|
220
|
+
color: var(--xh-listbox-loading-fg, var(--xh-fg-muted));
|
|
209
221
|
font-size: var(--xh-listbox-loading-font-size, var(--xh-_listbox-font-size));
|
|
210
222
|
line-height: var(--xh-leading-none);
|
|
211
223
|
text-align: center;
|
|
@@ -215,6 +227,15 @@
|
|
|
215
227
|
display: none;
|
|
216
228
|
}
|
|
217
229
|
|
|
230
|
+
/* 首次加载:文案前一枚加载环,由加载环配方画(连接层投影 data-xh-loading-ring 与 data-loading),
|
|
231
|
+
直径取所在尺寸档的图标档 */
|
|
232
|
+
[data-scope='listbox'][data-part='loading']::before {
|
|
233
|
+
content: '';
|
|
234
|
+
flex: none;
|
|
235
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
|
|
236
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
|
|
237
|
+
}
|
|
238
|
+
|
|
218
239
|
/* 取下一页的按钮:铺满一行摆在列表尾——铺满一行的独立动作条目,接 Action Control 的 row 档、
|
|
219
240
|
ghost 形态:宽度由容器给、高度随内容、按下只换面不缩放;盒几何、悬停 / 按下 / 禁用面、
|
|
220
241
|
焦点环与粗指针热区全由家族给,白底承载 hover 100 → pressed 200。
|
|
@@ -250,7 +271,7 @@
|
|
|
250
271
|
--xh-collection-inline-padding: var(--xh-listbox-item-px, var(--xh-_listbox-item-px));
|
|
251
272
|
--xh-collection-gap: var(--xh-listbox-item-gap, var(--xh-_listbox-gap));
|
|
252
273
|
--xh-collection-font-size: var(--xh-listbox-item-font-size, var(--xh-_listbox-font-size));
|
|
253
|
-
--xh-collection-radius: var(--xh-listbox-item-radius, var(--xh-shape-
|
|
274
|
+
--xh-collection-radius: var(--xh-listbox-item-radius, var(--xh-shape-inset));
|
|
254
275
|
/* 作者的图标尺槽经桥接槽下发到条目,家族缺省按 data-xh-collection-size 取档 */
|
|
255
276
|
--xh-collection-glyph-size: var(--xh-listbox-icon-size, var(--xh-_collection-glyph-size));
|
|
256
277
|
--xh-collection-fg-rest: var(--xh-listbox-item-fg, var(--xh-fg-default));
|
|
@@ -347,4 +368,23 @@
|
|
|
347
368
|
print-color-adjust: exact;
|
|
348
369
|
}
|
|
349
370
|
}
|
|
371
|
+
|
|
372
|
+
@media (forced-colors: active) {
|
|
373
|
+
/* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
|
|
374
|
+
字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
|
|
375
|
+
条目面上取 CanvasText;按下与没被高亮时的悬停,家族把条目涂成 Highlight,字形换 HighlightText;
|
|
376
|
+
禁用取 GrayText */
|
|
377
|
+
[data-scope='listbox'][data-part='item-indicator']:empty::before {
|
|
378
|
+
forced-color-adjust: none;
|
|
379
|
+
background-color: CanvasText;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
[data-scope='listbox'][data-part='item']:not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error]):is(:active, [data-pressed], :hover:not(:focus-visible, [data-highlighted])) [data-scope='listbox'][data-part='item-indicator']:empty::before {
|
|
383
|
+
background-color: HighlightText;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
[data-scope='listbox'][data-part='item']:is([aria-disabled='true'], [data-disabled]) [data-scope='listbox'][data-part='item-indicator']:empty::before {
|
|
387
|
+
background-color: GrayText;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
350
390
|
}
|
package/css/loading-bar.css
CHANGED
|
@@ -40,11 +40,12 @@
|
|
|
40
40
|
display: none;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
/*
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
/* 走满之后才淡出:complete 期间根节点保持不透明,进度段冲到头的平移播完,机器才进 finishing。
|
|
44
|
+
满格先停一拍(延迟一个 micro)再淡:用户要看清「走完了」,一到头就开始淡读起来像中途断掉。
|
|
45
|
+
机器等的是浏览器实际起播的这段过渡(含延迟),不按毫秒猜 */
|
|
46
46
|
[data-scope='loading-bar'][data-part='root'][data-state='finishing'] {
|
|
47
47
|
opacity: 0;
|
|
48
|
+
transition-delay: var(--xh-motion-duration-micro);
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/* 背景槽。默认透明:顶部加载条通常直接压在页面顶边上,一条贯穿整屏的浅色底
|
|
@@ -57,17 +58,24 @@
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
61
|
+
* 进度段。铺满轨道,按连接层交出的比例往行首平移、由轨道裁掉:推进只走合成,
|
|
62
|
+
* 不重排也不重绘;末端的亮边跟着它一起走。背景色不走内联:要别的颜色改 --xh-loading-bar-range 这个槽,或者换语气。
|
|
62
63
|
*
|
|
63
64
|
* 语气取装饰档 --xh-_tone-soft:那一档压在画布上够 3:1,细带才看得出来。
|
|
64
65
|
* 槽位由 root 上的 data-tone 声明,继承下来。
|
|
65
66
|
* 没写 data-tone 时该槽没被声明,退回原来的品牌色。
|
|
66
67
|
*/
|
|
67
68
|
[data-scope='loading-bar'][data-part='range'] {
|
|
69
|
+
inline-size: 100%;
|
|
68
70
|
block-size: 100%;
|
|
69
71
|
background: var(--xh-loading-bar-range, var(--xh-_tone-soft, var(--xh-bg-brand)));
|
|
70
|
-
|
|
72
|
+
translate: calc((var(--xh-_loading-bar-value, 0) - 1) * 100%) 0;
|
|
73
|
+
transition: translate var(--xh-loading-bar-speed, var(--xh-motion-duration-move)) var(--xh-motion-ease-continuous);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* translate 只认物理方向:RTL 下行首在右边,平移方向翻转 */
|
|
77
|
+
[data-scope='loading-bar'][data-part='range']:dir(rtl) {
|
|
78
|
+
translate: calc((1 - var(--xh-_loading-bar-value, 0)) * 100%) 0;
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
/* 渲染了亮边才把进度段变成定位面:亮边贴在它的末端 */
|
|
@@ -94,7 +102,7 @@
|
|
|
94
102
|
);
|
|
95
103
|
}
|
|
96
104
|
|
|
97
|
-
/*
|
|
105
|
+
/* 条子还没起步时亮边一起收着:进度为 0 的末端不该先亮出一道边 */
|
|
98
106
|
[data-scope='loading-bar'][data-part='peg'][data-state='idle'] {
|
|
99
107
|
opacity: 0;
|
|
100
108
|
}
|
|
@@ -103,19 +111,25 @@
|
|
|
103
111
|
display: none;
|
|
104
112
|
}
|
|
105
113
|
|
|
106
|
-
/*
|
|
107
|
-
|
|
114
|
+
/* 减少动效:作者写进两个时长槽的值不作数,退回令牌——进度段的平移随几何时长立刻到位,
|
|
115
|
+
收尾的淡出保留减弱档的那一小段。一条按 200ms 一拍持续推进的带子正是最容易引发不适的那种动效。
|
|
108
116
|
两条规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
|
|
109
117
|
@media (prefers-reduced-motion: reduce) {
|
|
110
|
-
[data-scope='loading-bar'][data-part='root']
|
|
118
|
+
[data-scope='loading-bar'][data-part='root'] {
|
|
119
|
+
transition-duration: var(--xh-motion-duration-exit);
|
|
120
|
+
}
|
|
121
|
+
|
|
111
122
|
[data-scope='loading-bar'][data-part='range'] {
|
|
112
|
-
transition:
|
|
123
|
+
transition-duration: var(--xh-motion-duration-move);
|
|
113
124
|
}
|
|
114
125
|
}
|
|
115
126
|
|
|
116
|
-
:where([data-motion='reduce']) [data-scope='loading-bar'][data-part='root']
|
|
127
|
+
:where([data-motion='reduce']) [data-scope='loading-bar'][data-part='root'] {
|
|
128
|
+
transition-duration: var(--xh-motion-duration-exit);
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
:where([data-motion='reduce']) [data-scope='loading-bar'][data-part='range'] {
|
|
118
|
-
transition:
|
|
132
|
+
transition-duration: var(--xh-motion-duration-move);
|
|
119
133
|
}
|
|
120
134
|
|
|
121
135
|
@media print {
|