@xihan-ui/styles 1.0.0-alpha.1 → 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 +527 -0
- package/README.md +1 -1
- package/css/accordion.css +61 -5
- package/css/affix.css +5 -0
- package/css/alert.css +35 -5
- package/css/anchor.css +12 -7
- package/css/avatar-group.css +8 -3
- package/css/avatar.css +8 -3
- package/css/back-top.css +21 -1
- package/css/badge.css +21 -2
- package/css/breadcrumb.css +29 -4
- package/css/button-group.css +19 -13
- package/css/button.css +57 -11
- package/css/calendar.css +124 -2
- package/css/card.css +10 -5
- package/css/carousel.css +41 -5
- package/css/cascader.css +188 -102
- package/css/checkbox-group.css +46 -19
- package/css/checkbox.css +59 -8
- package/css/clipboard.css +7 -1
- package/css/code-block.css +17 -7
- package/css/collapsible.css +47 -2
- package/css/color-picker.css +117 -46
- package/css/combobox.css +132 -52
- package/css/composer.css +10 -3
- package/css/context-menu.css +101 -75
- package/css/countdown.css +5 -0
- package/css/date-field.css +96 -14
- package/css/date-picker.css +281 -65
- package/css/descriptions.css +7 -2
- package/css/dialog.css +109 -22
- package/css/download-trigger.css +76 -0
- package/css/drawer.css +75 -23
- package/css/dynamic-input.css +73 -17
- package/css/editable.css +17 -10
- package/css/ellipsis.css +6 -1
- package/css/empty-state.css +12 -7
- package/css/field.css +14 -6
- package/css/fieldset.css +69 -0
- package/css/file-upload.css +50 -7
- package/css/flex.css +5 -0
- package/css/float-button.css +21 -1
- package/css/floating-panel.css +310 -0
- package/css/form.css +10 -5
- package/css/gradient-text.css +5 -0
- package/css/grid.css +5 -0
- package/css/heatmap.css +410 -0
- package/css/highlight.css +6 -1
- package/css/hotkeys.css +90 -0
- package/css/hover-card.css +58 -50
- package/css/icon-wrapper.css +5 -0
- package/css/icon.css +5 -0
- package/css/image-cropper.css +231 -0
- package/css/image-viewer.css +167 -22
- package/css/image.css +7 -2
- package/css/infinite-scroll.css +6 -1
- package/css/json-viewer.css +241 -0
- package/css/layout.css +11 -10
- package/css/list.css +13 -8
- package/css/listbox.css +25 -4
- package/css/loading-bar.css +12 -1
- package/css/log.css +6 -1
- package/css/marquee.css +14 -0
- package/css/masonry.css +63 -0
- package/css/mention.css +105 -32
- package/css/menu.css +131 -46
- package/css/menubar.css +150 -66
- package/css/navigation-menu.css +59 -29
- package/css/number-animation.css +8 -3
- package/css/number-field.css +178 -16
- package/css/overlay-arrow.css +51 -0
- package/css/page-header.css +10 -5
- package/css/pagination.css +18 -13
- package/css/password-input.css +356 -0
- package/css/pin-input.css +18 -10
- package/css/popconfirm.css +73 -16
- package/css/popover.css +88 -44
- package/css/popselect.css +201 -52
- package/css/progress.css +52 -7
- package/css/qr-code.css +6 -1
- package/css/radio-group.css +19 -8
- package/css/rating.css +7 -2
- package/css/reset.css +17 -0
- package/css/result.css +11 -6
- package/css/scroll-area.css +65 -94
- package/css/scrollbar.css +167 -0
- package/css/segmented.css +215 -0
- package/css/select.css +292 -124
- package/css/separator.css +7 -2
- package/css/side-nav.css +116 -19
- package/css/signature-pad.css +144 -0
- package/css/skeleton.css +12 -1
- package/css/slider.css +15 -10
- package/css/space.css +117 -0
- package/css/spinner.css +31 -11
- package/css/splitter.css +5 -0
- package/css/statistic.css +14 -9
- package/css/steps.css +30 -8
- package/css/switch.css +62 -13
- package/css/table.css +136 -37
- package/css/tabs.css +9 -4
- package/css/tag.css +177 -0
- package/css/tags-input.css +83 -40
- package/css/text-field.css +154 -36
- package/css/thread.css +6 -1
- package/css/time-field.css +102 -16
- package/css/time-picker.css +264 -69
- package/css/time.css +5 -0
- package/css/timeline.css +15 -10
- package/css/timer.css +119 -0
- package/css/toast.css +46 -21
- package/css/toaster.css +6 -1
- package/css/toggle-group.css +5 -0
- package/css/toggle.css +11 -6
- package/css/tone.css +10 -5
- package/css/toolbar.css +6 -1
- package/css/tooltip.css +54 -38
- package/css/tour.css +128 -63
- package/css/transfer.css +73 -17
- package/css/tree-select.css +203 -83
- package/css/tree.css +90 -1
- package/css/typography.css +9 -4
- package/css/undefined.css +11 -1
- package/css/virtualizer.css +8 -1
- package/css/watermark.css +6 -2
- package/index.css +17 -1
- package/index.unlayered.css +9394 -2883
- package/package.json +19 -4
- package/css/motion.css +0 -58
package/css/menubar.css
CHANGED
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
@layer xihan.components {
|
|
2
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
|
+
[data-scope='menubar'] {
|
|
4
|
+
--xh-menubar-skin: 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
2
7
|
/* 一排 trigger。主轴跟着 data-orientation 走:菜单栏本身可以横排也可以竖排 */
|
|
3
8
|
[data-scope='menubar'][data-part='root'] {
|
|
4
|
-
/*
|
|
5
|
-
|
|
6
|
-
--xh-_menubar-trigger-py: var(--xh-space-1);
|
|
7
|
-
--xh-_menubar-trigger-px: var(--xh-control-px-sm);
|
|
8
|
-
--xh-_menubar-item-py: var(--xh-space-1_5);
|
|
9
|
-
--xh-_menubar-item-px: var(--xh-control-px-md);
|
|
10
|
-
--xh-_menubar-font-size: var(--xh-text-body-size);
|
|
11
|
-
|
|
12
|
-
/* 展开着的那张菜单的 trigger 走品牌淡底强档,随语气换色相;没写 data-tone 时退回品牌淡底。
|
|
13
|
-
悬停与键盘焦点恒中性灰轻档、不接语气槽——两档同色相的话哪张开着就认不出来了。
|
|
14
|
-
聚焦环不在其列,它恒是 --xh-ring-focus */
|
|
15
|
-
--xh-_menubar-active-bg: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
|
|
9
|
+
/* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
10
|
+
--xh-icon-size: var(--xh-menubar-icon-size, var(--xh-glyph-size-text));
|
|
16
11
|
|
|
17
12
|
display: flex;
|
|
18
13
|
align-items: center;
|
|
19
|
-
gap: var(--xh-menubar-gap, var(--xh-space-1));
|
|
20
|
-
padding-block: var(--xh-menubar-py, var(--xh-space-1));
|
|
21
|
-
padding-inline: var(--xh-menubar-px, var(--xh-space-1));
|
|
22
|
-
border-radius: var(--xh-menubar-radius, var(--xh-shape-control));
|
|
23
|
-
background: var(--xh-menubar-bg, transparent);
|
|
24
|
-
color: var(--xh-menubar-fg, var(--xh-fg-default));
|
|
14
|
+
gap: var(--xh-menubar-root-gap, var(--xh-space-1));
|
|
15
|
+
padding-block: var(--xh-menubar-root-py, var(--xh-space-1));
|
|
16
|
+
padding-inline: var(--xh-menubar-root-px, var(--xh-space-1));
|
|
17
|
+
border-radius: var(--xh-menubar-root-radius, var(--xh-shape-control));
|
|
18
|
+
background: var(--xh-menubar-root-bg, transparent);
|
|
19
|
+
color: var(--xh-menubar-root-fg, var(--xh-fg-default));
|
|
25
20
|
}
|
|
26
21
|
|
|
27
22
|
[data-scope='menubar'][data-part='root'][hidden] {
|
|
@@ -33,25 +28,6 @@
|
|
|
33
28
|
align-items: stretch;
|
|
34
29
|
}
|
|
35
30
|
|
|
36
|
-
/* —— 尺寸 —— */
|
|
37
|
-
/* 缺省档写在上面的基础规则里。trigger 的行内内缩缺省落在控件尺 sm 档、再往下取空间尺;
|
|
38
|
-
条目纵向走 space 档、行内内缩走 control-px 档(随密度轴),换档各挪一级 */
|
|
39
|
-
[data-scope='menubar'][data-part='root'][data-size='sm'] {
|
|
40
|
-
--xh-_menubar-trigger-py: var(--xh-space-0_5);
|
|
41
|
-
--xh-_menubar-trigger-px: var(--xh-space-1_5);
|
|
42
|
-
--xh-_menubar-item-py: var(--xh-space-1);
|
|
43
|
-
--xh-_menubar-item-px: var(--xh-control-px-sm);
|
|
44
|
-
--xh-_menubar-font-size: var(--xh-font-size-sm);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
[data-scope='menubar'][data-part='root'][data-size='lg'] {
|
|
48
|
-
--xh-_menubar-trigger-py: var(--xh-space-2);
|
|
49
|
-
--xh-_menubar-trigger-px: var(--xh-control-px-md);
|
|
50
|
-
--xh-_menubar-item-py: var(--xh-space-2);
|
|
51
|
-
--xh-_menubar-item-px: var(--xh-control-px-lg);
|
|
52
|
-
--xh-_menubar-font-size: var(--xh-font-size-lg);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
31
|
/* root 只是 roving tabindex 的兜底落点,焦点转投给 trigger 之后就不再停留,不画环 */
|
|
56
32
|
[data-scope='menubar'][data-part='root']:focus-visible {
|
|
57
33
|
outline: none;
|
|
@@ -112,8 +88,12 @@
|
|
|
112
88
|
|
|
113
89
|
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
114
90
|
[data-scope='menubar'][data-part='positioner'] {
|
|
91
|
+
/* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,content 继承它限高;
|
|
92
|
+
引擎没算(尚未落位 / 无引擎)时不额外限高 */
|
|
93
|
+
--xh-_menubar-available-h: 100vh;
|
|
94
|
+
|
|
115
95
|
position: fixed;
|
|
116
|
-
z-index: var(--xh-layer-popover);
|
|
96
|
+
z-index: var(--xh-menubar-layer, var(--xh-layer-popover));
|
|
117
97
|
/* 空壳不吃指针,交互只发生在 content 上 */
|
|
118
98
|
pointer-events: none;
|
|
119
99
|
}
|
|
@@ -123,26 +103,71 @@
|
|
|
123
103
|
visibility: hidden;
|
|
124
104
|
}
|
|
125
105
|
|
|
106
|
+
/* —— 尺寸 —— */
|
|
107
|
+
/* 尺寸档只换这六个私有槽,换档不必给每个部件各写一条选择器。
|
|
108
|
+
root 与 positioner 各起一头:trigger 从 root 继承,菜单里的条目从 positioner 继承——
|
|
109
|
+
浮层搬去了 portal 落点,不再是 root 的后代。
|
|
110
|
+
缺省档写在第一条:trigger 与条目的行内内缩都走 control-px 档(随密度轴)、纵向走 space 档,换档各挪一级 */
|
|
111
|
+
[data-scope='menubar']:is([data-part='root'], [data-part='positioner']) {
|
|
112
|
+
--xh-_menubar-trigger-py: var(--xh-space-1);
|
|
113
|
+
--xh-_menubar-trigger-px: var(--xh-control-px-md);
|
|
114
|
+
--xh-_menubar-item-py: var(--xh-space-1_5);
|
|
115
|
+
--xh-_menubar-item-px: var(--xh-control-px-md);
|
|
116
|
+
--xh-_menubar-item-gap: var(--xh-control-gap-md);
|
|
117
|
+
--xh-_menubar-font-size: var(--xh-text-body-size);
|
|
118
|
+
|
|
119
|
+
/* 展开着的那张菜单的 trigger 走品牌淡底强档,随语气换色相;没写 data-tone 时退回品牌淡底。
|
|
120
|
+
悬停与键盘焦点恒中性灰轻档、不接语气槽——两档同色相的话哪张开着就认不出来了。
|
|
121
|
+
聚焦环不在其列,它恒是 --xh-ring-focus */
|
|
122
|
+
--xh-_menubar-active-bg: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
|
|
123
|
+
|
|
124
|
+
/* 打开子菜单的触发条目走品牌淡底强档,随语气换色相;没写 data-tone 时退回品牌淡底 */
|
|
125
|
+
--xh-_menubar-item-active-bg: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
[data-scope='menubar'][data-size='sm']:is([data-part='root'], [data-part='positioner']) {
|
|
129
|
+
--xh-_menubar-trigger-py: var(--xh-space-0_5);
|
|
130
|
+
--xh-_menubar-trigger-px: var(--xh-control-px-sm);
|
|
131
|
+
--xh-_menubar-item-py: var(--xh-space-1);
|
|
132
|
+
--xh-_menubar-item-px: var(--xh-control-px-sm);
|
|
133
|
+
--xh-_menubar-item-gap: var(--xh-control-gap-sm);
|
|
134
|
+
--xh-_menubar-font-size: var(--xh-control-font-sm);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
[data-scope='menubar'][data-size='lg']:is([data-part='root'], [data-part='positioner']) {
|
|
138
|
+
--xh-_menubar-trigger-py: var(--xh-space-2);
|
|
139
|
+
--xh-_menubar-trigger-px: var(--xh-control-px-lg);
|
|
140
|
+
--xh-_menubar-item-py: var(--xh-space-2);
|
|
141
|
+
--xh-_menubar-item-px: var(--xh-control-px-lg);
|
|
142
|
+
--xh-_menubar-item-gap: var(--xh-control-gap-lg);
|
|
143
|
+
--xh-_menubar-font-size: var(--xh-control-font-lg);
|
|
144
|
+
}
|
|
145
|
+
|
|
126
146
|
[data-scope='menubar'][data-part='content'] {
|
|
127
147
|
display: flex;
|
|
128
148
|
flex-direction: column;
|
|
129
|
-
min-inline-size: var(--xh-menubar-
|
|
130
|
-
max-inline-size: var(--xh-menubar-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
149
|
+
min-inline-size: var(--xh-menubar-min-w, var(--xh-overlay-menu-min-w));
|
|
150
|
+
max-inline-size: var(--xh-menubar-max-w, var(--xh-overlay-max-w));
|
|
151
|
+
/* 两道上限取更小的那道:自己的高度上限,以及落定那一侧真正剩下的空间。
|
|
152
|
+
列表族的 16rem 对命令菜单偏矮,这里另给一档 */
|
|
153
|
+
max-block-size: min(var(--xh-menubar-max-h, var(--xh-overlay-menu-max-h)), var(--xh-_menubar-available-h));
|
|
154
|
+
padding-block: var(--xh-menubar-py, var(--xh-space-1));
|
|
155
|
+
padding-inline: var(--xh-menubar-px, var(--xh-space-1));
|
|
156
|
+
border: var(--xh-stroke-thin) solid var(--xh-menubar-border, var(--xh-border-default));
|
|
157
|
+
border-radius: var(--xh-menubar-radius, var(--xh-shape-surface));
|
|
158
|
+
background: var(--xh-menubar-bg, var(--xh-bg-surface));
|
|
159
|
+
color: var(--xh-menubar-fg, var(--xh-fg-default));
|
|
160
|
+
box-shadow: var(--xh-menubar-shadow, var(--xh-elevation-floating));
|
|
161
|
+
/* 条目超过上限就在菜单内部滚。条目的焦点环是内收的,滚动容器裁在内边距缘上,环切不着 */
|
|
162
|
+
overflow-y: auto;
|
|
138
163
|
pointer-events: auto;
|
|
139
164
|
}
|
|
140
165
|
|
|
141
166
|
/* display 会盖掉 hidden 属性的 UA 规则,收起态显式让位。
|
|
142
167
|
连接层给 content 发 hidden,这一条漏了整张菜单就永远收不起来 */
|
|
143
|
-
[data-
|
|
144
|
-
|
|
145
|
-
|
|
168
|
+
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
|
|
169
|
+
收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
|
|
170
|
+
[hidden]{display:none}——退场动画得先能播。真正的收起由宿主在退场结束后落成内联 display。 */
|
|
146
171
|
|
|
147
172
|
/* 容器只是"没有条目锚点时"的 Tab 兜底落点,落焦不画环:高亮永远长在条目上 */
|
|
148
173
|
[data-scope='menubar'][data-part='content']:focus-visible {
|
|
@@ -152,14 +177,19 @@
|
|
|
152
177
|
/* 展开时轻微涨开。只在切换到别张菜单时不重播——那由 data-state 的翻转天然保证:
|
|
153
178
|
一张关一张开,动画各跑各的 */
|
|
154
179
|
[data-scope='menubar'][data-part='content'][data-state='open'] {
|
|
155
|
-
animation: xh-
|
|
180
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
156
181
|
}
|
|
157
182
|
|
|
158
|
-
/*
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
183
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来 */
|
|
184
|
+
[data-scope='menubar'][data-part='content'][data-state='closed'] {
|
|
185
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* 在一排入口间换张时两侧都瞬时:交叉淡变读起来就是闪烁,且退场关键帧从不透明度 1
|
|
189
|
+
起跳,打断未播完的进场还会亮一下。原生菜单栏的成规——首开有进场、末收有退场、
|
|
190
|
+
换张不播。没有动画时退场闸门当场落定,收起即藏 */
|
|
191
|
+
[data-scope='menubar'][data-part='content'][data-instant] {
|
|
192
|
+
animation: none;
|
|
163
193
|
}
|
|
164
194
|
|
|
165
195
|
[data-scope='menubar'][data-part='group'] {
|
|
@@ -178,7 +208,7 @@
|
|
|
178
208
|
padding-block: var(--xh-menubar-group-label-py, var(--xh-space-1));
|
|
179
209
|
padding-inline: var(--xh-menubar-group-label-px, var(--xh-_menubar-item-px));
|
|
180
210
|
color: var(--xh-menubar-group-label-fg, var(--xh-fg-subtle));
|
|
181
|
-
font-size: var(--xh-menubar-group-label-font-size, var(--xh-
|
|
211
|
+
font-size: var(--xh-menubar-group-label-font-size, var(--xh-text-caption-size));
|
|
182
212
|
font-weight: var(--xh-menubar-group-label-font-weight, var(--xh-font-weight-medium));
|
|
183
213
|
line-height: var(--xh-leading-none);
|
|
184
214
|
user-select: none;
|
|
@@ -191,7 +221,7 @@
|
|
|
191
221
|
[data-scope='menubar'][data-part='item'] {
|
|
192
222
|
display: flex;
|
|
193
223
|
align-items: center;
|
|
194
|
-
gap: var(--xh-menubar-item-gap, var(--xh-
|
|
224
|
+
gap: var(--xh-menubar-item-gap, var(--xh-_menubar-item-gap));
|
|
195
225
|
padding-block: var(--xh-menubar-item-py, var(--xh-_menubar-item-py));
|
|
196
226
|
padding-inline: var(--xh-menubar-item-px, var(--xh-_menubar-item-px));
|
|
197
227
|
border-radius: var(--xh-menubar-item-radius, var(--xh-shape-control));
|
|
@@ -211,14 +241,44 @@
|
|
|
211
241
|
display: none;
|
|
212
242
|
}
|
|
213
243
|
|
|
214
|
-
/*
|
|
215
|
-
|
|
216
|
-
子部件够不着那个伪类,只能读这个标记 */
|
|
217
|
-
[data-scope='menubar'][data-part='item']:not([data-disabled]):is(:hover, :focus, [data-highlighted]) {
|
|
244
|
+
/* 悬停与键盘锚点共用中性灰轻档:锚点只认连接层打的 data-highlighted,不读 :focus */
|
|
245
|
+
[data-scope='menubar'][data-part='item']:not([data-disabled]):is(:hover, [data-highlighted]) {
|
|
218
246
|
background: var(--xh-menubar-item-bg-hover, var(--xh-bg-subtle));
|
|
219
247
|
}
|
|
220
248
|
|
|
221
|
-
|
|
249
|
+
/* 打开子菜单的触发条目是展开路径,走品牌淡底加粗强档。
|
|
250
|
+
必须排在轻档之后:悬停或焦点回到它身上时同特指度靠书写顺序压过轻档 */
|
|
251
|
+
[data-scope='menubar'][data-part='item']:not([data-disabled])[data-state='open'] {
|
|
252
|
+
background: var(--xh-menubar-item-bg-active, var(--xh-_menubar-item-active-bg));
|
|
253
|
+
font-weight: var(--xh-menubar-item-active-font-weight, var(--xh-font-weight-semibold));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* 带子菜单的条目行尾画右向小箭头:不点开也看得出还有下一级。
|
|
257
|
+
位置靠 margin 顶到行尾,图形取兜底字形令牌 */
|
|
258
|
+
[data-scope='menubar'][data-part='item'][aria-haspopup='menu']::after {
|
|
259
|
+
content: '';
|
|
260
|
+
flex: none;
|
|
261
|
+
margin-inline-start: auto;
|
|
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
|
+
background-color: currentColor;
|
|
265
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
266
|
+
mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* rtl 下子菜单开在左侧,箭头跟着指向行进方向 */
|
|
270
|
+
[dir='rtl'] [data-scope='menubar'][data-part='item'][aria-haspopup='menu']::after {
|
|
271
|
+
-webkit-mask-image: var(--xh-glyph-mark-chevron-left);
|
|
272
|
+
mask-image: var(--xh-glyph-mark-chevron-left);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* 键盘落焦的条目画内收环;指针触发的聚焦不画 */
|
|
276
|
+
[data-scope='menubar'][data-part='item']:focus-visible {
|
|
277
|
+
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
278
|
+
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
[data-scope='menubar'][data-part='item']:focus:not(:focus-visible) {
|
|
222
282
|
outline: none;
|
|
223
283
|
}
|
|
224
284
|
|
|
@@ -246,7 +306,7 @@
|
|
|
246
306
|
align-items: center;
|
|
247
307
|
justify-content: center;
|
|
248
308
|
inline-size: var(--xh-menubar-item-indicator-size, var(--xh-control-indicator-size));
|
|
249
|
-
color: var(--xh-menubar-item-indicator-fg, var(--xh-fg-
|
|
309
|
+
color: var(--xh-menubar-item-indicator-fg, var(--xh-fg-brand));
|
|
250
310
|
}
|
|
251
311
|
|
|
252
312
|
[data-scope='menubar'][data-part='item-indicator'][hidden] {
|
|
@@ -264,14 +324,26 @@
|
|
|
264
324
|
margin-block: var(--xh-menubar-separator-my, var(--xh-space-1));
|
|
265
325
|
background: var(--xh-menubar-separator-color, var(--xh-border-default));
|
|
266
326
|
}
|
|
327
|
+
|
|
328
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
329
|
+
[data-scope='menubar'][data-part='item-indicator']:empty::before {
|
|
330
|
+
content: '';
|
|
331
|
+
display: inline-block;
|
|
332
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
333
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
334
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
335
|
+
background-color: currentColor;
|
|
336
|
+
-webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
337
|
+
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
338
|
+
}
|
|
267
339
|
}
|
|
268
340
|
|
|
269
341
|
@layer xihan.motion {
|
|
270
342
|
/* 自带前缀独占一个名字,不动公共的那份关键帧 */
|
|
271
|
-
@keyframes xh-
|
|
343
|
+
@keyframes xh-pop-in {
|
|
272
344
|
from {
|
|
273
345
|
opacity: 0;
|
|
274
|
-
scale:
|
|
346
|
+
scale: var(--xh-motion-scale-enter);
|
|
275
347
|
}
|
|
276
348
|
|
|
277
349
|
to {
|
|
@@ -279,4 +351,16 @@
|
|
|
279
351
|
scale: 1;
|
|
280
352
|
}
|
|
281
353
|
}
|
|
354
|
+
|
|
355
|
+
@keyframes xh-pop-out {
|
|
356
|
+
from {
|
|
357
|
+
opacity: 1;
|
|
358
|
+
scale: 1;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
to {
|
|
362
|
+
opacity: 0;
|
|
363
|
+
scale: var(--xh-motion-scale-enter);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
282
366
|
}
|
package/css/navigation-menu.css
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
@layer xihan.motion {
|
|
2
2
|
/* 面板往下探一小截再落位:纯淡入看不出它是从哪条 trigger 长出来的 */
|
|
3
|
-
@keyframes xh-
|
|
3
|
+
@keyframes xh-pop-in {
|
|
4
4
|
from {
|
|
5
5
|
opacity: 0;
|
|
6
|
-
|
|
6
|
+
scale: var(--xh-motion-scale-enter);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
to {
|
|
10
10
|
opacity: 1;
|
|
11
|
-
|
|
11
|
+
scale: 1;
|
|
12
|
+
}
|
|
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);
|
|
12
24
|
}
|
|
13
25
|
}
|
|
14
26
|
}
|
|
15
27
|
|
|
16
28
|
@layer xihan.components {
|
|
29
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
30
|
+
[data-scope='navigation-menu'] {
|
|
31
|
+
--xh-navigation-menu-skin: 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
17
34
|
/* 根节点是 nav 地标,不参与排版;给 relative 是为了让共享外壳(viewport)有个定位参照系。
|
|
18
35
|
这里不给 display,UA 的 [hidden]{display:none} 就仍然压得住 */
|
|
19
36
|
[data-scope='navigation-menu'][data-part='root'] {
|
|
@@ -24,14 +41,17 @@
|
|
|
24
41
|
--xh-_navigation-menu-trigger-h: var(--xh-control-h-md);
|
|
25
42
|
--xh-_navigation-menu-trigger-px: var(--xh-control-px-md);
|
|
26
43
|
--xh-_navigation-menu-trigger-gap: var(--xh-control-gap-md);
|
|
27
|
-
--xh-_navigation-menu-link-
|
|
44
|
+
--xh-_navigation-menu-link-py: var(--xh-space-1_5);
|
|
45
|
+
--xh-_navigation-menu-link-px: var(--xh-control-px-md);
|
|
28
46
|
--xh-_navigation-menu-link-font-size: var(--xh-text-body-size);
|
|
29
47
|
|
|
30
|
-
/*
|
|
31
|
-
|
|
48
|
+
/* 悬停与键盘锚点恒中性灰轻档、不接语气槽——两档同色相的话打开路径就认不出来了 */
|
|
49
|
+
--xh-_navigation-menu-highlight-bg: var(--xh-bg-subtle);
|
|
50
|
+
|
|
51
|
+
/* 语气落在三处:展开着的 trigger 的底色、当前链接的文字色、指示条。
|
|
52
|
+
没写 data-tone 时这几个 --xh-_tone-* 都没被声明,各自退回品牌色。
|
|
32
53
|
聚焦环不在其列,它恒是 --xh-ring-focus */
|
|
33
|
-
--xh-_navigation-menu-
|
|
34
|
-
--xh-_navigation-menu-open-fg: var(--xh-_tone-fg, var(--xh-fg-default));
|
|
54
|
+
--xh-_navigation-menu-active-bg: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
|
|
35
55
|
--xh-_navigation-menu-current-fg: var(--xh-_tone-fg, var(--xh-fg-brand));
|
|
36
56
|
--xh-_navigation-menu-accent: var(--xh-_tone, var(--xh-fg-brand));
|
|
37
57
|
|
|
@@ -44,21 +64,23 @@
|
|
|
44
64
|
/* 缺省档写在上面的基础规则里。链接的内边距不在控件内边距那把尺上(它比控件矮一档),
|
|
45
65
|
三档一律取空间尺,缺省档的取值原样保留 */
|
|
46
66
|
[data-scope='navigation-menu'][data-part='root'][data-size='sm'] {
|
|
47
|
-
--xh-_navigation-menu-font-size: var(--xh-font-
|
|
67
|
+
--xh-_navigation-menu-font-size: var(--xh-control-font-sm);
|
|
48
68
|
--xh-_navigation-menu-trigger-h: var(--xh-control-h-sm);
|
|
49
69
|
--xh-_navigation-menu-trigger-px: var(--xh-control-px-sm);
|
|
50
70
|
--xh-_navigation-menu-trigger-gap: var(--xh-control-gap-sm);
|
|
51
|
-
--xh-_navigation-menu-link-
|
|
52
|
-
--xh-_navigation-menu-link-
|
|
71
|
+
--xh-_navigation-menu-link-py: var(--xh-space-1);
|
|
72
|
+
--xh-_navigation-menu-link-px: var(--xh-control-px-sm);
|
|
73
|
+
--xh-_navigation-menu-link-font-size: var(--xh-control-font-sm);
|
|
53
74
|
}
|
|
54
75
|
|
|
55
76
|
[data-scope='navigation-menu'][data-part='root'][data-size='lg'] {
|
|
56
|
-
--xh-_navigation-menu-font-size: var(--xh-font-
|
|
77
|
+
--xh-_navigation-menu-font-size: var(--xh-control-font-lg);
|
|
57
78
|
--xh-_navigation-menu-trigger-h: var(--xh-control-h-lg);
|
|
58
79
|
--xh-_navigation-menu-trigger-px: var(--xh-control-px-lg);
|
|
59
80
|
--xh-_navigation-menu-trigger-gap: var(--xh-control-gap-lg);
|
|
60
|
-
--xh-_navigation-menu-link-
|
|
61
|
-
--xh-_navigation-menu-link-
|
|
81
|
+
--xh-_navigation-menu-link-py: var(--xh-space-2);
|
|
82
|
+
--xh-_navigation-menu-link-px: var(--xh-control-px-lg);
|
|
83
|
+
--xh-_navigation-menu-link-font-size: var(--xh-control-font-lg);
|
|
62
84
|
}
|
|
63
85
|
|
|
64
86
|
/* 指示条的定位参照系(它是 absolute,量出来的偏移就是相对这里的)。
|
|
@@ -109,7 +131,7 @@
|
|
|
109
131
|
line-height: var(--xh-leading-none);
|
|
110
132
|
white-space: nowrap;
|
|
111
133
|
cursor: pointer;
|
|
112
|
-
transition:
|
|
134
|
+
transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
[data-scope='navigation-menu'][data-part='trigger'][hidden] {
|
|
@@ -125,8 +147,11 @@
|
|
|
125
147
|
outline-offset: var(--xh-ring-offset);
|
|
126
148
|
}
|
|
127
149
|
|
|
150
|
+
/* 展开着的那一张是打开路径,走品牌淡底强档:哪一张开着必须一眼看得出来。
|
|
151
|
+
不加粗:横排的栏加粗会推挤相邻触发器。
|
|
152
|
+
必须排在轻档之后:指针回到它身上时同特指度靠书写顺序压过轻档 */
|
|
128
153
|
[data-scope='navigation-menu'][data-part='trigger'][data-state='open'] {
|
|
129
|
-
|
|
154
|
+
background: var(--xh-navigation-menu-trigger-bg-active, var(--xh-_navigation-menu-active-bg));
|
|
130
155
|
}
|
|
131
156
|
|
|
132
157
|
/* 集合条目用 data-disabled,不用 :disabled:它带的是 aria-disabled,
|
|
@@ -144,24 +169,24 @@
|
|
|
144
169
|
/* 面板贴着自己那一项落位:横排从 trigger 底下长出来 */
|
|
145
170
|
[data-scope='navigation-menu'][data-part='content'] {
|
|
146
171
|
position: absolute;
|
|
147
|
-
z-index: var(--xh-layer-popover);
|
|
172
|
+
z-index: var(--xh-navigation-menu-layer, var(--xh-layer-popover));
|
|
148
173
|
inset-block-start: calc(100% + var(--xh-navigation-menu-content-offset, var(--xh-space-1)));
|
|
149
174
|
inset-inline-start: 0;
|
|
150
175
|
display: flex;
|
|
151
176
|
flex-direction: column;
|
|
152
177
|
gap: var(--xh-navigation-menu-content-gap, var(--xh-space-1));
|
|
153
|
-
min-inline-size: var(--xh-navigation-menu-content-min-w, var(--xh-overlay-min-w));
|
|
154
|
-
padding: var(--xh-navigation-menu-content-p, var(--xh-space-
|
|
178
|
+
min-inline-size: var(--xh-navigation-menu-content-min-w, var(--xh-overlay-menu-min-w));
|
|
179
|
+
padding: var(--xh-navigation-menu-content-p, var(--xh-space-1));
|
|
155
180
|
border: var(--xh-stroke-thin) solid var(--xh-navigation-menu-content-border, var(--xh-border-default));
|
|
156
181
|
border-radius: var(--xh-navigation-menu-content-radius, var(--xh-shape-surface));
|
|
157
182
|
background: var(--xh-navigation-menu-content-bg, var(--xh-bg-surface));
|
|
158
|
-
box-shadow: var(--xh-navigation-menu-content-shadow, var(--xh-elevation-
|
|
183
|
+
box-shadow: var(--xh-navigation-menu-content-shadow, var(--xh-elevation-floating));
|
|
159
184
|
}
|
|
160
185
|
|
|
161
186
|
/* display 会盖掉 hidden 属性的 UA 规则,收起态显式让位 */
|
|
162
|
-
[data-
|
|
163
|
-
|
|
164
|
-
|
|
187
|
+
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
|
|
188
|
+
收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
|
|
189
|
+
[hidden]{display:none}——退场动画得先能播。真正的收起由宿主在退场结束后落成内联 display。 */
|
|
165
190
|
|
|
166
191
|
/* 竖排导航:面板改从侧边长出来 */
|
|
167
192
|
[data-scope='navigation-menu'][data-part='content'][data-orientation='vertical'] {
|
|
@@ -170,7 +195,12 @@
|
|
|
170
195
|
}
|
|
171
196
|
|
|
172
197
|
[data-scope='navigation-menu'][data-part='content'][data-state='open'] {
|
|
173
|
-
animation: xh-
|
|
198
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来 */
|
|
202
|
+
[data-scope='navigation-menu'][data-part='content'][data-state='closed'] {
|
|
203
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
174
204
|
}
|
|
175
205
|
|
|
176
206
|
/* 面板整批塞进共享外壳时,落位归外壳管,面板自己回到静态流里——
|
|
@@ -186,8 +216,8 @@
|
|
|
186
216
|
[data-scope='navigation-menu'][data-part='link'] {
|
|
187
217
|
display: flex;
|
|
188
218
|
align-items: center;
|
|
189
|
-
padding-block: var(--xh-navigation-menu-link-py, var(--xh-_navigation-menu-link-
|
|
190
|
-
padding-inline: var(--xh-navigation-menu-link-px, var(--xh-_navigation-menu-link-
|
|
219
|
+
padding-block: var(--xh-navigation-menu-link-py, var(--xh-_navigation-menu-link-py));
|
|
220
|
+
padding-inline: var(--xh-navigation-menu-link-px, var(--xh-_navigation-menu-link-px));
|
|
191
221
|
border-radius: var(--xh-navigation-menu-link-radius, var(--xh-shape-control));
|
|
192
222
|
color: var(--xh-navigation-menu-link-fg, var(--xh-fg-default));
|
|
193
223
|
font-size: var(--xh-navigation-menu-link-font-size, var(--xh-_navigation-menu-link-font-size));
|
|
@@ -222,7 +252,7 @@
|
|
|
222
252
|
margin: 0;
|
|
223
253
|
inset-block-end: calc(var(--xh-navigation-menu-indicator-thickness, var(--xh-stroke-thick)) * -1);
|
|
224
254
|
block-size: var(--xh-navigation-menu-indicator-thickness, var(--xh-stroke-thick));
|
|
225
|
-
border-radius: var(--xh-navigation-menu-indicator-radius, var(--xh-
|
|
255
|
+
border-radius: var(--xh-navigation-menu-indicator-radius, var(--xh-shape-pill));
|
|
226
256
|
background: var(--xh-navigation-menu-indicator-color, var(--xh-_navigation-menu-accent));
|
|
227
257
|
transition:
|
|
228
258
|
inset-inline-start var(--xh-motion-duration-enter) var(--xh-motion-ease-enter),
|
|
@@ -247,7 +277,7 @@
|
|
|
247
277
|
/* 共享面板外壳:只管落位与统一的面板外观,里面装哪一份内容归 content */
|
|
248
278
|
[data-scope='navigation-menu'][data-part='viewport'] {
|
|
249
279
|
position: absolute;
|
|
250
|
-
z-index: var(--xh-layer-popover);
|
|
280
|
+
z-index: var(--xh-navigation-menu-layer, var(--xh-layer-popover));
|
|
251
281
|
inset-block-start: calc(100% + var(--xh-navigation-menu-content-offset, var(--xh-space-1)));
|
|
252
282
|
inset-inline-start: 0;
|
|
253
283
|
display: block;
|
|
@@ -255,7 +285,7 @@
|
|
|
255
285
|
border: var(--xh-stroke-thin) solid var(--xh-navigation-menu-content-border, var(--xh-border-default));
|
|
256
286
|
border-radius: var(--xh-navigation-menu-content-radius, var(--xh-shape-surface));
|
|
257
287
|
background: var(--xh-navigation-menu-content-bg, var(--xh-bg-surface));
|
|
258
|
-
box-shadow: var(--xh-navigation-menu-content-shadow, var(--xh-elevation-
|
|
288
|
+
box-shadow: var(--xh-navigation-menu-content-shadow, var(--xh-elevation-floating));
|
|
259
289
|
}
|
|
260
290
|
|
|
261
291
|
[data-scope='navigation-menu'][data-part='viewport'][hidden] {
|
package/css/number-animation.css
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
@layer xihan.components {
|
|
2
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
|
+
[data-scope='number-animation'] {
|
|
4
|
+
--xh-number-animation-skin: 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
2
7
|
[data-scope='number-animation'][data-part='root'] {
|
|
3
8
|
/* 不写尺寸就跟着上下文的字号走:这个数常常摆在别人的标题、卡片标题或统计数值槽里,
|
|
4
9
|
自带一个字号只会跟摆放它的地方打架。三个档位各自换掉这个私有槽 */
|
|
@@ -19,14 +24,14 @@
|
|
|
19
24
|
|
|
20
25
|
/* —— 尺寸 —— */
|
|
21
26
|
[data-scope='number-animation'][data-part='root'][data-size='sm'] {
|
|
22
|
-
--xh-_number-animation-size: var(--xh-font-
|
|
27
|
+
--xh-_number-animation-size: var(--xh-control-font-lg);
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
[data-scope='number-animation'][data-part='root'][data-size='md'] {
|
|
26
|
-
--xh-_number-animation-size: var(--xh-
|
|
31
|
+
--xh-_number-animation-size: var(--xh-text-heading-2-size);
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
[data-scope='number-animation'][data-part='root'][data-size='lg'] {
|
|
30
|
-
--xh-_number-animation-size: var(--xh-
|
|
35
|
+
--xh-_number-animation-size: var(--xh-text-heading-1-size);
|
|
31
36
|
}
|
|
32
37
|
}
|