@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/tooltip.css
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
@layer xihan.motion {
|
|
2
2
|
/* 动画名的查找只认「文档里有没有这个名字」:引用别处文件里的名字,那份文件不一定在场,
|
|
3
3
|
动画会静默地整个不跑。每份皮肤都能单独引入,所以它用到的关键帧都写在自己身上。 */
|
|
4
|
-
@keyframes xh-
|
|
4
|
+
@keyframes xh-pop-in {
|
|
5
5
|
from {
|
|
6
6
|
opacity: 0;
|
|
7
|
+
scale: var(--xh-motion-scale-enter);
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
to {
|
|
10
11
|
opacity: 1;
|
|
12
|
+
scale: 1;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@keyframes xh-pop-out {
|
|
17
|
+
from {
|
|
18
|
+
opacity: 1;
|
|
19
|
+
scale: 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
to {
|
|
23
|
+
opacity: 0;
|
|
24
|
+
scale: var(--xh-motion-scale-enter);
|
|
11
25
|
}
|
|
12
26
|
}
|
|
13
27
|
}
|
|
@@ -40,7 +54,7 @@
|
|
|
40
54
|
position: fixed;
|
|
41
55
|
inset-block-start: 0;
|
|
42
56
|
inset-inline-start: 0;
|
|
43
|
-
z-index: var(--xh-layer-tooltip);
|
|
57
|
+
z-index: var(--xh-tooltip-layer, var(--xh-layer-tooltip));
|
|
44
58
|
/* 浮层不承载交互:指针必须能穿过去点到底下的东西 */
|
|
45
59
|
pointer-events: none;
|
|
46
60
|
}
|
|
@@ -55,25 +69,36 @@
|
|
|
55
69
|
箭头是它的后代,语气槽一并继承 */
|
|
56
70
|
--xh-_tooltip-py: var(--xh-space-1);
|
|
57
71
|
--xh-_tooltip-px: var(--xh-space-2);
|
|
58
|
-
--xh-_tooltip-font-size: var(--xh-
|
|
72
|
+
--xh-_tooltip-font-size: var(--xh-control-caption-md);
|
|
59
73
|
|
|
60
74
|
/* 与 positioner 相反:浮层本体要能接指针,指针停在提示上就不该收起
|
|
61
75
|
(长文案需要停留细看)。positioner 仍是 none,空白区域照样点得穿。 */
|
|
76
|
+
/* 显式声明 display 是为了盖掉 UA 的 [hidden]{display:none}:收起那一帧 content 仍带 hidden,
|
|
77
|
+
盒子得先在,退场动画才播得出来。真正的收起由宿主在退场结束后落成内联 display */
|
|
78
|
+
display: block;
|
|
62
79
|
pointer-events: auto;
|
|
63
80
|
max-inline-size: var(--xh-tooltip-max-w, var(--xh-overlay-max-w));
|
|
64
81
|
padding-block: var(--xh-tooltip-py, var(--xh-_tooltip-py));
|
|
65
82
|
padding-inline: var(--xh-tooltip-px, var(--xh-_tooltip-px));
|
|
83
|
+
/* 这里刻意用 control 而不是浮层那档 surface:提示气泡通常只有一行字、高度接近控件,
|
|
84
|
+
8px 圆角在这个尺寸上占比过大,看着会发胖。档位定义里为此单列了一条 */
|
|
66
85
|
border-radius: var(--xh-tooltip-radius, var(--xh-shape-control));
|
|
67
86
|
/* 实心底与其上的文字色随语气走。没写 data-tone 时两个槽都没被声明,退回原来的取值 */
|
|
68
87
|
background: var(--xh-tooltip-bg, var(--xh-_tone, var(--xh-fg-default)));
|
|
69
88
|
color: var(--xh-tooltip-fg, var(--xh-_tone-on, var(--xh-bg-surface)));
|
|
70
89
|
font-size: var(--xh-tooltip-font-size, var(--xh-_tooltip-font-size));
|
|
71
90
|
line-height: var(--xh-leading-normal);
|
|
72
|
-
box-shadow: var(--xh-tooltip-shadow, var(--xh-elevation-
|
|
91
|
+
box-shadow: var(--xh-tooltip-shadow, var(--xh-elevation-floating));
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
[data-scope='tooltip'][data-part='content'][data-state='open'] {
|
|
76
|
-
animation: xh-
|
|
95
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
|
|
99
|
+
免得动画结束到真收起之间闪一下原样 */
|
|
100
|
+
[data-scope='tooltip'][data-part='content'][data-state='closed'] {
|
|
101
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
77
102
|
}
|
|
78
103
|
|
|
79
104
|
/* —— 尺寸 —— */
|
|
@@ -82,46 +107,30 @@
|
|
|
82
107
|
[data-scope='tooltip'][data-part='content'][data-size='sm'] {
|
|
83
108
|
--xh-_tooltip-py: var(--xh-space-0_5);
|
|
84
109
|
--xh-_tooltip-px: var(--xh-space-1_5);
|
|
85
|
-
--xh-_tooltip-font-size: var(--xh-
|
|
110
|
+
--xh-_tooltip-font-size: var(--xh-control-caption-sm);
|
|
86
111
|
}
|
|
87
112
|
|
|
88
113
|
[data-scope='tooltip'][data-part='content'][data-size='lg'] {
|
|
89
114
|
--xh-_tooltip-py: var(--xh-space-1_5);
|
|
90
115
|
--xh-_tooltip-px: var(--xh-space-2_5);
|
|
91
|
-
--xh-_tooltip-font-size: var(--xh-
|
|
116
|
+
--xh-_tooltip-font-size: var(--xh-control-caption-lg);
|
|
92
117
|
}
|
|
93
118
|
|
|
94
|
-
/*
|
|
119
|
+
/* 箭头的底色与描边色,几何在 overlay-arrow.css。
|
|
95
120
|
交叉轴落点由定位引擎经内联自定义属性写进来,没给时退回居中 */
|
|
96
121
|
[data-scope='tooltip'][data-part='arrow'] {
|
|
97
|
-
--xh-_tooltip-arrow-size: var(--xh-tooltip-arrow-size, var(--xh-overlay-arrow-size));
|
|
98
122
|
--xh-_tooltip-arrow-x: 50%;
|
|
99
123
|
--xh-_tooltip-arrow-y: 50%;
|
|
124
|
+
--xh-_overlay-arrow-size: var(--xh-tooltip-arrow-size, var(--xh-overlay-arrow-size));
|
|
125
|
+
--xh-_overlay-arrow-x: var(--xh-_tooltip-arrow-x);
|
|
126
|
+
--xh-_overlay-arrow-y: var(--xh-_tooltip-arrow-y);
|
|
100
127
|
|
|
101
|
-
position: absolute;
|
|
102
|
-
inline-size: var(--xh-_tooltip-arrow-size);
|
|
103
|
-
block-size: var(--xh-_tooltip-arrow-size);
|
|
104
128
|
background: var(--xh-tooltip-bg, var(--xh-_tone, var(--xh-fg-default)));
|
|
105
|
-
transform: rotate(45deg);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
[data-scope='tooltip'][data-part='arrow'][data-placement^='bottom'] {
|
|
109
|
-
inset-block-start: calc(var(--xh-_tooltip-arrow-size) / -2);
|
|
110
|
-
inset-inline-start: calc(var(--xh-_tooltip-arrow-x) - var(--xh-_tooltip-arrow-size) / 2);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
[data-scope='tooltip'][data-part='arrow'][data-placement^='top'] {
|
|
114
|
-
inset-block-end: calc(var(--xh-_tooltip-arrow-size) / -2);
|
|
115
|
-
inset-inline-start: calc(var(--xh-_tooltip-arrow-x) - var(--xh-_tooltip-arrow-size) / 2);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
[data-scope='tooltip'][data-part='arrow'][data-placement^='left'] {
|
|
119
|
-
inset-block-start: calc(var(--xh-_tooltip-arrow-y) - var(--xh-_tooltip-arrow-size) / 2);
|
|
120
|
-
inset-inline-end: calc(var(--xh-_tooltip-arrow-size) / -2);
|
|
121
129
|
}
|
|
122
130
|
|
|
123
|
-
[
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
/* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
|
|
132
|
+
写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
|
|
133
|
+
[data-scope='tooltip'][data-part='trigger'][hidden] {
|
|
134
|
+
display: none;
|
|
126
135
|
}
|
|
127
136
|
}
|
package/css/tour.css
CHANGED
|
@@ -21,16 +21,27 @@
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
@keyframes xh-tour-content-in {
|
|
24
|
+
@keyframes xh-pop-in {
|
|
26
25
|
from {
|
|
27
26
|
opacity: 0;
|
|
28
|
-
|
|
27
|
+
scale: var(--xh-motion-scale-enter);
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
to {
|
|
32
31
|
opacity: 1;
|
|
33
|
-
|
|
32
|
+
scale: 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@keyframes xh-pop-out {
|
|
37
|
+
from {
|
|
38
|
+
opacity: 1;
|
|
39
|
+
scale: 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
to {
|
|
43
|
+
opacity: 0;
|
|
44
|
+
scale: var(--xh-motion-scale-enter);
|
|
34
45
|
}
|
|
35
46
|
}
|
|
36
47
|
|
|
@@ -46,6 +57,19 @@
|
|
|
46
57
|
scale: 1;
|
|
47
58
|
}
|
|
48
59
|
}
|
|
60
|
+
|
|
61
|
+
/* 退场反向放大淡出,与进场对称 */
|
|
62
|
+
@keyframes xh-tour-spotlight-out {
|
|
63
|
+
from {
|
|
64
|
+
opacity: 1;
|
|
65
|
+
scale: 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
to {
|
|
69
|
+
opacity: 0;
|
|
70
|
+
scale: calc(2 - var(--xh-motion-scale-enter));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
49
73
|
}
|
|
50
74
|
|
|
51
75
|
@layer xihan.components {
|
|
@@ -57,14 +81,23 @@
|
|
|
57
81
|
/* 根节点只是几个浮层的归属容器,不参与排版。
|
|
58
82
|
这里不给 display,UA 的 [hidden]{display:none} 就仍然压得住 */
|
|
59
83
|
[data-scope='tour'][data-part='root'] {
|
|
84
|
+
/* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
85
|
+
--xh-icon-size: var(--xh-tour-icon-size, var(--xh-glyph-size-text));
|
|
86
|
+
|
|
60
87
|
color: var(--xh-tour-fg, var(--xh-fg-default));
|
|
61
88
|
}
|
|
62
89
|
|
|
90
|
+
/* 浮层被搬到 portal 落点,继承不到 root 上的槽:这把尺在被搬走的那一侧再声明一次,
|
|
91
|
+
关闭钮与条目里作者塞的图标才和皮肤画的兜底字形一样大 */
|
|
92
|
+
[data-scope='tour'][data-part='content'] {
|
|
93
|
+
--xh-icon-size: var(--xh-tour-icon-size, var(--xh-glyph-size-text));
|
|
94
|
+
}
|
|
95
|
+
|
|
63
96
|
/* 遮罩:整页压暗,把注意力逼到高亮框那一块上 */
|
|
64
97
|
[data-scope='tour'][data-part='backdrop'] {
|
|
65
98
|
position: fixed;
|
|
66
99
|
inset: 0;
|
|
67
|
-
z-index: var(--xh-tour-backdrop-
|
|
100
|
+
z-index: var(--xh-tour-backdrop-layer, var(--xh-layer-modal));
|
|
68
101
|
background: var(--xh-tour-backdrop-bg, var(--xh-bg-overlay));
|
|
69
102
|
}
|
|
70
103
|
|
|
@@ -77,14 +110,14 @@
|
|
|
77
110
|
}
|
|
78
111
|
|
|
79
112
|
[data-scope='tour'][data-part='backdrop'][data-state='closed'] {
|
|
80
|
-
animation: xh-fade-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit);
|
|
113
|
+
animation: xh-fade-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
81
114
|
}
|
|
82
115
|
|
|
83
116
|
/* 挖洞的高亮框。位置与尺寸由连接层量出来写进内联 style(position/inset/尺寸那几条轴归它),
|
|
84
117
|
这里只管长相:一圈描边 + 一片铺满视口的投影当暗幕,中间那块因此是亮的——
|
|
85
118
|
这就是"洞"。不吃指针:它盖在目标上面,吃了的话目标就再也点不动了 */
|
|
86
119
|
[data-scope='tour'][data-part='spotlight'] {
|
|
87
|
-
z-index: var(--xh-tour-spotlight-
|
|
120
|
+
z-index: var(--xh-tour-spotlight-layer, var(--xh-layer-modal));
|
|
88
121
|
pointer-events: none;
|
|
89
122
|
border-radius: var(--xh-tour-spotlight-radius, var(--xh-shape-surface));
|
|
90
123
|
box-shadow:
|
|
@@ -106,18 +139,29 @@
|
|
|
106
139
|
animation: xh-tour-spotlight-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
107
140
|
}
|
|
108
141
|
|
|
142
|
+
/* 退场与气泡并行播,同一段时长;收起那一帧 hidden 由宿主押后到气泡的退场结束 */
|
|
143
|
+
[data-scope='tour'][data-part='spotlight'][data-state='closed'] {
|
|
144
|
+
animation: xh-tour-spotlight-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
145
|
+
}
|
|
146
|
+
|
|
109
147
|
/* 高亮框在场时遮罩让位:暗幕已经由那圈铺满视口的投影负责,
|
|
110
148
|
两层叠加会把页面压得过暗,而且洞里也会跟着变暗——洞就白挖了。
|
|
111
|
-
居中步的高亮框带 hidden
|
|
112
|
-
|
|
113
|
-
|
|
149
|
+
居中步的高亮框带 hidden,此时遮罩照常压暗(那一步本来就没有要突出的元素)。
|
|
150
|
+
两条兄弟选择器各管一个方向,谁写在前面都算数:遮罩与高亮框同为浮层落点里的兄弟,
|
|
151
|
+
不再共有 root 这个祖先 */
|
|
152
|
+
[data-scope='tour'][data-part='backdrop']:has(~ [data-scope='tour'][data-part='spotlight']:not([hidden])),
|
|
153
|
+
[data-scope='tour'][data-part='spotlight']:not([hidden]) ~ [data-scope='tour'][data-part='backdrop'] {
|
|
114
154
|
background: transparent;
|
|
115
155
|
}
|
|
116
156
|
|
|
117
157
|
/* 空壳不吃指针,交互只发生在 content 上。
|
|
118
158
|
锚定步的坐标由定位引擎写进内联 style,这里不碰那两条轴 */
|
|
119
159
|
[data-scope='tour'][data-part='positioner'] {
|
|
120
|
-
|
|
160
|
+
/* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,气泡继承它限高;
|
|
161
|
+
居中步与尚未落位时不额外限高 */
|
|
162
|
+
--xh-_tour-available-h: 100vh;
|
|
163
|
+
|
|
164
|
+
z-index: var(--xh-tour-positioner-layer, var(--xh-layer-popover));
|
|
121
165
|
pointer-events: none;
|
|
122
166
|
}
|
|
123
167
|
|
|
@@ -127,7 +171,7 @@
|
|
|
127
171
|
display: flex;
|
|
128
172
|
align-items: center;
|
|
129
173
|
justify-content: center;
|
|
130
|
-
padding: var(--xh-space-4);
|
|
174
|
+
padding: var(--xh-tour-positioner-padding, var(--xh-space-4));
|
|
131
175
|
}
|
|
132
176
|
|
|
133
177
|
/* 必须排在 data-position='center' 之后:两条选择器的特指度相同(都是三个属性),
|
|
@@ -142,21 +186,22 @@
|
|
|
142
186
|
flex-direction: column;
|
|
143
187
|
gap: var(--xh-tour-gap, var(--xh-space-2));
|
|
144
188
|
inline-size: max-content;
|
|
145
|
-
max-inline-size: var(--xh-tour-max-w,
|
|
146
|
-
padding-block: var(--xh-tour-py, var(--xh-
|
|
147
|
-
padding-inline: var(--xh-tour-px, var(--xh-
|
|
189
|
+
max-inline-size: var(--xh-tour-max-w, var(--xh-overlay-max-w-lg));
|
|
190
|
+
padding-block: var(--xh-tour-py, var(--xh-surface-py-md));
|
|
191
|
+
padding-inline: var(--xh-tour-px, var(--xh-surface-px-md));
|
|
192
|
+
/* 引导步骤的正文长度由作者定,矮视口下不限高气泡会整块伸出视口 */
|
|
193
|
+
max-block-size: min(var(--xh-tour-max-h, var(--xh-overlay-max-h)), var(--xh-_tour-available-h));
|
|
148
194
|
border: var(--xh-stroke-thin) solid var(--xh-tour-border, var(--xh-border-default));
|
|
149
195
|
border-radius: var(--xh-tour-radius, var(--xh-shape-surface));
|
|
150
196
|
background: var(--xh-tour-bg, var(--xh-bg-surface));
|
|
151
197
|
color: var(--xh-tour-fg, var(--xh-fg-default));
|
|
152
|
-
box-shadow: var(--xh-tour-shadow, var(--xh-elevation-
|
|
198
|
+
box-shadow: var(--xh-tour-shadow, var(--xh-elevation-sheet));
|
|
153
199
|
pointer-events: auto;
|
|
154
200
|
}
|
|
155
201
|
|
|
156
|
-
/*
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
202
|
+
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 popover 一致:
|
|
203
|
+
收起态连接层会给 content 打 hidden,补上这条退场动画就一帧都播不出来。
|
|
204
|
+
真正的收起由退场闸门落成内联 display,节点始终留在原地。 */
|
|
160
205
|
|
|
161
206
|
/* 焦点落在气泡本身(Enter/Space 归"下一步"管),但它是纯容器,不画焦点环 */
|
|
162
207
|
[data-scope='tour'][data-part='content']:focus-visible {
|
|
@@ -164,7 +209,13 @@
|
|
|
164
209
|
}
|
|
165
210
|
|
|
166
211
|
[data-scope='tour'][data-part='content'][data-state='open'] {
|
|
167
|
-
animation: xh-
|
|
212
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
|
|
216
|
+
免得动画结束到收起落下来之间闪一下原样 */
|
|
217
|
+
[data-scope='tour'][data-part='content'][data-state='closed'] {
|
|
218
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
168
219
|
}
|
|
169
220
|
|
|
170
221
|
[data-scope='tour'][data-part='title'] {
|
|
@@ -178,7 +229,7 @@
|
|
|
178
229
|
否则长标题会直接钻到按钮底下。只在真有关闭按钮时让位。 */
|
|
179
230
|
[data-scope='tour'][data-part='content']:has([data-scope='tour'][data-part='close-trigger'])
|
|
180
231
|
[data-scope='tour'][data-part='title'] {
|
|
181
|
-
padding-inline-end: calc(var(--xh-control-h-sm) + var(--xh-space-2));
|
|
232
|
+
padding-inline-end: calc(var(--xh-tour-close-size, var(--xh-control-h-sm)) + var(--xh-space-2));
|
|
182
233
|
}
|
|
183
234
|
|
|
184
235
|
[data-scope='tour'][data-part='description'] {
|
|
@@ -190,7 +241,7 @@
|
|
|
190
241
|
|
|
191
242
|
/* "第 m 步,共 n 步":辅助信息,字号压一档,与按钮排在同一行的两端 */
|
|
192
243
|
[data-scope='tour'][data-part='progress-text'] {
|
|
193
|
-
font-size: var(--xh-tour-progress-font-size, var(--xh-
|
|
244
|
+
font-size: var(--xh-tour-progress-font-size, var(--xh-text-caption-size));
|
|
194
245
|
color: var(--xh-tour-progress-fg, var(--xh-fg-subtle));
|
|
195
246
|
}
|
|
196
247
|
|
|
@@ -201,10 +252,10 @@
|
|
|
201
252
|
align-items: center;
|
|
202
253
|
justify-content: center;
|
|
203
254
|
block-size: var(--xh-control-h-sm);
|
|
204
|
-
padding-inline: var(--xh-control-px-md);
|
|
255
|
+
padding-inline: var(--xh-tour-skip-trigger-px, var(--xh-control-px-md));
|
|
205
256
|
border: var(--xh-stroke-thin) solid transparent;
|
|
206
|
-
border-radius: var(--xh-shape-control);
|
|
207
|
-
font-size: var(--xh-
|
|
257
|
+
border-radius: var(--xh-tour-action-radius, var(--xh-shape-control));
|
|
258
|
+
font-size: var(--xh-text-secondary-size);
|
|
208
259
|
cursor: pointer;
|
|
209
260
|
}
|
|
210
261
|
|
|
@@ -254,13 +305,16 @@
|
|
|
254
305
|
display: inline-flex;
|
|
255
306
|
align-items: center;
|
|
256
307
|
justify-content: center;
|
|
257
|
-
block-size: var(--xh-control-h-sm);
|
|
258
|
-
inline-size: var(--xh-control-h-sm);
|
|
308
|
+
block-size: var(--xh-tour-close-size, var(--xh-control-h-sm));
|
|
309
|
+
inline-size: var(--xh-tour-close-size, var(--xh-control-h-sm));
|
|
259
310
|
border: 0;
|
|
260
|
-
border-radius: var(--xh-shape-control);
|
|
311
|
+
border-radius: var(--xh-tour-close-radius, var(--xh-shape-control));
|
|
261
312
|
background: transparent;
|
|
262
313
|
color: var(--xh-fg-muted);
|
|
263
314
|
cursor: pointer;
|
|
315
|
+
transition:
|
|
316
|
+
background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
317
|
+
scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
264
318
|
}
|
|
265
319
|
|
|
266
320
|
[data-scope='tour'][data-part='close-trigger'][hidden] {
|
|
@@ -268,10 +322,15 @@
|
|
|
268
322
|
}
|
|
269
323
|
|
|
270
324
|
[data-scope='tour'][data-part='close-trigger']:hover {
|
|
271
|
-
background: var(--xh-bg-subtle);
|
|
325
|
+
background: var(--xh-tour-close-bg-hover, var(--xh-bg-subtle-hover));
|
|
272
326
|
color: var(--xh-fg-default);
|
|
273
327
|
}
|
|
274
328
|
|
|
329
|
+
[data-scope='tour'][data-part='close-trigger']:active {
|
|
330
|
+
background: var(--xh-tour-close-bg-active, var(--xh-bg-subtle-active));
|
|
331
|
+
scale: var(--xh-motion-scale-press);
|
|
332
|
+
}
|
|
333
|
+
|
|
275
334
|
[data-scope='tour'][data-part='prev-trigger']:focus-visible,
|
|
276
335
|
[data-scope='tour'][data-part='next-trigger']:focus-visible,
|
|
277
336
|
[data-scope='tour'][data-part='skip-trigger']:focus-visible,
|
|
@@ -280,50 +339,42 @@
|
|
|
280
339
|
outline-offset: var(--xh-ring-offset);
|
|
281
340
|
}
|
|
282
341
|
|
|
283
|
-
/*
|
|
284
|
-
|
|
342
|
+
/* 箭头的底色与描边色,几何在 overlay-arrow.css。
|
|
343
|
+
交叉轴落点由定位引擎经内联自定义属性写进来,没给时退回居中 */
|
|
285
344
|
[data-scope='tour'][data-part='arrow'] {
|
|
286
|
-
--xh-_tour-arrow-size: var(--xh-tour-arrow-size, var(--xh-overlay-arrow-size));
|
|
287
345
|
--xh-_tour-arrow-x: 50%;
|
|
288
346
|
--xh-_tour-arrow-y: 50%;
|
|
347
|
+
--xh-_overlay-arrow-size: var(--xh-tour-arrow-size, var(--xh-overlay-arrow-size));
|
|
348
|
+
--xh-_overlay-arrow-x: var(--xh-_tour-arrow-x);
|
|
349
|
+
--xh-_overlay-arrow-y: var(--xh-_tour-arrow-y);
|
|
289
350
|
|
|
290
|
-
position: absolute;
|
|
291
|
-
inline-size: var(--xh-_tour-arrow-size);
|
|
292
|
-
block-size: var(--xh-_tour-arrow-size);
|
|
293
351
|
background: var(--xh-tour-bg, var(--xh-bg-surface));
|
|
294
352
|
border: var(--xh-stroke-thin) solid var(--xh-tour-border, var(--xh-border-default));
|
|
295
|
-
rotate: 45deg;
|
|
296
353
|
}
|
|
297
354
|
|
|
355
|
+
/* 居中步没有锚点,连接层会给箭头发 hidden */
|
|
298
356
|
[data-scope='tour'][data-part='arrow'][hidden] {
|
|
299
357
|
display: none;
|
|
300
358
|
}
|
|
301
359
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
border-block-start: 0;
|
|
313
|
-
border-inline-start: 0;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
[data-scope='tour'][data-part='arrow'][data-placement^='right'] {
|
|
317
|
-
inset-inline-start: calc(var(--xh-_tour-arrow-size) / -2);
|
|
318
|
-
inset-block-start: calc(var(--xh-_tour-arrow-y) - var(--xh-_tour-arrow-size) / 2);
|
|
319
|
-
border-block-start: 0;
|
|
320
|
-
border-inline-end: 0;
|
|
360
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
361
|
+
[data-scope='tour'][data-part='close-trigger']:empty::before {
|
|
362
|
+
content: '';
|
|
363
|
+
display: inline-block;
|
|
364
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
365
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
366
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
367
|
+
background-color: currentColor;
|
|
368
|
+
-webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
369
|
+
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
321
370
|
}
|
|
371
|
+
}
|
|
322
372
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
373
|
+
@layer xihan.components {
|
|
374
|
+
/* 气泡限高之后只让正文让步:标题与上下步按钮滚出视线就点不到了 */
|
|
375
|
+
[data-scope='tour'][data-part='description'] {
|
|
376
|
+
flex: 1 1 auto;
|
|
377
|
+
min-block-size: 0;
|
|
378
|
+
overflow-y: auto;
|
|
328
379
|
}
|
|
329
380
|
}
|
package/css/transfer.css
CHANGED
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
中间那栏没有对应的角色节点(anatomy 里两个按钮是 root 的直接子节点),
|
|
11
11
|
所以只能按位置显式安放,不能靠自动流——自动流会把"往左搬"甩到右侧面板的位置上 */
|
|
12
12
|
[data-scope='transfer'][data-part='root'] {
|
|
13
|
+
/* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
14
|
+
--xh-icon-size: var(--xh-transfer-icon-size, var(--xh-glyph-size-text));
|
|
15
|
+
|
|
13
16
|
display: grid;
|
|
14
17
|
grid-template-rows: 1fr 1fr;
|
|
15
18
|
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
|
@@ -84,7 +87,7 @@
|
|
|
84
87
|
[data-scope='transfer'][data-part='panel-count'] {
|
|
85
88
|
flex: none;
|
|
86
89
|
color: var(--xh-transfer-count-fg, var(--xh-fg-subtle));
|
|
87
|
-
font-size: var(--xh-transfer-count-font-size, var(--xh-
|
|
90
|
+
font-size: var(--xh-transfer-count-font-size, var(--xh-text-caption-size));
|
|
88
91
|
line-height: var(--xh-leading-none);
|
|
89
92
|
font-variant-numeric: tabular-nums;
|
|
90
93
|
}
|
|
@@ -120,12 +123,15 @@
|
|
|
120
123
|
cursor: not-allowed;
|
|
121
124
|
}
|
|
122
125
|
|
|
126
|
+
/* 两侧列表定高:高度只由这个槽给,与条目数无关。左右两块因此恒等高,
|
|
127
|
+
搬走条目、搜索筛掉条目、整侧搬空,面板都停在原地不缩。
|
|
128
|
+
flex-basis 取 auto 而不是 0,块尺寸才是这一栏真正的主轴基准 */
|
|
123
129
|
[data-scope='transfer'][data-part='list'] {
|
|
124
130
|
display: flex;
|
|
125
|
-
flex: 1;
|
|
131
|
+
flex: 1 1 auto;
|
|
126
132
|
flex-direction: column;
|
|
127
|
-
|
|
128
|
-
|
|
133
|
+
gap: var(--xh-transfer-list-gap, var(--xh-list-option-gap));
|
|
134
|
+
block-size: var(--xh-transfer-list-h, var(--xh-viewport-h-md));
|
|
129
135
|
padding-block: var(--xh-transfer-list-py, var(--xh-space-1));
|
|
130
136
|
padding-inline: var(--xh-transfer-list-px, var(--xh-space-1));
|
|
131
137
|
overflow: auto;
|
|
@@ -190,13 +196,13 @@
|
|
|
190
196
|
flex: none;
|
|
191
197
|
align-items: center;
|
|
192
198
|
justify-content: center;
|
|
193
|
-
inline-size: var(--xh-transfer-checkbox-size,
|
|
194
|
-
block-size: var(--xh-transfer-checkbox-size,
|
|
199
|
+
inline-size: var(--xh-transfer-checkbox-size, var(--xh-control-indicator-size));
|
|
200
|
+
block-size: var(--xh-transfer-checkbox-size, var(--xh-control-indicator-size));
|
|
195
201
|
border: var(--xh-stroke-thin) solid var(--xh-transfer-checkbox-border, var(--xh-border-control));
|
|
196
|
-
border-radius: var(--xh-transfer-checkbox-radius, var(--xh-
|
|
202
|
+
border-radius: var(--xh-transfer-checkbox-radius, var(--xh-shape-inset));
|
|
197
203
|
background: var(--xh-transfer-checkbox-bg, var(--xh-bg-canvas));
|
|
198
204
|
color: var(--xh-transfer-checkbox-fg, var(--xh-fg-on-brand));
|
|
199
|
-
font-size: var(--xh-transfer-checkbox-font-size,
|
|
205
|
+
font-size: var(--xh-transfer-checkbox-font-size, calc(var(--xh-control-indicator-size) * 0.75));
|
|
200
206
|
line-height: var(--xh-leading-none);
|
|
201
207
|
transition:
|
|
202
208
|
background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
@@ -211,24 +217,68 @@
|
|
|
211
217
|
|
|
212
218
|
/* 勾中即填色。全选格三态里 all 与 some 都算"有值",与条目共用同一副填色 */
|
|
213
219
|
[data-scope='transfer'][data-part='item-checkbox'][data-state='checked'],
|
|
214
|
-
[data-scope='transfer'][data-part='select-all-trigger']:is([data-state='
|
|
220
|
+
[data-scope='transfer'][data-part='select-all-trigger']:is([data-state='checked'], [data-state='indeterminate'])::before {
|
|
215
221
|
border-color: var(--xh-transfer-checkbox-border-checked, var(--xh-bg-brand));
|
|
216
222
|
background: var(--xh-transfer-checkbox-bg-checked, var(--xh-bg-brand));
|
|
217
223
|
}
|
|
218
224
|
|
|
219
|
-
/*
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
/* 没写内容就由皮肤画勾;作者往格子里塞了自己的图形,这条规则即不命中。
|
|
226
|
+
底下两处(全选格的两态)不带这条守卫:触发器里装的是全选那行文字,:empty 恒不命中 */
|
|
227
|
+
[data-scope='transfer'][data-part='item-checkbox'][data-state='checked']:empty::before {
|
|
228
|
+
content: '';
|
|
229
|
+
display: inline-block;
|
|
230
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
231
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
232
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
233
|
+
background-color: currentColor;
|
|
234
|
+
-webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
235
|
+
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
222
236
|
}
|
|
223
237
|
|
|
224
238
|
/* 全选格的三态:all 打勾、some 打横杠、none 留空。
|
|
225
|
-
some 就是读屏听到的 aria-checked=mixed,两者同源,样式只认 data-state
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
239
|
+
some 就是读屏听到的 aria-checked=mixed,两者同源,样式只认 data-state。
|
|
240
|
+
|
|
241
|
+
字形走 ::after 而不是画方框的那颗 ::before:mask 会把所在元素的描边与底色一并裁成
|
|
242
|
+
字形的轮廓,写在 ::before 上就等于把方框本身裁没了,只剩一枚白勾。条目那一侧是
|
|
243
|
+
真实节点当方框、它的 ::before 当字形的两层结构,这里没有第二个节点,只能用
|
|
244
|
+
第二个伪元素补上那一层。
|
|
245
|
+
方框是行首那颗 ::before、宽度即勾选格尺寸,所以字形按「盒与字形的宽度差之半」
|
|
246
|
+
内推即落在圆心;纵向靠 inset-block: 0 + margin-block: auto 居中。
|
|
247
|
+
font-size 与 ::before 同值,--xh-icon-size 的 1em 兜底才和条目那侧量得一样大 */
|
|
248
|
+
[data-scope='transfer'][data-part='select-all-trigger'][data-state='checked']::after {
|
|
249
|
+
content: '';
|
|
250
|
+
position: absolute;
|
|
251
|
+
inset-block: 0;
|
|
252
|
+
inset-inline-start: 0;
|
|
253
|
+
margin-block: auto;
|
|
254
|
+
margin-inline-start: calc(
|
|
255
|
+
(var(--xh-transfer-checkbox-size, var(--xh-control-indicator-size)) - var(--xh-icon-size, var(--xh-glyph-size-text))) /
|
|
256
|
+
2
|
|
257
|
+
);
|
|
258
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
259
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
260
|
+
background-color: var(--xh-transfer-checkbox-fg, var(--xh-fg-on-brand));
|
|
261
|
+
font-size: var(--xh-transfer-checkbox-font-size, calc(var(--xh-control-indicator-size) * 0.75));
|
|
262
|
+
-webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
263
|
+
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
[data-scope='transfer'][data-part='select-all-trigger'][data-state='indeterminate']::after {
|
|
267
|
+
content: '';
|
|
268
|
+
position: absolute;
|
|
269
|
+
inset-block: 0;
|
|
270
|
+
inset-inline-start: 0;
|
|
271
|
+
margin-block: auto;
|
|
272
|
+
margin-inline-start: calc(
|
|
273
|
+
(var(--xh-transfer-checkbox-size, var(--xh-control-indicator-size)) - var(--xh-icon-size, var(--xh-glyph-size-text))) /
|
|
274
|
+
2
|
|
275
|
+
);
|
|
276
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
277
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
278
|
+
background-color: var(--xh-transfer-checkbox-fg, var(--xh-fg-on-brand));
|
|
279
|
+
font-size: var(--xh-transfer-checkbox-font-size, calc(var(--xh-control-indicator-size) * 0.75));
|
|
280
|
+
-webkit-mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
|
|
281
|
+
mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
|
|
232
282
|
}
|
|
233
283
|
|
|
234
284
|
[data-scope='transfer'][data-part='item-checkbox'][data-disabled] {
|
|
@@ -238,7 +288,9 @@
|
|
|
238
288
|
|
|
239
289
|
/* 全选格是原生按钮(三态经 aria-checked 上报,激活由平台负责),
|
|
240
290
|
禁用因此写 :disabled,不写 data-disabled */
|
|
291
|
+
/* position 是给叠在方框上的那颗字形 ::after 当定位基准 */
|
|
241
292
|
[data-scope='transfer'][data-part='select-all-trigger'] {
|
|
293
|
+
position: relative;
|
|
242
294
|
display: inline-flex;
|
|
243
295
|
flex: none;
|
|
244
296
|
gap: var(--xh-transfer-select-all-gap, var(--xh-control-gap-sm));
|
|
@@ -248,15 +300,17 @@
|
|
|
248
300
|
border-radius: var(--xh-transfer-select-all-radius, var(--xh-shape-control));
|
|
249
301
|
background: none;
|
|
250
302
|
color: var(--xh-transfer-select-all-fg, var(--xh-fg-muted));
|
|
251
|
-
font-size: var(--xh-transfer-select-all-font-size, var(--xh-
|
|
303
|
+
font-size: var(--xh-transfer-select-all-font-size, var(--xh-text-caption-size));
|
|
252
304
|
font-weight: var(--xh-font-weight-medium);
|
|
253
305
|
line-height: var(--xh-leading-none);
|
|
254
306
|
cursor: pointer;
|
|
255
307
|
}
|
|
256
308
|
|
|
309
|
+
/* 往内收,与搜索框、条目同一口径:全选格长在面板里,面板收 overflow,
|
|
310
|
+
环画在外沿会被裁掉 */
|
|
257
311
|
[data-scope='transfer'][data-part='select-all-trigger']:focus-visible {
|
|
258
312
|
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
259
|
-
outline-offset: var(--xh-ring-
|
|
313
|
+
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
260
314
|
}
|
|
261
315
|
|
|
262
316
|
[data-scope='transfer'][data-part='select-all-trigger']:disabled {
|
|
@@ -322,4 +376,27 @@
|
|
|
322
376
|
[data-scope='transfer'][data-part='to-source-trigger'][hidden] {
|
|
323
377
|
display: none;
|
|
324
378
|
}
|
|
379
|
+
|
|
380
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
381
|
+
[data-scope='transfer'][data-part='to-source-trigger']:empty::before {
|
|
382
|
+
content: '';
|
|
383
|
+
display: inline-block;
|
|
384
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
385
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
386
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
387
|
+
background-color: currentColor;
|
|
388
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-left) center / contain no-repeat;
|
|
389
|
+
mask: var(--xh-glyph-mark-chevron-left) center / contain no-repeat;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
[data-scope='transfer'][data-part='to-target-trigger']:empty::before {
|
|
393
|
+
content: '';
|
|
394
|
+
display: inline-block;
|
|
395
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
396
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
397
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
398
|
+
background-color: currentColor;
|
|
399
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
400
|
+
mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
401
|
+
}
|
|
325
402
|
}
|