@xihan-ui/styles 2.1.0 → 3.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 +1227 -0
- package/README.md +6 -1
- package/component-tokens.d.ts +505 -96
- package/components.tokens.json +34636 -25846
- package/css/accordion.css +34 -8
- package/css/alert.css +59 -1
- package/css/anchor.css +46 -8
- package/css/approval.css +116 -76
- package/css/avatar-group.css +1 -1
- package/css/avatar.css +13 -5
- package/css/back-top.css +61 -42
- package/css/badge.css +62 -12
- package/css/bar-code.css +1 -1
- package/css/breadcrumb.css +62 -3
- package/css/button-group.css +4 -4
- package/css/button.css +67 -19
- package/css/calendar-picker.css +19 -0
- package/css/calendar-range-picker.css +39 -2
- package/css/card.css +115 -1
- package/css/carousel.css +148 -43
- package/css/cartesian-chart.css +830 -0
- package/css/cascader.css +181 -65
- package/css/checkbox-group.css +59 -89
- package/css/checkbox.css +16 -49
- package/css/citation.css +470 -0
- package/css/clipboard.css +20 -63
- package/css/code-view.css +101 -6
- package/css/collapsible.css +34 -8
- package/css/color-field.css +18 -0
- package/css/color-picker.css +55 -58
- package/css/color-slider.css +22 -15
- package/css/color-swatch-picker.css +3 -1
- package/css/combobox.css +80 -33
- package/css/command.css +45 -43
- package/css/context-menu.css +39 -22
- package/css/date-field.css +23 -0
- package/css/date-picker.css +57 -22
- package/css/date-range-picker.css +301 -12
- package/css/description.css +17 -1
- package/css/descriptions.css +42 -0
- package/css/dialog.css +94 -36
- package/css/diff-view.css +97 -12
- package/css/download-trigger.css +44 -78
- package/css/drawer.css +160 -119
- package/css/editable.css +19 -0
- package/css/empty-state.css +7 -6
- package/css/field-array.css +36 -0
- package/css/field.css +16 -18
- package/css/file-upload.css +125 -135
- package/css/flex.css +324 -8
- package/css/float-button.css +165 -38
- package/css/floating-panel.css +53 -19
- package/css/form.css +23 -17
- package/css/funnel-chart.css +106 -0
- package/css/graph-chart.css +205 -0
- package/css/grid-list.css +235 -0
- package/css/grid.css +252 -1
- package/css/heatmap.css +119 -36
- package/css/hierarchy-chart.css +298 -0
- package/css/hover-card.css +31 -14
- package/css/icon.css +100 -0
- package/css/image-cropper.css +33 -7
- package/css/image-viewer.css +167 -22
- package/css/image.css +23 -4
- package/css/input-group.css +11 -13
- package/css/json-viewer.css +50 -2
- package/css/layout.css +68 -18
- package/css/liquid.css +106 -0
- package/css/list.css +1 -1
- package/css/listbox.css +46 -6
- package/css/loading-bar.css +27 -13
- package/css/log.css +129 -33
- package/css/markdown-stream.css +1 -1
- package/css/marquee.css +163 -7
- package/css/matrix-code.css +1 -1
- package/css/mention.css +35 -19
- package/css/menu.css +35 -21
- package/css/menubar.css +36 -20
- package/css/message-feed.css +172 -51
- package/css/navigation-menu.css +172 -11
- package/css/notification.css +429 -108
- package/css/number-field.css +22 -0
- package/css/page-header.css +3 -1
- package/css/pagination.css +126 -24
- package/css/password-input.css +40 -8
- package/css/pie-chart.css +247 -0
- package/css/popconfirm.css +44 -50
- package/css/popover.css +50 -14
- package/css/progress.css +308 -10
- package/css/prompt-input.css +36 -0
- package/css/question-flow.css +97 -57
- package/css/radar-chart.css +233 -0
- package/css/radio-group.css +363 -5
- package/css/rating.css +21 -23
- package/css/reasoning.css +61 -54
- package/css/resizable.css +6 -1
- package/css/sankey-chart.css +174 -0
- package/css/scroll-area.css +32 -0
- package/css/scrollbar.css +1 -1
- package/css/select.css +74 -55
- package/css/side-nav.css +173 -24
- package/css/signature-pad.css +16 -1
- package/css/skeleton.css +13 -14
- package/css/slider.css +35 -13
- package/css/sortable.css +37 -7
- package/css/sparkline.css +164 -0
- package/css/spinner.css +50 -22
- package/css/splitter.css +7 -1
- package/css/statistic.css +10 -0
- package/css/steps.css +248 -29
- package/css/switch.css +23 -48
- package/css/table.css +158 -118
- package/css/tabs.css +231 -19
- package/css/tag-group.css +27 -3
- package/css/tag.css +53 -12
- package/css/tags-input.css +40 -3
- package/css/text-field.css +19 -0
- package/css/time-field.css +20 -1
- package/css/time-picker.css +44 -15
- package/css/time-range-picker.css +45 -16
- package/css/timeline.css +1 -1
- package/css/toggle-group.css +4 -4
- package/css/toggle.css +4 -3
- package/css/tool-call.css +59 -51
- package/css/toolbar.css +101 -3
- package/css/tooltip.css +15 -2
- package/css/tour.css +42 -12
- package/css/transfer.css +98 -75
- package/css/tree-select.css +232 -53
- package/css/tree.css +201 -55
- package/css/truncate.css +55 -12
- package/css/typography.css +93 -0
- package/css/virtualizer.css +56 -0
- package/css/watermark.css +23 -0
- package/family/action-control.css +14 -5
- package/family/chart.css +480 -0
- package/family/check-mark.css +94 -0
- package/family/choice-card.css +97 -0
- package/family/collection-item.css +9 -15
- package/family/field-chrome.css +1 -12
- package/family/loading-ring.css +95 -0
- package/family/material.css +72 -0
- package/family/menu-choice.css +56 -0
- package/family/motion.css +207 -10
- package/family/tag-list.css +59 -0
- package/index.css +22997 -13678
- package/index.unlayered.css +12928 -3605
- package/package.json +20 -8
- package/css/gradient-text.css +0 -91
- package/css/icon-wrapper.css +0 -81
- package/css/segmented.css +0 -280
- package/css/toast.css +0 -499
package/css/diff-view.css
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
/* 定义 diff view 样式。 */
|
|
7
7
|
|
|
8
|
+
/* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
|
|
9
|
+
@import '../family/motion.css';
|
|
8
10
|
/* 独立皮肤同时传递引入折叠格按钮的动作控件配方;full bundle 递归去重。 */
|
|
9
11
|
@import '../family/action-control.css';
|
|
10
12
|
|
|
@@ -22,7 +24,7 @@
|
|
|
22
24
|
|
|
23
25
|
/* 尺寸缺省档:不写 data-size 时的取值。三档都只写这三个私有槽,
|
|
24
26
|
公开槽留在读处当首选,作者在祖先上设的覆盖才赢得过档位声明 */
|
|
25
|
-
--xh-_diff-view-font-size: var(--xh-control-font-
|
|
27
|
+
--xh-_diff-view-font-size: var(--xh-control-font-md);
|
|
26
28
|
--xh-_diff-view-px: var(--xh-space-3);
|
|
27
29
|
--xh-_diff-view-py: var(--xh-space-2);
|
|
28
30
|
|
|
@@ -126,7 +128,7 @@
|
|
|
126
128
|
|
|
127
129
|
/* 点开折叠格才露出来的那几行播一次入场;收起是硬切,不占一段退场窗口 */
|
|
128
130
|
[data-scope='diff-view'][data-part='row'][data-revealed] {
|
|
129
|
-
animation: xh-
|
|
131
|
+
animation: xh-drop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter-strong);
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
/* 行号是画上去的不是写上去的:复制差异不带它,读屏也不逐行念数字 */
|
|
@@ -341,6 +343,74 @@
|
|
|
341
343
|
mask: var(--xh-glyph-mark-warning) center / contain no-repeat;
|
|
342
344
|
}
|
|
343
345
|
|
|
346
|
+
/* 行评论:每格正文让出一列(一行高的正方格)给评论钮,没有钮的空侧也让,两侧代码才对得齐 */
|
|
347
|
+
[data-scope='diff-view'][data-part='root'][data-commentable] {
|
|
348
|
+
--xh-_diff-view-comment-col: var(--xh-diff-view-comment-col, var(--xh-diff-view-line-height, var(--xh-text-code-leading)));
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
[data-scope='diff-view'][data-part='root'][data-commentable] [data-part='line-content'] {
|
|
352
|
+
position: relative;
|
|
353
|
+
padding-inline-start: var(--xh-_diff-view-comment-col);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* 评论钮接 Action Control icon 档、ghost 形态,边长压到一行高 */
|
|
357
|
+
[data-scope='diff-view'][data-part='comment-trigger'] {
|
|
358
|
+
--xh-action-visual-size: var(--xh-_diff-view-comment-col);
|
|
359
|
+
--xh-action-min-inline-size: var(--xh-_diff-view-comment-col);
|
|
360
|
+
--xh-action-radius: var(--xh-diff-view-comment-trigger-radius, var(--xh-shape-control));
|
|
361
|
+
--xh-action-fg-rest: var(--xh-diff-view-comment-trigger-fg, var(--xh-fg-muted));
|
|
362
|
+
--xh-icon-size: var(--xh-diff-view-comment-trigger-icon-size, var(--xh-glyph-size-sm));
|
|
363
|
+
|
|
364
|
+
position: absolute;
|
|
365
|
+
inset-block-start: 0;
|
|
366
|
+
inset-inline-start: 0;
|
|
367
|
+
block-size: var(--xh-_diff-view-comment-col);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
[data-scope='diff-view'][data-part='comment-trigger'][hidden] {
|
|
371
|
+
display: none;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
[data-scope='diff-view'][data-part='comment-trigger']::before {
|
|
375
|
+
content: '';
|
|
376
|
+
display: block;
|
|
377
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
|
|
378
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
|
|
379
|
+
background-color: currentColor;
|
|
380
|
+
-webkit-mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
|
|
381
|
+
mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/* 指针设备上平时透明(仍可聚焦),悬停到这一行或焦点进了视口才显出来;触屏上常显 */
|
|
385
|
+
@media (hover: hover) and (pointer: fine) {
|
|
386
|
+
[data-scope='diff-view'][data-part='comment-trigger'] {
|
|
387
|
+
--xh-action-opacity-rest: 0;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
[data-scope='diff-view'][data-part='row']:hover [data-part='comment-trigger'],
|
|
391
|
+
[data-scope='diff-view'][data-part='viewport']:focus-within [data-part='comment-trigger'] {
|
|
392
|
+
--xh-action-opacity-rest: 1;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/* 挂在正文格里、代码下方的评论:一张静态内容面,文字按正文排,不随代码的变更色 */
|
|
397
|
+
[data-scope='diff-view'][data-part='comment-thread'] {
|
|
398
|
+
display: block;
|
|
399
|
+
box-sizing: border-box;
|
|
400
|
+
max-inline-size: var(--xh-diff-view-comment-thread-max-w, var(--xh-measure-prose));
|
|
401
|
+
margin-block: var(--xh-diff-view-comment-thread-my, var(--xh-space-2));
|
|
402
|
+
padding: var(--xh-diff-view-comment-thread-p, var(--xh-space-3));
|
|
403
|
+
border: var(--xh-stroke-thin) solid var(--xh-diff-view-comment-thread-border, var(--xh-border-default));
|
|
404
|
+
border-radius: var(--xh-diff-view-comment-thread-radius, var(--xh-shape-surface));
|
|
405
|
+
background: var(--xh-diff-view-comment-thread-bg, var(--xh-bg-surface));
|
|
406
|
+
color: var(--xh-diff-view-comment-thread-fg, var(--xh-fg-default));
|
|
407
|
+
white-space: normal;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
[data-scope='diff-view'][data-part='comment-thread'][hidden] {
|
|
411
|
+
display: none;
|
|
412
|
+
}
|
|
413
|
+
|
|
344
414
|
/* 尺寸档改字号、内衬与图标档 */
|
|
345
415
|
[data-scope='diff-view'][data-part='root'][data-size='sm'] {
|
|
346
416
|
--xh-icon-size: var(--xh-diff-view-icon-size, var(--xh-glyph-size-sm));
|
|
@@ -409,20 +479,35 @@
|
|
|
409
479
|
outline: var(--xh-stroke-thick) dashed currentColor;
|
|
410
480
|
outline-offset: calc(-1 * var(--xh-stroke-thick));
|
|
411
481
|
}
|
|
482
|
+
|
|
483
|
+
/* 纸上按不了评论钮 */
|
|
484
|
+
[data-scope='diff-view'][data-part='comment-trigger'] {
|
|
485
|
+
display: none;
|
|
486
|
+
}
|
|
412
487
|
}
|
|
413
|
-
}
|
|
414
488
|
|
|
415
|
-
@
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
489
|
+
@media (forced-colors: active) {
|
|
490
|
+
/* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
|
|
491
|
+
字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
|
|
492
|
+
按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
|
|
493
|
+
落在 Canvas 面上的取 CanvasText;
|
|
494
|
+
禁用取 GrayText */
|
|
495
|
+
[data-scope='diff-view'][data-part='truncation']::before {
|
|
496
|
+
forced-color-adjust: none;
|
|
497
|
+
background-color: CanvasText;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
[data-scope='diff-view'][data-part='comment-trigger']::before {
|
|
501
|
+
forced-color-adjust: none;
|
|
502
|
+
background-color: ButtonText;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
[data-scope='diff-view'][data-part='comment-trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed])::before {
|
|
506
|
+
background-color: HighlightText;
|
|
421
507
|
}
|
|
422
508
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
translate: 0 0;
|
|
509
|
+
[data-scope='diff-view'][data-part='comment-trigger'][data-disabled]::before {
|
|
510
|
+
background-color: GrayText;
|
|
426
511
|
}
|
|
427
512
|
}
|
|
428
513
|
}
|
package/css/download-trigger.css
CHANGED
|
@@ -5,28 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
/* 定义 download trigger 样式。 */
|
|
7
7
|
|
|
8
|
+
/* 共享关键帧由 family/motion.css 提供,本皮肤 @import 它,单独引入仍成立。 */
|
|
9
|
+
@import '../family/motion.css';
|
|
8
10
|
@import '../family/action-control.css';
|
|
9
|
-
|
|
10
|
-
@layer xihan.motion {
|
|
11
|
-
/* 转圈的关键帧定义在本文件里:引用别处文件的动画名时那份文件不一定在场,动画会静默不跑 */
|
|
12
|
-
@keyframes xh-download-trigger-rotate {
|
|
13
|
-
to {
|
|
14
|
-
rotate: 360deg;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@keyframes xh-download-trigger-loading-reveal {
|
|
19
|
-
to {
|
|
20
|
-
opacity: 1;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@keyframes xh-download-trigger-content-hide {
|
|
25
|
-
to {
|
|
26
|
-
color: transparent;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
11
|
+
@import '../family/loading-ring.css';
|
|
30
12
|
|
|
31
13
|
@layer xihan.components {
|
|
32
14
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
@@ -68,6 +50,10 @@
|
|
|
68
50
|
--xh-icon-size: var(--xh-download-trigger-icon-size, var(--xh-_action-profile-glyph-size));
|
|
69
51
|
/* 取数在途那枚圆环的颜色:字被 content-hide 关键帧压成透明,环不能跟着 currentColor 走,取加载态的前景 */
|
|
70
52
|
--xh-_download-trigger-loading-fg: var(--xh-download-trigger-loading-fg, var(--xh-download-trigger-fg, var(--xh-_action-variant-fg-loading)));
|
|
53
|
+
/* 取数在途的环由加载环配方压在钮正中(连接层投影 data-xh-loading-ring="overlay"),直径取钮的图标档;
|
|
54
|
+
起始边取钮在途时的真实前景,转速认使用者槽 */
|
|
55
|
+
--xh-_loading-ring-fg: var(--xh-_download-trigger-loading-fg);
|
|
56
|
+
--xh-_loading-ring-duration: var(--xh-download-trigger-loading-duration, var(--xh-motion-loop-spin));
|
|
71
57
|
|
|
72
58
|
/* safe:文案放不下时居中改成靠行首排,裁掉的是末尾那截,开头仍然读得到 */
|
|
73
59
|
justify-content: safe center;
|
|
@@ -92,9 +78,9 @@
|
|
|
92
78
|
}
|
|
93
79
|
|
|
94
80
|
/* 没写内容就由皮肤画兜底字形;作者往按钮里塞了文字或自己的图形,这几条即不命中。
|
|
95
|
-
字形另起一颗 ::after:::before
|
|
96
|
-
|
|
97
|
-
[data-scope='download-trigger'][data-part='root']:empty
|
|
81
|
+
字形另起一颗 ::after:::before 是加载环,mask 会把描边裁成字形轮廓、环就此消失。
|
|
82
|
+
字形取前景色:取数在途时随前景一起淡到透明,把位置让给环 */
|
|
83
|
+
[data-scope='download-trigger'][data-part='root']:empty::after {
|
|
98
84
|
content: '';
|
|
99
85
|
display: inline-block;
|
|
100
86
|
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
@@ -105,72 +91,33 @@
|
|
|
105
91
|
mask: var(--xh-glyph-mark-download) center / contain no-repeat;
|
|
106
92
|
}
|
|
107
93
|
|
|
108
|
-
/*
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
var(--xh-motion-duration-micro) forwards;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
[data-scope='download-trigger'][data-part='root'][aria-busy='true']::before {
|
|
116
|
-
content: '';
|
|
117
|
-
position: absolute;
|
|
118
|
-
inset: 0;
|
|
119
|
-
inline-size: 1em;
|
|
120
|
-
block-size: 1em;
|
|
121
|
-
margin: auto;
|
|
122
|
-
border: var(--xh-stroke-thin) solid transparent;
|
|
123
|
-
border-block-start-color: var(--xh-_download-trigger-loading-fg);
|
|
124
|
-
/* 正圆的加载环:正方盒取 circle */
|
|
125
|
-
border-radius: var(--xh-shape-circle);
|
|
126
|
-
opacity: 0;
|
|
127
|
-
animation:
|
|
128
|
-
xh-download-trigger-rotate var(--xh-download-trigger-loading-duration, var(--xh-spin-duration)) var(--xh-motion-ease-loop) infinite,
|
|
129
|
-
xh-download-trigger-loading-reveal var(--xh-motion-duration-micro) var(--xh-motion-ease-enter) var(--xh-motion-duration-micro) forwards;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
@media (prefers-reduced-motion: reduce) {
|
|
133
|
-
[data-scope='download-trigger'][data-part='root'][aria-busy='true'] {
|
|
134
|
-
color: transparent;
|
|
135
|
-
animation: none;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
[data-scope='download-trigger'][data-part='root'][aria-busy='true']::before {
|
|
139
|
-
border-style: dotted;
|
|
140
|
-
border-color: var(--xh-_download-trigger-loading-fg);
|
|
141
|
-
opacity: 1;
|
|
142
|
-
animation: none;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
:where([data-motion='reduce']) [data-scope='download-trigger'][data-part='root'][aria-busy='true'] {
|
|
147
|
-
color: transparent;
|
|
148
|
-
animation: none;
|
|
149
|
-
}
|
|
94
|
+
/* 取数在途:钮里原有的文字与字形随前景淡到透明留位,进入在途等一个 micro 才起淡(快速取数什么都不闪),
|
|
95
|
+
与环同一段等待;退出在途不等,按 micro 淡回。环的前景另由私有槽给,不跟着透明 */
|
|
96
|
+
[data-scope='download-trigger'][data-part='root'][data-loading] {
|
|
97
|
+
--xh-action-fg-loading: transparent;
|
|
150
98
|
|
|
151
|
-
|
|
152
|
-
border-style: dotted;
|
|
153
|
-
border-color: var(--xh-_download-trigger-loading-fg);
|
|
154
|
-
opacity: 1;
|
|
155
|
-
animation: none;
|
|
99
|
+
transition-delay: var(--xh-motion-duration-micro);
|
|
156
100
|
}
|
|
157
101
|
|
|
158
102
|
/* 手指落点:配方 text 档用 ::after 把块轴命中区扩到 44px;没写内容的按钮 ::after 已被兜底字形占着,
|
|
159
|
-
|
|
160
|
-
两颗伪元素轮着用。字形那条只写了尺寸与 mask,配方的定位、44px 下限与 -50% 平移会从同一个
|
|
103
|
+
这一档改用不在途时的 ::before 扩——取数在途时 ::before 是加载环,钮也按不动,不再需要热区。字形那条只写了尺寸与 mask,配方的定位、44px 下限与 -50% 平移会从同一个
|
|
161
104
|
::after 漏进来:字形被拎出行内流、盒撑到 44px 高,按钮随之收窄一格字形——这里逐项钉回 */
|
|
162
105
|
@media (pointer: coarse) {
|
|
163
|
-
[data-scope='download-trigger'][data-part='root']:empty
|
|
106
|
+
[data-scope='download-trigger'][data-part='root']:empty::after {
|
|
164
107
|
position: static;
|
|
165
108
|
min-block-size: 0;
|
|
166
109
|
translate: none;
|
|
167
110
|
}
|
|
168
111
|
|
|
169
|
-
|
|
112
|
+
/* 热区收下加载环的几何:环的描边不画、指针照接;退出在途时环在这一档直接收起,不留一圈放大的环淡出 */
|
|
113
|
+
[data-scope='download-trigger'][data-part='root']:empty:not([data-loading])::before {
|
|
170
114
|
content: '';
|
|
171
115
|
position: absolute;
|
|
172
|
-
|
|
173
|
-
|
|
116
|
+
border-color: transparent;
|
|
117
|
+
margin: 0;
|
|
118
|
+
pointer-events: auto;
|
|
119
|
+
inset-block: 50% auto;
|
|
120
|
+
inset-inline: 50% auto;
|
|
174
121
|
min-block-size: 44px;
|
|
175
122
|
inline-size: 100%;
|
|
176
123
|
block-size: 100%;
|
|
@@ -178,8 +125,27 @@
|
|
|
178
125
|
}
|
|
179
126
|
|
|
180
127
|
/* 与家族同一笔:起点是逻辑属性、平移是物理通道,rtl 下行内分量掉头,热区才落回按钮中心 */
|
|
181
|
-
[data-scope='download-trigger'][data-part='root']:empty:not([
|
|
128
|
+
[data-scope='download-trigger'][data-part='root']:empty:not([data-loading]):dir(rtl)::before {
|
|
182
129
|
translate: 50% -50%;
|
|
183
130
|
}
|
|
184
131
|
}
|
|
132
|
+
|
|
133
|
+
@media (forced-colors: active) {
|
|
134
|
+
/* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
|
|
135
|
+
字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
|
|
136
|
+
按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
|
|
137
|
+
禁用取 GrayText */
|
|
138
|
+
[data-scope='download-trigger'][data-part='root']:empty::after {
|
|
139
|
+
forced-color-adjust: none;
|
|
140
|
+
background-color: ButtonText;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
[data-scope='download-trigger'][data-part='root']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::after {
|
|
144
|
+
background-color: HighlightText;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
[data-scope='download-trigger'][data-part='root'][data-disabled]:empty::after {
|
|
148
|
+
background-color: GrayText;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
185
151
|
}
|
package/css/drawer.css
CHANGED
|
@@ -9,95 +9,6 @@
|
|
|
9
9
|
@import '../family/motion.css';
|
|
10
10
|
@import '../family/action-control.css';
|
|
11
11
|
|
|
12
|
-
@layer xihan.motion {
|
|
13
|
-
/* 四条边各一对滑入/滑出。位移量用 translate 的百分比,参照的是面板自己的边框盒,
|
|
14
|
-
所以不管 --xh-drawer-size 被改成多少,"正好推到视口外"这件事都成立。
|
|
15
|
-
|
|
16
|
-
位移写成两个私有槽位而不是写死 ±100%:贴边用的是逻辑 inset(inset-inline-start 等),
|
|
17
|
-
RTL 下 inline-end 落在物理左边;transform 没有逻辑等价物,若这里写死物理方向,
|
|
18
|
-
就会出现"面板贴在左边、却从右边滑进来"。槽位在 RTL 下翻符号,两者才始终同向。
|
|
19
|
-
竖排书写模式下 block 轴不再是 Y 轴,位移会退化为纵向,但贴边本身仍由逻辑 inset 保证。 */
|
|
20
|
-
@keyframes xh-drawer-in-right {
|
|
21
|
-
from {
|
|
22
|
-
translate: var(--xh-_drawer-shift-inline, 100%) 0;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
to {
|
|
26
|
-
translate: 0 0;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@keyframes xh-drawer-out-right {
|
|
31
|
-
from {
|
|
32
|
-
translate: 0 0;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
to {
|
|
36
|
-
translate: var(--xh-_drawer-shift-inline, 100%) 0;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@keyframes xh-drawer-in-left {
|
|
41
|
-
from {
|
|
42
|
-
translate: calc(-1 * var(--xh-_drawer-shift-inline, 100%)) 0;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
to {
|
|
46
|
-
translate: 0 0;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@keyframes xh-drawer-out-left {
|
|
51
|
-
from {
|
|
52
|
-
translate: 0 0;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
to {
|
|
56
|
-
translate: calc(-1 * var(--xh-_drawer-shift-inline, 100%)) 0;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@keyframes xh-drawer-in-top {
|
|
61
|
-
from {
|
|
62
|
-
translate: 0 calc(-1 * var(--xh-_drawer-shift-block, 100%));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
to {
|
|
66
|
-
translate: 0 0;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
@keyframes xh-drawer-out-top {
|
|
71
|
-
from {
|
|
72
|
-
translate: 0 0;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
to {
|
|
76
|
-
translate: 0 calc(-1 * var(--xh-_drawer-shift-block, 100%));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@keyframes xh-drawer-in-bottom {
|
|
81
|
-
from {
|
|
82
|
-
translate: 0 var(--xh-_drawer-shift-block, 100%);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
to {
|
|
86
|
-
translate: 0 0;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@keyframes xh-drawer-out-bottom {
|
|
91
|
-
from {
|
|
92
|
-
translate: 0 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
to {
|
|
96
|
-
translate: 0 var(--xh-_drawer-shift-block, 100%);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
12
|
@layer xihan.components {
|
|
102
13
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
103
14
|
[data-scope='drawer'] {
|
|
@@ -209,7 +120,8 @@
|
|
|
209
120
|
background: transparent;
|
|
210
121
|
}
|
|
211
122
|
|
|
212
|
-
|
|
123
|
+
/* 挂载时就开着的那一段(data-instant)属于首帧,遮罩与面板都直接呈现 */
|
|
124
|
+
[data-scope='drawer'][data-part='backdrop'][data-state='open']:not([data-instant]) {
|
|
213
125
|
animation: xh-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
214
126
|
}
|
|
215
127
|
|
|
@@ -235,9 +147,9 @@
|
|
|
235
147
|
不构成固定定位的包含块,两种结构下参照的都是视口,位置一致;
|
|
236
148
|
contained 时上面那条把它一并换成 absolute,参照的就是作者那个容器。 */
|
|
237
149
|
[data-scope='drawer'][data-part='content'] {
|
|
238
|
-
/* 位移方向的私有槽位:默认按 LTR,RTL
|
|
239
|
-
--xh-_drawer-shift-inline:
|
|
240
|
-
--xh-_drawer-shift-block:
|
|
150
|
+
/* 位移方向的私有槽位:默认按 LTR,RTL 在下面整体翻符号。幅度取整幅位移令牌,减弱动效下归零 */
|
|
151
|
+
--xh-_drawer-shift-inline: var(--xh-motion-travel);
|
|
152
|
+
--xh-_drawer-shift-block: var(--xh-motion-travel);
|
|
241
153
|
/* 尺寸档只换这一个私有槽:左右放置时它是面板宽度、上下放置时是面板高度,
|
|
242
154
|
两种取法都在下面「四条边」那两条规则里。声明在 content 而不是 root:
|
|
243
155
|
content 会被 portal 到 body,root 上的槽位继承不过来(data-side 也是同一个道理) */
|
|
@@ -276,7 +188,7 @@
|
|
|
276
188
|
}
|
|
277
189
|
|
|
278
190
|
[data-scope='drawer'][data-part='content']:dir(rtl) {
|
|
279
|
-
--xh-_drawer-shift-inline: -
|
|
191
|
+
--xh-_drawer-shift-inline: calc(-1 * var(--xh-motion-travel));
|
|
280
192
|
}
|
|
281
193
|
|
|
282
194
|
/* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致。
|
|
@@ -312,7 +224,8 @@
|
|
|
312
224
|
[data-scope='drawer'][data-part='content'][data-side='left'],
|
|
313
225
|
[data-scope='drawer'][data-part='content'][data-side='right'] {
|
|
314
226
|
inset-block: 0;
|
|
315
|
-
|
|
227
|
+
/* 调过厚度就按连接层写进私有槽的像素走,压过 size 档与使用者槽 */
|
|
228
|
+
inline-size: var(--xh-_drawer-panel-size, var(--xh-drawer-size, var(--xh-_drawer-size)));
|
|
316
229
|
/* 视口比抽屉还窄时让位,否则面板会顶出一条横向滚动条 */
|
|
317
230
|
max-inline-size: 100%;
|
|
318
231
|
}
|
|
@@ -334,7 +247,7 @@
|
|
|
334
247
|
[data-scope='drawer'][data-part='content'][data-side='top'],
|
|
335
248
|
[data-scope='drawer'][data-part='content'][data-side='bottom'] {
|
|
336
249
|
inset-inline: 0;
|
|
337
|
-
block-size: var(--xh-drawer-size, var(--xh-_drawer-size));
|
|
250
|
+
block-size: var(--xh-_drawer-panel-size, var(--xh-drawer-size, var(--xh-_drawer-size)));
|
|
338
251
|
max-block-size: 100%;
|
|
339
252
|
}
|
|
340
253
|
|
|
@@ -350,39 +263,44 @@
|
|
|
350
263
|
border-start-end-radius: var(--xh-drawer-radius, var(--xh-shape-overlay));
|
|
351
264
|
}
|
|
352
265
|
|
|
353
|
-
/*
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
[data-scope='drawer'][data-part='content'][data-side='right'][data-state='open'] {
|
|
357
|
-
animation: xh-drawer-in-right var(--xh-motion-duration-slide) var(--xh-motion-ease-slide);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
[data-scope='drawer'][data-part='content'][data-side='right'][data-state='closed'] {
|
|
361
|
-
animation: xh-drawer-out-right var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
362
|
-
}
|
|
266
|
+
/* 滑入/滑出共用整幅滑入关键帧,四条边只在两个方向槽里写起点。位移取整幅位移令牌,
|
|
267
|
+
translate 的百分比参照面板自己的边框盒,所以不管 --xh-drawer-size 被改成多少,
|
|
268
|
+
"正好推到视口外"这件事都成立。
|
|
363
269
|
|
|
364
|
-
|
|
365
|
-
|
|
270
|
+
方向槽由上面的 --xh-_drawer-shift-* 换算而不是写死物理方向:贴边用的是逻辑 inset
|
|
271
|
+
(inset-inline-start 等),RTL 下 inline-end 落在物理左边;translate 没有逻辑等价物,
|
|
272
|
+
若这里写死物理方向,就会出现"面板贴在左边、却从右边滑进来"。shift 槽在 RTL 下翻符号,
|
|
273
|
+
两者才始终同向。竖排书写模式下 block 轴不再是 Y 轴,位移会退化为纵向,但贴边本身仍由逻辑 inset 保证。 */
|
|
274
|
+
[data-scope='drawer'][data-part='content'][data-side='right'] {
|
|
275
|
+
--xh-_slide-from-x: var(--xh-_drawer-shift-inline);
|
|
366
276
|
}
|
|
367
277
|
|
|
368
|
-
[data-scope='drawer'][data-part='content'][data-side='left']
|
|
369
|
-
|
|
278
|
+
[data-scope='drawer'][data-part='content'][data-side='left'] {
|
|
279
|
+
--xh-_slide-from-x: calc(-1 * var(--xh-_drawer-shift-inline));
|
|
370
280
|
}
|
|
371
281
|
|
|
372
|
-
[data-scope='drawer'][data-part='content'][data-side='top']
|
|
373
|
-
|
|
282
|
+
[data-scope='drawer'][data-part='content'][data-side='top'] {
|
|
283
|
+
--xh-_slide-from-y: calc(-1 * var(--xh-_drawer-shift-block));
|
|
374
284
|
}
|
|
375
285
|
|
|
376
|
-
[data-scope='drawer'][data-part='content'][data-side='
|
|
377
|
-
|
|
286
|
+
[data-scope='drawer'][data-part='content'][data-side='bottom'] {
|
|
287
|
+
--xh-_slide-from-y: var(--xh-_drawer-shift-block);
|
|
378
288
|
}
|
|
379
289
|
|
|
380
|
-
|
|
381
|
-
|
|
290
|
+
/* 入场是整面板从画外推入的大尺度位移:走 --xh-motion-duration-slide 与 --xh-motion-ease-slide;
|
|
291
|
+
退场仍走 exit 档。并列的一段淡变取淡变档:缺省起止都是不透明、看不出来,减弱动效下
|
|
292
|
+
整幅位移归零、进出场由它表达。退场一律 forwards:presence 要等 animationend 才卸载,
|
|
293
|
+
不定住终态,面板会在最后一帧弹回原位再消失。 */
|
|
294
|
+
[data-scope='drawer'][data-part='content'][data-state='open']:not([data-instant]) {
|
|
295
|
+
animation:
|
|
296
|
+
xh-slide-in var(--xh-motion-duration-slide) var(--xh-motion-ease-slide),
|
|
297
|
+
xh-slide-fade-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
|
|
382
298
|
}
|
|
383
299
|
|
|
384
|
-
[data-scope='drawer'][data-part='content'][data-
|
|
385
|
-
animation:
|
|
300
|
+
[data-scope='drawer'][data-part='content'][data-state='closed'] {
|
|
301
|
+
animation:
|
|
302
|
+
xh-slide-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards,
|
|
303
|
+
xh-slide-fade-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
|
|
386
304
|
}
|
|
387
305
|
|
|
388
306
|
/* —— 面板三段 —— */
|
|
@@ -500,12 +418,135 @@
|
|
|
500
418
|
mask: var(--xh-glyph-mark-close) center / contain no-repeat;
|
|
501
419
|
}
|
|
502
420
|
|
|
421
|
+
/* —— 改尺 ——
|
|
422
|
+
把手是一条透明的命中区,贴在朝向页面的那条边上,中间一段指示条标出这里能推:
|
|
423
|
+
左右放置时是竖条、上下放置时是横条。贴边用逻辑属性:right 贴的是行尾侧,把手落在行首那条边,
|
|
424
|
+
与机器按书写方向翻转推动方向同源。厚度跟手,不挂过渡 */
|
|
425
|
+
[data-scope='drawer'][data-part='content'][data-resizing] {
|
|
426
|
+
user-select: none;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
[data-scope='drawer'][data-part='resize-trigger'] {
|
|
430
|
+
--xh-_drawer-resize-indicator: var(--xh-drawer-resize-trigger-bg, var(--xh-border-control));
|
|
431
|
+
|
|
432
|
+
position: absolute;
|
|
433
|
+
display: block;
|
|
434
|
+
border: 0;
|
|
435
|
+
padding: 0;
|
|
436
|
+
background: transparent;
|
|
437
|
+
touch-action: none;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
[data-scope='drawer'][data-part='resize-trigger']::after {
|
|
441
|
+
content: '';
|
|
442
|
+
position: absolute;
|
|
443
|
+
inset-block-start: 50%;
|
|
444
|
+
inset-inline-start: 50%;
|
|
445
|
+
border-radius: var(--xh-drawer-resize-trigger-radius, var(--xh-shape-pill));
|
|
446
|
+
background: var(--xh-_drawer-resize-indicator);
|
|
447
|
+
pointer-events: none;
|
|
448
|
+
/* 起点是逻辑属性、平移是物理通道:行内分量乘方向符号,RTL 下指示条才落回把手正中 */
|
|
449
|
+
translate: calc(-50% * var(--xh-direction-sign)) -50%;
|
|
450
|
+
transition: background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
[data-scope='drawer'][data-part='resize-trigger']:hover {
|
|
454
|
+
--xh-_drawer-resize-indicator: var(--xh-drawer-resize-trigger-bg-hover, var(--xh-border-control-hover));
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-resizing] {
|
|
458
|
+
--xh-_drawer-resize-indicator: var(--xh-drawer-resize-trigger-bg-active, var(--xh-bg-brand));
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/* 键盘落在把手上时指示条换成焦点色:命中区贴着面板边,外扩的环会压到页面上 */
|
|
462
|
+
[data-scope='drawer'][data-part='resize-trigger']:focus-visible {
|
|
463
|
+
--xh-_drawer-resize-indicator: var(--xh-ring-focus);
|
|
464
|
+
|
|
465
|
+
outline: none;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='left'],
|
|
469
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='right'] {
|
|
470
|
+
inset-block: 0;
|
|
471
|
+
inline-size: var(--xh-drawer-resize-trigger-size, var(--xh-space-2));
|
|
472
|
+
cursor: ew-resize;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='right'] {
|
|
476
|
+
inset-inline-start: 0;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='left'] {
|
|
480
|
+
inset-inline-end: 0;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='top'],
|
|
484
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='bottom'] {
|
|
485
|
+
inset-inline: 0;
|
|
486
|
+
block-size: var(--xh-drawer-resize-trigger-size, var(--xh-space-2));
|
|
487
|
+
cursor: ns-resize;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='top'] {
|
|
491
|
+
inset-block-end: 0;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
[data-scope='drawer'][data-part='resize-trigger'][data-side='bottom'] {
|
|
495
|
+
inset-block-start: 0;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
[data-scope='drawer'][data-part='resize-trigger']:is([data-side='left'], [data-side='right'])::after {
|
|
499
|
+
inline-size: var(--xh-drawer-resize-indicator-thickness, var(--xh-stroke-strong));
|
|
500
|
+
block-size: var(--xh-drawer-resize-indicator-length, var(--xh-space-8));
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
[data-scope='drawer'][data-part='resize-trigger']:is([data-side='top'], [data-side='bottom'])::after {
|
|
504
|
+
inline-size: var(--xh-drawer-resize-indicator-length, var(--xh-space-8));
|
|
505
|
+
block-size: var(--xh-drawer-resize-indicator-thickness, var(--xh-stroke-strong));
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
[data-scope='drawer'][data-part='resize-trigger'][hidden] {
|
|
509
|
+
display: none;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* 强制色下指示条的底色会被系统色吃掉:改画成正文色,调整中与聚焦时取高亮色 */
|
|
513
|
+
@media (forced-colors: active) {
|
|
514
|
+
[data-scope='drawer'][data-part='resize-trigger']::after {
|
|
515
|
+
forced-color-adjust: none;
|
|
516
|
+
background: CanvasText;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
[data-scope='drawer'][data-part='resize-trigger']:is([data-resizing], :focus-visible)::after {
|
|
520
|
+
background: Highlight;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
503
524
|
@media print {
|
|
504
525
|
/* 打印:定位层与遮罩是交互期才存在的东西,落到纸上只会盖住底下的正文。
|
|
505
526
|
收起写在这份皮肤里而不是 reset:reset 层排在组件层之前,组件层里任何一条 display 都压得住它。 */
|
|
506
527
|
[data-scope='drawer'][data-part='backdrop'],
|
|
507
|
-
[data-scope='drawer'][data-part='positioner']
|
|
528
|
+
[data-scope='drawer'][data-part='positioner'],
|
|
529
|
+
[data-scope='drawer'][data-part='resize-trigger'] {
|
|
508
530
|
display: none;
|
|
509
531
|
}
|
|
510
532
|
}
|
|
533
|
+
|
|
534
|
+
@media (forced-colors: active) {
|
|
535
|
+
/* 兜底字形是 mask 挖出来的一块底色,这一档里底色被系统换成 Canvas,字形跟着消失。
|
|
536
|
+
字形退出强制换色、直接写系统色(不能取 currentColor:退出强制换色的伪元素读到的是被系统换掉之前的作者色):
|
|
537
|
+
按钮面上取 ButtonText,悬停与按下时家族把按钮涂成 Highlight、字形换 HighlightText;
|
|
538
|
+
禁用取 GrayText */
|
|
539
|
+
[data-scope='drawer'][data-part='close-trigger']:empty::before {
|
|
540
|
+
forced-color-adjust: none;
|
|
541
|
+
background-color: ButtonText;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
[data-scope='drawer'][data-part='close-trigger']:not([data-disabled]):not([data-loading]):is(:hover, :active, [data-pressed]):empty::before {
|
|
545
|
+
background-color: HighlightText;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
[data-scope='drawer'][data-part='close-trigger'][data-disabled]:empty::before {
|
|
549
|
+
background-color: GrayText;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
511
552
|
}
|