@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/context-menu.css
CHANGED
|
@@ -4,26 +4,54 @@
|
|
|
4
4
|
--xh-context-menu-skin: 1;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
/*
|
|
8
|
-
[data-scope='context-menu'][data-part='
|
|
9
|
-
/*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
8
|
+
[data-scope='context-menu'][data-part='positioner'] {
|
|
9
|
+
/* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,content 继承它限高;
|
|
10
|
+
引擎没算(尚未落位 / 无引擎)时不额外限高 */
|
|
11
|
+
--xh-_context-menu-available-h: 100vh;
|
|
12
|
+
|
|
13
|
+
/* 条目列表的自绘条浮在内容之上:轨道不上底色,实色轨道会在菜单右缘糊一条竖灰带 */
|
|
14
|
+
--xh-scrollbar-track-bg: transparent;
|
|
15
|
+
|
|
16
|
+
position: fixed;
|
|
17
|
+
z-index: var(--xh-context-menu-layer, var(--xh-layer-popover));
|
|
18
|
+
/* 空壳不吃指针,交互只发生在 content 上 */
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* 锚点被滚出可视区:整个浮层随之收起 */
|
|
23
|
+
[data-scope='context-menu'][data-part='positioner'][data-hidden] {
|
|
24
|
+
visibility: hidden;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
|
|
28
|
+
[data-scope='context-menu']:is([data-part='root'], [data-part='positioner']) {
|
|
29
|
+
/* 尺寸档只换这四个私有槽,条目与分组标题都从这两处继承它们,
|
|
30
|
+
换档不必给每个部件各写一条选择器 */
|
|
31
|
+
--xh-_context-menu-item-py: var(--xh-list-option-py-md);
|
|
13
32
|
--xh-_context-menu-item-px: var(--xh-control-px-md);
|
|
14
33
|
--xh-_context-menu-item-gap: var(--xh-control-gap-md);
|
|
15
|
-
--xh-_context-menu-font-size: var(--xh-
|
|
34
|
+
--xh-_context-menu-font-size: var(--xh-control-font-md);
|
|
16
35
|
|
|
17
36
|
/* 打开子菜单的触发条目走品牌淡底强档,随语气换色相;没写 data-tone 时退回品牌淡底。
|
|
18
37
|
悬停与键盘焦点恒中性灰轻档、不接语气槽——两档同色相的话打开路径就认不出来了 */
|
|
19
38
|
--xh-_context-menu-item-active-bg: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
|
|
39
|
+
}
|
|
20
40
|
|
|
21
|
-
|
|
22
|
-
|
|
41
|
+
/* 根只是把触发区与浮层圈在一起做作用域,不该在作者布局里多插一层盒子 */
|
|
42
|
+
[data-scope='context-menu'][data-part='root'] {
|
|
43
|
+
/* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
44
|
+
--xh-icon-size: var(--xh-context-menu-icon-size, var(--xh-glyph-size-text));
|
|
23
45
|
|
|
24
46
|
display: contents;
|
|
25
47
|
}
|
|
26
48
|
|
|
49
|
+
/* 浮层被搬到 portal 落点,继承不到 root 上的槽:这把尺在被搬走的那一侧再声明一次,
|
|
50
|
+
关闭钮与条目里作者塞的图标才和皮肤画的兜底字形一样大 */
|
|
51
|
+
[data-scope='context-menu'][data-part='content'] {
|
|
52
|
+
--xh-icon-size: var(--xh-context-menu-icon-size, var(--xh-glyph-size-text));
|
|
53
|
+
}
|
|
54
|
+
|
|
27
55
|
[data-scope='context-menu'][data-part='root'][hidden] {
|
|
28
56
|
display: none;
|
|
29
57
|
}
|
|
@@ -31,18 +59,18 @@
|
|
|
31
59
|
/* —— 尺寸 —— */
|
|
32
60
|
/* 缺省档写在上面的基础规则里。条目高度由 padding 撑出来:
|
|
33
61
|
纵向走 space 档、行内内缩走 control-px 档(随密度轴),换档各挪一级 */
|
|
34
|
-
[data-scope='context-menu'][data-part='root'][data-size='sm'] {
|
|
35
|
-
--xh-_context-menu-item-py: var(--xh-
|
|
62
|
+
[data-scope='context-menu']:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
|
|
63
|
+
--xh-_context-menu-item-py: var(--xh-list-option-py-sm);
|
|
36
64
|
--xh-_context-menu-item-px: var(--xh-control-px-sm);
|
|
37
65
|
--xh-_context-menu-item-gap: var(--xh-control-gap-sm);
|
|
38
|
-
--xh-_context-menu-font-size: var(--xh-font-
|
|
66
|
+
--xh-_context-menu-font-size: var(--xh-control-font-sm);
|
|
39
67
|
}
|
|
40
68
|
|
|
41
|
-
[data-scope='context-menu'][data-part='root'][data-size='lg'] {
|
|
42
|
-
--xh-_context-menu-item-py: var(--xh-
|
|
69
|
+
[data-scope='context-menu']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
|
|
70
|
+
--xh-_context-menu-item-py: var(--xh-list-option-py-lg);
|
|
43
71
|
--xh-_context-menu-item-px: var(--xh-control-px-lg);
|
|
44
72
|
--xh-_context-menu-item-gap: var(--xh-control-gap-lg);
|
|
45
|
-
--xh-_context-menu-font-size: var(--xh-font-
|
|
73
|
+
--xh-_context-menu-font-size: var(--xh-control-font-lg);
|
|
46
74
|
}
|
|
47
75
|
|
|
48
76
|
/* 触发区是作者自己的一块内容,尺寸与排布归他;这里只管交互观感:
|
|
@@ -57,38 +85,32 @@
|
|
|
57
85
|
outline-offset: var(--xh-ring-offset);
|
|
58
86
|
}
|
|
59
87
|
|
|
60
|
-
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
61
|
-
[data-scope='context-menu'][data-part='positioner'] {
|
|
62
|
-
position: fixed;
|
|
63
|
-
z-index: var(--xh-layer-popover);
|
|
64
|
-
/* 空壳不吃指针,交互只发生在 content 上 */
|
|
65
|
-
pointer-events: none;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/* 锚点被滚出可视区:整个浮层随之收起 */
|
|
69
|
-
[data-scope='context-menu'][data-part='positioner'][data-hidden] {
|
|
70
|
-
visibility: hidden;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
88
|
[data-scope='context-menu'][data-part='content'] {
|
|
74
89
|
display: flex;
|
|
75
90
|
flex-direction: column;
|
|
91
|
+
gap: var(--xh-context-menu-content-gap, var(--xh-list-option-gap));
|
|
76
92
|
min-inline-size: var(--xh-context-menu-min-w, var(--xh-overlay-menu-min-w));
|
|
77
93
|
max-inline-size: var(--xh-context-menu-max-w, var(--xh-overlay-max-w));
|
|
94
|
+
/* 两道上限取更小的那道:自己的高度上限,以及落定那一侧真正剩下的空间。
|
|
95
|
+
列表族的 16rem 对命令菜单偏矮,这里另给一档 */
|
|
96
|
+
max-block-size: min(var(--xh-context-menu-max-h, var(--xh-overlay-menu-max-h)), var(--xh-_context-menu-available-h));
|
|
78
97
|
padding-block: var(--xh-context-menu-py, var(--xh-space-1));
|
|
79
98
|
padding-inline: var(--xh-context-menu-px, var(--xh-space-1));
|
|
80
99
|
border: var(--xh-stroke-thin) solid var(--xh-context-menu-border, var(--xh-border-default));
|
|
81
100
|
border-radius: var(--xh-context-menu-radius, var(--xh-shape-surface));
|
|
82
101
|
background: var(--xh-context-menu-bg, var(--xh-bg-surface));
|
|
83
102
|
color: var(--xh-context-menu-fg, var(--xh-fg-default));
|
|
84
|
-
box-shadow: var(--xh-context-menu-shadow, var(--xh-elevation-
|
|
103
|
+
box-shadow: var(--xh-context-menu-shadow, var(--xh-elevation-floating));
|
|
104
|
+
/* 条目超过上限就在菜单内部滚。条目的焦点环是内收的,滚动容器裁在内边距缘上,环切不着 */
|
|
105
|
+
overflow-y: auto;
|
|
85
106
|
pointer-events: auto;
|
|
86
107
|
}
|
|
87
108
|
|
|
88
|
-
/*
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
109
|
+
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
|
|
110
|
+
收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
|
|
111
|
+
[hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
|
|
112
|
+
真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
|
|
113
|
+
其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
|
|
92
114
|
|
|
93
115
|
/* 焦点落在容器上只有一种情形:指针打开、还没有任何条目当锚点。那一刻它认领着 Tab 位,
|
|
94
116
|
环画在浮层内沿,用户才看得出键盘此刻在哪儿;有锚点时环长在条目上,容器不再画 */
|
|
@@ -104,12 +126,19 @@
|
|
|
104
126
|
/* 展开时轻微涨开:菜单是被光标"点出来"的,纯淡入显得它一直都在
|
|
105
127
|
(不设 transform-origin:那个属性没有逻辑关键字,写死方向会在 RTL 下反着涨) */
|
|
106
128
|
[data-scope='context-menu'][data-part='content'][data-state='open'] {
|
|
107
|
-
animation: xh-
|
|
129
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
|
|
133
|
+
免得动画结束到真收起之间闪一下原样 */
|
|
134
|
+
[data-scope='context-menu'][data-part='content'][data-state='closed'] {
|
|
135
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
108
136
|
}
|
|
109
137
|
|
|
110
138
|
[data-scope='context-menu'][data-part='group'] {
|
|
111
139
|
display: flex;
|
|
112
140
|
flex-direction: column;
|
|
141
|
+
gap: var(--xh-context-menu-group-gap, var(--xh-list-option-gap));
|
|
113
142
|
}
|
|
114
143
|
|
|
115
144
|
[data-scope='context-menu'][data-part='group'][hidden] {
|
|
@@ -123,7 +152,7 @@
|
|
|
123
152
|
padding-block: var(--xh-context-menu-group-label-py, var(--xh-space-1));
|
|
124
153
|
padding-inline: var(--xh-context-menu-group-label-px, var(--xh-_context-menu-item-px));
|
|
125
154
|
color: var(--xh-context-menu-group-label-fg, var(--xh-fg-subtle));
|
|
126
|
-
font-size: var(--xh-context-menu-group-label-font-size, var(--xh-
|
|
155
|
+
font-size: var(--xh-context-menu-group-label-font-size, var(--xh-text-caption-size));
|
|
127
156
|
font-weight: var(--xh-context-menu-group-label-font-weight, var(--xh-font-weight-medium));
|
|
128
157
|
line-height: var(--xh-leading-none);
|
|
129
158
|
user-select: none;
|
|
@@ -156,10 +185,8 @@
|
|
|
156
185
|
display: none;
|
|
157
186
|
}
|
|
158
187
|
|
|
159
|
-
/*
|
|
160
|
-
|
|
161
|
-
子部件够不着那个伪类,只能读这个标记 */
|
|
162
|
-
[data-scope='context-menu'][data-part='item']:not([data-disabled]):is(:hover, :focus, [data-highlighted]) {
|
|
188
|
+
/* 悬停与键盘锚点共用中性灰轻档:锚点只认连接层打的 data-highlighted,不读 :focus */
|
|
189
|
+
[data-scope='context-menu'][data-part='item']:not([data-disabled]):is(:hover, [data-highlighted]) {
|
|
163
190
|
background: var(--xh-context-menu-item-bg-hover, var(--xh-bg-subtle));
|
|
164
191
|
}
|
|
165
192
|
|
|
@@ -170,6 +197,25 @@
|
|
|
170
197
|
font-weight: var(--xh-context-menu-item-active-font-weight, var(--xh-font-weight-semibold));
|
|
171
198
|
}
|
|
172
199
|
|
|
200
|
+
/* 带子菜单的条目行尾画右向小箭头:不点开也看得出还有下一级。
|
|
201
|
+
位置靠 margin 顶到行尾,图形取兜底字形令牌 */
|
|
202
|
+
[data-scope='context-menu'][data-part='item'][aria-haspopup='menu']::after {
|
|
203
|
+
content: '';
|
|
204
|
+
flex: none;
|
|
205
|
+
margin-inline-start: auto;
|
|
206
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
207
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
208
|
+
background-color: currentColor;
|
|
209
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
210
|
+
mask: var(--xh-glyph-mark-chevron-right) center / contain no-repeat;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* rtl 下子菜单开在左侧,箭头跟着指向行进方向 */
|
|
214
|
+
[dir='rtl'] [data-scope='context-menu'][data-part='item'][aria-haspopup='menu']::after {
|
|
215
|
+
-webkit-mask-image: var(--xh-glyph-mark-chevron-left);
|
|
216
|
+
mask-image: var(--xh-glyph-mark-chevron-left);
|
|
217
|
+
}
|
|
218
|
+
|
|
173
219
|
/* 键盘走到条目上要画环:轻档底色只有 1.1:1,够不上焦点指示器的对比度要求。
|
|
174
220
|
指针悬停走的是程序化聚焦,鼠标模态下 :focus-visible 不匹配,不会误画 */
|
|
175
221
|
[data-scope='context-menu'][data-part='item']:focus-visible {
|
|
@@ -206,7 +252,7 @@
|
|
|
206
252
|
align-items: center;
|
|
207
253
|
justify-content: center;
|
|
208
254
|
inline-size: var(--xh-context-menu-item-indicator-size, var(--xh-control-indicator-size));
|
|
209
|
-
color: var(--xh-context-menu-item-indicator-fg, var(--xh-
|
|
255
|
+
color: var(--xh-context-menu-item-indicator-fg, var(--xh-_tone, var(--xh-fg-brand)));
|
|
210
256
|
}
|
|
211
257
|
|
|
212
258
|
[data-scope='context-menu'][data-part='item-indicator'][hidden] {
|
|
@@ -219,7 +265,7 @@
|
|
|
219
265
|
|
|
220
266
|
[data-scope='context-menu'][data-part='separator'] {
|
|
221
267
|
block-size: var(--xh-context-menu-separator-thickness, var(--xh-stroke-thin));
|
|
222
|
-
margin-block: var(--xh-context-menu-separator-my, var(--xh-space-
|
|
268
|
+
margin-block: var(--xh-context-menu-separator-my, var(--xh-space-0_5));
|
|
223
269
|
background: var(--xh-context-menu-separator-color, var(--xh-border-default));
|
|
224
270
|
}
|
|
225
271
|
|
|
@@ -227,57 +273,39 @@
|
|
|
227
273
|
display: none;
|
|
228
274
|
}
|
|
229
275
|
|
|
230
|
-
/*
|
|
276
|
+
/* 箭头的底色与描边色,几何在 overlay-arrow.css。
|
|
231
277
|
交叉轴落点由定位引擎经内联自定义属性写进来,没给时退回居中 */
|
|
232
278
|
[data-scope='context-menu'][data-part='arrow'] {
|
|
233
|
-
--xh-_context-menu-arrow-size: var(--xh-context-menu-arrow-size, var(--xh-overlay-arrow-size));
|
|
234
279
|
--xh-_context-menu-arrow-x: 50%;
|
|
235
280
|
--xh-_context-menu-arrow-y: 50%;
|
|
281
|
+
--xh-_overlay-arrow-size: var(--xh-context-menu-arrow-size, var(--xh-overlay-arrow-size));
|
|
282
|
+
--xh-_overlay-arrow-x: var(--xh-_context-menu-arrow-x);
|
|
283
|
+
--xh-_overlay-arrow-y: var(--xh-_context-menu-arrow-y);
|
|
236
284
|
|
|
237
|
-
position: absolute;
|
|
238
|
-
inline-size: var(--xh-_context-menu-arrow-size);
|
|
239
|
-
block-size: var(--xh-_context-menu-arrow-size);
|
|
240
285
|
background: var(--xh-context-menu-bg, var(--xh-bg-surface));
|
|
241
286
|
border: var(--xh-stroke-thin) solid var(--xh-context-menu-border, var(--xh-border-default));
|
|
242
|
-
rotate: 45deg;
|
|
243
287
|
}
|
|
244
288
|
|
|
245
289
|
[data-scope='context-menu'][data-part='arrow'][hidden] {
|
|
246
290
|
display: none;
|
|
247
291
|
}
|
|
248
292
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
border-block-start: 0;
|
|
260
|
-
border-inline-start: 0;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
[data-scope='context-menu'][data-part='arrow'][data-placement^='right'] {
|
|
264
|
-
inset-inline-start: calc(var(--xh-_context-menu-arrow-size) / -2);
|
|
265
|
-
inset-block-start: calc(var(--xh-_context-menu-arrow-y) - var(--xh-_context-menu-arrow-size) / 2);
|
|
266
|
-
border-block-start: 0;
|
|
267
|
-
border-inline-end: 0;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
[data-scope='context-menu'][data-part='arrow'][data-placement^='left'] {
|
|
271
|
-
inset-inline-end: calc(var(--xh-_context-menu-arrow-size) / -2);
|
|
272
|
-
inset-block-start: calc(var(--xh-_context-menu-arrow-y) - var(--xh-_context-menu-arrow-size) / 2);
|
|
273
|
-
border-block-end: 0;
|
|
274
|
-
border-inline-start: 0;
|
|
293
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
294
|
+
[data-scope='context-menu'][data-part='item-indicator']:empty::before {
|
|
295
|
+
content: '';
|
|
296
|
+
display: inline-block;
|
|
297
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
298
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
299
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
300
|
+
background-color: currentColor;
|
|
301
|
+
-webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
302
|
+
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
275
303
|
}
|
|
276
304
|
}
|
|
277
305
|
|
|
278
306
|
@layer xihan.motion {
|
|
279
307
|
/* 自带前缀独占一个名字,不动公共的那份关键帧 */
|
|
280
|
-
@keyframes xh-
|
|
308
|
+
@keyframes xh-pop-in {
|
|
281
309
|
from {
|
|
282
310
|
opacity: 0;
|
|
283
311
|
scale: var(--xh-motion-scale-enter);
|
|
@@ -288,4 +316,15 @@
|
|
|
288
316
|
scale: 1;
|
|
289
317
|
}
|
|
290
318
|
}
|
|
319
|
+
@keyframes xh-pop-out {
|
|
320
|
+
from {
|
|
321
|
+
opacity: 1;
|
|
322
|
+
scale: 1;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
to {
|
|
326
|
+
opacity: 0;
|
|
327
|
+
scale: var(--xh-motion-scale-enter);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
291
330
|
}
|
package/css/date-field.css
CHANGED
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
|
|
7
7
|
/* 与文本框、数字框同一套堆叠:标签一行、分段框一行 */
|
|
8
8
|
[data-scope='date-field'][data-part='root'] {
|
|
9
|
+
/* 作者塞进来的图标跟着控件的尺寸档走;它自己写了 size 时仍以作者的为准 */
|
|
10
|
+
--xh-icon-size: var(--xh-date-field-icon-size, var(--xh-glyph-size-md));
|
|
11
|
+
|
|
9
12
|
/* 尺寸档只换这四个私有槽,标题与分段框都从 root 继承它们,换档不必给每个部件各写一条选择器 */
|
|
10
13
|
--xh-_date-field-control-h: var(--xh-control-h-md);
|
|
11
14
|
--xh-_date-field-control-px: var(--xh-control-px-md);
|
|
12
|
-
--xh-_date-field-
|
|
13
|
-
--xh-_date-field-
|
|
15
|
+
--xh-_date-field-gap: var(--xh-control-gap-md);
|
|
16
|
+
--xh-_date-field-font-size: var(--xh-control-font-md);
|
|
17
|
+
--xh-_date-field-label-font-size: var(--xh-control-font-md);
|
|
14
18
|
/* 形态档只换这三个私有槽:底色与两档描边 */
|
|
15
19
|
--xh-_date-field-control-bg: var(--xh-bg-canvas);
|
|
16
20
|
--xh-_date-field-control-border: var(--xh-border-control);
|
|
@@ -27,17 +31,21 @@
|
|
|
27
31
|
|
|
28
32
|
/* —— 尺寸 —— */
|
|
29
33
|
[data-scope='date-field'][data-part='root'][data-size='sm'] {
|
|
34
|
+
--xh-icon-size: var(--xh-date-field-icon-size, var(--xh-glyph-size-sm));
|
|
30
35
|
--xh-_date-field-control-h: var(--xh-control-h-sm);
|
|
31
36
|
--xh-_date-field-control-px: var(--xh-control-px-sm);
|
|
32
|
-
--xh-_date-field-
|
|
33
|
-
--xh-_date-field-
|
|
37
|
+
--xh-_date-field-gap: var(--xh-control-gap-sm);
|
|
38
|
+
--xh-_date-field-font-size: var(--xh-control-font-sm);
|
|
39
|
+
--xh-_date-field-label-font-size: var(--xh-control-font-sm);
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
[data-scope='date-field'][data-part='root'][data-size='lg'] {
|
|
43
|
+
--xh-icon-size: var(--xh-date-field-icon-size, var(--xh-glyph-size-lg));
|
|
37
44
|
--xh-_date-field-control-h: var(--xh-control-h-lg);
|
|
38
45
|
--xh-_date-field-control-px: var(--xh-control-px-lg);
|
|
39
|
-
--xh-_date-field-
|
|
40
|
-
--xh-_date-field-
|
|
46
|
+
--xh-_date-field-gap: var(--xh-control-gap-lg);
|
|
47
|
+
--xh-_date-field-font-size: var(--xh-control-font-lg);
|
|
48
|
+
--xh-_date-field-label-font-size: var(--xh-control-font-lg);
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
/* —— 形态 —— */
|
|
@@ -55,11 +63,11 @@
|
|
|
55
63
|
--xh-_date-field-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
56
64
|
}
|
|
57
65
|
|
|
58
|
-
/*
|
|
66
|
+
/* 无框:底与常态描边透明,悬停与聚焦浮出描边 */
|
|
59
67
|
[data-scope='date-field'][data-part='root'][data-variant='ghost'] {
|
|
60
68
|
--xh-_date-field-control-bg: transparent;
|
|
61
69
|
--xh-_date-field-control-border: transparent;
|
|
62
|
-
--xh-_date-field-control-border-hover:
|
|
70
|
+
--xh-_date-field-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
/* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
|
|
@@ -72,8 +80,6 @@
|
|
|
72
80
|
font-size: var(--xh-date-field-label-font-size, var(--xh-_date-field-label-font-size));
|
|
73
81
|
font-weight: var(--xh-date-field-label-font-weight, var(--xh-text-label-weight));
|
|
74
82
|
line-height: var(--xh-leading-none);
|
|
75
|
-
/* 点标题会把焦点送进首段,指针得说明这件事 */
|
|
76
|
-
cursor: default;
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
[data-scope='date-field'][data-part='label'][hidden] {
|
|
@@ -85,11 +91,12 @@
|
|
|
85
91
|
cursor: not-allowed;
|
|
86
92
|
}
|
|
87
93
|
|
|
88
|
-
/* 分段框整体长得像一个输入框:边框与背景长在 control
|
|
89
|
-
段与段之间的分隔符('/'、'年')由作者自己写在段之间,不在角色表里 */
|
|
94
|
+
/* 分段框整体长得像一个输入框:边框与背景长在 control 上,各段只是里面的文字 */
|
|
90
95
|
[data-scope='date-field'][data-part='control'] {
|
|
91
96
|
display: inline-flex;
|
|
97
|
+
min-inline-size: var(--xh-date-field-control-min-w, var(--xh-control-min-w));
|
|
92
98
|
align-items: center;
|
|
99
|
+
gap: var(--xh-date-field-control-gap, var(--xh-_date-field-gap));
|
|
93
100
|
block-size: var(--xh-date-field-control-h, var(--xh-_date-field-control-h));
|
|
94
101
|
padding-inline: var(--xh-date-field-control-px, var(--xh-_date-field-control-px));
|
|
95
102
|
padding-block: 0;
|
|
@@ -115,14 +122,17 @@
|
|
|
115
122
|
|
|
116
123
|
/* 焦点落在某一段上,而边框长在 control 上:焦点环得由内向外借一层。
|
|
117
124
|
control 自己不占 Tab 位,:focus-within 是它唯一能感知组内焦点的方式 */
|
|
118
|
-
[data-scope='date-field'][data-part='control']:focus-within {
|
|
119
|
-
border-color: var(--xh-date-field-control-border-focus, var(--xh-
|
|
125
|
+
[data-scope='date-field'][data-part='control']:focus-within:not([data-disabled]) {
|
|
126
|
+
border-color: var(--xh-date-field-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
|
|
120
127
|
outline: var(--xh-ring-width) solid var(--xh-_date-field-ring);
|
|
121
128
|
outline-offset: var(--xh-ring-offset);
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
[data-scope='date-field'][data-part='control'][data-invalid] {
|
|
125
|
-
border-color: var(--xh-date-field-control-border-invalid, var(--xh-
|
|
132
|
+
border-color: var(--xh-date-field-control-border-invalid, var(--xh-border-invalid));
|
|
133
|
+
|
|
134
|
+
/* 校验失败时环也跟着变红:两圈等宽相邻却一红一蓝,读的人不知道哪个才是当前状态 */
|
|
135
|
+
--xh-_date-field-ring: var(--xh-ring-invalid);
|
|
126
136
|
}
|
|
127
137
|
|
|
128
138
|
/* 只读仍可聚焦、可换段,不置灰,只把底色压下去表示"改不动" */
|
|
@@ -137,12 +147,25 @@
|
|
|
137
147
|
cursor: not-allowed;
|
|
138
148
|
}
|
|
139
149
|
|
|
150
|
+
/* 段位与作者写在段间的分隔符('/'、'年')都在这一层里:它占满盒里剩下的宽度,
|
|
151
|
+
清空钮因此靠在框内末端 */
|
|
152
|
+
[data-scope='date-field'][data-part='segment-group'] {
|
|
153
|
+
display: inline-flex;
|
|
154
|
+
flex: 1 1 auto;
|
|
155
|
+
align-items: center;
|
|
156
|
+
min-inline-size: 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
[data-scope='date-field'][data-part='segment-group'][hidden] {
|
|
160
|
+
display: none;
|
|
161
|
+
}
|
|
162
|
+
|
|
140
163
|
/* 每一段是一块可聚焦的文字:宽度随内容走,两侧留一点让选中底色不贴着数字 */
|
|
141
164
|
[data-scope='date-field'][data-part='segment'] {
|
|
142
165
|
display: inline-block;
|
|
143
166
|
padding-inline: var(--xh-date-field-segment-px, var(--xh-space-1));
|
|
144
167
|
padding-block: var(--xh-date-field-segment-py, var(--xh-space-0));
|
|
145
|
-
border-radius: var(--xh-date-field-segment-radius, var(--xh-
|
|
168
|
+
border-radius: var(--xh-date-field-segment-radius, var(--xh-shape-inset));
|
|
146
169
|
color: inherit;
|
|
147
170
|
font: inherit;
|
|
148
171
|
/* 等宽数字:各位字宽不一时,上下键连按会让整行数字左右跳 */
|
|
@@ -187,6 +210,60 @@
|
|
|
187
210
|
color: var(--xh-date-field-segment-fg-focus, var(--xh-_date-field-segment-fg));
|
|
188
211
|
}
|
|
189
212
|
|
|
213
|
+
/* 清空钮排在段位之后、与框等高的一颗小方钮:没值或不可编辑时连接层给 hidden 收起 */
|
|
214
|
+
[data-scope='date-field'][data-part='clear-trigger'] {
|
|
215
|
+
display: inline-flex;
|
|
216
|
+
flex: none;
|
|
217
|
+
align-items: center;
|
|
218
|
+
justify-content: center;
|
|
219
|
+
inline-size: var(--xh-date-field-action-size, var(--xh-control-action-size));
|
|
220
|
+
block-size: var(--xh-date-field-action-size, var(--xh-control-action-size));
|
|
221
|
+
padding: 0;
|
|
222
|
+
border: 0;
|
|
223
|
+
border-radius: var(--xh-date-field-action-radius, var(--xh-shape-control));
|
|
224
|
+
background: var(--xh-date-field-action-bg, transparent);
|
|
225
|
+
color: var(--xh-date-field-action-fg, var(--xh-fg-muted));
|
|
226
|
+
font-family: inherit;
|
|
227
|
+
font-size: var(--xh-date-field-action-font-size, var(--xh-text-secondary-size));
|
|
228
|
+
line-height: var(--xh-leading-none);
|
|
229
|
+
cursor: pointer;
|
|
230
|
+
user-select: none;
|
|
231
|
+
transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter), scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* 上面给了 display,UA 的 [hidden]{display:none} 已被盖掉,这里补回来 */
|
|
235
|
+
[data-scope='date-field'][data-part='clear-trigger'][hidden] {
|
|
236
|
+
display: none;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
[data-scope='date-field'][data-part='clear-trigger']:hover {
|
|
240
|
+
background: var(--xh-date-field-action-bg-hover, var(--xh-bg-subtle-hover));
|
|
241
|
+
color: var(--xh-date-field-action-fg-hover, var(--xh-fg-default));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
[data-scope='date-field'][data-part='clear-trigger']:active {
|
|
245
|
+
background: var(--xh-date-field-action-bg-active, var(--xh-bg-subtle-active));
|
|
246
|
+
scale: var(--xh-motion-scale-press);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* 按钮不占 Tab 位(tabindex=-1),留给程序化聚焦兜底,落焦时得看得见 */
|
|
250
|
+
[data-scope='date-field'][data-part='clear-trigger']:focus-visible {
|
|
251
|
+
outline: var(--xh-ring-width) solid var(--xh-_date-field-ring);
|
|
252
|
+
outline-offset: var(--xh-ring-offset);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这条即不命中 */
|
|
256
|
+
[data-scope='date-field'][data-part='clear-trigger']:empty::before {
|
|
257
|
+
content: '';
|
|
258
|
+
display: inline-block;
|
|
259
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
260
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
261
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
262
|
+
background-color: currentColor;
|
|
263
|
+
-webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
264
|
+
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
265
|
+
}
|
|
266
|
+
|
|
190
267
|
/* 连接层把它写成 type=hidden,UA 自己就不渲染;这里的视觉隐藏是给元素升级前那一瞬兜底
|
|
191
268
|
(作者手写的是一个普通 input,升级完成前它是可见的文本框)。
|
|
192
269
|
刻意不写 display:写了反而会盖掉 UA 对 type=hidden 的收起,把它显出来 */
|