@xihan-ui/styles 1.0.0 → 2.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 +5146 -6
- package/README.md +22 -2
- package/component-tokens.d.ts +4212 -0
- package/component-tokens.js +2 -0
- package/components.tokens.json +80116 -0
- package/css/accordion.css +131 -75
- package/css/affix.css +16 -1
- package/css/alert.css +114 -67
- package/css/anchor.css +99 -27
- package/css/approval.css +461 -0
- package/css/avatar-group.css +14 -6
- package/css/avatar.css +33 -9
- package/css/back-top.css +103 -48
- package/css/badge.css +42 -14
- package/css/bar-code.css +62 -0
- package/css/breadcrumb.css +40 -21
- package/css/button-group.css +146 -24
- package/css/button.css +116 -99
- package/css/calendar-picker.css +448 -0
- package/css/calendar-range-picker.css +517 -0
- package/css/card.css +54 -77
- package/css/carousel.css +412 -68
- package/css/cascader.css +429 -246
- package/css/checkbox-group.css +225 -77
- package/css/checkbox.css +174 -37
- package/css/clipboard.css +266 -47
- package/css/code-view.css +279 -0
- package/css/collapsible.css +108 -63
- package/css/color-field.css +158 -0
- package/css/color-picker.css +172 -184
- package/css/color-slider.css +274 -0
- package/css/color-swatch-picker.css +243 -0
- package/css/color-swatch.css +35 -0
- package/css/combobox.css +267 -273
- package/css/command.css +399 -0
- package/css/context-menu.css +183 -108
- package/css/date-field.css +94 -121
- package/css/date-picker.css +486 -249
- package/css/date-range-picker.css +559 -0
- package/css/description.css +51 -0
- package/css/descriptions.css +133 -87
- package/css/dialog.css +247 -68
- package/css/diff-view.css +428 -0
- package/css/download-trigger.css +155 -46
- package/css/drawer.css +194 -111
- package/css/editable.css +172 -152
- package/css/empty-state.css +80 -11
- package/css/field-array.css +190 -0
- package/css/field.css +84 -31
- package/css/fieldset.css +51 -18
- package/css/file-upload.css +134 -36
- package/css/flex.css +20 -1
- package/css/float-button.css +238 -57
- package/css/floating-panel.css +173 -92
- package/css/focus.css +46 -0
- package/css/forced-colors.css +93 -0
- package/css/form.css +254 -77
- package/css/gradient-text.css +34 -10
- package/css/grid.css +516 -5
- package/css/heatmap.css +87 -29
- package/css/highlight.css +20 -5
- package/css/hover-card.css +97 -47
- package/css/icon-wrapper.css +15 -3
- package/css/icon.css +74 -8
- package/css/image-cropper.css +143 -29
- package/css/image-viewer.css +150 -89
- package/css/image.css +30 -1
- package/css/infinite-scroll.css +51 -1
- package/css/input-group.css +277 -0
- package/css/json-viewer.css +102 -45
- package/css/kbd.css +72 -0
- package/css/label.css +78 -0
- package/css/layers.css +5 -0
- package/css/layout.css +175 -31
- package/css/list.css +24 -3
- package/css/listbox.css +208 -67
- package/css/loading-bar.css +52 -3
- package/css/log.css +144 -9
- package/css/markdown-stream.css +149 -0
- package/css/marquee.css +27 -1
- package/css/masonry.css +7 -0
- package/css/matrix-code.css +67 -0
- package/css/mention.css +234 -152
- package/css/menu.css +180 -83
- package/css/menubar.css +204 -136
- package/css/message-feed.css +197 -0
- package/css/navigation-menu.css +144 -90
- package/css/notification.css +178 -100
- package/css/number-animation.css +7 -0
- package/css/number-field.css +120 -277
- package/css/overlay-arrow.css +12 -7
- package/css/page-header.css +99 -14
- package/css/pagination.css +175 -135
- package/css/password-input.css +222 -219
- package/css/pin-input.css +101 -67
- package/css/pointer.css +36 -0
- package/css/popconfirm.css +185 -94
- package/css/popover.css +121 -77
- package/css/progress.css +60 -12
- package/css/prompt-input.css +224 -0
- package/css/question-flow.css +513 -0
- package/css/radio-group.css +147 -30
- package/css/rating.css +193 -43
- package/css/reasoning.css +336 -0
- package/css/reset.css +84 -6
- package/css/resizable.css +237 -0
- package/css/scroll-area.css +68 -7
- package/css/scrollbar.css +47 -13
- package/css/segmented.css +94 -29
- package/css/select.css +288 -274
- package/css/separator.css +101 -1
- package/css/side-nav.css +133 -75
- package/css/signature-pad.css +74 -54
- package/css/skeleton.css +84 -11
- package/css/slider.css +132 -39
- package/css/sortable.css +198 -0
- package/css/spinner.css +126 -12
- package/css/splitter.css +29 -8
- package/css/statistic.css +55 -0
- package/css/steps.css +206 -72
- package/css/switch.css +268 -36
- package/css/table.css +695 -118
- package/css/tabs.css +604 -42
- package/css/tag-group.css +219 -0
- package/css/tag.css +118 -28
- package/css/tags-input.css +156 -274
- package/css/text-field.css +101 -249
- package/css/time-field.css +100 -128
- package/css/time-picker.css +323 -252
- package/css/time-range-picker.css +719 -0
- package/css/timeline.css +202 -68
- package/css/timer.css +56 -52
- package/css/timestamp.css +34 -0
- package/css/toast.css +373 -144
- package/css/toggle-group.css +309 -76
- package/css/toggle.css +116 -85
- package/css/tone.css +47 -0
- package/css/tool-call.css +421 -0
- package/css/toolbar.css +181 -33
- package/css/tooltip.css +107 -36
- package/css/tour.css +183 -152
- package/css/transfer.css +351 -138
- package/css/tree-select.css +323 -216
- package/css/tree.css +294 -62
- package/css/truncate.css +65 -0
- package/css/typography.css +228 -5
- package/css/undefined.css +10 -1
- package/css/virtualizer.css +9 -10
- package/css/visually-hidden.css +7 -0
- package/css/watermark.css +7 -0
- package/family/action-control.css +487 -0
- package/family/collection-item.css +721 -0
- package/family/field-chrome.css +298 -0
- package/family/motion.css +166 -0
- package/family/swatch.css +59 -0
- package/index.css +41705 -126
- package/index.unlayered.css +33692 -17339
- package/package.json +51 -17
- package/css/calendar.css +0 -367
- package/css/code-block.css +0 -91
- package/css/composer.css +0 -134
- package/css/countdown.css +0 -26
- package/css/dynamic-input.css +0 -220
- package/css/ellipsis.css +0 -52
- package/css/hotkeys.css +0 -90
- package/css/popselect.css +0 -391
- package/css/qr-code.css +0 -55
- package/css/result.css +0 -119
- package/css/space.css +0 -117
- package/css/thread.css +0 -120
- package/css/time.css +0 -25
package/css/toast.css
CHANGED
|
@@ -1,34 +1,57 @@
|
|
|
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
|
+
/* 定义 toast 样式。 */
|
|
7
|
+
|
|
8
|
+
/* Toast 独立皮肤同时传递引入操作 / 关闭钮的动作控件配方;full bundle 递归去重。 */
|
|
9
|
+
@import '../family/action-control.css';
|
|
10
|
+
|
|
1
11
|
@layer xihan.motion {
|
|
2
|
-
/*
|
|
3
|
-
* 九个位共用同一条进出场,位移不跟着落位走:要按位置分方向就得从摞的
|
|
4
|
-
* data-placement 反向选到条子上,落位一改名整条动效静默失效。
|
|
5
|
-
* 竖向一小段位移在九个位上都说得通。
|
|
6
|
-
*/
|
|
12
|
+
/* 新条目从视口边缘外进入,同时落到自己的折叠层级。 */
|
|
7
13
|
@keyframes xh-toast-in {
|
|
8
14
|
from {
|
|
9
15
|
opacity: 0;
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
transform: translateY(calc(var(--xh-toast-dir, 1) * (var(--xh-toast-offset-collapsed, 0px) - 100%)))
|
|
17
|
+
scale(var(--xh-toast-scale-collapsed, 1));
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
to {
|
|
15
21
|
opacity: 1;
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
transform: translateY(calc(var(--xh-toast-dir, 1) * var(--xh-toast-offset-collapsed, 0px)))
|
|
23
|
+
scale(var(--xh-toast-scale-collapsed, 1));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@keyframes xh-toast-spin {
|
|
28
|
+
to {
|
|
29
|
+
rotate: 360deg;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* 倒计时条:从占满一整条收到零。走一遍就到头,时长由连接层写进时长槽 */
|
|
34
|
+
@keyframes xh-countdown {
|
|
35
|
+
from {
|
|
36
|
+
inline-size: 100%;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
to {
|
|
40
|
+
inline-size: 0%;
|
|
18
41
|
}
|
|
19
42
|
}
|
|
20
43
|
|
|
21
44
|
@keyframes xh-toast-out {
|
|
22
45
|
from {
|
|
23
46
|
opacity: 1;
|
|
24
|
-
|
|
25
|
-
|
|
47
|
+
transform: translateY(calc(var(--xh-toast-dir, 1) * var(--xh-toast-y, 0px)))
|
|
48
|
+
scale(var(--xh-toast-scale, 1));
|
|
26
49
|
}
|
|
27
50
|
|
|
28
51
|
to {
|
|
29
52
|
opacity: 0;
|
|
30
|
-
|
|
31
|
-
|
|
53
|
+
transform: translateY(calc(var(--xh-toast-dir, 1) * (var(--xh-toast-y, 0px) - 100%)))
|
|
54
|
+
scale(var(--xh-toast-scale, 1));
|
|
32
55
|
}
|
|
33
56
|
}
|
|
34
57
|
}
|
|
@@ -39,29 +62,13 @@
|
|
|
39
62
|
--xh-toast-skin: 1;
|
|
40
63
|
}
|
|
41
64
|
|
|
42
|
-
/*
|
|
43
|
-
* 一摞 = 一整面视口大小的定位面:贴边靠 padding,落位靠 justify/align 表达。
|
|
44
|
-
* 不用四角 inset 逐个摆,是因为 column flex 的 align-items 走的是行内轴,
|
|
45
|
-
* RTL 下 start/end 自动跟着翻;写死 inset-inline-start 的话居中那三个位
|
|
46
|
-
* 还得再配一次 translate,方向一变就错。
|
|
47
|
-
* 摞由全局服务渲染,没有对应的容器组件——一次操作的反馈落在哪儿是整个服务的口径。
|
|
48
|
-
*/
|
|
65
|
+
/* 固定宽度的堆叠定位面;每条 Toast 在其中绝对定位。 */
|
|
49
66
|
[data-scope='toast'][data-part='group'] {
|
|
50
67
|
position: fixed;
|
|
51
|
-
inset-block: 0;
|
|
52
|
-
inset-inline: 0;
|
|
53
68
|
z-index: var(--xh-toast-layer, var(--xh-layer-toast));
|
|
54
|
-
display:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
justify-content: flex-start;
|
|
58
|
-
align-items: center;
|
|
59
|
-
padding-block: var(--xh-toast-inset, var(--xh-space-6));
|
|
60
|
-
padding-inline: var(--xh-toast-inset, var(--xh-space-6));
|
|
61
|
-
/* 摞内间距由服务写进内联 style,这里绝不重复写:
|
|
62
|
-
写了也会被内联盖掉,只会让人误以为间距归样式层管 */
|
|
63
|
-
/* 整面铺开就等于罩住了整块视口。面本身不吃指针,只有条子吃(见下),
|
|
64
|
-
否则底下的页面就再也点不动了 */
|
|
69
|
+
display: block;
|
|
70
|
+
inline-size: min(var(--xh-toast-inline-size, 28.75rem), calc(100vw - var(--xh-space-8)));
|
|
71
|
+
block-size: 0;
|
|
65
72
|
pointer-events: none;
|
|
66
73
|
}
|
|
67
74
|
|
|
@@ -69,61 +76,86 @@
|
|
|
69
76
|
display: none;
|
|
70
77
|
}
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
[data-scope='toast'][data-part='group'][data-placement='bottom'] {
|
|
80
|
+
inset-block-end: max(var(--xh-toast-inset, var(--xh-space-4)), env(safe-area-inset-bottom));
|
|
81
|
+
inset-inline-start: 50%;
|
|
82
|
+
translate: -50% 0;
|
|
75
83
|
}
|
|
76
84
|
|
|
77
|
-
[data-scope='toast'][data-part='group'][data-placement
|
|
78
|
-
|
|
85
|
+
[data-scope='toast'][data-part='group'][data-placement='top'] {
|
|
86
|
+
inset-block-start: max(var(--xh-toast-inset, var(--xh-space-4)), env(safe-area-inset-top));
|
|
87
|
+
inset-inline-start: 50%;
|
|
88
|
+
translate: -50% 0;
|
|
79
89
|
}
|
|
80
90
|
|
|
81
|
-
/* 行内轴落位:不带后缀的 top / middle / bottom 用基线的居中 */
|
|
82
91
|
[data-scope='toast'][data-part='group'][data-placement$='-start'] {
|
|
83
|
-
|
|
92
|
+
inset-inline-start: max(var(--xh-toast-inset, var(--xh-space-4)), env(safe-area-inset-left));
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
[data-scope='toast'][data-part='group'][data-placement$='-end'] {
|
|
87
|
-
|
|
96
|
+
inset-inline-end: max(var(--xh-toast-inset, var(--xh-space-4)), env(safe-area-inset-right));
|
|
88
97
|
}
|
|
89
98
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
[data-scope='toast'][data-part='group'][data-placement^='bottom'][data-placement$='-start'],
|
|
100
|
+
[data-scope='toast'][data-part='group'][data-placement^='bottom'][data-placement$='-end'] {
|
|
101
|
+
inset-block-end: max(var(--xh-toast-inset, var(--xh-space-4)), env(safe-area-inset-bottom));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
[data-scope='toast'][data-part='group'][data-placement^='top'][data-placement$='-start'],
|
|
105
|
+
[data-scope='toast'][data-part='group'][data-placement^='top'][data-placement$='-end'] {
|
|
106
|
+
inset-block-start: max(var(--xh-toast-inset, var(--xh-space-4)), env(safe-area-inset-top));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* 中性浮层承载整条反馈,语气只落到状态字形和标题。
|
|
110
|
+
面走 sheet 三件套(§8.4:--xh-material-elevated-bg / -border / -shadow,亮暗两档同有 1px 描边)。 */
|
|
95
111
|
[data-scope='toast'][data-part='root'] {
|
|
96
|
-
/*
|
|
97
|
-
--xh-icon-size: var(--xh-toast-icon-size, var(--xh-
|
|
112
|
+
/* 作者塞进指示符槽的图标与皮肤画的兜底字形同一把尺:Feedback 指示符统一 md 档(§6.5) */
|
|
113
|
+
--xh-icon-size: var(--xh-toast-icon-size, var(--xh-glyph-size-md));
|
|
98
114
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
--xh-_toast-tint: var(--xh-_tone-subtle);
|
|
102
|
-
--xh-_toast-edge: var(--xh-_tone-border);
|
|
115
|
+
--xh-toast-y: var(--xh-toast-offset-collapsed, 0px);
|
|
116
|
+
--xh-toast-scale: var(--xh-toast-scale-collapsed, 1);
|
|
103
117
|
|
|
118
|
+
position: relative;
|
|
104
119
|
display: flex;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
inline-size: var(--xh-toast-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
border: var(--xh-stroke-thin) solid var(--xh-toast-border, var(--xh-_toast-edge));
|
|
118
|
-
border-radius: var(--xh-toast-radius, var(--xh-shape-surface));
|
|
119
|
-
background: var(--xh-toast-bg, var(--xh-_toast-tint));
|
|
120
|
-
color: var(--xh-toast-fg, var(--xh-fg-default));
|
|
121
|
-
box-shadow: var(--xh-toast-shadow, var(--xh-elevation-sheet));
|
|
122
|
-
font-size: var(--xh-toast-font-size, var(--xh-text-body-size));
|
|
120
|
+
flex: none;
|
|
121
|
+
align-items: flex-start;
|
|
122
|
+
gap: var(--xh-toast-gap, var(--xh-space-1_5));
|
|
123
|
+
inline-size: min(var(--xh-toast-inline-size, 28.75rem), 100%);
|
|
124
|
+
padding-block: var(--xh-toast-py, var(--xh-space-3));
|
|
125
|
+
padding-inline: var(--xh-toast-px, var(--xh-space-4));
|
|
126
|
+
border: var(--xh-stroke-thin) solid var(--xh-toast-border, var(--xh-material-elevated-border));
|
|
127
|
+
border-radius: var(--xh-toast-radius, var(--xh-shape-overlay));
|
|
128
|
+
background: var(--xh-toast-bg, var(--xh-material-elevated-bg));
|
|
129
|
+
color: var(--xh-toast-fg, var(--xh-material-elevated-fg));
|
|
130
|
+
box-shadow: var(--xh-toast-shadow, var(--xh-material-elevated-shadow));
|
|
131
|
+
font-size: var(--xh-toast-font-size, var(--xh-text-label-size));
|
|
123
132
|
line-height: var(--xh-toast-leading, var(--xh-text-body-leading));
|
|
124
133
|
/* 摞的定位面整面铺开且不吃指针,条子必须自己吃回来:
|
|
125
134
|
悬停按住计时、按钮可点、焦点进出,全指着这一条 */
|
|
126
135
|
pointer-events: auto;
|
|
136
|
+
transform: translateY(calc(var(--xh-toast-dir, 1) * var(--xh-toast-y))) scale(var(--xh-toast-scale));
|
|
137
|
+
transform-origin: bottom center;
|
|
138
|
+
transition:
|
|
139
|
+
transform var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous),
|
|
140
|
+
block-size var(--xh-motion-duration-enter) var(--xh-motion-ease-continuous),
|
|
141
|
+
opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
[data-scope='toast'][data-part='group'] [data-scope='toast'][data-part='root'] {
|
|
145
|
+
position: absolute;
|
|
146
|
+
inset-inline: 0;
|
|
147
|
+
inline-size: 100%;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
[data-scope='toast'][data-part='root'][data-placement^='bottom'] {
|
|
151
|
+
--xh-toast-dir: -1;
|
|
152
|
+
inset-block-end: 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
[data-scope='toast'][data-part='root'][data-placement^='top'] {
|
|
156
|
+
--xh-toast-dir: 1;
|
|
157
|
+
inset-block-start: 0;
|
|
158
|
+
transform-origin: top center;
|
|
127
159
|
}
|
|
128
160
|
|
|
129
161
|
/* 退场窗口走完连接层给的是 hidden 属性,而上面声明了 display——
|
|
@@ -134,126 +166,305 @@
|
|
|
134
166
|
|
|
135
167
|
/* 生命周期只有三段,unmounted 那段由上面的 [hidden] 收走,这里只管前两段 */
|
|
136
168
|
[data-scope='toast'][data-part='root'][data-state='visible'] {
|
|
137
|
-
animation: xh-toast-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
169
|
+
animation: xh-toast-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong) backwards;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
[data-scope='toast'][data-part='root'][data-stack-index]:not([data-frontmost]):not([data-expanded]) {
|
|
173
|
+
block-size: var(--xh-toast-front-height, auto);
|
|
174
|
+
overflow: hidden;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
[data-scope='toast'][data-part='root'][data-stack-index]:not([data-frontmost]):not([data-expanded])
|
|
178
|
+
> :not([data-part='close-trigger']) {
|
|
179
|
+
opacity: 0;
|
|
138
180
|
}
|
|
139
181
|
|
|
140
|
-
|
|
182
|
+
[data-scope='toast'][data-part='root'][data-expanded] {
|
|
183
|
+
--xh-toast-y: var(--xh-toast-offset-expanded, 0px);
|
|
184
|
+
--xh-toast-scale: 1;
|
|
185
|
+
block-size: var(--xh-toast-height, auto);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
[data-scope='toast'][data-part='root'] > :not([data-part='close-trigger']) {
|
|
189
|
+
transition: opacity var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* forwards 不能省:退场窗口(removeDelay 默认 300ms)比退场动画长,
|
|
141
193
|
不定住末帧的话动画跑完会弹回全不透明,条子在被收起前先闪一下 */
|
|
142
194
|
[data-scope='toast'][data-part='root'][data-state='dismissing'] {
|
|
143
195
|
animation: xh-toast-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
144
196
|
}
|
|
145
197
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
198
|
+
/*
|
|
199
|
+
* 语气的非颜色通道。行首字形按 data-tone 区分信息、成功、警告与失败;加载中另由 data-loading 说,
|
|
200
|
+
* 字形换成转圈但配色仍照语气走。
|
|
201
|
+
* 作者未渲染 indicator 时由 root 的伪元素补上。
|
|
202
|
+
*/
|
|
203
|
+
[data-scope='toast'][data-part='root']::before {
|
|
204
|
+
content: '';
|
|
205
|
+
flex: none;
|
|
206
|
+
display: inline-block;
|
|
207
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
208
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
209
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
210
|
+
background-color: var(--xh-toast-icon-fg, var(--xh-_tone-fg));
|
|
211
|
+
-webkit-mask: var(--xh-glyph-mark-info) center / contain no-repeat;
|
|
212
|
+
mask: var(--xh-glyph-mark-info) center / contain no-repeat;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
[data-scope='toast'][data-part='root'][data-tone='success']::before {
|
|
216
|
+
-webkit-mask-image: var(--xh-glyph-mark-check);
|
|
217
|
+
mask-image: var(--xh-glyph-mark-check);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
[data-scope='toast'][data-part='root'][data-tone='warning']::before {
|
|
221
|
+
-webkit-mask-image: var(--xh-glyph-mark-warning);
|
|
222
|
+
mask-image: var(--xh-glyph-mark-warning);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
[data-scope='toast'][data-part='root'][data-tone='danger']::before {
|
|
226
|
+
-webkit-mask-image: var(--xh-glyph-mark-close);
|
|
227
|
+
mask-image: var(--xh-glyph-mark-close);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* 加载中不是语气:只换字形,颜色沿用当前语气的前景档;写在四档语气之后,转圈压过它们 */
|
|
231
|
+
[data-scope='toast'][data-part='root'][data-loading]::before {
|
|
232
|
+
-webkit-mask-image: var(--xh-glyph-mark-rotate-right);
|
|
233
|
+
mask-image: var(--xh-glyph-mark-rotate-right);
|
|
234
|
+
animation: xh-toast-spin var(--xh-spin-duration) var(--xh-motion-ease-loop) infinite;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* 减少动效:转圈停下,静止的箭头仍然读得出「还没好」;「在等什么」由条子上的
|
|
238
|
+
role=status 与可见文案继续承担。
|
|
239
|
+
两组规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
|
|
240
|
+
@media (prefers-reduced-motion: reduce) {
|
|
241
|
+
[data-scope='toast'][data-part='root'][data-loading]::before {
|
|
242
|
+
animation: none;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
:where([data-motion='reduce']) [data-scope='toast'][data-part='root'][data-loading]::before {
|
|
247
|
+
animation: none;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* 作者渲染了指示符部件,行首那枚兜底字形就让位给它,一行里不出现两枚图形 */
|
|
251
|
+
[data-scope='toast'][data-part='root']:has([data-part='indicator'])::before {
|
|
252
|
+
content: none;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* 指示符部件:字形与 root 上那枚同尺同色,作者往里塞节点即整枚换掉 */
|
|
256
|
+
[data-scope='toast'][data-part='indicator'] {
|
|
257
|
+
flex: none;
|
|
258
|
+
display: inline-flex;
|
|
259
|
+
align-items: center;
|
|
260
|
+
justify-content: center;
|
|
261
|
+
box-sizing: content-box;
|
|
262
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
263
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
264
|
+
padding: var(--xh-toast-indicator-p, var(--xh-space-1));
|
|
265
|
+
color: var(--xh-toast-icon-fg, var(--xh-_tone-fg));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
269
|
+
[data-scope='toast'][data-part='indicator']:empty::before {
|
|
270
|
+
content: '';
|
|
271
|
+
display: inline-block;
|
|
272
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
273
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
274
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
275
|
+
background-color: currentColor;
|
|
276
|
+
-webkit-mask: var(--xh-glyph-mark-info) center / contain no-repeat;
|
|
277
|
+
mask: var(--xh-glyph-mark-info) center / contain no-repeat;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
[data-scope='toast'][data-part='indicator'][data-tone='success']:empty::before {
|
|
281
|
+
-webkit-mask-image: var(--xh-glyph-mark-check);
|
|
282
|
+
mask-image: var(--xh-glyph-mark-check);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
[data-scope='toast'][data-part='indicator'][data-tone='warning']:empty::before {
|
|
286
|
+
-webkit-mask-image: var(--xh-glyph-mark-warning);
|
|
287
|
+
mask-image: var(--xh-glyph-mark-warning);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
[data-scope='toast'][data-part='indicator'][data-tone='danger']:empty::before {
|
|
291
|
+
-webkit-mask-image: var(--xh-glyph-mark-close);
|
|
292
|
+
mask-image: var(--xh-glyph-mark-close);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
[data-scope='toast'][data-part='indicator'][data-loading]:empty::before {
|
|
296
|
+
-webkit-mask-image: var(--xh-glyph-mark-rotate-right);
|
|
297
|
+
mask-image: var(--xh-glyph-mark-rotate-right);
|
|
298
|
+
animation: xh-toast-spin var(--xh-spin-duration) var(--xh-motion-ease-loop) infinite;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* 减少动效:与 root 上那枚同一处理——转圈停下,静止的箭头仍读得出「还没好」。
|
|
302
|
+
两组规则是同一件事的两个触发条件:系统偏好与作者打的 data-motion */
|
|
303
|
+
@media (prefers-reduced-motion: reduce) {
|
|
304
|
+
[data-scope='toast'][data-part='indicator'][data-loading]:empty::before {
|
|
305
|
+
animation: none;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
:where([data-motion='reduce']) [data-scope='toast'][data-part='indicator'][data-loading]:empty::before {
|
|
310
|
+
animation: none;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
[data-scope='toast'][data-part='indicator'][hidden] {
|
|
314
|
+
display: none;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
[data-scope='toast'][data-part='content'] {
|
|
151
318
|
flex: 1 1 auto;
|
|
319
|
+
display: flex;
|
|
320
|
+
flex-direction: column;
|
|
321
|
+
align-self: center;
|
|
322
|
+
min-inline-size: 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
[data-scope='toast'][data-part='title'],
|
|
326
|
+
[data-scope='toast'][data-part='description'] {
|
|
327
|
+
margin: 0;
|
|
152
328
|
min-inline-size: 0;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
font-
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
[data-scope='toast'][data-part='title'] {
|
|
332
|
+
color: var(--xh-toast-title-fg, var(--xh-_tone-fg));
|
|
333
|
+
font-size: var(--xh-toast-title-font-size, var(--xh-text-label-size));
|
|
334
|
+
font-weight: var(--xh-toast-title-font-weight, var(--xh-font-weight-semibold));
|
|
158
335
|
line-height: var(--xh-toast-title-leading, var(--xh-text-body-leading));
|
|
159
336
|
}
|
|
160
337
|
|
|
338
|
+
[data-scope='toast'][data-part='description'] {
|
|
339
|
+
color: var(--xh-toast-description-fg, var(--xh-fg-muted));
|
|
340
|
+
font-size: var(--xh-toast-description-font-size, var(--xh-text-secondary-size));
|
|
341
|
+
line-height: var(--xh-toast-description-leading, var(--xh-leading-normal));
|
|
342
|
+
}
|
|
343
|
+
|
|
161
344
|
/* 没给文案时仍然要留在 DOM 里(aria-labelledby 指着它),
|
|
162
345
|
但空盒子会照吃一份 gap,条子看着就多出一截莫名的留白 */
|
|
163
346
|
[data-scope='toast'][data-part='title']:empty {
|
|
164
347
|
display: none;
|
|
165
348
|
}
|
|
166
349
|
|
|
350
|
+
[data-scope='toast'][data-part='description']:empty {
|
|
351
|
+
display: none;
|
|
352
|
+
}
|
|
353
|
+
|
|
167
354
|
[data-scope='toast'][data-part='title'][hidden] {
|
|
168
355
|
display: none;
|
|
169
356
|
}
|
|
170
357
|
|
|
358
|
+
/* 操作钮是带文案的离散动作钮:盒几何、悬停 / 按下与 0.97 按压、粗指针热区、焦点环、禁用面全由 Action Control
|
|
359
|
+
的 text outline 档给(连接层投 sm;非 Button 的触发器缺省中性描边、透明底,§7.2.2),组件只映射既有使用者槽。
|
|
360
|
+
语气只落到状态字形和标题:这颗钮坐在带 data-tone 的条子里,底 / 边 / 字钉在中性语义面上,不随语气;
|
|
361
|
+
条子是 sheet 白面承载:hover --xh-bg-subtle(100)→ pressed --xh-bg-subtle-hover(200)。
|
|
362
|
+
条子是单行 flex,按钮不参与伸缩:文案长了该换行的是文字 */
|
|
171
363
|
[data-scope='toast'][data-part='action-trigger'] {
|
|
172
|
-
|
|
364
|
+
--xh-action-visual-size: var(--xh-toast-action-h, var(--xh-_action-profile-visual-size));
|
|
365
|
+
--xh-action-padding-inline: var(--xh-toast-action-px, var(--xh-_action-profile-padding-inline));
|
|
366
|
+
--xh-action-radius: var(--xh-toast-action-radius, var(--xh-shape-control));
|
|
367
|
+
--xh-action-bg-rest: var(--xh-toast-action-bg, transparent);
|
|
368
|
+
--xh-action-bg-hover: var(--xh-toast-action-bg-hover, var(--xh-bg-subtle));
|
|
369
|
+
--xh-action-bg-pressed: var(--xh-toast-action-bg-active, var(--xh-bg-subtle-hover));
|
|
370
|
+
--xh-action-fg-rest: var(--xh-toast-action-fg, var(--xh-fg-default));
|
|
371
|
+
--xh-action-fg-hover: var(--xh-toast-action-fg, var(--xh-fg-default));
|
|
372
|
+
--xh-action-fg-pressed: var(--xh-toast-action-fg, var(--xh-fg-default));
|
|
373
|
+
--xh-action-border-rest: var(--xh-toast-action-border, var(--xh-border-control));
|
|
374
|
+
--xh-action-border-hover: var(--xh-toast-action-border, var(--xh-border-control-hover));
|
|
375
|
+
--xh-action-border-pressed: var(--xh-toast-action-border, var(--xh-border-control-hover));
|
|
376
|
+
--xh-action-highlight-rest: transparent;
|
|
377
|
+
--xh-action-shadow-rest: none;
|
|
378
|
+
--xh-action-shadow-hover: none;
|
|
379
|
+
--xh-action-shadow-pressed: none;
|
|
380
|
+
|
|
173
381
|
flex: none;
|
|
174
|
-
|
|
175
|
-
align-items: center;
|
|
176
|
-
justify-content: center;
|
|
177
|
-
block-size: var(--xh-toast-action-h, var(--xh-control-h-sm));
|
|
178
|
-
padding-inline: var(--xh-toast-action-px, var(--xh-control-px-sm));
|
|
179
|
-
border: var(--xh-stroke-thin) solid var(--xh-toast-action-border, var(--xh-border-default));
|
|
180
|
-
border-radius: var(--xh-toast-action-radius, var(--xh-shape-control));
|
|
181
|
-
background: var(--xh-toast-action-bg, var(--xh-bg-subtle));
|
|
182
|
-
color: var(--xh-toast-action-fg, var(--xh-fg-default));
|
|
183
|
-
/* 按钮不继承字族字号,不接回来的话条子里会突然冒出一段系统 UI 字体 */
|
|
184
|
-
font: inherit;
|
|
382
|
+
align-self: center;
|
|
185
383
|
font-weight: var(--xh-toast-action-font-weight, var(--xh-font-weight-medium));
|
|
186
|
-
line-height: var(--xh-leading-none);
|
|
187
|
-
cursor: pointer;
|
|
188
384
|
}
|
|
189
385
|
|
|
386
|
+
/* 家族那条 display 会把 UA 的 [hidden]{display:none} 盖掉 */
|
|
190
387
|
[data-scope='toast'][data-part='action-trigger'][hidden] {
|
|
191
388
|
display: none;
|
|
192
389
|
}
|
|
193
390
|
|
|
194
|
-
|
|
195
|
-
|
|
391
|
+
/*
|
|
392
|
+
* 倒计时条。总时长由连接层写进 --xh-toast-progress-duration(不自动消失的那些整条收起),
|
|
393
|
+
* 计时被按住时动画一并停住——停表这件事此前没有任何可画的地方。
|
|
394
|
+
* 取装饰档 --xh-_tone-soft:压在同族淡底上仍看得出来。
|
|
395
|
+
*/
|
|
396
|
+
[data-scope='toast'][data-part='progress'] {
|
|
397
|
+
position: absolute;
|
|
398
|
+
inset-block-end: 0;
|
|
399
|
+
inset-inline-start: 0;
|
|
400
|
+
overflow: hidden;
|
|
401
|
+
inline-size: 100%;
|
|
402
|
+
block-size: var(--xh-toast-progress-thickness, var(--xh-space-0_5));
|
|
403
|
+
background: var(--xh-toast-progress-bg, var(--xh-_tone-soft));
|
|
404
|
+
animation: xh-countdown var(--xh-toast-progress-duration, var(--xh-motion-duration-slide)) var(--xh-motion-ease-loop) forwards;
|
|
196
405
|
}
|
|
197
406
|
|
|
198
|
-
[data-scope='toast'][data-part='
|
|
199
|
-
|
|
407
|
+
[data-scope='toast'][data-part='root'][data-paused] [data-part='progress'] {
|
|
408
|
+
animation-play-state: paused;
|
|
200
409
|
}
|
|
201
410
|
|
|
202
|
-
[data-scope='toast'][data-part='
|
|
203
|
-
|
|
204
|
-
outline-offset: var(--xh-ring-offset);
|
|
411
|
+
[data-scope='toast'][data-part='progress'][hidden] {
|
|
412
|
+
display: none;
|
|
205
413
|
}
|
|
206
414
|
|
|
415
|
+
/* 关闭钮是只有字形的离散动作钮:盒几何、悬停 / 按下与 0.97 按压、粗指针热区、焦点环、禁用面全由 Action Control
|
|
416
|
+
的 icon ghost 档给(连接层投 xs:24px 正方盒,与此前 --xh-control-action-size 同尺寸;那颗叉排在单行短消息里,
|
|
417
|
+
走行级动作钮那一档),组件只映射既有使用者槽。静息透明,sheet 白面承载 hover 100 → pressed 200,
|
|
418
|
+
写了语气时悬停底跟着语气走(--xh-_tone-subtle)。
|
|
419
|
+
有悬停能力的设备上默认静默、指针进入条子或焦点落进条子后显现——不走家族的 hover-focus 显示策略:
|
|
420
|
+
那一档用 visibility 收起,这颗叉占 Tab 位,收成 visibility: hidden 后键盘就够不到它了;
|
|
421
|
+
这里只压 opacity 与 pointer-events,焦点仍能落进来 */
|
|
207
422
|
[data-scope='toast'][data-part='close-trigger'] {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
cursor: pointer;
|
|
225
|
-
transition:
|
|
226
|
-
background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
227
|
-
color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
228
|
-
scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
229
|
-
}
|
|
423
|
+
--xh-action-visual-size: var(--xh-toast-close-size, var(--xh-_action-profile-visual-size));
|
|
424
|
+
--xh-action-min-inline-size: var(--xh-toast-close-size, var(--xh-_action-profile-visual-size));
|
|
425
|
+
--xh-action-radius: var(--xh-toast-close-radius, var(--xh-shape-control));
|
|
426
|
+
--xh-action-bg-rest: var(--xh-toast-close-bg, var(--xh-_action-variant-bg-rest));
|
|
427
|
+
--xh-action-bg-hover: var(--xh-toast-close-bg-hover, var(--xh-_action-variant-bg-hover));
|
|
428
|
+
--xh-action-bg-pressed: var(--xh-toast-close-bg-active, var(--xh-_action-variant-bg-pressed));
|
|
429
|
+
--xh-action-fg-rest: var(--xh-toast-close-fg, var(--xh-fg-muted));
|
|
430
|
+
--xh-action-fg-hover: var(--xh-toast-close-fg-hover, var(--xh-fg-default));
|
|
431
|
+
--xh-action-fg-pressed: var(--xh-toast-close-fg-hover, var(--xh-fg-default));
|
|
432
|
+
--xh-action-border-rest: var(--xh-toast-close-border, var(--xh-_action-variant-border-rest));
|
|
433
|
+
--xh-action-highlight-rest: transparent;
|
|
434
|
+
--xh-action-shadow-rest: none;
|
|
435
|
+
--xh-action-shadow-hover: none;
|
|
436
|
+
--xh-action-shadow-pressed: none;
|
|
437
|
+
/* 叉的字形按钮档取值(xs → 16px),与 root 上给指示符的 md 档分开 */
|
|
438
|
+
--xh-icon-size: var(--xh-toast-icon-size, var(--xh-_action-profile-glyph-size));
|
|
230
439
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
[data-scope='toast'][data-part='close-trigger'][hidden] {
|
|
234
|
-
display: none;
|
|
440
|
+
flex: none;
|
|
441
|
+
align-self: center;
|
|
235
442
|
}
|
|
236
443
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
444
|
+
@media (hover: hover) {
|
|
445
|
+
[data-scope='toast'][data-part='close-trigger'] {
|
|
446
|
+
opacity: 0;
|
|
447
|
+
pointer-events: none;
|
|
448
|
+
}
|
|
241
449
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
450
|
+
[data-scope='toast'][data-part='root']:hover [data-part='close-trigger'],
|
|
451
|
+
[data-scope='toast'][data-part='root']:focus-within [data-part='close-trigger'] {
|
|
452
|
+
opacity: 1;
|
|
453
|
+
pointer-events: auto;
|
|
454
|
+
}
|
|
245
455
|
}
|
|
246
456
|
|
|
247
|
-
/*
|
|
248
|
-
|
|
249
|
-
[data-
|
|
250
|
-
|
|
251
|
-
|
|
457
|
+
/* 折叠堆叠只允许最前一条露出关闭入口;触屏没有 hover,必须显式收起后台按钮。 */
|
|
458
|
+
[data-scope='toast'][data-part='root'][data-stack-index]:not([data-frontmost]):not([data-expanded])
|
|
459
|
+
[data-part='close-trigger'] {
|
|
460
|
+
opacity: 0;
|
|
461
|
+
pointer-events: none;
|
|
252
462
|
}
|
|
253
463
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
464
|
+
/* closable=false 时连接层同时给了 hidden 与 disabled,这条是它真正收起的那一半:
|
|
465
|
+
上面声明了 display,不补回来就会留下一个按不动的叉,比压根没有叉更让人困惑 */
|
|
466
|
+
[data-scope='toast'][data-part='close-trigger'][hidden] {
|
|
467
|
+
display: none;
|
|
257
468
|
}
|
|
258
469
|
|
|
259
470
|
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
@@ -267,4 +478,22 @@
|
|
|
267
478
|
-webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
268
479
|
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
269
480
|
}
|
|
481
|
+
|
|
482
|
+
@media print {
|
|
483
|
+
/* 打印:轻提示是瞬态的,打印那一刻恰好在场就会横在正文上,且它已经错过了被读到的时机。 */
|
|
484
|
+
[data-scope='toast'][data-part='group'] {
|
|
485
|
+
display: none;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/* 摞收起后条子本不该出现在纸上;这一条兜的是作者把条子摆在别处的用法:
|
|
489
|
+
动画会被定格在任意一帧——转了一半的圈。取值与减弱动效那一档相同。 */
|
|
490
|
+
[data-scope='toast'][data-part='root'][data-loading]::before {
|
|
491
|
+
animation: none;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
[data-scope='toast'][data-part='content'][hidden],
|
|
496
|
+
[data-scope='toast'][data-part='description'][hidden] {
|
|
497
|
+
display: none;
|
|
498
|
+
}
|
|
270
499
|
}
|