@xihan-ui/styles 1.0.0-alpha.2 → 1.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +447 -0
- package/README.md +1 -1
- package/css/accordion.css +56 -5
- package/css/alert.css +30 -5
- package/css/anchor.css +7 -7
- package/css/avatar-group.css +3 -3
- package/css/avatar.css +3 -3
- package/css/back-top.css +16 -1
- package/css/badge.css +16 -2
- package/css/breadcrumb.css +24 -4
- package/css/button-group.css +14 -13
- package/css/button.css +42 -11
- package/css/calendar.css +119 -2
- package/css/card.css +5 -5
- package/css/carousel.css +36 -5
- package/css/cascader.css +183 -102
- package/css/checkbox-group.css +41 -19
- package/css/checkbox.css +54 -8
- package/css/clipboard.css +2 -1
- package/css/code-block.css +12 -7
- package/css/collapsible.css +42 -2
- package/css/color-picker.css +111 -45
- package/css/combobox.css +114 -53
- package/css/composer.css +5 -3
- package/css/context-menu.css +97 -69
- package/css/date-field.css +91 -14
- package/css/date-picker.css +276 -65
- package/css/descriptions.css +2 -2
- package/css/dialog.css +40 -13
- package/css/download-trigger.css +76 -0
- package/css/drawer.css +45 -14
- package/css/dynamic-input.css +68 -17
- package/css/editable.css +12 -10
- package/css/ellipsis.css +1 -1
- package/css/empty-state.css +7 -7
- package/css/field.css +9 -6
- package/css/fieldset.css +69 -0
- package/css/file-upload.css +45 -7
- package/css/float-button.css +16 -1
- package/css/floating-panel.css +310 -0
- package/css/form.css +4 -4
- package/css/heatmap.css +410 -0
- package/css/highlight.css +1 -1
- package/css/hotkeys.css +90 -0
- package/css/hover-card.css +40 -45
- package/css/image-cropper.css +231 -0
- package/css/image-viewer.css +137 -12
- package/css/image.css +2 -2
- package/css/infinite-scroll.css +1 -1
- package/css/json-viewer.css +241 -0
- package/css/layout.css +6 -10
- package/css/list.css +8 -8
- package/css/listbox.css +20 -4
- package/css/loading-bar.css +7 -1
- package/css/log.css +1 -1
- package/css/marquee.css +9 -0
- package/css/masonry.css +63 -0
- package/css/mention.css +87 -33
- package/css/menu.css +113 -47
- package/css/menubar.css +146 -60
- package/css/navigation-menu.css +54 -29
- package/css/number-animation.css +3 -3
- package/css/number-field.css +173 -16
- package/css/overlay-arrow.css +51 -0
- package/css/page-header.css +5 -5
- package/css/pagination.css +13 -13
- package/css/password-input.css +356 -0
- package/css/pin-input.css +13 -10
- package/css/popconfirm.css +46 -10
- package/css/popover.css +70 -45
- package/css/popselect.css +183 -53
- package/css/progress.css +47 -7
- package/css/qr-code.css +1 -1
- package/css/radio-group.css +14 -8
- package/css/rating.css +2 -2
- package/css/reset.css +17 -0
- package/css/result.css +6 -6
- package/css/scroll-area.css +61 -89
- package/css/scrollbar.css +167 -0
- package/css/segmented.css +215 -0
- package/css/select.css +274 -125
- package/css/separator.css +2 -2
- package/css/side-nav.css +111 -19
- package/css/signature-pad.css +144 -0
- package/css/skeleton.css +7 -1
- package/css/slider.css +10 -10
- package/css/space.css +117 -0
- package/css/spinner.css +22 -10
- package/css/statistic.css +9 -9
- package/css/steps.css +25 -8
- package/css/switch.css +48 -6
- package/css/table.css +131 -37
- package/css/tabs.css +4 -4
- package/css/tag.css +177 -0
- package/css/tags-input.css +78 -40
- package/css/text-field.css +149 -36
- package/css/thread.css +1 -1
- package/css/time-field.css +97 -16
- package/css/time-picker.css +259 -69
- package/css/timeline.css +10 -10
- package/css/timer.css +119 -0
- package/css/toast.css +34 -10
- package/css/toaster.css +1 -1
- package/css/toggle.css +6 -6
- package/css/tone.css +10 -5
- package/css/toolbar.css +1 -1
- package/css/tooltip.css +36 -33
- package/css/tour.css +103 -58
- package/css/transfer.css +68 -17
- package/css/tree-select.css +185 -84
- package/css/tree.css +85 -1
- package/css/typography.css +4 -4
- package/css/undefined.css +11 -1
- package/css/virtualizer.css +3 -1
- package/css/watermark.css +1 -2
- package/index.css +17 -0
- package/index.unlayered.css +8659 -2799
- package/package.json +19 -3
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
@layer xihan.components {
|
|
2
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
|
+
[data-scope='download-trigger'] {
|
|
4
|
+
--xh-download-trigger-skin: 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* 触发器就是这一个原生按钮,两个适配器都由组件自己渲染它,
|
|
9
|
+
* 所以外观得由设计系统给出一份完整的中性按钮:底色、描边、高度、字号都上令牌,
|
|
10
|
+
* 要换成品牌样式的作者改 --xh-download-trigger-* 这一族槽位,或直接写自己的类名。
|
|
11
|
+
*/
|
|
12
|
+
[data-scope='download-trigger'][data-part='root'] {
|
|
13
|
+
display: inline-flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
gap: var(--xh-download-trigger-gap, var(--xh-control-gap-md));
|
|
17
|
+
block-size: var(--xh-download-trigger-h, var(--xh-control-h-md));
|
|
18
|
+
padding-inline: var(--xh-download-trigger-px, var(--xh-control-px-md));
|
|
19
|
+
padding-block: 0;
|
|
20
|
+
border: var(--xh-stroke-thin) solid var(--xh-download-trigger-border, var(--xh-border-control));
|
|
21
|
+
border-radius: var(--xh-download-trigger-radius, var(--xh-shape-control));
|
|
22
|
+
background: var(--xh-download-trigger-bg, var(--xh-bg-canvas));
|
|
23
|
+
color: var(--xh-download-trigger-fg, var(--xh-fg-default));
|
|
24
|
+
/* 表单控件不继承页面字体,只给字号会让按钮用 UA 默认字族 */
|
|
25
|
+
font-family: inherit;
|
|
26
|
+
font-size: var(--xh-download-trigger-font-size, var(--xh-text-label-size));
|
|
27
|
+
font-weight: var(--xh-download-trigger-font-weight, var(--xh-text-label-weight));
|
|
28
|
+
line-height: var(--xh-leading-none);
|
|
29
|
+
white-space: nowrap;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
/* 导出键常被连点,触屏上默认会当成双击缩放 */
|
|
32
|
+
user-select: none;
|
|
33
|
+
touch-action: manipulation;
|
|
34
|
+
transition:
|
|
35
|
+
background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
36
|
+
border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* 上面声明了 display,会盖掉 UA 的 [hidden] 规则,收起态要在这里接回来 */
|
|
40
|
+
[data-scope='download-trigger'][data-part='root'][hidden] {
|
|
41
|
+
display: none;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[data-scope='download-trigger'][data-part='root']:hover {
|
|
45
|
+
border-color: var(--xh-download-trigger-border-hover, var(--xh-border-control-hover));
|
|
46
|
+
background: var(--xh-download-trigger-bg-hover, var(--xh-bg-subtle-hover));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
[data-scope='download-trigger'][data-part='root']:active {
|
|
50
|
+
background: var(--xh-download-trigger-bg-active, var(--xh-bg-subtle-active));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
[data-scope='download-trigger'][data-part='root']:focus-visible {
|
|
54
|
+
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
55
|
+
outline-offset: var(--xh-ring-offset);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* 取数在途:按钮留在原地不动,只换指针形状——位置一变,正要再点的人就点空了 */
|
|
59
|
+
[data-scope='download-trigger'][data-part='root'][data-state='preparing'] {
|
|
60
|
+
cursor: progress;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* 单体原生控件的禁用走 :disabled。前景与底色一起换,禁用前后两侧都由令牌管着;
|
|
65
|
+
* 用了 fg-disabled 就不再叠 opacity——两样一起用会压到读不出来。
|
|
66
|
+
* 这条排在悬停与按下之后,特异度相同、后写的赢。
|
|
67
|
+
* 描边仍按可操作区那一档:这是一颗独立按钮,四周没有别的结构标出它的位置,
|
|
68
|
+
* 描边一压下去整颗按钮在页面上就没影了。
|
|
69
|
+
*/
|
|
70
|
+
[data-scope='download-trigger'][data-part='root']:disabled {
|
|
71
|
+
border-color: var(--xh-download-trigger-border-disabled, var(--xh-border-control));
|
|
72
|
+
background: var(--xh-download-trigger-bg-disabled, var(--xh-bg-muted));
|
|
73
|
+
color: var(--xh-fg-disabled);
|
|
74
|
+
cursor: not-allowed;
|
|
75
|
+
}
|
|
76
|
+
}
|
package/css/drawer.css
CHANGED
|
@@ -118,6 +118,9 @@
|
|
|
118
118
|
/* root 留在页面原地,只是 data-side / data-state 的落点,不该凭空多出一层盒子把
|
|
119
119
|
trigger 从作者的 flex / grid 行里挤出去,故 display: contents。 */
|
|
120
120
|
[data-scope='drawer'][data-part='root'] {
|
|
121
|
+
/* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
122
|
+
--xh-icon-size: var(--xh-drawer-icon-size, var(--xh-glyph-size-text));
|
|
123
|
+
|
|
121
124
|
display: contents;
|
|
122
125
|
}
|
|
123
126
|
|
|
@@ -177,10 +180,18 @@
|
|
|
177
180
|
[data-scope='drawer'][data-part='backdrop'] {
|
|
178
181
|
position: fixed;
|
|
179
182
|
inset: 0;
|
|
180
|
-
z-index: var(--xh-layer-drawer);
|
|
183
|
+
z-index: var(--xh-drawer-backdrop-layer, var(--xh-layer-drawer));
|
|
181
184
|
background: var(--xh-drawer-backdrop-bg, var(--xh-bg-overlay));
|
|
182
185
|
}
|
|
183
186
|
|
|
187
|
+
/* 挂在局部容器里:遮罩与定位层从视口坐标换成容器坐标,只罩住那个容器。
|
|
188
|
+
作者要给那个容器加 position(relative 之类),否则 absolute 会往上找到别的定位祖先——
|
|
189
|
+
这一条写进了示例与 props 说明 */
|
|
190
|
+
[data-scope='drawer'][data-part='backdrop'][data-contained],
|
|
191
|
+
[data-scope='drawer'][data-part='positioner'][data-contained] {
|
|
192
|
+
position: absolute;
|
|
193
|
+
}
|
|
194
|
+
|
|
184
195
|
[data-scope='drawer'][data-part='backdrop'][data-state='open'] {
|
|
185
196
|
animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
186
197
|
}
|
|
@@ -196,7 +207,7 @@
|
|
|
196
207
|
[data-scope='drawer'][data-part='positioner'] {
|
|
197
208
|
position: fixed;
|
|
198
209
|
inset: 0;
|
|
199
|
-
z-index: var(--xh-layer-drawer);
|
|
210
|
+
z-index: var(--xh-drawer-layer, var(--xh-layer-drawer));
|
|
200
211
|
pointer-events: none;
|
|
201
212
|
}
|
|
202
213
|
|
|
@@ -212,18 +223,18 @@
|
|
|
212
223
|
/* 尺寸档只换这一个私有槽:左右放置时它是面板宽度、上下放置时是面板高度,
|
|
213
224
|
两种取法都在下面「四条边」那两条规则里。声明在 content 而不是 root:
|
|
214
225
|
content 会被 portal 到 body,root 上的槽位继承不过来(data-side 也是同一个道理) */
|
|
215
|
-
--xh-_drawer-size:
|
|
226
|
+
--xh-_drawer-size: var(--xh-overlay-drawer-w-md);
|
|
216
227
|
|
|
217
228
|
position: fixed;
|
|
218
|
-
z-index: var(--xh-layer-drawer);
|
|
229
|
+
z-index: var(--xh-drawer-layer, var(--xh-layer-drawer));
|
|
219
230
|
display: flex;
|
|
220
231
|
flex-direction: column;
|
|
221
232
|
gap: var(--xh-drawer-gap, var(--xh-stack-gap-md));
|
|
222
|
-
padding-block: var(--xh-drawer-py, var(--xh-
|
|
223
|
-
padding-inline: var(--xh-drawer-px, var(--xh-
|
|
233
|
+
padding-block: var(--xh-drawer-py, var(--xh-surface-py-md));
|
|
234
|
+
padding-inline: var(--xh-drawer-px, var(--xh-surface-px-md));
|
|
224
235
|
background: var(--xh-drawer-bg, var(--xh-bg-surface));
|
|
225
236
|
color: var(--xh-drawer-fg, var(--xh-fg-default));
|
|
226
|
-
box-shadow: var(--xh-drawer-shadow, var(--xh-elevation-
|
|
237
|
+
box-shadow: var(--xh-drawer-shadow, var(--xh-elevation-sheet));
|
|
227
238
|
overflow: auto;
|
|
228
239
|
/* 尺寸是照视口那条边算出来的,padding 再往外顶就会把面板挤出屏幕、
|
|
229
240
|
逼出一条横向滚动条。reset 层已有同款兜底,这里显式写一遍表明尺寸算法依赖它 */
|
|
@@ -254,11 +265,11 @@
|
|
|
254
265
|
/* 只有面板厚度分档;中间档不写规则,缺省即中档。
|
|
255
266
|
data-size 与 data-side 一样同时打在 root 与 content 上,这里只认 content 自己那一份。 */
|
|
256
267
|
[data-scope='drawer'][data-part='content'][data-size='sm'] {
|
|
257
|
-
--xh-_drawer-size:
|
|
268
|
+
--xh-_drawer-size: var(--xh-overlay-drawer-w-sm);
|
|
258
269
|
}
|
|
259
270
|
|
|
260
271
|
[data-scope='drawer'][data-part='content'][data-size='lg'] {
|
|
261
|
-
--xh-_drawer-size:
|
|
272
|
+
--xh-_drawer-size: var(--xh-overlay-drawer-w-lg);
|
|
262
273
|
}
|
|
263
274
|
|
|
264
275
|
/* —— 四条边 ——
|
|
@@ -358,7 +369,7 @@
|
|
|
358
369
|
否则长标题会直接钻到按钮底下。只在真有关闭按钮时让位。 */
|
|
359
370
|
[data-scope='drawer'][data-part='content']:has([data-scope='drawer'][data-part='close-trigger'])
|
|
360
371
|
[data-scope='drawer'][data-part='title'] {
|
|
361
|
-
padding-inline-end: calc(var(--xh-control-h-sm) + var(--xh-space-3));
|
|
372
|
+
padding-inline-end: calc(var(--xh-drawer-close-size, var(--xh-control-h-sm)) + var(--xh-space-3));
|
|
362
373
|
}
|
|
363
374
|
|
|
364
375
|
[data-scope='drawer'][data-part='close-trigger'] {
|
|
@@ -368,13 +379,16 @@
|
|
|
368
379
|
display: inline-flex;
|
|
369
380
|
align-items: center;
|
|
370
381
|
justify-content: center;
|
|
371
|
-
block-size: var(--xh-control-h-sm);
|
|
372
|
-
inline-size: var(--xh-control-h-sm);
|
|
382
|
+
block-size: var(--xh-drawer-close-size, var(--xh-control-h-sm));
|
|
383
|
+
inline-size: var(--xh-drawer-close-size, var(--xh-control-h-sm));
|
|
373
384
|
border: 0;
|
|
374
|
-
border-radius: var(--xh-shape-control);
|
|
385
|
+
border-radius: var(--xh-drawer-close-radius, var(--xh-shape-control));
|
|
375
386
|
background: transparent;
|
|
376
387
|
color: var(--xh-fg-muted);
|
|
377
388
|
cursor: pointer;
|
|
389
|
+
transition:
|
|
390
|
+
background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
391
|
+
scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
378
392
|
}
|
|
379
393
|
|
|
380
394
|
[data-scope='drawer'][data-part='close-trigger'][hidden] {
|
|
@@ -382,12 +396,29 @@
|
|
|
382
396
|
}
|
|
383
397
|
|
|
384
398
|
[data-scope='drawer'][data-part='close-trigger']:hover {
|
|
385
|
-
background: var(--xh-bg-subtle);
|
|
399
|
+
background: var(--xh-drawer-close-bg-hover, var(--xh-bg-subtle-hover));
|
|
386
400
|
color: var(--xh-fg-default);
|
|
387
401
|
}
|
|
388
402
|
|
|
403
|
+
[data-scope='drawer'][data-part='close-trigger']:active {
|
|
404
|
+
background: var(--xh-drawer-close-bg-active, var(--xh-bg-subtle-active));
|
|
405
|
+
scale: var(--xh-motion-scale-press);
|
|
406
|
+
}
|
|
407
|
+
|
|
389
408
|
[data-scope='drawer'][data-part='close-trigger']:focus-visible {
|
|
390
409
|
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
391
410
|
outline-offset: var(--xh-ring-offset);
|
|
392
411
|
}
|
|
412
|
+
|
|
413
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
414
|
+
[data-scope='drawer'][data-part='close-trigger']:empty::before {
|
|
415
|
+
content: '';
|
|
416
|
+
display: inline-block;
|
|
417
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
418
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
419
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
420
|
+
background-color: currentColor;
|
|
421
|
+
-webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
422
|
+
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
423
|
+
}
|
|
393
424
|
}
|
package/css/dynamic-input.css
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
/* 一行一条,纵向堆叠;新增把手跟在最后一行下面 */
|
|
8
8
|
[data-scope='dynamic-input'][data-part='root'] {
|
|
9
|
+
/* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
|
|
10
|
+
--xh-icon-size: var(--xh-dynamic-input-icon-size, var(--xh-glyph-size-text));
|
|
11
|
+
|
|
9
12
|
display: flex;
|
|
10
13
|
flex-direction: column;
|
|
11
14
|
gap: var(--xh-dynamic-input-gap, var(--xh-space-2));
|
|
@@ -47,55 +50,69 @@
|
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
/* —— 行内三个把手 —— */
|
|
50
|
-
[data-scope='dynamic-input'][data-part='
|
|
53
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger'],
|
|
51
54
|
[data-scope='dynamic-input'][data-part='move-up-trigger'],
|
|
52
55
|
[data-scope='dynamic-input'][data-part='move-down-trigger'] {
|
|
53
56
|
display: inline-flex;
|
|
54
57
|
flex: none;
|
|
55
58
|
align-items: center;
|
|
56
59
|
justify-content: center;
|
|
57
|
-
inline-size: var(--xh-dynamic-input-trigger-size, var(--xh-control-action-size));
|
|
58
|
-
block-size: var(--xh-dynamic-input-trigger-size, var(--xh-control-action-size));
|
|
59
60
|
padding: 0;
|
|
60
61
|
border: 0;
|
|
61
|
-
border-radius: var(--xh-dynamic-input-trigger-radius, var(--xh-shape-control));
|
|
62
62
|
background: var(--xh-dynamic-input-trigger-bg, transparent);
|
|
63
63
|
color: var(--xh-dynamic-input-trigger-fg, var(--xh-fg-muted));
|
|
64
64
|
font-family: inherit;
|
|
65
|
-
font-size: var(--xh-dynamic-input-trigger-font-size, var(--xh-
|
|
65
|
+
font-size: var(--xh-dynamic-input-trigger-font-size, var(--xh-text-secondary-size));
|
|
66
66
|
line-height: var(--xh-leading-none);
|
|
67
67
|
cursor: pointer;
|
|
68
|
-
transition:
|
|
68
|
+
transition:
|
|
69
|
+
background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
70
|
+
scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* 行级删除把手:命中区取行内动作按钮尺寸,圆角取控件圆角 */
|
|
74
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger'] {
|
|
75
|
+
inline-size: var(--xh-dynamic-input-trigger-size, var(--xh-control-action-size));
|
|
76
|
+
block-size: var(--xh-dynamic-input-trigger-size, var(--xh-control-action-size));
|
|
77
|
+
border-radius: var(--xh-dynamic-input-trigger-radius, var(--xh-shape-control));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[data-scope='dynamic-input'][data-part='move-up-trigger'],
|
|
81
|
+
[data-scope='dynamic-input'][data-part='move-down-trigger'] {
|
|
82
|
+
inline-size: var(--xh-dynamic-input-trigger-size, var(--xh-control-action-size));
|
|
83
|
+
block-size: var(--xh-dynamic-input-trigger-size, var(--xh-control-action-size));
|
|
84
|
+
border-radius: var(--xh-dynamic-input-trigger-radius, var(--xh-shape-control));
|
|
69
85
|
}
|
|
70
86
|
|
|
71
87
|
/* 不换序时连接层给换序把手写 hidden;上面那条 display 会把 UA 的 [hidden]{display:none}
|
|
72
88
|
盖掉,少了这条把手还留在原地。删除把手同样声明了 display,作者自己收起它时要的是同一条 */
|
|
73
|
-
[data-scope='dynamic-input'][data-part='
|
|
89
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger'][hidden],
|
|
74
90
|
[data-scope='dynamic-input'][data-part='move-up-trigger'][hidden],
|
|
75
91
|
[data-scope='dynamic-input'][data-part='move-down-trigger'][hidden] {
|
|
76
92
|
display: none;
|
|
77
93
|
}
|
|
78
94
|
|
|
79
95
|
/* 按不动的把手不给悬停与按下反馈:它仍然可聚焦、可点,反馈会让人以为点得动 */
|
|
80
|
-
[data-scope='dynamic-input'][data-part='
|
|
96
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger']:hover:not([aria-disabled='true']),
|
|
81
97
|
[data-scope='dynamic-input'][data-part='move-up-trigger']:hover:not([aria-disabled='true']),
|
|
82
98
|
[data-scope='dynamic-input'][data-part='move-down-trigger']:hover:not([aria-disabled='true']) {
|
|
83
99
|
background: var(--xh-dynamic-input-trigger-bg-hover, var(--xh-bg-subtle-hover));
|
|
84
100
|
color: var(--xh-dynamic-input-trigger-fg-hover, var(--xh-fg-default));
|
|
85
101
|
}
|
|
86
102
|
|
|
87
|
-
[data-scope='dynamic-input'][data-part='
|
|
88
|
-
[data-scope='dynamic-input'][data-part='move-up-trigger']:
|
|
89
|
-
[data-scope='dynamic-input'][data-part='move-down-trigger']:
|
|
103
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger']:not([aria-disabled='true']):active,
|
|
104
|
+
[data-scope='dynamic-input'][data-part='move-up-trigger']:not([aria-disabled='true']):active,
|
|
105
|
+
[data-scope='dynamic-input'][data-part='move-down-trigger']:not([aria-disabled='true']):active {
|
|
90
106
|
background: var(--xh-dynamic-input-trigger-bg-active, var(--xh-bg-subtle-active));
|
|
107
|
+
scale: var(--xh-motion-scale-press);
|
|
91
108
|
}
|
|
92
109
|
|
|
93
110
|
/* 删除把手悬停转危险色:它是这一行里唯一不可撤销的动作 */
|
|
94
|
-
[data-scope='dynamic-input'][data-part='
|
|
95
|
-
color: var(--xh-dynamic-input-
|
|
111
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger']:hover:not([aria-disabled='true']) {
|
|
112
|
+
color: var(--xh-dynamic-input-item-delete-fg-hover, var(--xh-fg-danger-hover));
|
|
96
113
|
}
|
|
97
114
|
|
|
98
|
-
[data-scope='dynamic-input'][data-part='
|
|
115
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger']:focus-visible,
|
|
99
116
|
[data-scope='dynamic-input'][data-part='move-up-trigger']:focus-visible,
|
|
100
117
|
[data-scope='dynamic-input'][data-part='move-down-trigger']:focus-visible {
|
|
101
118
|
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
@@ -104,7 +121,7 @@
|
|
|
104
121
|
|
|
105
122
|
/* 到上下限、或整份禁用时用 aria-disabled 表达(原生 disabled 不派 click,禁用守卫走不到),
|
|
106
123
|
所以样式也得认这个属性,写 :disabled 永远不命中 */
|
|
107
|
-
[data-scope='dynamic-input'][data-part='
|
|
124
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger'][aria-disabled='true'],
|
|
108
125
|
[data-scope='dynamic-input'][data-part='move-up-trigger'][aria-disabled='true'],
|
|
109
126
|
[data-scope='dynamic-input'][data-part='move-down-trigger'][aria-disabled='true'] {
|
|
110
127
|
background: transparent;
|
|
@@ -144,7 +161,7 @@
|
|
|
144
161
|
background: var(--xh-dynamic-input-add-bg-hover, var(--xh-bg-subtle-hover));
|
|
145
162
|
}
|
|
146
163
|
|
|
147
|
-
[data-scope='dynamic-input'][data-part='add-trigger']:
|
|
164
|
+
[data-scope='dynamic-input'][data-part='add-trigger']:not([aria-disabled='true']):active {
|
|
148
165
|
background: var(--xh-dynamic-input-add-bg-active, var(--xh-bg-subtle-active));
|
|
149
166
|
}
|
|
150
167
|
|
|
@@ -154,9 +171,43 @@
|
|
|
154
171
|
}
|
|
155
172
|
|
|
156
173
|
[data-scope='dynamic-input'][data-part='add-trigger'][aria-disabled='true'] {
|
|
157
|
-
border-color: var(--xh-border-subtle);
|
|
174
|
+
border-color: var(--xh-dynamic-input-add-border-disabled, var(--xh-border-subtle));
|
|
158
175
|
background: transparent;
|
|
159
176
|
color: var(--xh-fg-disabled);
|
|
160
177
|
cursor: not-allowed;
|
|
161
178
|
}
|
|
179
|
+
|
|
180
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中 */
|
|
181
|
+
[data-scope='dynamic-input'][data-part='move-up-trigger']:empty::before {
|
|
182
|
+
content: '';
|
|
183
|
+
display: inline-block;
|
|
184
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
185
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
186
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
187
|
+
background-color: currentColor;
|
|
188
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-up) center / contain no-repeat;
|
|
189
|
+
mask: var(--xh-glyph-mark-chevron-up) center / contain no-repeat;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
[data-scope='dynamic-input'][data-part='move-down-trigger']:empty::before {
|
|
193
|
+
content: '';
|
|
194
|
+
display: inline-block;
|
|
195
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
196
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
197
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
198
|
+
background-color: currentColor;
|
|
199
|
+
-webkit-mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
|
|
200
|
+
mask: var(--xh-glyph-mark-chevron-down) center / contain no-repeat;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
[data-scope='dynamic-input'][data-part='item-delete-trigger']:empty::before {
|
|
204
|
+
content: '';
|
|
205
|
+
display: inline-block;
|
|
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
|
+
vertical-align: var(--xh-glyph-baseline-shift);
|
|
209
|
+
background-color: currentColor;
|
|
210
|
+
-webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
211
|
+
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
212
|
+
}
|
|
162
213
|
}
|
package/css/editable.css
CHANGED
|
@@ -34,8 +34,7 @@
|
|
|
34
34
|
cursor: not-allowed;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/* 预览区与输入框轮流上场,两者在同一处落脚:
|
|
38
|
-
area 定死最小宽高,切换形态时这一块不会忽大忽小地跳 */
|
|
37
|
+
/* 预览区与输入框轮流上场,两者在同一处落脚:area 给这一处定最小宽高 */
|
|
39
38
|
[data-scope='editable'][data-part='area'] {
|
|
40
39
|
display: inline-flex;
|
|
41
40
|
align-items: center;
|
|
@@ -47,21 +46,23 @@
|
|
|
47
46
|
display: none;
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
/*
|
|
51
|
-
|
|
49
|
+
/* 预览区的高度、内边距与边框都和输入框取同一档,只有描边是透明的:
|
|
50
|
+
单行值定在控件档上,多行值才往下长 */
|
|
52
51
|
[data-scope='editable'][data-part='preview'] {
|
|
53
|
-
display: inline-
|
|
52
|
+
display: inline-flex;
|
|
53
|
+
align-items: center;
|
|
54
54
|
inline-size: 100%;
|
|
55
|
+
min-block-size: var(--xh-editable-preview-min-h, var(--xh-control-h-md));
|
|
55
56
|
padding-inline: var(--xh-editable-preview-px, var(--xh-control-px-md));
|
|
56
57
|
padding-block: 0;
|
|
57
58
|
border: var(--xh-stroke-thin) solid transparent;
|
|
58
59
|
border-radius: var(--xh-editable-preview-radius, var(--xh-shape-control));
|
|
59
60
|
color: var(--xh-editable-preview-fg, var(--xh-fg-default));
|
|
60
61
|
font-size: var(--xh-editable-preview-font-size, var(--xh-text-body-size));
|
|
61
|
-
line-height: var(--xh-
|
|
62
|
-
/*
|
|
62
|
+
line-height: var(--xh-leading-normal);
|
|
63
|
+
/* 值里的换行与连续空格照原样显示,过长的行断开而不撑破弹性行 */
|
|
63
64
|
white-space: pre-wrap;
|
|
64
|
-
overflow-wrap:
|
|
65
|
+
overflow-wrap: anywhere;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/* 编辑态由连接层给 hidden;上面那条 display 会盖掉 UA 规则,少了这条就收不起来 */
|
|
@@ -140,12 +141,13 @@
|
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
[data-scope='editable'][data-part='input']:focus-visible {
|
|
144
|
+
border-color: var(--xh-editable-input-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
|
|
143
145
|
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
144
146
|
outline-offset: var(--xh-ring-offset);
|
|
145
147
|
}
|
|
146
148
|
|
|
147
149
|
[data-scope='editable'][data-part='input'][data-invalid] {
|
|
148
|
-
border-color: var(--xh-editable-input-border-invalid, var(--xh-
|
|
150
|
+
border-color: var(--xh-editable-input-border-invalid, var(--xh-border-invalid));
|
|
149
151
|
}
|
|
150
152
|
|
|
151
153
|
/* 只读仍可聚焦、可复制,不置灰,只把底色压下去表示"改不动" */
|
|
@@ -188,7 +190,7 @@
|
|
|
188
190
|
background: var(--xh-editable-trigger-bg, var(--xh-bg-subtle));
|
|
189
191
|
color: var(--xh-editable-trigger-fg, var(--xh-fg-default));
|
|
190
192
|
font-family: inherit;
|
|
191
|
-
font-size: var(--xh-editable-trigger-font-size, var(--xh-
|
|
193
|
+
font-size: var(--xh-editable-trigger-font-size, var(--xh-text-secondary-size));
|
|
192
194
|
line-height: var(--xh-leading-none);
|
|
193
195
|
white-space: nowrap;
|
|
194
196
|
cursor: pointer;
|
package/css/ellipsis.css
CHANGED
package/css/empty-state.css
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
换档不必给每个部件各写一条选择器 */
|
|
10
10
|
--xh-_empty-state-gap: var(--xh-stack-gap-md);
|
|
11
11
|
--xh-_empty-state-py: var(--xh-section-py);
|
|
12
|
-
--xh-_empty-state-icon-size:
|
|
13
|
-
--xh-_empty-state-title-size: var(--xh-font-
|
|
12
|
+
--xh-_empty-state-icon-size: var(--xh-glyph-size-2xl);
|
|
13
|
+
--xh-_empty-state-title-size: var(--xh-control-font-lg);
|
|
14
14
|
/* 说明的读行宽度:整句话不收窄就会拉成一条难读的长行 */
|
|
15
15
|
--xh-_empty-state-measure: 32rem;
|
|
16
16
|
|
|
@@ -33,15 +33,15 @@
|
|
|
33
33
|
[data-scope='empty-state'][data-part='root'][data-size='sm'] {
|
|
34
34
|
--xh-_empty-state-gap: var(--xh-space-2);
|
|
35
35
|
--xh-_empty-state-py: var(--xh-space-4);
|
|
36
|
-
--xh-_empty-state-icon-size:
|
|
37
|
-
--xh-_empty-state-title-size: var(--xh-font-
|
|
36
|
+
--xh-_empty-state-icon-size: var(--xh-glyph-size-xl);
|
|
37
|
+
--xh-_empty-state-title-size: var(--xh-control-font-md);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
[data-scope='empty-state'][data-part='root'][data-size='lg'] {
|
|
41
41
|
--xh-_empty-state-gap: var(--xh-space-6);
|
|
42
42
|
--xh-_empty-state-py: var(--xh-space-8);
|
|
43
|
-
--xh-_empty-state-icon-size:
|
|
44
|
-
--xh-_empty-state-title-size: var(--xh-
|
|
43
|
+
--xh-_empty-state-icon-size: var(--xh-glyph-size-3xl);
|
|
44
|
+
--xh-_empty-state-title-size: var(--xh-text-heading-3-size);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
[data-scope='empty-state'][data-part='icon'] {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
inline-size: var(--xh-empty-state-icon-size, var(--xh-_empty-state-icon-size));
|
|
54
54
|
color: var(--xh-empty-state-icon-fg, var(--xh-fg-subtle));
|
|
55
55
|
/* 图标常是一个字形,字号跟着图标框走,line-height 不再另占高度 */
|
|
56
|
-
font-size: var(--xh-empty-state-icon-font-size, var(--xh-
|
|
56
|
+
font-size: var(--xh-empty-state-icon-font-size, var(--xh-text-heading-1-size));
|
|
57
57
|
line-height: var(--xh-leading-none);
|
|
58
58
|
}
|
|
59
59
|
|
package/css/field.css
CHANGED
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
[data-scope='form'][data-part='root'][data-layout='horizontal'] [data-scope='field'][data-part='label'] {
|
|
23
23
|
grid-column: 1;
|
|
24
24
|
justify-self: end;
|
|
25
|
-
/*
|
|
26
|
-
|
|
25
|
+
/* 与控件的首行文字对齐:行高保持正文行距(标签折行时每行不会撑成一个控件高),
|
|
26
|
+
上下留白把单行文本盒撑到控件高度;配的是哪一档控件由 --xh-field-control-h 告诉它 */
|
|
27
|
+
line-height: var(--xh-field-label-leading, var(--xh-leading-normal));
|
|
28
|
+
padding-block: calc((var(--xh-field-control-h, var(--xh-control-h-md)) - 1lh) / 2);
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
[data-scope='form'][data-part='root'][data-layout='horizontal'][data-label-align='start'] [data-scope='field'][data-part='label'] {
|
|
@@ -47,7 +49,7 @@
|
|
|
47
49
|
|
|
48
50
|
/* 必填星号:跟着根上的 data-required 亮,选填不标 */
|
|
49
51
|
[data-scope='field'][data-part='root'][data-required] [data-part='label']::after {
|
|
50
|
-
content:
|
|
52
|
+
content: var(--xh-glyph-mark-required);
|
|
51
53
|
margin-inline-start: var(--xh-space-1);
|
|
52
54
|
color: var(--xh-field-label-star, var(--xh-fg-danger));
|
|
53
55
|
}
|
|
@@ -65,12 +67,13 @@
|
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
[data-scope='field'][data-part='control']:focus-visible {
|
|
70
|
+
border-color: var(--xh-field-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
|
|
68
71
|
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
69
72
|
outline-offset: var(--xh-ring-offset);
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
[data-scope='field'][data-part='control'][data-invalid] {
|
|
73
|
-
border-color: var(--xh-field-control-border-invalid, var(--xh-
|
|
76
|
+
border-color: var(--xh-field-control-border-invalid, var(--xh-border-invalid));
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
/* 禁用由作者在控件上落原生 disabled,样式统一走 data-disabled */
|
|
@@ -83,7 +86,7 @@
|
|
|
83
86
|
[data-scope='field'][data-part='description'] {
|
|
84
87
|
margin: 0;
|
|
85
88
|
color: var(--xh-field-description-fg, var(--xh-fg-muted));
|
|
86
|
-
font-size: var(--xh-field-description-font-size, var(--xh-
|
|
89
|
+
font-size: var(--xh-field-description-font-size, var(--xh-text-secondary-size));
|
|
87
90
|
line-height: var(--xh-leading-normal);
|
|
88
91
|
}
|
|
89
92
|
|
|
@@ -95,7 +98,7 @@
|
|
|
95
98
|
[data-scope='field'][data-part='error-text'] {
|
|
96
99
|
margin: 0;
|
|
97
100
|
color: var(--xh-field-error-fg, var(--xh-fg-danger));
|
|
98
|
-
font-size: var(--xh-field-error-font-size, var(--xh-
|
|
101
|
+
font-size: var(--xh-field-error-font-size, var(--xh-text-secondary-size));
|
|
99
102
|
line-height: var(--xh-leading-normal);
|
|
100
103
|
}
|
|
101
104
|
}
|
package/css/fieldset.css
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
@layer xihan.components {
|
|
2
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
|
+
[data-scope='fieldset'] {
|
|
4
|
+
--xh-fieldset-skin: 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/* 抹掉 UA 给 <fieldset> 的边框、内外边距与 min-content 下限,间距全部改由令牌给。
|
|
8
|
+
display 落在 fieldset 的匿名内容盒上:首个 <legend> 不在这个盒子里,
|
|
9
|
+
所以 gap 只作用于组内各块,legend 与内容之间的留白由 legend 自己的下外边距给。 */
|
|
10
|
+
[data-scope='fieldset'][data-part='root'] {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: var(--xh-fieldset-gap, var(--xh-space-4));
|
|
14
|
+
margin: 0;
|
|
15
|
+
border: 0;
|
|
16
|
+
padding: 0;
|
|
17
|
+
min-inline-size: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[data-scope='fieldset'][data-part='root'][hidden] {
|
|
21
|
+
display: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[data-scope='fieldset'][data-part='legend'] {
|
|
25
|
+
padding: 0;
|
|
26
|
+
margin-block-end: var(--xh-fieldset-legend-gap, var(--xh-space-2));
|
|
27
|
+
color: var(--xh-fieldset-legend-fg, var(--xh-fg-default));
|
|
28
|
+
font-size: var(--xh-fieldset-legend-font-size, var(--xh-text-label-size));
|
|
29
|
+
font-weight: var(--xh-fieldset-legend-font-weight, var(--xh-text-label-weight));
|
|
30
|
+
line-height: var(--xh-leading-tight);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* 整组无效时组标题转警示色:没渲染错误文案的字段集上,这是屏幕上唯一变化的东西 */
|
|
34
|
+
[data-scope='fieldset'][data-part='root'][data-invalid] > [data-scope='fieldset'][data-part='legend'] {
|
|
35
|
+
color: var(--xh-fieldset-legend-fg-invalid, var(--xh-fg-danger));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* 整组禁用时组标题跟着变淡;组内控件由原生 fieldset[disabled] 各自呈现禁用态。
|
|
39
|
+
选择器与上一条同权重且排在后面,禁用与无效同时为真时以禁用为准。 */
|
|
40
|
+
[data-scope='fieldset'][data-part='root'] > [data-scope='fieldset'][data-part='legend'][data-disabled] {
|
|
41
|
+
color: var(--xh-fieldset-legend-fg-disabled, var(--xh-fg-subtle));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* 必填星号:跟着根上的 data-required 亮,选填不标 */
|
|
45
|
+
[data-scope='fieldset'][data-part='root'][data-required] > [data-scope='fieldset'][data-part='legend']::after {
|
|
46
|
+
content: var(--xh-glyph-mark-required);
|
|
47
|
+
margin-inline-start: var(--xh-space-1);
|
|
48
|
+
color: var(--xh-fieldset-legend-star, var(--xh-fg-danger));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
[data-scope='fieldset'][data-part='helper-text'] {
|
|
52
|
+
margin: 0;
|
|
53
|
+
color: var(--xh-fieldset-helper-fg, var(--xh-fg-muted));
|
|
54
|
+
font-size: var(--xh-fieldset-helper-font-size, var(--xh-text-secondary-size));
|
|
55
|
+
line-height: var(--xh-leading-normal);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
[data-scope='fieldset'][data-part='helper-text'][data-disabled] {
|
|
59
|
+
color: var(--xh-fieldset-helper-fg-disabled, var(--xh-fg-subtle));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* 不 invalid 时节点带 hidden:此处不声明 display,交给浏览器的 [hidden] 规则收起 */
|
|
63
|
+
[data-scope='fieldset'][data-part='error-text'] {
|
|
64
|
+
margin: 0;
|
|
65
|
+
color: var(--xh-fieldset-error-fg, var(--xh-fg-danger));
|
|
66
|
+
font-size: var(--xh-fieldset-error-font-size, var(--xh-text-secondary-size));
|
|
67
|
+
line-height: var(--xh-leading-normal);
|
|
68
|
+
}
|
|
69
|
+
}
|