@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/cascader.css
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
@layer xihan.components {
|
|
2
|
-
/*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
|
+
[data-scope='cascader'] {
|
|
4
|
+
--xh-cascader-skin: 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
8
|
+
[data-scope='cascader'][data-part='positioner'] {
|
|
9
|
+
position: fixed;
|
|
10
|
+
z-index: var(--xh-cascader-layer, var(--xh-layer-popover));
|
|
11
|
+
/* 空壳不吃指针,交互只发生在 content 里 */
|
|
12
|
+
pointer-events: none;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* 锚点被滚出可视区:整个浮层随之收起 */
|
|
16
|
+
[data-scope='cascader'][data-part='positioner'][data-hidden] {
|
|
17
|
+
visibility: hidden;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
|
|
21
|
+
[data-scope='cascader']:is([data-part='root'], [data-part='positioner']) {
|
|
22
|
+
/* 作者塞进指示符槽的图标跟着尺寸档走,与皮肤画的兜底字形同一把尺 */
|
|
23
|
+
--xh-icon-size: var(--xh-cascader-icon-size, var(--xh-glyph-size-md));
|
|
24
|
+
|
|
25
|
+
/* 尺寸档只换这几个私有槽,盒与列里的条目都从这两处继承它们,换档不必给每个部件各写一条选择器 */
|
|
7
26
|
--xh-_cascader-h: var(--xh-control-h-md);
|
|
8
27
|
--xh-_cascader-px: var(--xh-control-px-md);
|
|
9
28
|
--xh-_cascader-gap: var(--xh-control-gap-md);
|
|
@@ -22,9 +41,14 @@
|
|
|
22
41
|
/* 展开路径的底色:随语气走淡底,没写 data-tone 时退回品牌淡底 */
|
|
23
42
|
--xh-_cascader-active-bg: var(--xh-_tone-subtle, var(--xh-bg-brand-subtle));
|
|
24
43
|
|
|
44
|
+
/* 聚焦环恒用固定环色;校验失败时换成告警环色 */
|
|
45
|
+
--xh-_cascader-ring: var(--xh-ring-focus);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* 标签一行、盒一行的两行堆叠 */
|
|
49
|
+
[data-scope='cascader'][data-part='root'] {
|
|
25
50
|
display: inline-flex;
|
|
26
|
-
flex-
|
|
27
|
-
align-items: center;
|
|
51
|
+
flex-direction: column;
|
|
28
52
|
gap: var(--xh-cascader-gap, var(--xh-space-1));
|
|
29
53
|
}
|
|
30
54
|
|
|
@@ -36,48 +60,48 @@
|
|
|
36
60
|
/* —— 形态 —— */
|
|
37
61
|
/* 形态只决定描边与底色怎么用;用哪族颜色由 data-tone 决定,没写 tone 就沿用原来的中性配色 */
|
|
38
62
|
/* outline 就是缺省那一身:描边加画布底,写出来只为让三档并列可读 */
|
|
39
|
-
[data-scope='cascader'][data-part='root'][data-variant='outline'] {
|
|
63
|
+
[data-scope='cascader']:is([data-part='root'], [data-part='positioner'])[data-variant='outline'] {
|
|
40
64
|
--xh-_cascader-border: var(--xh-border-control);
|
|
41
65
|
--xh-_cascader-border-hover: var(--xh-border-control-hover);
|
|
42
66
|
--xh-_cascader-bg: var(--xh-bg-canvas);
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
/* subtle 是填充式:底色接过「这里能点」的表达,描边随之让位 */
|
|
46
|
-
[data-scope='cascader'][data-part='root'][data-variant='subtle'] {
|
|
70
|
+
[data-scope='cascader']:is([data-part='root'], [data-part='positioner'])[data-variant='subtle'] {
|
|
47
71
|
--xh-_cascader-border: transparent;
|
|
48
72
|
--xh-_cascader-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
49
73
|
--xh-_cascader-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
|
|
50
74
|
}
|
|
51
75
|
|
|
52
|
-
/*
|
|
53
|
-
[data-scope='cascader'][data-part='root'][data-variant='ghost'] {
|
|
76
|
+
/* 无框:底与常态描边透明,悬停浮出描边,聚焦由焦点环表达 */
|
|
77
|
+
[data-scope='cascader']:is([data-part='root'], [data-part='positioner'])[data-variant='ghost'] {
|
|
54
78
|
--xh-_cascader-border: transparent;
|
|
55
|
-
--xh-_cascader-border-hover:
|
|
79
|
+
--xh-_cascader-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
|
|
56
80
|
--xh-_cascader-bg: transparent;
|
|
57
81
|
}
|
|
58
82
|
|
|
59
83
|
/* —— 尺寸 —— */
|
|
60
84
|
/* 缺省档写在上面的基础规则里 */
|
|
61
|
-
[data-scope='cascader'][data-part='root'][data-size='sm'] {
|
|
85
|
+
[data-scope='cascader']:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
|
|
86
|
+
--xh-icon-size: var(--xh-cascader-icon-size, var(--xh-glyph-size-sm));
|
|
62
87
|
--xh-_cascader-h: var(--xh-control-h-sm);
|
|
63
88
|
--xh-_cascader-px: var(--xh-control-px-sm);
|
|
64
89
|
--xh-_cascader-gap: var(--xh-control-gap-sm);
|
|
65
|
-
--xh-_cascader-font-size: var(--xh-font-
|
|
66
|
-
--xh-_cascader-label-font-size: var(--xh-font-
|
|
90
|
+
--xh-_cascader-font-size: var(--xh-control-font-sm);
|
|
91
|
+
--xh-_cascader-label-font-size: var(--xh-control-font-sm);
|
|
67
92
|
}
|
|
68
93
|
|
|
69
|
-
[data-scope='cascader'][data-part='root'][data-size='lg'] {
|
|
94
|
+
[data-scope='cascader']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
|
|
95
|
+
--xh-icon-size: var(--xh-cascader-icon-size, var(--xh-glyph-size-lg));
|
|
70
96
|
--xh-_cascader-h: var(--xh-control-h-lg);
|
|
71
97
|
--xh-_cascader-px: var(--xh-control-px-lg);
|
|
72
98
|
--xh-_cascader-gap: var(--xh-control-gap-lg);
|
|
73
|
-
--xh-_cascader-font-size: var(--xh-font-
|
|
74
|
-
--xh-_cascader-label-font-size: var(--xh-font-
|
|
99
|
+
--xh-_cascader-font-size: var(--xh-control-font-lg);
|
|
100
|
+
--xh-_cascader-label-font-size: var(--xh-control-font-lg);
|
|
75
101
|
}
|
|
76
102
|
|
|
77
103
|
[data-scope='cascader'][data-part='label'] {
|
|
78
|
-
|
|
79
|
-
flex-basis: 100%;
|
|
80
|
-
color: var(--xh-cascader-label-fg, var(--xh-fg-muted));
|
|
104
|
+
color: var(--xh-cascader-label-fg, var(--xh-fg-default));
|
|
81
105
|
font-size: var(--xh-cascader-label-font-size, var(--xh-_cascader-label-font-size));
|
|
82
106
|
font-weight: var(--xh-cascader-label-font-weight, var(--xh-text-label-weight));
|
|
83
107
|
line-height: var(--xh-leading-none);
|
|
@@ -88,64 +112,88 @@
|
|
|
88
112
|
color: var(--xh-fg-subtle);
|
|
89
113
|
}
|
|
90
114
|
|
|
91
|
-
/*
|
|
92
|
-
|
|
93
|
-
[data-scope='cascader'][data-part='trigger'] {
|
|
115
|
+
/* 盒:描边、底色、控件高度与行内内衬都落在这一层,触发按钮与清空按钮在里面并排 */
|
|
116
|
+
[data-scope='cascader'][data-part='control'] {
|
|
94
117
|
display: inline-flex;
|
|
95
|
-
flex: 1;
|
|
96
118
|
align-items: center;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
border: var(--xh-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
color: var(--xh-cascader-trigger-fg, var(--xh-fg-default));
|
|
106
|
-
font-family: inherit;
|
|
107
|
-
font-size: var(--xh-cascader-trigger-font-size, var(--xh-_cascader-font-size));
|
|
108
|
-
line-height: var(--xh-leading-none);
|
|
109
|
-
text-align: start;
|
|
119
|
+
gap: var(--xh-cascader-control-gap, var(--xh-_cascader-gap));
|
|
120
|
+
min-inline-size: var(--xh-cascader-control-min-w, var(--xh-control-min-w));
|
|
121
|
+
block-size: var(--xh-cascader-control-h, var(--xh-_cascader-h));
|
|
122
|
+
padding-inline: var(--xh-cascader-control-px, var(--xh-_cascader-px));
|
|
123
|
+
border: var(--xh-stroke-thin) solid var(--xh-cascader-control-border, var(--xh-_cascader-border));
|
|
124
|
+
border-radius: var(--xh-cascader-control-radius, var(--xh-shape-control));
|
|
125
|
+
background: var(--xh-cascader-control-bg, var(--xh-_cascader-bg));
|
|
126
|
+
color: var(--xh-cascader-control-fg, var(--xh-fg-default));
|
|
110
127
|
cursor: pointer;
|
|
111
128
|
transition: border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
112
129
|
}
|
|
113
130
|
|
|
114
|
-
[data-scope='cascader'][data-part='
|
|
131
|
+
[data-scope='cascader'][data-part='control'][hidden] {
|
|
115
132
|
display: none;
|
|
116
133
|
}
|
|
117
134
|
|
|
118
135
|
/* hover 只在中性态换描边:invalid 正拿边框颜色说事,被 hover 盖掉那条信息就没了 */
|
|
119
|
-
[data-scope='cascader'][data-part='
|
|
120
|
-
border-color: var(--xh-cascader-
|
|
136
|
+
[data-scope='cascader'][data-part='control']:hover:not([data-disabled], [data-invalid]) {
|
|
137
|
+
border-color: var(--xh-cascader-control-border-hover, var(--xh-_cascader-border-hover));
|
|
121
138
|
}
|
|
122
139
|
|
|
123
|
-
/*
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
outline: var(--xh-ring-width) solid var(--xh-ring
|
|
140
|
+
/* Tab 停靠点是盒里的 trigger(展开后才移进列里),环画在盒上 */
|
|
141
|
+
[data-scope='cascader'][data-part='control']:focus-within:not([data-disabled]) {
|
|
142
|
+
border-color: var(--xh-cascader-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
|
|
143
|
+
outline: var(--xh-ring-width) solid var(--xh-_cascader-ring);
|
|
127
144
|
outline-offset: var(--xh-ring-offset);
|
|
128
145
|
}
|
|
129
146
|
|
|
130
|
-
[data-scope='cascader'][data-part='
|
|
131
|
-
border-color: var(--xh-cascader-
|
|
147
|
+
[data-scope='cascader'][data-part='control'][data-invalid] {
|
|
148
|
+
border-color: var(--xh-cascader-control-border-invalid, var(--xh-border-invalid));
|
|
149
|
+
|
|
150
|
+
/* 校验失败时环也跟着变红:两圈等宽相邻却一红一蓝,读的人不知道哪个才是当前状态 */
|
|
151
|
+
--xh-_cascader-ring: var(--xh-ring-invalid);
|
|
132
152
|
}
|
|
133
153
|
|
|
134
154
|
/* 只读仍可聚焦、浮层仍展得开、列仍能浏览,所以不置灰,只把底色压下去表示「改不动」 */
|
|
135
|
-
[data-scope='cascader'][data-part='
|
|
136
|
-
background: var(--xh-cascader-
|
|
155
|
+
[data-scope='cascader'][data-part='control'][data-readonly] {
|
|
156
|
+
background: var(--xh-cascader-control-bg-readonly, var(--xh-bg-subtle));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
[data-scope='cascader'][data-part='control'][data-disabled] {
|
|
160
|
+
background: var(--xh-cascader-control-bg-disabled, var(--xh-bg-subtle));
|
|
161
|
+
color: var(--xh-fg-disabled);
|
|
162
|
+
cursor: not-allowed;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* 盒内那颗可聚焦的按钮:不画描边不铺底也不自带高度,只占满剩余宽度、排布回显与箭头 */
|
|
166
|
+
[data-scope='cascader'][data-part='trigger'] {
|
|
167
|
+
display: inline-flex;
|
|
168
|
+
flex: 1 1 auto;
|
|
169
|
+
align-items: center;
|
|
170
|
+
justify-content: space-between;
|
|
171
|
+
gap: var(--xh-cascader-trigger-gap, var(--xh-_cascader-gap));
|
|
172
|
+
min-inline-size: 0;
|
|
173
|
+
padding: 0;
|
|
174
|
+
border: 0;
|
|
175
|
+
background: transparent;
|
|
176
|
+
color: var(--xh-cascader-trigger-fg, var(--xh-fg-default));
|
|
177
|
+
font-family: inherit;
|
|
178
|
+
font-size: var(--xh-cascader-trigger-font-size, var(--xh-_cascader-font-size));
|
|
179
|
+
line-height: var(--xh-leading-none);
|
|
180
|
+
text-align: start;
|
|
181
|
+
cursor: pointer;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
[data-scope='cascader'][data-part='trigger'][hidden] {
|
|
185
|
+
display: none;
|
|
137
186
|
}
|
|
138
187
|
|
|
139
188
|
/* trigger 是单体控件,用原生 disabled(列里的集合条目一律 aria-disabled,写 :disabled 永不命中) */
|
|
140
189
|
[data-scope='cascader'][data-part='trigger']:disabled {
|
|
141
|
-
background: var(--xh-cascader-trigger-bg-disabled, var(--xh-bg-subtle));
|
|
142
190
|
color: var(--xh-fg-disabled);
|
|
143
191
|
cursor: not-allowed;
|
|
144
192
|
}
|
|
145
193
|
|
|
146
|
-
/*
|
|
194
|
+
/* 路径连起来会很长,必须能截断;框宽由盒定,这里得允许自己被压缩 */
|
|
147
195
|
[data-scope='cascader'][data-part='value-text'] {
|
|
148
|
-
flex: 1;
|
|
196
|
+
flex: 1 1 auto;
|
|
149
197
|
min-inline-size: 0;
|
|
150
198
|
overflow: hidden;
|
|
151
199
|
white-space: nowrap;
|
|
@@ -161,6 +209,12 @@
|
|
|
161
209
|
color: var(--xh-fg-disabled);
|
|
162
210
|
}
|
|
163
211
|
|
|
212
|
+
/* 有值时清空钮顶上来,箭头让位:两个图标并排堆着,用户分不清点哪个。
|
|
213
|
+
让位而不是禁用——禁用的图标还占着位置,看着像坏了 */
|
|
214
|
+
[data-scope='cascader'][data-part='indicator'][data-clearable] {
|
|
215
|
+
display: none;
|
|
216
|
+
}
|
|
217
|
+
|
|
164
218
|
[data-scope='cascader'][data-part='indicator'] {
|
|
165
219
|
display: inline-flex;
|
|
166
220
|
flex: none;
|
|
@@ -176,7 +230,14 @@
|
|
|
176
230
|
|
|
177
231
|
/* 没写内容就由皮肤画箭头;作者往部件里塞了自己的图形,这条规则即不命中 */
|
|
178
232
|
[data-scope='cascader'][data-part='indicator']:empty::before {
|
|
179
|
-
content: '
|
|
233
|
+
content: '';
|
|
234
|
+
display: inline-block;
|
|
235
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
236
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
237
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
238
|
+
background-color: currentColor;
|
|
239
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
|
|
240
|
+
mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
|
|
180
241
|
}
|
|
181
242
|
|
|
182
243
|
[data-scope='cascader'][data-part='indicator'][data-state='open'] {
|
|
@@ -187,7 +248,7 @@
|
|
|
187
248
|
color: var(--xh-fg-disabled);
|
|
188
249
|
}
|
|
189
250
|
|
|
190
|
-
/*
|
|
251
|
+
/* 盒内靠右的小方钮,不撑高那一行 */
|
|
191
252
|
[data-scope='cascader'][data-part='clear-trigger'] {
|
|
192
253
|
display: inline-flex;
|
|
193
254
|
flex: none;
|
|
@@ -201,24 +262,25 @@
|
|
|
201
262
|
background: var(--xh-cascader-action-bg, transparent);
|
|
202
263
|
color: var(--xh-cascader-action-fg, var(--xh-fg-muted));
|
|
203
264
|
font-family: inherit;
|
|
204
|
-
font-size: var(--xh-cascader-action-font-size, var(--xh-
|
|
265
|
+
font-size: var(--xh-cascader-action-font-size, var(--xh-text-secondary-size));
|
|
205
266
|
line-height: var(--xh-leading-none);
|
|
206
267
|
cursor: pointer;
|
|
207
268
|
user-select: none;
|
|
208
|
-
transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
269
|
+
transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter), scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
209
270
|
}
|
|
210
271
|
|
|
211
272
|
[data-scope='cascader'][data-part='clear-trigger'][hidden] {
|
|
212
273
|
display: none;
|
|
213
274
|
}
|
|
214
275
|
|
|
215
|
-
[data-scope='cascader'][data-part='clear-trigger']:hover
|
|
276
|
+
[data-scope='cascader'][data-part='clear-trigger']:hover {
|
|
216
277
|
background: var(--xh-cascader-action-bg-hover, var(--xh-bg-subtle-hover));
|
|
217
278
|
color: var(--xh-cascader-action-fg-hover, var(--xh-fg-default));
|
|
218
279
|
}
|
|
219
280
|
|
|
220
|
-
[data-scope='cascader'][data-part='clear-trigger']:active
|
|
281
|
+
[data-scope='cascader'][data-part='clear-trigger']:active {
|
|
221
282
|
background: var(--xh-cascader-action-bg-active, var(--xh-bg-subtle-active));
|
|
283
|
+
scale: var(--xh-motion-scale-press);
|
|
222
284
|
}
|
|
223
285
|
|
|
224
286
|
/* 清空按钮退出了 Tab 序列(tabindex=-1),正常操作走不到这里;
|
|
@@ -228,47 +290,28 @@
|
|
|
228
290
|
outline-offset: var(--xh-ring-offset);
|
|
229
291
|
}
|
|
230
292
|
|
|
231
|
-
/* 无选中、只读、整控件禁用三种情况下都按不动,用的是原生 disabled */
|
|
232
|
-
[data-scope='cascader'][data-part='clear-trigger']:disabled {
|
|
233
|
-
background: var(--xh-cascader-action-bg, transparent);
|
|
234
|
-
color: var(--xh-fg-disabled);
|
|
235
|
-
cursor: not-allowed;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
|
|
239
|
-
[data-scope='cascader'][data-part='positioner'] {
|
|
240
|
-
position: fixed;
|
|
241
|
-
z-index: var(--xh-layer-popover);
|
|
242
|
-
/* 空壳不吃指针,交互只发生在 content 里 */
|
|
243
|
-
pointer-events: none;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/* 锚点被滚出可视区:整个浮层随之收起 */
|
|
247
|
-
[data-scope='cascader'][data-part='positioner'][data-hidden] {
|
|
248
|
-
visibility: hidden;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
293
|
/* 级联的骨架就在这一条上:列沿书写方向并排,一层一列。
|
|
252
294
|
横向随列数增减,因此不设固定宽度,只给每列自己的宽度 */
|
|
253
295
|
[data-scope='cascader'][data-part='content'] {
|
|
254
296
|
display: flex;
|
|
255
297
|
flex-direction: row;
|
|
256
298
|
align-items: stretch;
|
|
257
|
-
max-inline-size: var(--xh-cascader-content-max-w,
|
|
299
|
+
max-inline-size: var(--xh-cascader-content-max-w, var(--xh-overlay-max-w-xl));
|
|
258
300
|
border: var(--xh-stroke-thin) solid var(--xh-cascader-content-border, var(--xh-border-default));
|
|
259
301
|
border-radius: var(--xh-cascader-content-radius, var(--xh-shape-surface));
|
|
260
302
|
background: var(--xh-cascader-content-bg, var(--xh-bg-surface));
|
|
261
303
|
color: var(--xh-cascader-content-fg, var(--xh-fg-default));
|
|
262
|
-
box-shadow: var(--xh-cascader-content-shadow, var(--xh-elevation-
|
|
304
|
+
box-shadow: var(--xh-cascader-content-shadow, var(--xh-elevation-floating));
|
|
263
305
|
/* 列多到放不下时整体横向滚动;纵向溢出归每一列自己 */
|
|
264
306
|
overflow-x: auto;
|
|
265
307
|
pointer-events: auto;
|
|
266
308
|
}
|
|
267
309
|
|
|
268
|
-
/*
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
310
|
+
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
|
|
311
|
+
收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
|
|
312
|
+
[hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
|
|
313
|
+
真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
|
|
314
|
+
其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
|
|
272
315
|
|
|
273
316
|
/* 容器只是焦点域的兜底落点,落焦不画环:高亮永远长在条目上 */
|
|
274
317
|
[data-scope='cascader'][data-part='content']:focus-visible {
|
|
@@ -276,14 +319,13 @@
|
|
|
276
319
|
}
|
|
277
320
|
|
|
278
321
|
[data-scope='cascader'][data-part='content'][data-state='open'] {
|
|
279
|
-
|
|
280
|
-
--xh-_cascader-slide: -0.25rem;
|
|
281
|
-
|
|
282
|
-
animation: xh-cascader-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
322
|
+
animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
283
323
|
}
|
|
284
324
|
|
|
285
|
-
|
|
286
|
-
|
|
325
|
+
/* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
|
|
326
|
+
免得动画结束到真收起之间闪一下原样 */
|
|
327
|
+
[data-scope='cascader'][data-part='content'][data-state='closed'] {
|
|
328
|
+
animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
287
329
|
}
|
|
288
330
|
|
|
289
331
|
/* 一列:宽度由内容撑出、设下限防塌,高度定死——切换展开路径时浮层不上下跳动,
|
|
@@ -293,7 +335,7 @@
|
|
|
293
335
|
flex: none;
|
|
294
336
|
flex-direction: column;
|
|
295
337
|
min-inline-size: var(--xh-cascader-column-min-w, 7rem);
|
|
296
|
-
block-size: var(--xh-cascader-column-h,
|
|
338
|
+
block-size: var(--xh-cascader-column-h, var(--xh-viewport-h-sm));
|
|
297
339
|
padding-block: var(--xh-cascader-column-py, var(--xh-space-1));
|
|
298
340
|
padding-inline: var(--xh-cascader-column-px, var(--xh-space-1));
|
|
299
341
|
overflow-y: auto;
|
|
@@ -326,7 +368,7 @@
|
|
|
326
368
|
display: flex;
|
|
327
369
|
align-items: center;
|
|
328
370
|
gap: var(--xh-cascader-row-gap, var(--xh-_cascader-gap));
|
|
329
|
-
max-inline-size: var(--xh-cascader-row-max-w,
|
|
371
|
+
max-inline-size: var(--xh-cascader-row-max-w, var(--xh-overlay-max-w));
|
|
330
372
|
padding-block: var(--xh-cascader-row-py, var(--xh-space-1_5));
|
|
331
373
|
padding-inline: var(--xh-cascader-row-px, var(--xh-control-px-md));
|
|
332
374
|
border-radius: var(--xh-cascader-row-radius, var(--xh-shape-control));
|
|
@@ -356,14 +398,14 @@
|
|
|
356
398
|
}
|
|
357
399
|
|
|
358
400
|
/* 必须排在轻档之后:锚点走到路径上时同特指度靠书写顺序压过轻档 */
|
|
359
|
-
[data-scope='cascader'][data-part='item']:not([data-disabled])[data-
|
|
401
|
+
[data-scope='cascader'][data-part='item']:not([data-disabled])[data-in-path] {
|
|
360
402
|
background: var(--xh-cascader-row-bg-active, var(--xh-_cascader-active-bg));
|
|
361
403
|
font-weight: var(--xh-cascader-row-active-font-weight, var(--xh-font-weight-semibold));
|
|
362
404
|
}
|
|
363
405
|
|
|
364
406
|
/* 选中只换文字色与字重,配合行尾的 ✓ 标记;底色强档归展开路径、轻档归悬停,
|
|
365
407
|
三者因此能同时看见 */
|
|
366
|
-
[data-scope='cascader'][data-part='item'][data-
|
|
408
|
+
[data-scope='cascader']:is([data-part='item'], [data-part='search-item'])[data-state='checked'] {
|
|
367
409
|
color: var(--xh-cascader-row-fg-selected, var(--xh-_cascader-selected-fg));
|
|
368
410
|
font-weight: var(--xh-cascader-row-selected-font-weight, var(--xh-font-weight-medium));
|
|
369
411
|
}
|
|
@@ -428,10 +470,17 @@
|
|
|
428
470
|
|
|
429
471
|
/* 没写内容就由皮肤画勾;作者往部件里塞了自己的图形,这条规则即不命中 */
|
|
430
472
|
[data-scope='cascader'][data-part='item-indicator']:empty::before {
|
|
431
|
-
content: '
|
|
473
|
+
content: '';
|
|
474
|
+
display: inline-block;
|
|
475
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
476
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
477
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
478
|
+
background-color: currentColor;
|
|
479
|
+
-webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
480
|
+
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
432
481
|
}
|
|
433
482
|
|
|
434
|
-
[data-scope='cascader'][data-part='item-indicator'][data-
|
|
483
|
+
[data-scope='cascader'][data-part='item-indicator'][data-state='checked'] {
|
|
435
484
|
visibility: visible;
|
|
436
485
|
}
|
|
437
486
|
|
|
@@ -441,8 +490,15 @@
|
|
|
441
490
|
visibility: visible;
|
|
442
491
|
}
|
|
443
492
|
|
|
444
|
-
[data-scope='cascader'][data-part='item-indicator'][data-indeterminate]:not([data-
|
|
445
|
-
content: '
|
|
493
|
+
[data-scope='cascader'][data-part='item-indicator'][data-indeterminate]:not([data-state='checked']):empty::before {
|
|
494
|
+
content: '';
|
|
495
|
+
display: inline-block;
|
|
496
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
497
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
498
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
499
|
+
background-color: currentColor;
|
|
500
|
+
-webkit-mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
|
|
501
|
+
mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
|
|
446
502
|
font-weight: var(--xh-font-weight-semibold);
|
|
447
503
|
}
|
|
448
504
|
|
|
@@ -479,11 +535,12 @@
|
|
|
479
535
|
display: none;
|
|
480
536
|
}
|
|
481
537
|
|
|
538
|
+
/* 与列同高:搜索视图与浏览视图互换时浮层不改高度,候选多了在列表内自己滚 */
|
|
482
539
|
[data-scope='cascader'][data-part='search-list'] {
|
|
483
540
|
display: flex;
|
|
484
541
|
flex-basis: 100%;
|
|
485
542
|
flex-direction: column;
|
|
486
|
-
|
|
543
|
+
block-size: var(--xh-cascader-column-h, var(--xh-viewport-h-sm));
|
|
487
544
|
padding: var(--xh-cascader-search-p, var(--xh-space-1));
|
|
488
545
|
overflow-y: auto;
|
|
489
546
|
}
|
|
@@ -522,6 +579,12 @@
|
|
|
522
579
|
background: var(--xh-cascader-row-bg-hover, var(--xh-bg-subtle));
|
|
523
580
|
}
|
|
524
581
|
|
|
582
|
+
/* 焦点恒在输入框,环只跟虚拟高亮走,悬停不画;往内收,行是撑满列宽的,环画在外沿会被裁掉 */
|
|
583
|
+
[data-scope='cascader'][data-part='search-item']:not([data-disabled])[data-highlighted] {
|
|
584
|
+
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
585
|
+
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
586
|
+
}
|
|
587
|
+
|
|
525
588
|
[data-scope='cascader'][data-part='search-item'][data-disabled] {
|
|
526
589
|
color: var(--xh-fg-disabled);
|
|
527
590
|
cursor: not-allowed;
|
|
@@ -552,21 +615,44 @@
|
|
|
552
615
|
[data-scope='cascader'][data-part='empty'][hidden] {
|
|
553
616
|
display: none;
|
|
554
617
|
}
|
|
618
|
+
|
|
619
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
620
|
+
[data-scope='cascader'][data-part='clear-trigger']:empty::before {
|
|
621
|
+
content: '';
|
|
622
|
+
display: inline-block;
|
|
623
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
624
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
625
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
626
|
+
background-color: currentColor;
|
|
627
|
+
-webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
628
|
+
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
629
|
+
}
|
|
555
630
|
}
|
|
556
631
|
|
|
557
632
|
@layer xihan.motion {
|
|
558
633
|
/* 浮层是横向长出来的:淡入之外再沿书写方向起始缘推一小段,观感上像列被「拉开」。
|
|
559
634
|
位移量从 content 上的私有槽取,rtl 侧翻符号后同一份关键帧两个方向都对。
|
|
560
635
|
关键帧写在本文件里、名字带组件前缀,不动公共的那一份 */
|
|
561
|
-
@keyframes xh-
|
|
636
|
+
@keyframes xh-pop-in {
|
|
562
637
|
from {
|
|
563
638
|
opacity: 0;
|
|
564
|
-
|
|
639
|
+
scale: var(--xh-motion-scale-enter);
|
|
565
640
|
}
|
|
566
641
|
|
|
567
642
|
to {
|
|
568
643
|
opacity: 1;
|
|
569
|
-
|
|
644
|
+
scale: 1;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
@keyframes xh-pop-out {
|
|
648
|
+
from {
|
|
649
|
+
opacity: 1;
|
|
650
|
+
scale: 1;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
to {
|
|
654
|
+
opacity: 0;
|
|
655
|
+
scale: var(--xh-motion-scale-enter);
|
|
570
656
|
}
|
|
571
657
|
}
|
|
572
658
|
}
|
package/css/checkbox-group.css
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
@layer xihan.components {
|
|
2
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
|
+
[data-scope='checkbox-group'] {
|
|
4
|
+
--xh-checkbox-group-skin: 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
2
7
|
/* 组容器:label、trigger、条目都是它的直接子节点,排布方式只能读 data-orientation——
|
|
3
8
|
连接层明说了 role=group 不接受 aria-orientation,那个属性它根本没输出 */
|
|
4
9
|
[data-scope='checkbox-group'][data-part='root'] {
|
|
10
|
+
/* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
11
|
+
--xh-icon-size: var(--xh-checkbox-group-icon-size, var(--xh-glyph-size-text));
|
|
12
|
+
|
|
5
13
|
display: flex;
|
|
6
14
|
gap: var(--xh-checkbox-group-gap, var(--xh-stack-gap-md));
|
|
7
15
|
}
|
|
@@ -57,7 +65,6 @@
|
|
|
57
65
|
[data-scope='checkbox-group'][data-part='item'][data-disabled] {
|
|
58
66
|
color: var(--xh-checkbox-group-item-fg-disabled, var(--xh-fg-disabled));
|
|
59
67
|
cursor: not-allowed;
|
|
60
|
-
opacity: var(--xh-state-disabled-opacity);
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
/* 只读整组都改不动,但不是禁用:颜色照常,只把"可点"这个暗示收回来。
|
|
@@ -76,13 +83,13 @@
|
|
|
76
83
|
flex: none;
|
|
77
84
|
align-items: center;
|
|
78
85
|
justify-content: center;
|
|
79
|
-
inline-size: var(--xh-checkbox-group-indicator-size,
|
|
80
|
-
block-size: var(--xh-checkbox-group-indicator-size,
|
|
86
|
+
inline-size: var(--xh-checkbox-group-indicator-size, var(--xh-control-indicator-size));
|
|
87
|
+
block-size: var(--xh-checkbox-group-indicator-size, var(--xh-control-indicator-size));
|
|
81
88
|
border: var(--xh-stroke-thin) solid var(--xh-checkbox-group-indicator-border, var(--xh-border-control));
|
|
82
|
-
border-radius: var(--xh-checkbox-group-indicator-radius, var(--xh-
|
|
89
|
+
border-radius: var(--xh-checkbox-group-indicator-radius, var(--xh-shape-inset));
|
|
83
90
|
background: var(--xh-checkbox-group-indicator-bg, var(--xh-bg-canvas));
|
|
84
91
|
color: var(--xh-checkbox-group-indicator-fg, var(--xh-fg-on-brand));
|
|
85
|
-
font-size: var(--xh-checkbox-group-indicator-font-size,
|
|
92
|
+
font-size: var(--xh-checkbox-group-indicator-font-size, calc(var(--xh-control-indicator-size) * 0.75));
|
|
86
93
|
line-height: var(--xh-leading-none);
|
|
87
94
|
transition:
|
|
88
95
|
background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
@@ -102,32 +109,53 @@
|
|
|
102
109
|
border-color: var(--xh-checkbox-group-indicator-border-hover, var(--xh-border-control-hover));
|
|
103
110
|
}
|
|
104
111
|
|
|
105
|
-
/* 选中即填色:条目是二态,全选格三态里
|
|
112
|
+
/* 选中即填色:条目是二态,全选格三态里 checked 与 indeterminate 都算"有值",共用同一副填色 */
|
|
106
113
|
[data-scope='checkbox-group'][data-part='indicator'][data-state='checked'],
|
|
107
|
-
[data-scope='checkbox-group'][data-part='trigger']:is([data-state='
|
|
114
|
+
[data-scope='checkbox-group'][data-part='trigger']:is([data-state='checked'], [data-state='indeterminate'])::before {
|
|
108
115
|
border-color: var(--xh-checkbox-group-indicator-border-checked, var(--xh-bg-brand));
|
|
109
116
|
background: var(--xh-checkbox-group-indicator-bg-checked, var(--xh-bg-brand));
|
|
110
117
|
}
|
|
111
118
|
|
|
112
119
|
/* 勾号由皮肤补,作者不必自己往 indicator 里塞字符 */
|
|
113
|
-
[data-scope='checkbox-group'][data-part='indicator'][data-state='checked']::before {
|
|
114
|
-
content: '
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
[data-scope='checkbox-group'][data-part='indicator'][data-state='checked']:empty::before {
|
|
121
|
+
content: '';
|
|
122
|
+
display: inline-block;
|
|
123
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
124
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
125
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
126
|
+
background-color: currentColor;
|
|
127
|
+
-webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
128
|
+
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* 全选格的三态:checked 打勾、indeterminate 打横杠、unchecked 留空。
|
|
132
|
+
indeterminate 就是读屏听到的 aria-checked=mixed,两者同源,样式只认 data-state */
|
|
133
|
+
[data-scope='checkbox-group'][data-part='trigger'][data-state='checked']::before {
|
|
134
|
+
content: '';
|
|
135
|
+
display: inline-block;
|
|
136
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
137
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
138
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
139
|
+
background-color: currentColor;
|
|
140
|
+
-webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
141
|
+
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
121
142
|
}
|
|
122
143
|
|
|
123
|
-
[data-scope='checkbox-group'][data-part='trigger'][data-state='
|
|
124
|
-
content: '
|
|
144
|
+
[data-scope='checkbox-group'][data-part='trigger'][data-state='indeterminate']::before {
|
|
145
|
+
content: '';
|
|
146
|
+
display: inline-block;
|
|
147
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
148
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
149
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
150
|
+
background-color: currentColor;
|
|
151
|
+
-webkit-mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
|
|
152
|
+
mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
|
|
125
153
|
}
|
|
126
154
|
|
|
127
155
|
/* 校验失败标在每个方框上:root 上的 data-invalid 是唯一出处,条目自己不带这个属性 */
|
|
128
156
|
[data-scope='checkbox-group'][data-part='root'][data-invalid]
|
|
129
157
|
[data-scope='checkbox-group'][data-part='indicator'] {
|
|
130
|
-
border-color: var(--xh-checkbox-group-indicator-border-invalid, var(--xh-
|
|
158
|
+
border-color: var(--xh-checkbox-group-indicator-border-invalid, var(--xh-border-invalid));
|
|
131
159
|
}
|
|
132
160
|
|
|
133
161
|
[data-scope='checkbox-group'][data-part='item-text'] {
|
|
@@ -158,7 +186,6 @@
|
|
|
158
186
|
[data-scope='checkbox-group'][data-part='trigger'][data-disabled] {
|
|
159
187
|
color: var(--xh-checkbox-group-trigger-fg-disabled, var(--xh-fg-disabled));
|
|
160
188
|
cursor: not-allowed;
|
|
161
|
-
opacity: var(--xh-state-disabled-opacity);
|
|
162
189
|
}
|
|
163
190
|
|
|
164
191
|
/* 只读与禁用会同时出现在 trigger 上(连接层两个属性各写各的),
|