@xihan-ui/styles 1.0.0-alpha.2 → 1.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +447 -0
- package/README.md +1 -1
- package/css/accordion.css +56 -5
- package/css/alert.css +30 -5
- package/css/anchor.css +7 -7
- package/css/avatar-group.css +3 -3
- package/css/avatar.css +3 -3
- package/css/back-top.css +16 -1
- package/css/badge.css +16 -2
- package/css/breadcrumb.css +24 -4
- package/css/button-group.css +14 -13
- package/css/button.css +42 -11
- package/css/calendar.css +119 -2
- package/css/card.css +5 -5
- package/css/carousel.css +36 -5
- package/css/cascader.css +183 -102
- package/css/checkbox-group.css +41 -19
- package/css/checkbox.css +54 -8
- package/css/clipboard.css +2 -1
- package/css/code-block.css +12 -7
- package/css/collapsible.css +42 -2
- package/css/color-picker.css +111 -45
- package/css/combobox.css +114 -53
- package/css/composer.css +5 -3
- package/css/context-menu.css +97 -69
- package/css/date-field.css +91 -14
- package/css/date-picker.css +276 -65
- package/css/descriptions.css +2 -2
- package/css/dialog.css +40 -13
- package/css/download-trigger.css +76 -0
- package/css/drawer.css +45 -14
- package/css/dynamic-input.css +68 -17
- package/css/editable.css +12 -10
- package/css/ellipsis.css +1 -1
- package/css/empty-state.css +7 -7
- package/css/field.css +9 -6
- package/css/fieldset.css +69 -0
- package/css/file-upload.css +45 -7
- package/css/float-button.css +16 -1
- package/css/floating-panel.css +310 -0
- package/css/form.css +4 -4
- package/css/heatmap.css +410 -0
- package/css/highlight.css +1 -1
- package/css/hotkeys.css +90 -0
- package/css/hover-card.css +40 -45
- package/css/image-cropper.css +231 -0
- package/css/image-viewer.css +137 -12
- package/css/image.css +2 -2
- package/css/infinite-scroll.css +1 -1
- package/css/json-viewer.css +241 -0
- package/css/layout.css +6 -10
- package/css/list.css +8 -8
- package/css/listbox.css +20 -4
- package/css/loading-bar.css +7 -1
- package/css/log.css +1 -1
- package/css/marquee.css +9 -0
- package/css/masonry.css +63 -0
- package/css/mention.css +87 -33
- package/css/menu.css +113 -47
- package/css/menubar.css +146 -60
- package/css/navigation-menu.css +54 -29
- package/css/number-animation.css +3 -3
- package/css/number-field.css +173 -16
- package/css/overlay-arrow.css +51 -0
- package/css/page-header.css +5 -5
- package/css/pagination.css +13 -13
- package/css/password-input.css +356 -0
- package/css/pin-input.css +13 -10
- package/css/popconfirm.css +46 -10
- package/css/popover.css +70 -45
- package/css/popselect.css +183 -53
- package/css/progress.css +47 -7
- package/css/qr-code.css +1 -1
- package/css/radio-group.css +14 -8
- package/css/rating.css +2 -2
- package/css/reset.css +17 -0
- package/css/result.css +6 -6
- package/css/scroll-area.css +61 -89
- package/css/scrollbar.css +167 -0
- package/css/segmented.css +215 -0
- package/css/select.css +274 -125
- package/css/separator.css +2 -2
- package/css/side-nav.css +111 -19
- package/css/signature-pad.css +144 -0
- package/css/skeleton.css +7 -1
- package/css/slider.css +10 -10
- package/css/space.css +117 -0
- package/css/spinner.css +22 -10
- package/css/statistic.css +9 -9
- package/css/steps.css +25 -8
- package/css/switch.css +48 -6
- package/css/table.css +131 -37
- package/css/tabs.css +4 -4
- package/css/tag.css +177 -0
- package/css/tags-input.css +78 -40
- package/css/text-field.css +149 -36
- package/css/thread.css +1 -1
- package/css/time-field.css +97 -16
- package/css/time-picker.css +259 -69
- package/css/timeline.css +10 -10
- package/css/timer.css +119 -0
- package/css/toast.css +34 -10
- package/css/toaster.css +1 -1
- package/css/toggle.css +6 -6
- package/css/tone.css +10 -5
- package/css/toolbar.css +1 -1
- package/css/tooltip.css +36 -33
- package/css/tour.css +103 -58
- package/css/transfer.css +68 -17
- package/css/tree-select.css +185 -84
- package/css/tree.css +85 -1
- package/css/typography.css +4 -4
- package/css/undefined.css +11 -1
- package/css/virtualizer.css +3 -1
- package/css/watermark.css +1 -2
- package/index.css +17 -0
- package/index.unlayered.css +8659 -2799
- package/package.json +19 -3
package/css/mention.css
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
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
|
+
@keyframes xh-pop-out {
|
|
16
|
+
from {
|
|
17
|
+
opacity: 1;
|
|
18
|
+
scale: 1;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
to {
|
|
22
|
+
opacity: 0;
|
|
23
|
+
scale: var(--xh-motion-scale-enter);
|
|
11
24
|
}
|
|
12
25
|
}
|
|
13
26
|
}
|
|
@@ -18,9 +31,27 @@
|
|
|
18
31
|
--xh-mention-skin: 1;
|
|
19
32
|
}
|
|
20
33
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
35
|
+
[data-scope='mention'][data-part='positioner'] {
|
|
36
|
+
/* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,内容层继承它限高;
|
|
37
|
+
引擎没算(尚未落位 / 无引擎)时不额外限高 */
|
|
38
|
+
--xh-_mention-available-h: 100vh;
|
|
39
|
+
|
|
40
|
+
position: fixed;
|
|
41
|
+
z-index: var(--xh-mention-layer, var(--xh-layer-popover));
|
|
42
|
+
/* 空壳不吃指针,交互只发生在 content 上 */
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* 输入框被滚出可视区:整个浮层随之收起 */
|
|
47
|
+
[data-scope='mention'][data-part='positioner'][data-hidden] {
|
|
48
|
+
visibility: hidden;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
|
|
52
|
+
[data-scope='mention']:is([data-part='root'], [data-part='positioner']) {
|
|
53
|
+
/* 尺寸档只换这五个私有槽,输入框与候选都从这两处继承它们,换档不必给每个部件各写一条选择器 */
|
|
54
|
+
--xh-_mention-h: var(--xh-control-h-md);
|
|
24
55
|
--xh-_mention-px: var(--xh-control-px-md);
|
|
25
56
|
--xh-_mention-py: var(--xh-field-py);
|
|
26
57
|
--xh-_mention-gap: var(--xh-control-gap-md);
|
|
@@ -33,7 +64,9 @@
|
|
|
33
64
|
|
|
34
65
|
/* 聚焦环恒用固定环色,不随语气走 */
|
|
35
66
|
--xh-_mention-ring: var(--xh-ring-focus);
|
|
67
|
+
}
|
|
36
68
|
|
|
69
|
+
[data-scope='mention'][data-part='root'] {
|
|
37
70
|
display: block;
|
|
38
71
|
}
|
|
39
72
|
|
|
@@ -44,37 +77,39 @@
|
|
|
44
77
|
|
|
45
78
|
/* —— 尺寸 —— */
|
|
46
79
|
/* 缺省档写在上面的基础规则里 */
|
|
47
|
-
[data-scope='mention'][data-part='root'][data-size='sm'] {
|
|
80
|
+
[data-scope='mention']:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
|
|
81
|
+
--xh-_mention-h: var(--xh-control-h-sm);
|
|
48
82
|
--xh-_mention-px: var(--xh-control-px-sm);
|
|
49
83
|
--xh-_mention-py: var(--xh-space-1);
|
|
50
84
|
--xh-_mention-gap: var(--xh-control-gap-sm);
|
|
51
|
-
--xh-_mention-font-size: var(--xh-font-
|
|
85
|
+
--xh-_mention-font-size: var(--xh-control-font-sm);
|
|
52
86
|
}
|
|
53
87
|
|
|
54
|
-
[data-scope='mention'][data-part='root'][data-size='lg'] {
|
|
88
|
+
[data-scope='mention']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
|
|
89
|
+
--xh-_mention-h: var(--xh-control-h-lg);
|
|
55
90
|
--xh-_mention-px: var(--xh-control-px-lg);
|
|
56
91
|
--xh-_mention-py: var(--xh-space-3);
|
|
57
92
|
--xh-_mention-gap: var(--xh-control-gap-lg);
|
|
58
|
-
--xh-_mention-font-size: var(--xh-font-
|
|
93
|
+
--xh-_mention-font-size: var(--xh-control-font-lg);
|
|
59
94
|
}
|
|
60
95
|
|
|
61
96
|
/* —— 形态 —— */
|
|
62
97
|
/* 输入类不做 solid:实心底压着可编辑的正文,读起来像块不可点的色板。
|
|
63
98
|
形态只决定描边与底色怎么用,用哪族颜色由 data-tone 决定 */
|
|
64
|
-
[data-scope='mention'][data-part='root'][data-variant='outline'] {
|
|
99
|
+
[data-scope='mention']:is([data-part='root'], [data-part='positioner'])[data-variant='outline'] {
|
|
65
100
|
--xh-_mention-input-bg: var(--xh-bg-canvas);
|
|
66
101
|
--xh-_mention-input-border: var(--xh-border-control);
|
|
67
102
|
--xh-_mention-input-border-hover: var(--xh-border-control-hover);
|
|
68
103
|
}
|
|
69
104
|
|
|
70
105
|
/* 填充式:底色顶替描边,悬停时才浮出一道淡边 */
|
|
71
|
-
[data-scope='mention'][data-part='root'][data-variant='subtle'] {
|
|
106
|
+
[data-scope='mention']:is([data-part='root'], [data-part='positioner'])[data-variant='subtle'] {
|
|
72
107
|
--xh-_mention-input-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
|
|
73
108
|
--xh-_mention-input-border: transparent;
|
|
74
109
|
--xh-_mention-input-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
75
110
|
}
|
|
76
111
|
|
|
77
|
-
[data-scope='mention'][data-part='root'][data-variant='ghost'] {
|
|
112
|
+
[data-scope='mention']:is([data-part='root'], [data-part='positioner'])[data-variant='ghost'] {
|
|
78
113
|
--xh-_mention-input-bg: transparent;
|
|
79
114
|
--xh-_mention-input-border: transparent;
|
|
80
115
|
--xh-_mention-input-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
@@ -85,6 +120,9 @@
|
|
|
85
120
|
[data-scope='mention'][data-part='input'] {
|
|
86
121
|
display: block;
|
|
87
122
|
inline-size: 100%;
|
|
123
|
+
min-inline-size: var(--xh-mention-input-min-w, var(--xh-control-min-w));
|
|
124
|
+
/* 缺省宿主是 textarea:高度按行数撑,控件档只兜住底线 */
|
|
125
|
+
min-block-size: var(--xh-mention-input-h, var(--xh-_mention-h));
|
|
88
126
|
padding-block: var(--xh-mention-input-py, var(--xh-_mention-py));
|
|
89
127
|
padding-inline: var(--xh-mention-input-px, var(--xh-_mention-px));
|
|
90
128
|
border: var(--xh-stroke-thin) solid var(--xh-mention-input-border, var(--xh-_mention-input-border));
|
|
@@ -100,6 +138,13 @@
|
|
|
100
138
|
transition: border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
101
139
|
}
|
|
102
140
|
|
|
141
|
+
/* 单行宿主定高到控件档,纵向内距归零,与并排的其他控件等高。
|
|
142
|
+
单行与多行在 DOM 上只差一个标签名,没有别的标记可选,所以按标签名分支 */
|
|
143
|
+
input[data-scope='mention'][data-part='input'] {
|
|
144
|
+
block-size: var(--xh-mention-input-h, var(--xh-_mention-h));
|
|
145
|
+
padding-block: 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
103
148
|
[data-scope='mention'][data-part='input'][hidden] {
|
|
104
149
|
display: none;
|
|
105
150
|
}
|
|
@@ -108,16 +153,28 @@
|
|
|
108
153
|
color: var(--xh-mention-placeholder-fg, var(--xh-fg-subtle));
|
|
109
154
|
}
|
|
110
155
|
|
|
111
|
-
[data-scope='mention'][data-part='input']:hover:not(:disabled) {
|
|
156
|
+
[data-scope='mention'][data-part='input']:hover:not(:disabled, [data-invalid]) {
|
|
112
157
|
border-color: var(--xh-mention-input-border-hover, var(--xh-_mention-input-border-hover));
|
|
113
158
|
}
|
|
114
159
|
|
|
115
160
|
[data-scope='mention'][data-part='input']:focus-visible {
|
|
116
|
-
border-color: var(--xh-mention-input-border-focus, var(--xh-
|
|
161
|
+
border-color: var(--xh-mention-input-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
|
|
117
162
|
outline: var(--xh-ring-width) solid var(--xh-_mention-ring);
|
|
118
163
|
outline-offset: var(--xh-ring-offset);
|
|
119
164
|
}
|
|
120
165
|
|
|
166
|
+
[data-scope='mention'][data-part='input'][data-invalid] {
|
|
167
|
+
border-color: var(--xh-mention-input-border-invalid, var(--xh-border-invalid));
|
|
168
|
+
|
|
169
|
+
/* 校验失败时环也跟着变红:两圈等宽相邻却一红一蓝,读的人不知道哪个才是当前状态 */
|
|
170
|
+
--xh-_mention-ring: var(--xh-ring-invalid);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* 只读仍可聚焦、可复制,所以不置灰,只把底色压下去表示"改不动" */
|
|
174
|
+
[data-scope='mention'][data-part='input'][readonly] {
|
|
175
|
+
background: var(--xh-mention-input-bg-readonly, var(--xh-bg-subtle));
|
|
176
|
+
}
|
|
177
|
+
|
|
121
178
|
/* 输入框是单体表单控件,禁用走原生 disabled(候选那边一律 aria-disabled) */
|
|
122
179
|
[data-scope='mention'][data-part='input']:disabled {
|
|
123
180
|
background: var(--xh-mention-input-bg-disabled, var(--xh-bg-subtle));
|
|
@@ -127,40 +184,28 @@
|
|
|
127
184
|
cursor: not-allowed;
|
|
128
185
|
}
|
|
129
186
|
|
|
130
|
-
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
131
|
-
[data-scope='mention'][data-part='positioner'] {
|
|
132
|
-
position: fixed;
|
|
133
|
-
z-index: var(--xh-layer-popover);
|
|
134
|
-
/* 空壳不吃指针,交互只发生在 content 上 */
|
|
135
|
-
pointer-events: none;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/* 输入框被滚出可视区:整个浮层随之收起 */
|
|
139
|
-
[data-scope='mention'][data-part='positioner'][data-hidden] {
|
|
140
|
-
visibility: hidden;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
187
|
[data-scope='mention'][data-part='content'] {
|
|
144
188
|
display: flex;
|
|
145
189
|
flex-direction: column;
|
|
146
190
|
min-inline-size: var(--xh-mention-content-min-w, var(--xh-overlay-min-w));
|
|
147
191
|
max-inline-size: var(--xh-mention-content-max-w, var(--xh-overlay-max-w));
|
|
148
|
-
max-block-size: var(--xh-mention-content-max-h, var(--xh-overlay-max-h));
|
|
192
|
+
max-block-size: min(var(--xh-mention-content-max-h, var(--xh-overlay-max-h)), var(--xh-_mention-available-h));
|
|
149
193
|
padding-block: var(--xh-mention-content-py, var(--xh-space-1));
|
|
150
194
|
padding-inline: var(--xh-mention-content-px, var(--xh-space-1));
|
|
151
195
|
border: var(--xh-stroke-thin) solid var(--xh-mention-content-border, var(--xh-border-default));
|
|
152
196
|
border-radius: var(--xh-mention-content-radius, var(--xh-shape-surface));
|
|
153
197
|
background: var(--xh-mention-content-bg, var(--xh-bg-surface));
|
|
154
198
|
color: var(--xh-mention-content-fg, var(--xh-fg-default));
|
|
155
|
-
box-shadow: var(--xh-mention-content-shadow, var(--xh-elevation-
|
|
199
|
+
box-shadow: var(--xh-mention-content-shadow, var(--xh-elevation-floating));
|
|
156
200
|
overflow-y: auto;
|
|
157
201
|
pointer-events: auto;
|
|
158
202
|
}
|
|
159
203
|
|
|
160
|
-
/*
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
204
|
+
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
|
|
205
|
+
收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
|
|
206
|
+
[hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
|
|
207
|
+
真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
|
|
208
|
+
其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
|
|
164
209
|
|
|
165
210
|
/* 宿主把候选全筛没了:浮层还开着,但这一副框壳没有内容可框,整个让位。
|
|
166
211
|
组件不替宿主判空——「没有匹配项」要不要说话、说什么,是宿主的事 */
|
|
@@ -175,7 +220,13 @@
|
|
|
175
220
|
}
|
|
176
221
|
|
|
177
222
|
[data-scope='mention'][data-part='content'][data-state='open'] {
|
|
178
|
-
animation: xh-
|
|
223
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
|
|
227
|
+
免得动画结束到真收起之间闪一下原样 */
|
|
228
|
+
[data-scope='mention'][data-part='content'][data-state='closed'] {
|
|
229
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
179
230
|
}
|
|
180
231
|
|
|
181
232
|
[data-scope='mention'][data-part='item'] {
|
|
@@ -205,6 +256,9 @@
|
|
|
205
256
|
两套底色各画各的会出现"鼠标停在 A 上、回车却插进了 B" */
|
|
206
257
|
[data-scope='mention'][data-part='item'][data-highlighted]:not([data-disabled]) {
|
|
207
258
|
background: var(--xh-mention-item-bg-hover, var(--xh-bg-subtle));
|
|
259
|
+
/* 焦点恒在输入框,高亮条目自带内收环;列表是滚动容器,环画在外沿会被裁掉 */
|
|
260
|
+
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
261
|
+
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
208
262
|
}
|
|
209
263
|
|
|
210
264
|
/* 禁用走 aria-disabled 而非原生 disabled(原生 disabled 不派 click,禁用守卫就走不到),
|
package/css/menu.css
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
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
|
+
@keyframes xh-pop-out {
|
|
16
|
+
from {
|
|
17
|
+
opacity: 1;
|
|
18
|
+
scale: 1;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
to {
|
|
22
|
+
opacity: 0;
|
|
23
|
+
scale: var(--xh-motion-scale-enter);
|
|
11
24
|
}
|
|
12
25
|
}
|
|
13
26
|
}
|
|
@@ -20,8 +33,12 @@
|
|
|
20
33
|
|
|
21
34
|
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
22
35
|
[data-scope='menu'][data-part='positioner'] {
|
|
36
|
+
/* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,content 继承它限高;
|
|
37
|
+
引擎没算(尚未落位 / 无引擎)时不额外限高 */
|
|
38
|
+
--xh-_menu-available-h: 100vh;
|
|
39
|
+
|
|
23
40
|
position: fixed;
|
|
24
|
-
z-index: var(--xh-layer-popover);
|
|
41
|
+
z-index: var(--xh-menu-layer, var(--xh-layer-popover));
|
|
25
42
|
/* 空壳不吃指针,交互只发生在 content 上 */
|
|
26
43
|
pointer-events: none;
|
|
27
44
|
}
|
|
@@ -31,7 +48,23 @@
|
|
|
31
48
|
visibility: hidden;
|
|
32
49
|
}
|
|
33
50
|
|
|
51
|
+
/* 触发器的长相归作者,皮肤只表达展开态。私有槽声明在它自己身上:
|
|
52
|
+
菜单没有 root 部件,触发器上头没有别的 menu 节点可以挂 */
|
|
53
|
+
[data-scope='menu'][data-part='trigger'] {
|
|
54
|
+
/* 展开着的那张菜单的触发器走品牌淡底强档,随语气换色相;没写 data-tone 时退回品牌淡底 */
|
|
55
|
+
--xh-_menu-active-bg: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* 展开着的那一张是打开路径,走品牌淡底强档:哪一张开着必须一眼看得出来。
|
|
59
|
+
不加粗:加粗会推挤相邻内容 */
|
|
60
|
+
[data-scope='menu'][data-part='trigger']:not([data-disabled])[data-state='open'] {
|
|
61
|
+
background: var(--xh-menu-trigger-bg-active, var(--xh-_menu-active-bg));
|
|
62
|
+
}
|
|
63
|
+
|
|
34
64
|
[data-scope='menu'][data-part='content'] {
|
|
65
|
+
/* 作者塞进条目里的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
66
|
+
--xh-icon-size: var(--xh-menu-icon-size, var(--xh-glyph-size-text));
|
|
67
|
+
|
|
35
68
|
/* 尺寸档只换这四个私有槽,条目从 content 继承它们,换档不必给每个部件各写一条选择器。
|
|
36
69
|
菜单没有 root 部件(浮层树的最外层就是 content),三轴属性都落在这里 */
|
|
37
70
|
--xh-_menu-item-py: var(--xh-space-1_5);
|
|
@@ -47,20 +80,26 @@
|
|
|
47
80
|
flex-direction: column;
|
|
48
81
|
min-inline-size: var(--xh-menu-min-w, var(--xh-overlay-menu-min-w));
|
|
49
82
|
max-inline-size: var(--xh-menu-max-w, var(--xh-overlay-max-w));
|
|
83
|
+
/* 两道上限取更小的那道:自己的高度上限,以及落定那一侧真正剩下的空间。
|
|
84
|
+
列表族的 16rem 对命令菜单偏矮,这里另给一档 */
|
|
85
|
+
max-block-size: min(var(--xh-menu-max-h, var(--xh-overlay-menu-max-h)), var(--xh-_menu-available-h));
|
|
50
86
|
padding-block: var(--xh-menu-py, var(--xh-space-1));
|
|
51
87
|
padding-inline: var(--xh-menu-px, var(--xh-space-1));
|
|
52
88
|
border: var(--xh-stroke-thin) solid var(--xh-menu-border, var(--xh-border-default));
|
|
53
89
|
border-radius: var(--xh-menu-radius, var(--xh-shape-surface));
|
|
54
90
|
background: var(--xh-menu-bg, var(--xh-bg-surface));
|
|
55
91
|
color: var(--xh-menu-fg, var(--xh-fg-default));
|
|
56
|
-
box-shadow: var(--xh-menu-shadow, var(--xh-elevation-
|
|
92
|
+
box-shadow: var(--xh-menu-shadow, var(--xh-elevation-floating));
|
|
93
|
+
/* 条目超过上限就在菜单内部滚。条目的焦点环是内收的,滚动容器裁在内边距缘上,环切不着 */
|
|
94
|
+
overflow-y: auto;
|
|
57
95
|
pointer-events: auto;
|
|
58
96
|
}
|
|
59
97
|
|
|
60
|
-
/*
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
98
|
+
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
|
|
99
|
+
收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
|
|
100
|
+
[hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
|
|
101
|
+
真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
|
|
102
|
+
其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
|
|
64
103
|
|
|
65
104
|
/* 容器只是焦点域兜底落点,落焦不画环:高亮永远长在条目上 */
|
|
66
105
|
[data-scope='menu'][data-part='content']:focus-visible {
|
|
@@ -68,7 +107,13 @@
|
|
|
68
107
|
}
|
|
69
108
|
|
|
70
109
|
[data-scope='menu'][data-part='content'][data-state='open'] {
|
|
71
|
-
animation: xh-
|
|
110
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
|
|
114
|
+
免得动画结束到真收起之间闪一下原样 */
|
|
115
|
+
[data-scope='menu'][data-part='content'][data-state='closed'] {
|
|
116
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
72
117
|
}
|
|
73
118
|
|
|
74
119
|
/* —— 尺寸 —— */
|
|
@@ -78,14 +123,14 @@
|
|
|
78
123
|
--xh-_menu-item-py: var(--xh-space-1);
|
|
79
124
|
--xh-_menu-item-px: var(--xh-control-px-sm);
|
|
80
125
|
--xh-_menu-item-gap: var(--xh-control-gap-sm);
|
|
81
|
-
--xh-_menu-font-size: var(--xh-font-
|
|
126
|
+
--xh-_menu-font-size: var(--xh-control-font-sm);
|
|
82
127
|
}
|
|
83
128
|
|
|
84
129
|
[data-scope='menu'][data-part='content'][data-size='lg'] {
|
|
85
130
|
--xh-_menu-item-py: var(--xh-space-2);
|
|
86
131
|
--xh-_menu-item-px: var(--xh-control-px-lg);
|
|
87
132
|
--xh-_menu-item-gap: var(--xh-control-gap-lg);
|
|
88
|
-
--xh-_menu-font-size: var(--xh-font-
|
|
133
|
+
--xh-_menu-font-size: var(--xh-control-font-lg);
|
|
89
134
|
}
|
|
90
135
|
|
|
91
136
|
[data-scope='menu'][data-part='item'] {
|
|
@@ -106,8 +151,8 @@
|
|
|
106
151
|
color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
107
152
|
}
|
|
108
153
|
|
|
109
|
-
/*
|
|
110
|
-
[data-scope='menu'][data-part='item']:not([data-disabled]):is(:hover,
|
|
154
|
+
/* 悬停与键盘锚点共用中性灰轻档:锚点只认连接层打的 data-highlighted,不读 :focus */
|
|
155
|
+
[data-scope='menu'][data-part='item']:not([data-disabled]):is(:hover, [data-highlighted]) {
|
|
111
156
|
background: var(--xh-menu-item-bg-hover, var(--xh-bg-subtle));
|
|
112
157
|
}
|
|
113
158
|
|
|
@@ -118,7 +163,13 @@
|
|
|
118
163
|
font-weight: var(--xh-menu-item-active-font-weight, var(--xh-font-weight-semibold));
|
|
119
164
|
}
|
|
120
165
|
|
|
121
|
-
|
|
166
|
+
/* 键盘落焦的条目画内收环;指针触发的聚焦不画 */
|
|
167
|
+
[data-scope='menu'][data-part='item']:focus-visible {
|
|
168
|
+
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
169
|
+
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
[data-scope='menu'][data-part='item']:focus:not(:focus-visible) {
|
|
122
173
|
outline: none;
|
|
123
174
|
}
|
|
124
175
|
|
|
@@ -127,52 +178,67 @@
|
|
|
127
178
|
cursor: not-allowed;
|
|
128
179
|
}
|
|
129
180
|
|
|
181
|
+
/* 带子菜单的条目行尾画右向小箭头:不点开也看得出还有下一级。
|
|
182
|
+
位置靠 margin 顶到行尾,图形取兜底字形令牌 */
|
|
183
|
+
[data-scope='menu'][data-part='item'][aria-haspopup='menu']::after {
|
|
184
|
+
content: '';
|
|
185
|
+
flex: none;
|
|
186
|
+
margin-inline-start: auto;
|
|
187
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
188
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
189
|
+
background-color: currentColor;
|
|
190
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
191
|
+
mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* rtl 下子菜单开在左侧,箭头跟着指向行进方向 */
|
|
195
|
+
[dir='rtl'] [data-scope='menu'][data-part='item'][aria-haspopup='menu']::after {
|
|
196
|
+
-webkit-mask-image: var(--xh-glyph-mark-chevron-left);
|
|
197
|
+
mask-image: var(--xh-glyph-mark-chevron-left);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
[data-scope='menu'][data-part='group'] {
|
|
201
|
+
display: flex;
|
|
202
|
+
flex-direction: column;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
[data-scope='menu'][data-part='group'][hidden] {
|
|
206
|
+
display: none;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* 分组标题不是条目、进不了导航,画成小号次要文字,
|
|
210
|
+
内缩与条目对齐(同一个 padding-inline),标题与条目文字才在一条竖线上 */
|
|
211
|
+
[data-scope='menu'][data-part='group-label'] {
|
|
212
|
+
display: block;
|
|
213
|
+
padding-block: var(--xh-menu-group-label-py, var(--xh-space-1));
|
|
214
|
+
padding-inline: var(--xh-menu-group-label-px, var(--xh-_menu-item-px));
|
|
215
|
+
color: var(--xh-menu-group-label-fg, var(--xh-fg-subtle));
|
|
216
|
+
font-size: var(--xh-menu-group-label-font-size, var(--xh-text-caption-size));
|
|
217
|
+
font-weight: var(--xh-menu-group-label-font-weight, var(--xh-font-weight-medium));
|
|
218
|
+
line-height: var(--xh-leading-none);
|
|
219
|
+
user-select: none;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
[data-scope='menu'][data-part='group-label'][hidden] {
|
|
223
|
+
display: none;
|
|
224
|
+
}
|
|
225
|
+
|
|
130
226
|
[data-scope='menu'][data-part='separator'] {
|
|
131
227
|
block-size: var(--xh-menu-separator-thickness, var(--xh-stroke-thin));
|
|
132
228
|
margin-block: var(--xh-menu-separator-my, var(--xh-space-1));
|
|
133
229
|
background: var(--xh-menu-separator-color, var(--xh-border-default));
|
|
134
230
|
}
|
|
135
231
|
|
|
136
|
-
/*
|
|
232
|
+
/* 箭头的底色与描边色,几何在 overlay-arrow.css。
|
|
137
233
|
交叉轴落点由定位引擎经内联自定义属性写进来,没给时退回居中 */
|
|
138
234
|
[data-scope='menu'][data-part='arrow'] {
|
|
139
|
-
--xh-_menu-arrow-size: var(--xh-menu-arrow-size, var(--xh-overlay-arrow-size));
|
|
140
235
|
--xh-_menu-arrow-x: 50%;
|
|
141
236
|
--xh-_menu-arrow-y: 50%;
|
|
237
|
+
--xh-_overlay-arrow-size: var(--xh-menu-arrow-size, var(--xh-overlay-arrow-size));
|
|
238
|
+
--xh-_overlay-arrow-x: var(--xh-_menu-arrow-x);
|
|
239
|
+
--xh-_overlay-arrow-y: var(--xh-_menu-arrow-y);
|
|
142
240
|
|
|
143
|
-
position: absolute;
|
|
144
|
-
inline-size: var(--xh-_menu-arrow-size);
|
|
145
|
-
block-size: var(--xh-_menu-arrow-size);
|
|
146
241
|
background: var(--xh-menu-bg, var(--xh-bg-surface));
|
|
147
242
|
border: var(--xh-stroke-thin) solid var(--xh-menu-border, var(--xh-border-default));
|
|
148
|
-
rotate: 45deg;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
[data-scope='menu'][data-part='arrow'][data-placement^='bottom'] {
|
|
152
|
-
inset-block-start: calc(var(--xh-_menu-arrow-size) / -2);
|
|
153
|
-
inset-inline-start: calc(var(--xh-_menu-arrow-x) - var(--xh-_menu-arrow-size) / 2);
|
|
154
|
-
border-block-end: 0;
|
|
155
|
-
border-inline-end: 0;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
[data-scope='menu'][data-part='arrow'][data-placement^='top'] {
|
|
159
|
-
inset-block-end: calc(var(--xh-_menu-arrow-size) / -2);
|
|
160
|
-
inset-inline-start: calc(var(--xh-_menu-arrow-x) - var(--xh-_menu-arrow-size) / 2);
|
|
161
|
-
border-block-start: 0;
|
|
162
|
-
border-inline-start: 0;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
[data-scope='menu'][data-part='arrow'][data-placement^='right'] {
|
|
166
|
-
inset-inline-start: calc(var(--xh-_menu-arrow-size) / -2);
|
|
167
|
-
inset-block-start: calc(var(--xh-_menu-arrow-y) - var(--xh-_menu-arrow-size) / 2);
|
|
168
|
-
border-block-start: 0;
|
|
169
|
-
border-inline-end: 0;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
[data-scope='menu'][data-part='arrow'][data-placement^='left'] {
|
|
173
|
-
inset-inline-end: calc(var(--xh-_menu-arrow-size) / -2);
|
|
174
|
-
inset-block-start: calc(var(--xh-_menu-arrow-y) - var(--xh-_menu-arrow-size) / 2);
|
|
175
|
-
border-block-end: 0;
|
|
176
|
-
border-inline-start: 0;
|
|
177
243
|
}
|
|
178
244
|
}
|