@xihan-ui/styles 1.0.0-alpha.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 +44 -0
- package/LICENSE +21 -0
- package/README.md +27 -0
- package/css/accordion.css +108 -0
- package/css/affix.css +27 -0
- package/css/alert.css +108 -0
- package/css/anchor.css +137 -0
- package/css/avatar-group.css +82 -0
- package/css/avatar.css +55 -0
- package/css/back-top.css +61 -0
- package/css/badge.css +50 -0
- package/css/breadcrumb.css +127 -0
- package/css/button-group.css +131 -0
- package/css/button.css +98 -0
- package/css/calendar.css +219 -0
- package/css/card.css +116 -0
- package/css/carousel.css +193 -0
- package/css/cascader.css +397 -0
- package/css/checkbox-group.css +185 -0
- package/css/checkbox.css +91 -0
- package/css/clipboard.css +133 -0
- package/css/code-block.css +81 -0
- package/css/collapsible.css +63 -0
- package/css/color-picker.css +424 -0
- package/css/combobox.css +433 -0
- package/css/composer.css +127 -0
- package/css/context-menu.css +263 -0
- package/css/countdown.css +21 -0
- package/css/date-field.css +200 -0
- package/css/date-picker.css +231 -0
- package/css/descriptions.css +200 -0
- package/css/dialog.css +127 -0
- package/css/drawer.css +372 -0
- package/css/dynamic-input.css +157 -0
- package/css/editable.css +249 -0
- package/css/ellipsis.css +41 -0
- package/css/empty-state.css +78 -0
- package/css/field.css +65 -0
- package/css/file-upload.css +298 -0
- package/css/flex.css +95 -0
- package/css/float-button.css +121 -0
- package/css/form.css +185 -0
- package/css/gradient-text.css +62 -0
- package/css/grid.css +428 -0
- package/css/highlight.css +21 -0
- package/css/hover-card.css +146 -0
- package/css/icon-wrapper.css +64 -0
- package/css/icon.css +54 -0
- package/css/image.css +45 -0
- package/css/infinite-scroll.css +22 -0
- package/css/layers.css +2 -0
- package/css/layout.css +169 -0
- package/css/list.css +117 -0
- package/css/listbox.css +174 -0
- package/css/loading-bar.css +66 -0
- package/css/log.css +66 -0
- package/css/marquee.css +182 -0
- package/css/mention.css +222 -0
- package/css/menu.css +144 -0
- package/css/menubar.css +271 -0
- package/css/motion.css +58 -0
- package/css/navigation-menu.css +270 -0
- package/css/number-animation.css +32 -0
- package/css/number-field.css +219 -0
- package/css/page-header.css +85 -0
- package/css/pagination.css +148 -0
- package/css/pin-input.css +157 -0
- package/css/popconfirm.css +150 -0
- package/css/popover.css +150 -0
- package/css/popselect.css +207 -0
- package/css/progress.css +37 -0
- package/css/qr-code.css +50 -0
- package/css/radio-group.css +101 -0
- package/css/rating.css +141 -0
- package/css/reset.css +22 -0
- package/css/result.css +104 -0
- package/css/scroll-area.css +176 -0
- package/css/select.css +264 -0
- package/css/separator.css +17 -0
- package/css/skeleton.css +78 -0
- package/css/slider.css +197 -0
- package/css/spinner.css +74 -0
- package/css/splitter.css +127 -0
- package/css/statistic.css +67 -0
- package/css/steps.css +252 -0
- package/css/switch.css +61 -0
- package/css/table.css +404 -0
- package/css/tabs.css +157 -0
- package/css/tags-input.css +360 -0
- package/css/text-field.css +195 -0
- package/css/thread.css +107 -0
- package/css/time-field.css +200 -0
- package/css/time-picker.css +347 -0
- package/css/time.css +20 -0
- package/css/timeline.css +284 -0
- package/css/toast.css +195 -0
- package/css/toaster.css +69 -0
- package/css/toggle-group.css +160 -0
- package/css/toggle.css +103 -0
- package/css/tone.css +85 -0
- package/css/toolbar.css +114 -0
- package/css/tooltip.css +109 -0
- package/css/tour.css +305 -0
- package/css/transfer.css +318 -0
- package/css/tree-select.css +441 -0
- package/css/tree.css +204 -0
- package/css/typography.css +151 -0
- package/css/undefined.css +38 -0
- package/css/virtualizer.css +104 -0
- package/css/visually-hidden.css +13 -0
- package/css/watermark.css +48 -0
- package/index.css +113 -0
- package/index.unlayered.css +16164 -0
- package/package.json +163 -0
package/css/card.css
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
@layer xihan.components {
|
|
2
|
+
[data-scope='card'][data-part='root'] {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
/* 封面要被圆角裁住,所以根自己收边 */
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
border: var(--xh-stroke-thin) solid transparent;
|
|
8
|
+
border-radius: var(--xh-card-radius, var(--xh-shape-surface));
|
|
9
|
+
background: var(--xh-card-bg, var(--xh-bg-surface));
|
|
10
|
+
color: var(--xh-card-fg, var(--xh-fg-default));
|
|
11
|
+
/* 各段的内边距由根上这一个槽位统一给,换档只改这里 */
|
|
12
|
+
--xh-_card-pad: var(--xh-space-4);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* —— 形态 —— */
|
|
16
|
+
[data-scope='card'][data-part='root'][data-variant='outline'] {
|
|
17
|
+
border-color: var(--xh-card-border, var(--xh-border-default));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[data-scope='card'][data-part='root'][data-variant='subtle'] {
|
|
21
|
+
background: var(--xh-card-bg, var(--xh-bg-subtle));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[data-scope='card'][data-part='root'][data-variant='elevated'] {
|
|
25
|
+
box-shadow: var(--xh-elevation-2);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[data-scope='card'][data-part='root'][data-variant='ghost'] {
|
|
29
|
+
background: transparent;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* —— 尺寸 —— */
|
|
33
|
+
[data-scope='card'][data-part='root'][data-size='sm'] {
|
|
34
|
+
--xh-_card-pad: var(--xh-space-3);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
[data-scope='card'][data-part='root'][data-size='lg'] {
|
|
38
|
+
--xh-_card-pad: var(--xh-space-6);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* 悬停抬起:只在能用指针的设备上生效,触摸端不留一个按不掉的悬停态 */
|
|
42
|
+
@media (hover: hover) {
|
|
43
|
+
[data-scope='card'][data-part='root'][data-hoverable]:hover {
|
|
44
|
+
border-color: var(--xh-card-border, var(--xh-border-strong));
|
|
45
|
+
box-shadow: var(--xh-elevation-2);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
[data-scope='card'][data-part='root'][data-hoverable] {
|
|
50
|
+
transition:
|
|
51
|
+
box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
52
|
+
border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* —— 各段 —— */
|
|
56
|
+
/* 封面顶到根的边上,不吃内边距 */
|
|
57
|
+
[data-scope='card'][data-part='cover'] {
|
|
58
|
+
display: block;
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[data-scope='card'][data-part='header'] {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
gap: var(--xh-space-1);
|
|
66
|
+
padding: var(--xh-_card-pad);
|
|
67
|
+
/* 头下面若还有别的段,间距由那一段自己的内边距接上,这里不重复留白 */
|
|
68
|
+
padding-block-end: var(--xh-space-2);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[data-scope='card'][data-part='title'] {
|
|
72
|
+
font-size: var(--xh-card-title-font-size, var(--xh-font-size-md));
|
|
73
|
+
font-weight: var(--xh-font-weight-medium);
|
|
74
|
+
line-height: var(--xh-leading-tight);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
[data-scope='card'][data-part='root'][data-size='lg'] [data-part='title'] {
|
|
78
|
+
font-size: var(--xh-card-title-font-size, var(--xh-font-size-lg));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[data-scope='card'][data-part='description'] {
|
|
82
|
+
color: var(--xh-fg-muted);
|
|
83
|
+
font-size: var(--xh-font-size-sm);
|
|
84
|
+
line-height: var(--xh-leading-normal);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-scope='card'][data-part='body'] {
|
|
88
|
+
flex: 1 1 auto;
|
|
89
|
+
padding: var(--xh-_card-pad);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* 头与身相邻时,头已经收窄了下边距,身不必再从顶上留一份 */
|
|
93
|
+
[data-scope='card'][data-part='header'] + [data-part='body'] {
|
|
94
|
+
padding-block-start: var(--xh-space-2);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
[data-scope='card'][data-part='footer'] {
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: var(--xh-space-2);
|
|
101
|
+
padding: var(--xh-_card-pad);
|
|
102
|
+
padding-block-start: var(--xh-space-2);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* —— 分段 —— */
|
|
106
|
+
/* 分隔线画在下一段的上边,段与段之间才只有一条 */
|
|
107
|
+
[data-scope='card'][data-part='root'][data-segmented] [data-part='body'],
|
|
108
|
+
[data-scope='card'][data-part='root'][data-segmented] [data-part='footer'] {
|
|
109
|
+
border-block-start: var(--xh-stroke-thin) solid var(--xh-card-border, var(--xh-border-subtle));
|
|
110
|
+
padding-block-start: var(--xh-_card-pad);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
[data-scope='card'][data-part='root'][data-segmented] [data-part='header'] {
|
|
114
|
+
padding-block-end: var(--xh-_card-pad);
|
|
115
|
+
}
|
|
116
|
+
}
|
package/css/carousel.css
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
@layer xihan.components {
|
|
2
|
+
/* 根节点是 region 地标:把上一张 / 视口 / 下一张排成一行,指示点另起一行。
|
|
3
|
+
两端按钮浮在视口上还是排在两侧由作者定,这里只给最朴素的一版排布 */
|
|
4
|
+
[data-scope='carousel'][data-part='root'] {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-wrap: wrap;
|
|
7
|
+
align-items: center;
|
|
8
|
+
gap: var(--xh-carousel-gap, var(--xh-space-2));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
[data-scope='carousel'][data-part='root'][hidden] {
|
|
12
|
+
display: none;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* 纵轨时按钮在上下两端,整条竖着排 */
|
|
16
|
+
[data-scope='carousel'][data-part='root'][data-orientation='vertical'] {
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* 视口是裁切窗口:轨道比它宽(高),露在外面的那些张全靠它切掉。
|
|
21
|
+
min-inline-size: 0 是关键——弹性子项的默认最小尺寸是内容尺寸,
|
|
22
|
+
不压成 0 的话视口会被整条轨道撑开,什么都切不掉 */
|
|
23
|
+
[data-scope='carousel'][data-part='viewport'] {
|
|
24
|
+
flex: 1 1 auto;
|
|
25
|
+
min-inline-size: 0;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
border-radius: var(--xh-carousel-viewport-radius, var(--xh-shape-surface));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[data-scope='carousel'][data-part='viewport'][hidden] {
|
|
31
|
+
display: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* 被位移的那条轨道。
|
|
35
|
+
transform 归连接层:整页位移与拖拽中的像素偏移都写在它的内联 style 上,
|
|
36
|
+
样式层再碰这条轴就会把两个位移互相覆盖,画面当场错位。
|
|
37
|
+
这里只负责排布与过渡 */
|
|
38
|
+
[data-scope='carousel'][data-part='item-group'] {
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: row;
|
|
41
|
+
block-size: 100%;
|
|
42
|
+
transition: transform var(--xh-carousel-duration, var(--xh-motion-duration-enter))
|
|
43
|
+
var(--xh-carousel-ease, var(--xh-motion-ease-enter));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
[data-scope='carousel'][data-part='item-group'][hidden] {
|
|
47
|
+
display: none;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
[data-scope='carousel'][data-part='item-group'][data-orientation='vertical'] {
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* 拖拽期间关掉过渡:留着的话画面会拖着手指慢半拍,像在拉一根皮筋 */
|
|
55
|
+
[data-scope='carousel'][data-part='item-group'][data-dragging] {
|
|
56
|
+
transition: none;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* 一张幻灯片。
|
|
60
|
+
尺寸(flex-basis)与间距(padding)同样归连接层:一屏放几张只有它知道,
|
|
61
|
+
CSS 拿不到那个数(属性值参与不了计算)。这里只补三件配套的事:
|
|
62
|
+
· box-sizing —— 内联的 padding 不得把这张撑出格子(reset 层已有同款兜底);
|
|
63
|
+
· flex-grow/shrink 归零 —— 弹性布局默认会把不满一屏的那几张拉伸,位移就对不上了;
|
|
64
|
+
· min-inline-size: 0 —— 同视口,防止长内容把这张顶宽 */
|
|
65
|
+
[data-scope='carousel'][data-part='item'] {
|
|
66
|
+
box-sizing: border-box;
|
|
67
|
+
flex-grow: 0;
|
|
68
|
+
flex-shrink: 0;
|
|
69
|
+
min-inline-size: 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
[data-scope='carousel'][data-part='item'][hidden] {
|
|
73
|
+
display: none;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* 两端按钮:圆形、与控件同高,禁用时靠原生 :disabled 变灰 */
|
|
77
|
+
[data-scope='carousel'][data-part='prev-trigger'],
|
|
78
|
+
[data-scope='carousel'][data-part='next-trigger'] {
|
|
79
|
+
display: inline-flex;
|
|
80
|
+
flex: none;
|
|
81
|
+
align-items: center;
|
|
82
|
+
justify-content: center;
|
|
83
|
+
inline-size: var(--xh-carousel-trigger-size, var(--xh-control-h-md));
|
|
84
|
+
block-size: var(--xh-carousel-trigger-size, var(--xh-control-h-md));
|
|
85
|
+
border: var(--xh-stroke-thin) solid var(--xh-carousel-trigger-border, var(--xh-border-default));
|
|
86
|
+
border-radius: var(--xh-carousel-trigger-radius, var(--xh-shape-pill));
|
|
87
|
+
background: var(--xh-carousel-trigger-bg, var(--xh-bg-surface));
|
|
88
|
+
color: var(--xh-carousel-trigger-fg, var(--xh-fg-default));
|
|
89
|
+
line-height: var(--xh-leading-none);
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
transition:
|
|
92
|
+
background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
93
|
+
border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
[data-scope='carousel'][data-part='prev-trigger'][hidden],
|
|
97
|
+
[data-scope='carousel'][data-part='next-trigger'][hidden] {
|
|
98
|
+
display: none;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
[data-scope='carousel'][data-part='prev-trigger']:hover:not(:disabled),
|
|
102
|
+
[data-scope='carousel'][data-part='next-trigger']:hover:not(:disabled) {
|
|
103
|
+
background: var(--xh-carousel-trigger-bg-hover, var(--xh-bg-subtle-hover));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
[data-scope='carousel'][data-part='prev-trigger']:active:not(:disabled),
|
|
107
|
+
[data-scope='carousel'][data-part='next-trigger']:active:not(:disabled) {
|
|
108
|
+
background: var(--xh-carousel-trigger-bg-active, var(--xh-bg-subtle-active));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[data-scope='carousel'][data-part='prev-trigger']:focus-visible,
|
|
112
|
+
[data-scope='carousel'][data-part='next-trigger']:focus-visible,
|
|
113
|
+
[data-scope='carousel'][data-part='indicator']:focus-visible {
|
|
114
|
+
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
115
|
+
outline-offset: var(--xh-ring-offset);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* 两端到头时按钮是原生 disabled(不可聚焦、进不了 Tab 序列),所以这里必须用 :disabled;
|
|
119
|
+
连接层同时给的 data-disabled 只是留给作者的钩子 */
|
|
120
|
+
[data-scope='carousel'][data-part='prev-trigger']:disabled,
|
|
121
|
+
[data-scope='carousel'][data-part='next-trigger']:disabled {
|
|
122
|
+
color: var(--xh-fg-disabled);
|
|
123
|
+
cursor: not-allowed;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* 视口与指示点都不是可聚焦节点,落焦只会是浏览器兜底行为,别画焦点环 */
|
|
127
|
+
[data-scope='carousel'][data-part='viewport']:focus-visible,
|
|
128
|
+
[data-scope='carousel'][data-part='item-group']:focus-visible,
|
|
129
|
+
[data-scope='carousel'][data-part='indicator-group']:focus-visible {
|
|
130
|
+
outline: none;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
[data-scope='carousel'][data-part='indicator-group'] {
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-wrap: wrap;
|
|
136
|
+
align-items: center;
|
|
137
|
+
justify-content: center;
|
|
138
|
+
gap: var(--xh-carousel-indicator-gap, var(--xh-space-1));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
[data-scope='carousel'][data-part='indicator-group'][hidden] {
|
|
142
|
+
display: none;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[data-scope='carousel'][data-part='indicator-group'][data-orientation='vertical'] {
|
|
146
|
+
flex-direction: column;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* 横轨时指示点另起一行占满整宽(根节点开了 flex-wrap),不跟两端按钮挤在同一行 */
|
|
150
|
+
[data-scope='carousel'][data-part='indicator-group'][data-orientation='horizontal'] {
|
|
151
|
+
flex-basis: 100%;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* 指示点:一颗小圆点。点得动的东西必须够大才点得中,
|
|
155
|
+
所以圆点本身小、可点区域靠内边距撑到最小触达尺寸 */
|
|
156
|
+
[data-scope='carousel'][data-part='indicator'] {
|
|
157
|
+
display: inline-flex;
|
|
158
|
+
flex: none;
|
|
159
|
+
align-items: center;
|
|
160
|
+
justify-content: center;
|
|
161
|
+
inline-size: var(--xh-carousel-indicator-size, var(--xh-space-2));
|
|
162
|
+
block-size: var(--xh-carousel-indicator-size, var(--xh-space-2));
|
|
163
|
+
/* 圆点本身没有文字,按钮里的文案(页码)交给作者,默认不显示 */
|
|
164
|
+
padding: 0;
|
|
165
|
+
border: 0;
|
|
166
|
+
border-radius: var(--xh-carousel-indicator-radius, var(--xh-radius-full));
|
|
167
|
+
background: var(--xh-carousel-indicator-bg, var(--xh-border-strong));
|
|
168
|
+
font-size: 0;
|
|
169
|
+
cursor: pointer;
|
|
170
|
+
transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
[data-scope='carousel'][data-part='indicator'][hidden] {
|
|
174
|
+
display: none;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
[data-scope='carousel'][data-part='indicator']:hover:not([data-selected]) {
|
|
178
|
+
background: var(--xh-carousel-indicator-bg-hover, var(--xh-fg-subtle));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* 当前页:data-selected 与 aria-current='true' 由连接层成对给出,
|
|
182
|
+
样式挂在 data 钩子上,无障碍语义留给 aria,两边各司其职 */
|
|
183
|
+
[data-scope='carousel'][data-part='indicator'][data-selected] {
|
|
184
|
+
background: var(--xh-carousel-indicator-bg-selected, var(--xh-bg-brand));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* 减少动效:位移立刻到位。翻页本身照常发生,只是不再有滑动的过程 */
|
|
188
|
+
@media (prefers-reduced-motion: reduce) {
|
|
189
|
+
[data-scope='carousel'][data-part='item-group'] {
|
|
190
|
+
transition: none;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|