@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.
- package/CHANGELOG.md +2177 -0
- package/README.md +1 -1
- package/css/accordion.css +80 -6
- package/css/alert.css +43 -14
- package/css/anchor.css +8 -8
- package/css/avatar-group.css +7 -3
- package/css/avatar.css +9 -3
- package/css/back-top.css +22 -1
- package/css/badge.css +104 -32
- package/css/breadcrumb.css +25 -5
- package/css/button-group.css +18 -13
- package/css/button.css +48 -11
- package/css/calendar.css +150 -7
- package/css/card.css +20 -11
- package/css/carousel.css +36 -5
- package/css/cascader.css +211 -124
- package/css/checkbox-group.css +72 -22
- package/css/checkbox.css +70 -13
- package/css/clipboard.css +2 -1
- package/css/code-block.css +12 -7
- package/css/collapsible.css +49 -3
- package/css/color-picker.css +132 -46
- package/css/combobox.css +132 -60
- package/css/composer.css +5 -3
- package/css/context-menu.css +113 -74
- package/css/date-field.css +93 -16
- package/css/date-picker.css +293 -72
- package/css/descriptions.css +11 -5
- package/css/dialog.css +47 -14
- package/css/download-trigger.css +76 -0
- package/css/drawer.css +57 -16
- package/css/dynamic-input.css +75 -17
- package/css/editable.css +12 -10
- package/css/ellipsis.css +7 -1
- package/css/empty-state.css +22 -12
- package/css/field.css +16 -6
- package/css/fieldset.css +69 -0
- package/css/file-upload.css +46 -8
- package/css/flex.css +13 -7
- package/css/float-button.css +23 -1
- package/css/floating-panel.css +316 -0
- package/css/form.css +4 -4
- package/css/grid.css +11 -5
- package/css/heatmap.css +411 -0
- package/css/highlight.css +2 -2
- package/css/hotkeys.css +90 -0
- package/css/hover-card.css +43 -45
- package/css/image-cropper.css +233 -0
- package/css/image-viewer.css +155 -17
- package/css/image.css +2 -2
- package/css/infinite-scroll.css +1 -1
- package/css/json-viewer.css +274 -0
- package/css/layout.css +19 -15
- package/css/list.css +22 -13
- package/css/listbox.css +24 -6
- package/css/loading-bar.css +12 -5
- package/css/log.css +7 -3
- package/css/marquee.css +9 -0
- package/css/masonry.css +63 -0
- package/css/mention.css +100 -36
- package/css/menu.css +127 -50
- package/css/menubar.css +155 -61
- package/css/navigation-menu.css +56 -31
- package/css/notification.css +377 -0
- package/css/number-animation.css +3 -3
- package/css/number-field.css +182 -19
- package/css/overlay-arrow.css +51 -0
- package/css/page-header.css +12 -5
- package/css/pagination.css +171 -14
- package/css/password-input.css +356 -0
- package/css/pin-input.css +15 -12
- package/css/popconfirm.css +55 -12
- package/css/popover.css +73 -45
- package/css/popselect.css +207 -57
- package/css/progress.css +54 -8
- package/css/qr-code.css +1 -1
- package/css/radio-group.css +27 -10
- package/css/rating.css +4 -4
- package/css/reset.css +17 -0
- package/css/result.css +21 -11
- package/css/scroll-area.css +61 -89
- package/css/scrollbar.css +170 -0
- package/css/segmented.css +215 -0
- package/css/select.css +298 -131
- package/css/separator.css +2 -2
- package/css/side-nav.css +127 -24
- package/css/signature-pad.css +144 -0
- package/css/skeleton.css +7 -1
- package/css/slider.css +14 -12
- package/css/space.css +117 -0
- package/css/spinner.css +22 -10
- package/css/statistic.css +9 -9
- package/css/steps.css +29 -12
- package/css/switch.css +57 -8
- package/css/table.css +146 -44
- package/css/tabs.css +13 -5
- package/css/tag.css +179 -0
- package/css/tags-input.css +80 -42
- package/css/text-field.css +151 -38
- package/css/thread.css +11 -3
- package/css/time-field.css +99 -18
- package/css/time-picker.css +261 -71
- package/css/timeline.css +15 -15
- package/css/timer.css +119 -0
- package/css/toast.css +129 -55
- package/css/toggle-group.css +30 -4
- package/css/toggle.css +12 -6
- package/css/tone.css +57 -22
- package/css/toolbar.css +1 -1
- package/css/tooltip.css +40 -31
- package/css/tour.css +112 -61
- package/css/transfer.css +98 -21
- package/css/tree-select.css +215 -89
- package/css/tree.css +131 -5
- package/css/typography.css +5 -5
- package/css/undefined.css +12 -1
- package/css/virtualizer.css +3 -1
- package/css/watermark.css +1 -2
- package/index.css +18 -1
- package/index.unlayered.css +10356 -3255
- package/package.json +20 -4
- package/css/toaster.css +0 -74
package/css/progress.css
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
@layer xihan.motion {
|
|
2
|
+
/* 动画名的查找只认「文档里有没有这个名字」:引用别处文件里的名字,那份文件不一定在场,
|
|
3
|
+
动画会静默地整个不跑。每份皮肤都能单独引入,所以它用到的关键帧都写在自己身上。 */
|
|
4
|
+
@keyframes xh-progress-indeterminate {
|
|
5
|
+
from {
|
|
6
|
+
inset-inline-start: -40%;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
to {
|
|
10
|
+
inset-inline-start: 100%;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
@layer xihan.components {
|
|
2
16
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
17
|
[data-scope='progress'] {
|
|
@@ -7,7 +21,7 @@
|
|
|
7
21
|
/* 私有槽位:组件令牌 → 中档字面量两级回退。厚度写在 root 上而不是 track 上,
|
|
8
22
|
尺寸档才改得动一处就够,track 靠继承拿到值。 */
|
|
9
23
|
[data-scope='progress'][data-part='root'] {
|
|
10
|
-
--xh-_thickness: var(--xh-progress-thickness,
|
|
24
|
+
--xh-_thickness: var(--xh-progress-thickness, var(--xh-track-thickness));
|
|
11
25
|
|
|
12
26
|
display: inline-block;
|
|
13
27
|
inline-size: 100%;
|
|
@@ -17,7 +31,7 @@
|
|
|
17
31
|
overflow: hidden;
|
|
18
32
|
inline-size: 100%;
|
|
19
33
|
block-size: var(--xh-_thickness);
|
|
20
|
-
border-radius: var(--xh-shape-pill);
|
|
34
|
+
border-radius: var(--xh-progress-track-radius, var(--xh-shape-pill));
|
|
21
35
|
background: var(--xh-progress-track, var(--xh-bg-subtle-active));
|
|
22
36
|
}
|
|
23
37
|
|
|
@@ -25,7 +39,7 @@
|
|
|
25
39
|
轨道不跟着换族:只有已完成的那段换色,底槽保持中性才读得出"完成了多少"。 */
|
|
26
40
|
[data-scope='progress'][data-part='range'] {
|
|
27
41
|
block-size: 100%;
|
|
28
|
-
border-radius: var(--xh-shape-pill);
|
|
42
|
+
border-radius: var(--xh-progress-range-radius, var(--xh-shape-pill));
|
|
29
43
|
background: var(--xh-progress-range, var(--xh-_tone, var(--xh-bg-brand)));
|
|
30
44
|
transition: inline-size var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
31
45
|
}
|
|
@@ -95,15 +109,47 @@
|
|
|
95
109
|
transition: stroke-dashoffset var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
96
110
|
}
|
|
97
111
|
|
|
112
|
+
/* 进度未知:线形条改为一小段来回扫。宽度交给动画,连接层算出的 inline-size 与
|
|
113
|
+
那条过渡都得让开,否则每帧都在跟动画抢同一个属性 */
|
|
114
|
+
[data-scope='progress'][data-part='track'][data-state='indeterminate'] {
|
|
115
|
+
position: relative;
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
[data-scope='progress'][data-part='range'][data-state='indeterminate'] {
|
|
120
|
+
position: absolute;
|
|
121
|
+
inline-size: 40%;
|
|
122
|
+
transition: none;
|
|
123
|
+
animation: xh-progress-indeterminate var(--xh-progress-indeterminate-duration, calc(var(--xh-spin-duration) * 2)) var(--xh-ease-standard) infinite;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* 减弱动效档:不来回扫,改成一条铺满的静态条——进度仍然未知,只是不再动。
|
|
127
|
+
两条规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
|
|
128
|
+
@media (prefers-reduced-motion: reduce) {
|
|
129
|
+
[data-scope='progress'][data-part='range'][data-state='indeterminate'] {
|
|
130
|
+
position: static;
|
|
131
|
+
inline-size: 100%;
|
|
132
|
+
opacity: 0.5;
|
|
133
|
+
animation: none;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
:where([data-motion='reduce']) [data-scope='progress'][data-part='range'][data-state='indeterminate'] {
|
|
138
|
+
position: static;
|
|
139
|
+
inline-size: 100%;
|
|
140
|
+
opacity: 0.5;
|
|
141
|
+
animation: none;
|
|
142
|
+
}
|
|
143
|
+
|
|
98
144
|
/* 零进度:圆角端点会在长度为 0 处画出一个圆点,收掉它 */
|
|
99
145
|
[data-scope='progress'][data-part='range'][data-empty] {
|
|
100
146
|
visibility: hidden;
|
|
101
147
|
}
|
|
102
148
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
149
|
+
|
|
150
|
+
/* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
|
|
151
|
+
写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
|
|
152
|
+
[data-scope='progress'][data-part='root'][hidden] {
|
|
153
|
+
display: none;
|
|
108
154
|
}
|
|
109
155
|
}
|
package/css/qr-code.css
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
[data-scope='qr-code'][data-part='root'] {
|
|
19
19
|
display: block;
|
|
20
|
-
border-radius: var(--xh-qr-code-radius, var(--xh-
|
|
20
|
+
border-radius: var(--xh-qr-code-radius, var(--xh-shape-control));
|
|
21
21
|
background: var(--xh-qr-code-bg, var(--xh-color-neutral-0));
|
|
22
22
|
|
|
23
23
|
/* 模块那条 path 不带自己的填充色,从这里继承下去 */
|
package/css/radio-group.css
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
[data-scope='radio-group'][data-part='root'] {
|
|
8
8
|
/* 尺寸档只换这两个私有槽,标题与条目都从 root 继承它们,换档不必给每个部件各写一条选择器 */
|
|
9
9
|
--xh-_radio-group-item-gap: var(--xh-control-gap-md);
|
|
10
|
-
--xh-_radio-group-font-size: var(--xh-
|
|
10
|
+
--xh-_radio-group-font-size: var(--xh-control-font-md);
|
|
11
|
+
--xh-_radio-group-indicator: var(--xh-control-indicator-md);
|
|
11
12
|
/* 选中色随语气走。没写 data-tone 时 --xh-_tone 没被声明,退回原来的品牌色 */
|
|
12
13
|
--xh-_radio-group-accent: var(--xh-_tone, var(--xh-bg-brand));
|
|
13
14
|
|
|
@@ -27,12 +28,14 @@
|
|
|
27
28
|
/* —— 尺寸 —— */
|
|
28
29
|
[data-scope='radio-group'][data-part='root'][data-size='sm'] {
|
|
29
30
|
--xh-_radio-group-item-gap: var(--xh-control-gap-sm);
|
|
30
|
-
--xh-_radio-group-font-size: var(--xh-font-
|
|
31
|
+
--xh-_radio-group-font-size: var(--xh-control-font-sm);
|
|
32
|
+
--xh-_radio-group-indicator: var(--xh-control-indicator-sm);
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
[data-scope='radio-group'][data-part='root'][data-size='lg'] {
|
|
34
36
|
--xh-_radio-group-item-gap: var(--xh-control-gap-lg);
|
|
35
|
-
--xh-_radio-group-font-size: var(--xh-font-
|
|
37
|
+
--xh-_radio-group-font-size: var(--xh-control-font-lg);
|
|
38
|
+
--xh-_radio-group-indicator: var(--xh-control-indicator-lg);
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
[data-scope='radio-group'][data-part='label'] {
|
|
@@ -64,7 +67,6 @@
|
|
|
64
67
|
[data-scope='radio-group'][data-part='item'][data-disabled] {
|
|
65
68
|
color: var(--xh-radio-group-item-fg-disabled, var(--xh-fg-disabled));
|
|
66
69
|
cursor: not-allowed;
|
|
67
|
-
opacity: var(--xh-state-disabled-opacity);
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
[data-scope='radio-group'][data-part='indicator'] {
|
|
@@ -72,10 +74,10 @@
|
|
|
72
74
|
flex: none;
|
|
73
75
|
align-items: center;
|
|
74
76
|
justify-content: center;
|
|
75
|
-
inline-size:
|
|
76
|
-
block-size:
|
|
77
|
+
inline-size: var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator));
|
|
78
|
+
block-size: var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator));
|
|
77
79
|
border: var(--xh-stroke-thin) solid var(--xh-radio-group-indicator-border, var(--xh-border-control));
|
|
78
|
-
border-radius: var(--xh-shape-pill);
|
|
80
|
+
border-radius: var(--xh-radio-group-indicator-radius, var(--xh-shape-pill));
|
|
79
81
|
background: var(--xh-radio-group-indicator-bg, var(--xh-bg-canvas));
|
|
80
82
|
transition: border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
81
83
|
}
|
|
@@ -84,11 +86,18 @@
|
|
|
84
86
|
border-color: var(--xh-radio-group-indicator-border-checked, var(--xh-_radio-group-accent));
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
/*
|
|
89
|
+
/* 校验失败:圆圈描边转警示色,压在 checked 规则之后 */
|
|
90
|
+
[data-scope='radio-group'][data-part='indicator'][data-invalid],
|
|
91
|
+
[data-scope='radio-group'][data-part='indicator'][data-state='checked'][data-invalid] {
|
|
92
|
+
border-color: var(--xh-radio-group-indicator-border-invalid, var(--xh-border-invalid));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* 圆点用 scale 收放,选中态切换不引起布局抖动。
|
|
96
|
+
直径取指示器的一半:换尺寸档时圈与点一起走,比例不散 */
|
|
88
97
|
[data-scope='radio-group'][data-part='indicator']::before {
|
|
89
98
|
content: '';
|
|
90
|
-
inline-size:
|
|
91
|
-
block-size:
|
|
99
|
+
inline-size: calc(var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator)) / 2);
|
|
100
|
+
block-size: calc(var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator)) / 2);
|
|
92
101
|
border-radius: var(--xh-shape-pill);
|
|
93
102
|
background: var(--xh-radio-group-indicator-dot, var(--xh-_radio-group-accent));
|
|
94
103
|
scale: 0;
|
|
@@ -103,4 +112,12 @@
|
|
|
103
112
|
color: inherit;
|
|
104
113
|
user-select: none;
|
|
105
114
|
}
|
|
115
|
+
|
|
116
|
+
/* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
|
|
117
|
+
写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
|
|
118
|
+
[data-scope='radio-group'][data-part='root'][hidden],
|
|
119
|
+
[data-scope='radio-group'][data-part='item'][hidden],
|
|
120
|
+
[data-scope='radio-group'][data-part='indicator'][hidden] {
|
|
121
|
+
display: none;
|
|
122
|
+
}
|
|
106
123
|
}
|
package/css/rating.css
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
根上不留基准它就会贴到更外层的定位祖先上,原生校验提示跟着飘到页面别处。 */
|
|
9
9
|
[data-scope='rating'][data-part='root'] {
|
|
10
10
|
/* 尺寸档只换这三个私有槽,标题与星星都从 root 继承它们,换档不必给每个部件各写一条选择器 */
|
|
11
|
-
--xh-_rating-item-gap: var(--xh-
|
|
11
|
+
--xh-_rating-item-gap: var(--xh-control-gap-md);
|
|
12
12
|
--xh-_rating-item-size: var(--xh-font-size-2xl);
|
|
13
|
-
--xh-_rating-font-size: var(--xh-
|
|
13
|
+
--xh-_rating-font-size: var(--xh-control-font-md);
|
|
14
14
|
/* 点亮色随语气走。没写 data-tone 时 --xh-_tone 没被声明,退回原来的警示色 */
|
|
15
15
|
--xh-_rating-accent: var(--xh-_tone, var(--xh-color-warning-500));
|
|
16
16
|
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
[data-scope='rating'][data-part='root'][data-size='sm'] {
|
|
25
25
|
--xh-_rating-item-gap: var(--xh-control-gap-sm);
|
|
26
26
|
--xh-_rating-item-size: var(--xh-font-size-xl);
|
|
27
|
-
--xh-_rating-font-size: var(--xh-font-
|
|
27
|
+
--xh-_rating-font-size: var(--xh-control-font-sm);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
[data-scope='rating'][data-part='root'][data-size='lg'] {
|
|
31
31
|
--xh-_rating-item-gap: var(--xh-control-gap-lg);
|
|
32
32
|
--xh-_rating-item-size: var(--xh-font-size-3xl);
|
|
33
|
-
--xh-_rating-font-size: var(--xh-font-
|
|
33
|
+
--xh-_rating-font-size: var(--xh-control-font-lg);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/* 整体压暗只做一次,落在最外层:星星逐颗再叠 opacity 会越叠越黑 */
|
package/css/reset.css
CHANGED
|
@@ -19,4 +19,21 @@
|
|
|
19
19
|
font: inherit;
|
|
20
20
|
letter-spacing: inherit;
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* 浮层定位层的生命周期契约:落位才露。
|
|
25
|
+
*
|
|
26
|
+
* 坐标依赖浮层自己的尺寸,尺寸要等元素进 DOM 参与排版才量得到,所以浮层一定先渲染、
|
|
27
|
+
* 再量、再定位——展开的那几帧坐标还是兜底的 0。默认藏着,连接层算出坐标后打
|
|
28
|
+
* data-positioned 才显示,忘了接线的新浮层只会不显示,不会先在视口左上角闪一帧。
|
|
29
|
+
* 用 visibility 而不是 display:display:none 会让浮层退出排版,引擎量不到它的尺寸。
|
|
30
|
+
* 锚点被滚出可视区时引擎置 hidden,各皮肤另有一条 [data-hidden] 压回去。
|
|
31
|
+
*/
|
|
32
|
+
[data-scope][data-part='positioner'] {
|
|
33
|
+
visibility: hidden;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
[data-scope][data-part='positioner'][data-positioned] {
|
|
37
|
+
visibility: visible;
|
|
38
|
+
}
|
|
22
39
|
}
|
package/css/result.css
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
/* 三个尺寸档只换这几个私有槽,图标与标题都从 root 继承它们,
|
|
9
9
|
换档不必给每个部件各写一条选择器 */
|
|
10
10
|
--xh-_result-gap: var(--xh-stack-gap-md);
|
|
11
|
-
--xh-_result-py: var(--xh-section-py);
|
|
12
|
-
--xh-_result-icon-size:
|
|
13
|
-
--xh-_result-title-size: var(--xh-
|
|
11
|
+
--xh-_result-py: var(--xh-section-py-md);
|
|
12
|
+
--xh-_result-icon-size: var(--xh-glyph-size-3xl);
|
|
13
|
+
--xh-_result-title-size: var(--xh-text-heading-3-size);
|
|
14
14
|
/* 说明的读行宽度:整句话不收窄就会拉成一条难读的长行 */
|
|
15
15
|
--xh-_result-measure: 32rem;
|
|
16
16
|
/* 图标区的语气色,由 data-status 换掉;没写 status 就退成中性 */
|
|
@@ -34,17 +34,17 @@
|
|
|
34
34
|
|
|
35
35
|
/* —— 尺寸 —— */
|
|
36
36
|
[data-scope='result'][data-part='root'][data-size='sm'] {
|
|
37
|
-
--xh-_result-gap: var(--xh-
|
|
38
|
-
--xh-_result-py: var(--xh-
|
|
39
|
-
--xh-_result-icon-size:
|
|
40
|
-
--xh-_result-title-size: var(--xh-font-
|
|
37
|
+
--xh-_result-gap: var(--xh-stack-gap-sm);
|
|
38
|
+
--xh-_result-py: var(--xh-section-py-sm);
|
|
39
|
+
--xh-_result-icon-size: var(--xh-glyph-size-2xl);
|
|
40
|
+
--xh-_result-title-size: var(--xh-control-font-lg);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
[data-scope='result'][data-part='root'][data-size='lg'] {
|
|
44
|
-
--xh-_result-gap: var(--xh-
|
|
45
|
-
--xh-_result-py: var(--xh-
|
|
46
|
-
--xh-_result-icon-size:
|
|
47
|
-
--xh-_result-title-size: var(--xh-
|
|
44
|
+
--xh-_result-gap: var(--xh-stack-gap-lg);
|
|
45
|
+
--xh-_result-py: var(--xh-section-py-lg);
|
|
46
|
+
--xh-_result-icon-size: var(--xh-glyph-size-4xl);
|
|
47
|
+
--xh-_result-title-size: var(--xh-text-heading-2-size);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/* —— 语气 —— */
|
|
@@ -75,6 +75,9 @@
|
|
|
75
75
|
align-items: center;
|
|
76
76
|
justify-content: center;
|
|
77
77
|
flex: none;
|
|
78
|
+
/* 作者塞进图标槽的 XhIcon 与皮肤画的字形同一把尺,都按展示档的图标框量 */
|
|
79
|
+
--xh-icon-size: var(--xh-result-icon-size, var(--xh-_result-icon-size));
|
|
80
|
+
|
|
78
81
|
block-size: var(--xh-result-icon-size, var(--xh-_result-icon-size));
|
|
79
82
|
inline-size: var(--xh-result-icon-size, var(--xh-_result-icon-size));
|
|
80
83
|
color: var(--xh-result-icon-fg, var(--xh-_result-accent));
|
|
@@ -106,4 +109,11 @@
|
|
|
106
109
|
justify-content: center;
|
|
107
110
|
gap: var(--xh-result-action-gap, var(--xh-space-2));
|
|
108
111
|
}
|
|
112
|
+
|
|
113
|
+
/* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
|
|
114
|
+
写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
|
|
115
|
+
[data-scope='result'][data-part='icon'][hidden],
|
|
116
|
+
[data-scope='result'][data-part='action'][hidden] {
|
|
117
|
+
display: none;
|
|
118
|
+
}
|
|
109
119
|
}
|
package/css/scroll-area.css
CHANGED
|
@@ -1,37 +1,30 @@
|
|
|
1
|
-
@layer xihan.motion {
|
|
2
|
-
/* 滚动条从收起到露出的淡入。收起走的是 [hidden](display:none),没有退场动画可言——
|
|
3
|
-
display:none 是瞬时的,硬挂 fade-out 只会看到一帧都不播。
|
|
4
|
-
元素从 display:none 变回可见时动画会重新开始,这一条因此每次露面都播一遍。 */
|
|
5
|
-
@keyframes xh-scroll-area-bar-in {
|
|
6
|
-
from {
|
|
7
|
-
opacity: 0;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
to {
|
|
11
|
-
opacity: 1;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
1
|
@layer xihan.components {
|
|
17
2
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
18
3
|
[data-scope='scroll-area'] {
|
|
19
4
|
--xh-scroll-area-skin: 1;
|
|
20
5
|
}
|
|
21
6
|
|
|
22
|
-
/*
|
|
23
|
-
|
|
24
|
-
这份皮肤一个都不碰:内联优先级高于样式表,写了不但是死声明,
|
|
25
|
-
换轴的那一帧还会跟连接层清空另一轴的动作抢位置,把滑块钉在两轴都被约束的地方。
|
|
26
|
-
皮肤只管另一条轴(交叉轴)的尺寸、颜色、圆角与状态表现。 */
|
|
7
|
+
/* 滚动区是视口加两条 scrollbar 的组装:轨道、滑块与交叉口戴 data-scope="scrollbar",
|
|
8
|
+
它们的皮归 scrollbar.css;这里只管视口、内容层,以及充当 scrollbar 根节点的那个挂载点。 */
|
|
27
9
|
|
|
28
|
-
/*
|
|
10
|
+
/* 滚动条是绝对定位的,以它为参照,因此它必须自己建定位上下文。
|
|
29
11
|
overflow:hidden 管的是溢出边界:作者给 root 定了尺寸后,内容与滚动条都不该漫出这个框。 */
|
|
30
12
|
[data-scope='scroll-area'][data-part='root'] {
|
|
13
|
+
/* 厚度只算一次:尺寸档换的就是它,视口让道、交叉口让位与补丁都按同一个数 */
|
|
14
|
+
--xh-_scrollbar-thickness: var(--xh-scrollbar-thickness-md);
|
|
15
|
+
|
|
31
16
|
position: relative;
|
|
32
17
|
overflow: hidden;
|
|
33
18
|
}
|
|
34
19
|
|
|
20
|
+
[data-scope='scroll-area'][data-part='root'][data-size='sm'] {
|
|
21
|
+
--xh-_scrollbar-thickness: var(--xh-scrollbar-thickness-sm);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[data-scope='scroll-area'][data-part='root'][data-size='lg'] {
|
|
25
|
+
--xh-_scrollbar-thickness: var(--xh-scrollbar-thickness-lg);
|
|
26
|
+
}
|
|
27
|
+
|
|
35
28
|
/* 真正滚动的那层。原生滚动条藏起来,滚动能力一点不减——
|
|
36
29
|
键盘(PageUp/PageDown、方向键、Home/End)与滚轮走的都还是浏览器原生通路。 */
|
|
37
30
|
[data-scope='scroll-area'][data-part='viewport'] {
|
|
@@ -41,13 +34,17 @@
|
|
|
41
34
|
这两条是本文件里仅有的物理属性,换成逻辑写法会在多数浏览器上直接失效 */
|
|
42
35
|
overflow-x: auto;
|
|
43
36
|
overflow-y: auto;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* 藏原生滚动条的标准写法;下面那条 ::-webkit-scrollbar 兜住还没实现它的引擎。
|
|
40
|
+
只藏外观,滚动能力一点不动:这里刻意不写 overscroll-behavior,
|
|
41
|
+
滚到尽头要不要把滚动传给外层,仍然按浏览器的默认来。
|
|
42
|
+
触屏上自绘滚动条交给了原生(data-native),原生滚动条就留着 */
|
|
43
|
+
[data-scope='scroll-area'][data-part='viewport']:not([data-native]) {
|
|
47
44
|
scrollbar-width: none;
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
[data-scope='scroll-area'][data-part='viewport']::-webkit-scrollbar {
|
|
47
|
+
[data-scope='scroll-area'][data-part='viewport']:not([data-native])::-webkit-scrollbar {
|
|
51
48
|
/* 这里不是角色节点而是伪元素,不涉及 [hidden] 那条规矩 */
|
|
52
49
|
display: none;
|
|
53
50
|
}
|
|
@@ -69,14 +66,13 @@
|
|
|
69
66
|
}
|
|
70
67
|
|
|
71
68
|
/* 有滚动条要占道时,视口在那条轴上收窄一条道的宽度,末端内容不再被压在滚动条底下。
|
|
72
|
-
缩视口而不是给视口加内边距:滚动容器末端缘的 padding 计不计进 scrollWidth,各引擎不一致。
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
inline-size: calc(100% - var(--xh-scroll-area-bar-size, 10px));
|
|
69
|
+
缩视口而不是给视口加内边距:滚动容器末端缘的 padding 计不计进 scrollWidth,各引擎不一致。 */
|
|
70
|
+
[data-scope='scroll-area'][data-part='viewport'][data-lane-vertical] {
|
|
71
|
+
inline-size: calc(100% - var(--xh-_scrollbar-thickness));
|
|
76
72
|
}
|
|
77
73
|
|
|
78
|
-
[data-scope='scroll-area'][data-part='
|
|
79
|
-
block-size: calc(100% - var(--xh-
|
|
74
|
+
[data-scope='scroll-area'][data-part='viewport'][data-lane-horizontal] {
|
|
75
|
+
block-size: calc(100% - var(--xh-_scrollbar-thickness));
|
|
80
76
|
}
|
|
81
77
|
|
|
82
78
|
/* 横向溢出全靠它撑:内容若跟着视口一起收成 100% 宽,横轴永远量不出溢出,
|
|
@@ -85,91 +81,67 @@
|
|
|
85
81
|
min-inline-size: fit-content;
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
/*
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
/* 滚动条挂载点同时充当那条 scrollbar 的根节点:scrollbar 那份皮肤的根规则落在
|
|
85
|
+
[data-scope='scrollbar'][data-part='root'] 上,而这里没有那个节点,根该有的排布得在这儿补齐
|
|
86
|
+
(轨道与滑块的皮仍归 scrollbar 那一份)。滑块主轴的起点与长度由连接层写进内联样式,这里不碰。 */
|
|
91
87
|
[data-scope='scroll-area'][data-part='scrollbar'] {
|
|
92
88
|
position: absolute;
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
/* touch-action 关掉浏览器自己的手势:不关的话手指一按滑块页面就跟着滚,
|
|
90
|
+
指针随即被系统收走(pointercancel),拖到一半的滑块停在原地。
|
|
91
|
+
user-select 同理——拖动时选中页面文字会让滑块"粘"住。 */
|
|
95
92
|
touch-action: none;
|
|
96
93
|
user-select: none;
|
|
94
|
+
/* 露出与收起都淡变;收起态连 visibility 一起收,退场播完才真正摸不到 */
|
|
95
|
+
transition:
|
|
96
|
+
opacity var(--xh-motion-duration-enter) var(--xh-motion-ease-enter),
|
|
97
|
+
visibility 0s linear 0s;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
[data-scope='scroll-area'][data-part='scrollbar'][data-orientation='vertical'] {
|
|
100
101
|
inset-block: 0;
|
|
101
102
|
inset-inline-end: 0;
|
|
102
|
-
inline-size: var(--xh-
|
|
103
|
+
inline-size: var(--xh-_scrollbar-thickness);
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
[data-scope='scroll-area'][data-part='scrollbar'][data-orientation='horizontal'] {
|
|
106
107
|
inset-inline: 0;
|
|
107
108
|
inset-block-end: 0;
|
|
108
|
-
block-size: var(--xh-
|
|
109
|
+
block-size: var(--xh-_scrollbar-thickness);
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
/* 两条都在场:各自在末端让出交叉口那一格,交叉口由竖条里的 corner 补 */
|
|
113
|
+
[data-scope='scroll-area'][data-part='scrollbar'][data-orientation='vertical'][data-gutter] {
|
|
114
|
+
inset-block-end: var(--xh-_scrollbar-thickness);
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
[data-scope='scroll-area'][data-part='root']:focus-visible,
|
|
118
|
-
[data-scope='scroll-area'][data-part='content']:focus-visible,
|
|
119
|
-
[data-scope='scroll-area'][data-part='scrollbar']:focus-visible,
|
|
120
|
-
[data-scope='scroll-area'][data-part='corner']:focus-visible {
|
|
121
|
-
outline: none;
|
|
117
|
+
[data-scope='scroll-area'][data-part='scrollbar'][data-orientation='horizontal'][data-gutter] {
|
|
118
|
+
inset-inline-end: var(--xh-_scrollbar-thickness);
|
|
122
119
|
}
|
|
123
120
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
background: var(--xh-scroll-area-thumb-bg, var(--xh-color-neutral-400));
|
|
132
|
-
cursor: default;
|
|
133
|
-
transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
121
|
+
[data-scope='scroll-area'][data-part='scrollbar'][data-state='hidden'] {
|
|
122
|
+
visibility: hidden;
|
|
123
|
+
opacity: 0;
|
|
124
|
+
pointer-events: none;
|
|
125
|
+
transition:
|
|
126
|
+
opacity var(--xh-motion-duration-exit) var(--xh-motion-ease-exit),
|
|
127
|
+
visibility 0s linear var(--xh-motion-duration-exit);
|
|
134
128
|
}
|
|
135
129
|
|
|
136
|
-
/*
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
主轴那一侧一律不写:几何层量的轨道是 padding box,滑块长度也解析在同一个盒子上。 */
|
|
140
|
-
[data-scope='scroll-area'][data-part='thumb'][data-orientation='vertical'] {
|
|
141
|
-
inset-inline: var(--xh-scroll-area-bar-padding, 2px);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
[data-scope='scroll-area'][data-part='thumb'][data-orientation='horizontal'] {
|
|
145
|
-
inset-block: var(--xh-scroll-area-bar-padding, 2px);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
[data-scope='scroll-area'][data-part='thumb']:hover {
|
|
149
|
-
background: var(--xh-scroll-area-thumb-bg-hover, var(--xh-color-neutral-500));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/* 手正按在这条轴的滑块上时才变深:两条轴各有一个滑块,全打上标记就分不出手在哪一个上 */
|
|
153
|
-
[data-scope='scroll-area'][data-part='thumb'][data-dragging] {
|
|
154
|
-
background: var(--xh-scroll-area-thumb-bg-dragging, var(--xh-color-neutral-600));
|
|
130
|
+
/* 触屏上交给原生滚动:整条不占位也不画 */
|
|
131
|
+
[data-scope='scroll-area'][data-part='scrollbar'][data-native] {
|
|
132
|
+
display: none;
|
|
155
133
|
}
|
|
156
134
|
|
|
157
|
-
/*
|
|
158
|
-
|
|
159
|
-
[data-scope='scroll-area'][data-part='
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
inset-block-end: 0;
|
|
164
|
-
inset-inline-end: 0;
|
|
165
|
-
inline-size: var(--xh-scroll-area-bar-size, 10px);
|
|
166
|
-
block-size: var(--xh-scroll-area-bar-size, 10px);
|
|
167
|
-
background: var(--xh-scroll-area-corner-bg, var(--xh-bg-subtle));
|
|
135
|
+
/* 除视口外全是纯容器:既不进 Tab 序列也不承载焦点,作者若给它们加了 tabindex,
|
|
136
|
+
该显形的也该是视口那圈环,不是这里再多画一圈 */
|
|
137
|
+
[data-scope='scroll-area'][data-part='root']:focus-visible,
|
|
138
|
+
[data-scope='scroll-area'][data-part='content']:focus-visible,
|
|
139
|
+
[data-scope='scroll-area'][data-part='scrollbar']:focus-visible {
|
|
140
|
+
outline: none;
|
|
168
141
|
}
|
|
169
142
|
|
|
170
143
|
/* display 会盖掉 UA 的 [hidden]{display:none},凡是被赋了 display 的角色节点都要显式让位 */
|
|
171
|
-
[data-scope='scroll-area'][data-part='scrollbar'][hidden]
|
|
172
|
-
[data-scope='scroll-area'][data-part='corner'][hidden] {
|
|
144
|
+
[data-scope='scroll-area'][data-part='scrollbar'][hidden] {
|
|
173
145
|
display: none;
|
|
174
146
|
}
|
|
175
147
|
}
|