@xihan-ui/styles 1.0.0 → 2.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.
Files changed (171) hide show
  1. package/CHANGELOG.md +5146 -6
  2. package/README.md +22 -2
  3. package/component-tokens.d.ts +4212 -0
  4. package/component-tokens.js +2 -0
  5. package/components.tokens.json +80116 -0
  6. package/css/accordion.css +131 -75
  7. package/css/affix.css +16 -1
  8. package/css/alert.css +114 -67
  9. package/css/anchor.css +99 -27
  10. package/css/approval.css +461 -0
  11. package/css/avatar-group.css +14 -6
  12. package/css/avatar.css +33 -9
  13. package/css/back-top.css +103 -48
  14. package/css/badge.css +42 -14
  15. package/css/bar-code.css +62 -0
  16. package/css/breadcrumb.css +40 -21
  17. package/css/button-group.css +146 -24
  18. package/css/button.css +116 -99
  19. package/css/calendar-picker.css +448 -0
  20. package/css/calendar-range-picker.css +517 -0
  21. package/css/card.css +54 -77
  22. package/css/carousel.css +412 -68
  23. package/css/cascader.css +429 -246
  24. package/css/checkbox-group.css +225 -77
  25. package/css/checkbox.css +174 -37
  26. package/css/clipboard.css +266 -47
  27. package/css/code-view.css +279 -0
  28. package/css/collapsible.css +108 -63
  29. package/css/color-field.css +158 -0
  30. package/css/color-picker.css +172 -184
  31. package/css/color-slider.css +274 -0
  32. package/css/color-swatch-picker.css +243 -0
  33. package/css/color-swatch.css +35 -0
  34. package/css/combobox.css +267 -273
  35. package/css/command.css +399 -0
  36. package/css/context-menu.css +183 -108
  37. package/css/date-field.css +94 -121
  38. package/css/date-picker.css +486 -249
  39. package/css/date-range-picker.css +559 -0
  40. package/css/description.css +51 -0
  41. package/css/descriptions.css +133 -87
  42. package/css/dialog.css +247 -68
  43. package/css/diff-view.css +428 -0
  44. package/css/download-trigger.css +155 -46
  45. package/css/drawer.css +194 -111
  46. package/css/editable.css +172 -152
  47. package/css/empty-state.css +80 -11
  48. package/css/field-array.css +190 -0
  49. package/css/field.css +84 -31
  50. package/css/fieldset.css +51 -18
  51. package/css/file-upload.css +134 -36
  52. package/css/flex.css +20 -1
  53. package/css/float-button.css +238 -57
  54. package/css/floating-panel.css +173 -92
  55. package/css/focus.css +46 -0
  56. package/css/forced-colors.css +93 -0
  57. package/css/form.css +254 -77
  58. package/css/gradient-text.css +34 -10
  59. package/css/grid.css +516 -5
  60. package/css/heatmap.css +87 -29
  61. package/css/highlight.css +20 -5
  62. package/css/hover-card.css +97 -47
  63. package/css/icon-wrapper.css +15 -3
  64. package/css/icon.css +74 -8
  65. package/css/image-cropper.css +143 -29
  66. package/css/image-viewer.css +150 -89
  67. package/css/image.css +30 -1
  68. package/css/infinite-scroll.css +51 -1
  69. package/css/input-group.css +277 -0
  70. package/css/json-viewer.css +102 -45
  71. package/css/kbd.css +72 -0
  72. package/css/label.css +78 -0
  73. package/css/layers.css +5 -0
  74. package/css/layout.css +175 -31
  75. package/css/list.css +24 -3
  76. package/css/listbox.css +208 -67
  77. package/css/loading-bar.css +52 -3
  78. package/css/log.css +144 -9
  79. package/css/markdown-stream.css +149 -0
  80. package/css/marquee.css +27 -1
  81. package/css/masonry.css +7 -0
  82. package/css/matrix-code.css +67 -0
  83. package/css/mention.css +234 -152
  84. package/css/menu.css +180 -83
  85. package/css/menubar.css +204 -136
  86. package/css/message-feed.css +197 -0
  87. package/css/navigation-menu.css +144 -90
  88. package/css/notification.css +178 -100
  89. package/css/number-animation.css +7 -0
  90. package/css/number-field.css +120 -277
  91. package/css/overlay-arrow.css +12 -7
  92. package/css/page-header.css +99 -14
  93. package/css/pagination.css +175 -135
  94. package/css/password-input.css +222 -219
  95. package/css/pin-input.css +101 -67
  96. package/css/pointer.css +36 -0
  97. package/css/popconfirm.css +185 -94
  98. package/css/popover.css +121 -77
  99. package/css/progress.css +60 -12
  100. package/css/prompt-input.css +224 -0
  101. package/css/question-flow.css +513 -0
  102. package/css/radio-group.css +147 -30
  103. package/css/rating.css +193 -43
  104. package/css/reasoning.css +336 -0
  105. package/css/reset.css +84 -6
  106. package/css/resizable.css +237 -0
  107. package/css/scroll-area.css +68 -7
  108. package/css/scrollbar.css +47 -13
  109. package/css/segmented.css +94 -29
  110. package/css/select.css +288 -274
  111. package/css/separator.css +101 -1
  112. package/css/side-nav.css +133 -75
  113. package/css/signature-pad.css +74 -54
  114. package/css/skeleton.css +84 -11
  115. package/css/slider.css +132 -39
  116. package/css/sortable.css +198 -0
  117. package/css/spinner.css +126 -12
  118. package/css/splitter.css +29 -8
  119. package/css/statistic.css +55 -0
  120. package/css/steps.css +206 -72
  121. package/css/switch.css +268 -36
  122. package/css/table.css +695 -118
  123. package/css/tabs.css +604 -42
  124. package/css/tag-group.css +219 -0
  125. package/css/tag.css +118 -28
  126. package/css/tags-input.css +156 -274
  127. package/css/text-field.css +101 -249
  128. package/css/time-field.css +100 -128
  129. package/css/time-picker.css +323 -252
  130. package/css/time-range-picker.css +719 -0
  131. package/css/timeline.css +202 -68
  132. package/css/timer.css +56 -52
  133. package/css/timestamp.css +34 -0
  134. package/css/toast.css +373 -144
  135. package/css/toggle-group.css +309 -76
  136. package/css/toggle.css +116 -85
  137. package/css/tone.css +47 -0
  138. package/css/tool-call.css +421 -0
  139. package/css/toolbar.css +181 -33
  140. package/css/tooltip.css +107 -36
  141. package/css/tour.css +183 -152
  142. package/css/transfer.css +351 -138
  143. package/css/tree-select.css +323 -216
  144. package/css/tree.css +294 -62
  145. package/css/truncate.css +65 -0
  146. package/css/typography.css +228 -5
  147. package/css/undefined.css +10 -1
  148. package/css/virtualizer.css +9 -10
  149. package/css/visually-hidden.css +7 -0
  150. package/css/watermark.css +7 -0
  151. package/family/action-control.css +487 -0
  152. package/family/collection-item.css +721 -0
  153. package/family/field-chrome.css +298 -0
  154. package/family/motion.css +166 -0
  155. package/family/swatch.css +59 -0
  156. package/index.css +41705 -126
  157. package/index.unlayered.css +33692 -17339
  158. package/package.json +51 -17
  159. package/css/calendar.css +0 -367
  160. package/css/code-block.css +0 -91
  161. package/css/composer.css +0 -134
  162. package/css/countdown.css +0 -26
  163. package/css/dynamic-input.css +0 -220
  164. package/css/ellipsis.css +0 -52
  165. package/css/hotkeys.css +0 -90
  166. package/css/popselect.css +0 -391
  167. package/css/qr-code.css +0 -55
  168. package/css/result.css +0 -119
  169. package/css/space.css +0 -117
  170. package/css/thread.css +0 -120
  171. package/css/time.css +0 -25
package/css/popselect.css DELETED
@@ -1,391 +0,0 @@
1
- @layer xihan.motion {
2
- /* 动画名的查找只认「文档里有没有这个名字」:引用别处文件里的名字,那份文件不一定在场,
3
- 动画会静默地整个不跑。每份皮肤都能单独引入,所以它用到的关键帧都写在自己身上。 */
4
- @keyframes xh-pop-in {
5
- from {
6
- opacity: 0;
7
- scale: var(--xh-motion-scale-enter);
8
- }
9
-
10
- to {
11
- opacity: 1;
12
- scale: 1;
13
- }
14
- }
15
- @keyframes xh-pop-out {
16
- from {
17
- opacity: 1;
18
- scale: 1;
19
- }
20
-
21
- to {
22
- opacity: 0;
23
- scale: var(--xh-motion-scale-enter);
24
- }
25
- }
26
- }
27
-
28
- @layer xihan.components {
29
- /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
30
- [data-scope='popselect'] {
31
- --xh-popselect-skin: 1;
32
- }
33
-
34
- /* 坐标由定位引擎写进 style(inset-inline-start / inset-block-start),这里只定位模式与层级 */
35
- [data-scope='popselect'][data-part='positioner'] {
36
- /* 落定那一侧的可用高度,由定位引擎经内联自定义属性写进来,内容层继承它限高;
37
- 引擎没算(尚未落位 / 无引擎 / 贴边归零)时退回自己那档静态上限 */
38
- --xh-_popselect-available-h: 100vh;
39
-
40
- /* 候选列表的自绘条浮在内容之上:轨道不上底色,实色轨道会在列表右缘糊一条竖灰带 */
41
- --xh-scrollbar-track-bg: transparent;
42
-
43
- position: fixed;
44
- z-index: var(--xh-popselect-layer, var(--xh-layer-popover));
45
- /* 空壳不吃指针,交互只发生在 content 上 */
46
- pointer-events: none;
47
- }
48
-
49
- /* 锚点被滚出可视区:整个浮层随之收起 */
50
- [data-scope='popselect'][data-part='positioner'][data-hidden] {
51
- visibility: hidden;
52
- }
53
-
54
- /* 私有槽同时声明在根与 positioner 上:浮层被搬到 portal 落点,不是根的后代,继承不过去 */
55
- [data-scope='popselect']:is([data-part='root'], [data-part='positioner']) {
56
- /* 尺寸档只换这四个私有槽,触发器与条目都从这两处继承它们,换档不必给每个部件各写一条选择器 */
57
- --xh-_popselect-h: var(--xh-control-h-md);
58
- --xh-_popselect-px: var(--xh-control-px-md);
59
- --xh-_popselect-item-py: var(--xh-list-option-py-md);
60
- --xh-_popselect-item-px: var(--xh-control-px-md);
61
- --xh-_popselect-gap: var(--xh-control-gap-md);
62
- --xh-_popselect-font-size: var(--xh-control-font-md);
63
-
64
- /* 形态档只换这三个槽:缺省即 outline(描边 + 画布底) */
65
- --xh-_popselect-control-bg: var(--xh-bg-canvas);
66
- --xh-_popselect-control-border: var(--xh-border-control);
67
- --xh-_popselect-control-border-hover: var(--xh-border-control-hover);
68
-
69
- /* 聚焦环恒用固定环色;强调色随语气走,只落在勾选标记与选中文字上,正文文字色不动。
70
- 没写 data-tone 时 --xh-_tone 没被声明,两处都退回原来的取值 */
71
- --xh-_popselect-ring: var(--xh-ring-focus);
72
- --xh-_popselect-accent: var(--xh-_tone, var(--xh-fg-brand));
73
- --xh-_popselect-item-selected-fg: var(--xh-_tone-fg, var(--xh-fg-brand-strong));
74
- }
75
-
76
- [data-scope='popselect'][data-part='root'] {
77
- /* 作者塞进指示符槽的图标跟着控件的尺寸档走;它自己写了 size 时仍以作者的为准 */
78
- --xh-icon-size: var(--xh-popselect-icon-size, var(--xh-glyph-size-md));
79
-
80
- display: inline-flex;
81
- align-items: center;
82
- gap: var(--xh-popselect-root-gap, var(--xh-space-1));
83
- }
84
-
85
- /* 图标只跟着盒那一侧换档:浮层里的勾选标记有自己的指示符盒,换成整档图标会撑破它 */
86
- [data-scope='popselect'][data-part='root'][data-size='sm'] {
87
- --xh-icon-size: var(--xh-popselect-icon-size, var(--xh-glyph-size-sm));
88
- }
89
-
90
- [data-scope='popselect'][data-part='root'][data-size='lg'] {
91
- --xh-icon-size: var(--xh-popselect-icon-size, var(--xh-glyph-size-lg));
92
- }
93
-
94
- /* —— 尺寸 —— */
95
- /* 缺省档写在上面的基础规则里 */
96
- [data-scope='popselect']:is([data-part='root'], [data-part='positioner'])[data-size='sm'] {
97
- --xh-_popselect-h: var(--xh-control-h-sm);
98
- --xh-_popselect-px: var(--xh-control-px-sm);
99
- --xh-_popselect-item-py: var(--xh-list-option-py-sm);
100
- --xh-_popselect-item-px: var(--xh-control-px-sm);
101
- --xh-_popselect-gap: var(--xh-control-gap-sm);
102
- --xh-_popselect-font-size: var(--xh-control-font-sm);
103
- }
104
-
105
- [data-scope='popselect']:is([data-part='root'], [data-part='positioner'])[data-size='lg'] {
106
- --xh-_popselect-h: var(--xh-control-h-lg);
107
- --xh-_popselect-px: var(--xh-control-px-lg);
108
- --xh-_popselect-item-py: var(--xh-list-option-py-lg);
109
- --xh-_popselect-item-px: var(--xh-control-px-lg);
110
- --xh-_popselect-gap: var(--xh-control-gap-lg);
111
- --xh-_popselect-font-size: var(--xh-control-font-lg);
112
- }
113
-
114
- /* —— 形态 —— */
115
- /* 形态只决定描边与底色怎么用,用哪族颜色由 data-tone 决定 */
116
- [data-scope='popselect']:is([data-part='root'], [data-part='positioner'])[data-variant='outline'] {
117
- --xh-_popselect-control-bg: var(--xh-bg-canvas);
118
- --xh-_popselect-control-border: var(--xh-border-control);
119
- --xh-_popselect-control-border-hover: var(--xh-border-control-hover);
120
- }
121
-
122
- /* 填充式:底色顶替描边,悬停时才浮出一道淡边 */
123
- [data-scope='popselect']:is([data-part='root'], [data-part='positioner'])[data-variant='subtle'] {
124
- --xh-_popselect-control-bg: var(--xh-_tone-subtle, var(--xh-bg-subtle));
125
- --xh-_popselect-control-border: transparent;
126
- --xh-_popselect-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
127
- }
128
-
129
- /* 无框:底与常态描边透明,悬停浮出描边,聚焦由焦点环表达 */
130
- [data-scope='popselect']:is([data-part='root'], [data-part='positioner'])[data-variant='ghost'] {
131
- --xh-_popselect-control-bg: transparent;
132
- --xh-_popselect-control-border: transparent;
133
- --xh-_popselect-control-border-hover: var(--xh-_tone-border, var(--xh-border-control-hover));
134
- }
135
-
136
- /* 盒:描边、底色、圆角、控件高度与行内内衬都长在这一层,触发器与清空按钮在里面并排。
137
- 聚焦环也画在它上面,焦点落在哪颗按钮上,看到的都是同一个框亮起来 */
138
- [data-scope='popselect'][data-part='control'] {
139
- display: inline-flex;
140
- align-items: center;
141
- gap: var(--xh-popselect-control-gap, var(--xh-_popselect-gap));
142
- block-size: var(--xh-popselect-control-h, var(--xh-_popselect-h));
143
- padding-inline: var(--xh-popselect-control-px, var(--xh-_popselect-px));
144
- min-inline-size: var(--xh-popselect-control-min-w, var(--xh-control-min-w));
145
- border: var(--xh-stroke-thin) solid var(--xh-popselect-control-border, var(--xh-_popselect-control-border));
146
- border-radius: var(--xh-popselect-control-radius, var(--xh-shape-control));
147
- background: var(--xh-popselect-control-bg, var(--xh-_popselect-control-bg));
148
- }
149
-
150
- [data-scope='popselect'][data-part='control']:hover:not([data-disabled]) {
151
- border-color: var(--xh-popselect-control-border-hover, var(--xh-_popselect-control-border-hover));
152
- }
153
-
154
- /* 焦点落在盒内任一颗按钮上都画同一圈环;禁用时按钮不可聚焦,守卫只是把这条说死。
155
- 描边色与环共用一族语气色 */
156
- [data-scope='popselect'][data-part='control']:focus-within:not([data-disabled]) {
157
- border-color: var(--xh-popselect-control-border-focus, var(--xh-_tone, var(--xh-border-control-focus)));
158
- outline: var(--xh-ring-width) solid var(--xh-_popselect-ring);
159
- outline-offset: var(--xh-ring-offset);
160
- }
161
-
162
- [data-scope='popselect'][data-part='control'][data-disabled] {
163
- background: var(--xh-popselect-control-bg-disabled, var(--xh-bg-subtle));
164
- color: var(--xh-fg-disabled);
165
- cursor: not-allowed;
166
- }
167
-
168
- /* 触发器退化成盒里那颗可聚焦的按钮:描边、底色与内衬归盒,它只占满剩余一行 */
169
- [data-scope='popselect'][data-part='trigger'] {
170
- display: inline-flex;
171
- flex: 1 1 auto;
172
- align-items: center;
173
- justify-content: space-between;
174
- gap: var(--xh-popselect-trigger-gap, var(--xh-_popselect-gap));
175
- /* 弹性子项默认最小尺寸是内容尺寸,不归零则长值把盒撑破 */
176
- min-inline-size: 0;
177
- padding: 0;
178
- border: 0;
179
- background: transparent;
180
- color: var(--xh-popselect-trigger-fg, var(--xh-fg-default));
181
- font-size: var(--xh-popselect-trigger-font-size, var(--xh-_popselect-font-size));
182
- line-height: var(--xh-leading-none);
183
- text-align: start;
184
- cursor: pointer;
185
- }
186
-
187
- /* 环画在盒上,按钮自己不再画:两圈套着的环读起来像两个控件 */
188
- [data-scope='popselect'][data-part='trigger']:focus-visible {
189
- outline: none;
190
- }
191
-
192
- /* trigger 是单体控件,用原生 disabled(条目那边一律 aria-disabled) */
193
- [data-scope='popselect'][data-part='trigger']:disabled {
194
- color: var(--xh-fg-disabled);
195
- cursor: not-allowed;
196
- }
197
-
198
- /* 无选中:触发器上显示的是占位文字,画淡一档 */
199
- [data-scope='popselect'][data-part='trigger'][data-placeholder] {
200
- color: var(--xh-popselect-placeholder-fg, var(--xh-fg-subtle));
201
- }
202
-
203
- /* 清空钮:盒里排在触发器之后的方形小钮,没值即 hidden 收起 */
204
- [data-scope='popselect'][data-part='clear-trigger'] {
205
- display: inline-grid;
206
- flex: none;
207
- place-items: center;
208
- inline-size: var(--xh-popselect-action-size, var(--xh-control-action-size));
209
- block-size: var(--xh-popselect-action-size, var(--xh-control-action-size));
210
- padding: 0;
211
- border: none;
212
- border-radius: var(--xh-popselect-action-radius, var(--xh-shape-control));
213
- background: none;
214
- color: var(--xh-popselect-clear-fg, var(--xh-fg-subtle));
215
- line-height: var(--xh-leading-none);
216
- cursor: pointer;
217
- transition:
218
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
219
- color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
220
- scale var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
221
- }
222
-
223
- [data-scope='popselect'][data-part='clear-trigger']:hover {
224
- background: var(--xh-popselect-clear-bg-hover, var(--xh-bg-subtle-hover));
225
- color: var(--xh-popselect-clear-fg-hover, var(--xh-fg-default));
226
- }
227
-
228
- [data-scope='popselect'][data-part='clear-trigger']:active {
229
- background: var(--xh-popselect-clear-bg-active, var(--xh-bg-subtle-active));
230
- scale: var(--xh-motion-scale-press);
231
- }
232
-
233
- [data-scope='popselect'][data-part='clear-trigger']:focus-visible {
234
- outline: var(--xh-ring-width) solid var(--xh-_popselect-ring);
235
- outline-offset: var(--xh-ring-offset);
236
- }
237
-
238
- [data-scope='popselect'][data-part='clear-trigger'][hidden] {
239
- display: none;
240
- }
241
-
242
- /* 没写内容就由皮肤画叉;作者往部件里塞了自己的图形,这条规则即不命中 */
243
- [data-scope='popselect'][data-part='clear-trigger']:empty::before {
244
- content: '';
245
- display: inline-block;
246
- inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
247
- block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
248
- vertical-align: var(--xh-glyph-baseline-shift);
249
- background-color: currentColor;
250
- -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
251
- mask: var(--xh-glyph-mark-close) center / contain no-repeat;
252
- }
253
-
254
- [data-scope='popselect'][data-part='content'] {
255
- display: flex;
256
- flex-direction: column;
257
- gap: var(--xh-popselect-content-gap, var(--xh-list-option-gap));
258
- min-inline-size: var(--xh-popselect-content-min-w, var(--xh-overlay-menu-min-w));
259
- max-inline-size: var(--xh-popselect-content-max-w, var(--xh-overlay-max-w));
260
- max-block-size: min(var(--xh-popselect-content-max-h, var(--xh-overlay-menu-max-h)), var(--xh-_popselect-available-h));
261
- padding-block: var(--xh-popselect-content-py, var(--xh-space-1));
262
- padding-inline: var(--xh-popselect-content-px, var(--xh-space-1));
263
- border: var(--xh-stroke-thin) solid var(--xh-popselect-content-border, var(--xh-border-default));
264
- border-radius: var(--xh-popselect-content-radius, var(--xh-shape-surface));
265
- background: var(--xh-popselect-content-bg, var(--xh-bg-surface));
266
- color: var(--xh-popselect-content-fg, var(--xh-fg-default));
267
- box-shadow: var(--xh-popselect-content-shadow, var(--xh-elevation-floating));
268
- overflow-y: auto;
269
- pointer-events: auto;
270
- }
271
-
272
- /* 这里刻意没有 [data-part='content'][hidden] { display: none },与 dialog 一致:
273
- 收起态连接层会给 content 打 hidden,而上面那条 display 正是要盖掉 UA 的
274
- [hidden]{display:none}——退场动画得先能播。presence 读的是 content 的 animationName,
275
- 真正的收起由宿主在退场结束后落成内联 display:none(Vue 那边直接不渲染)。
276
- 其余声明了 display 的角色节点仍补 [hidden],那几处没有退场动画。 */
277
-
278
- /* 焦点落在容器上只有一种情形:指针打开、无选中值、还没有任何条目当锚点。
279
- 那一刻它认领着 Tab 位,环画在浮层内沿;有锚点时环长在条目上,容器不再画 */
280
- [data-scope='popselect'][data-part='content'][tabindex='0']:focus-visible {
281
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
282
- outline-offset: calc(-1 * var(--xh-ring-width));
283
- }
284
-
285
- [data-scope='popselect'][data-part='content']:not([tabindex='0']):focus-visible {
286
- outline: none;
287
- }
288
-
289
- [data-scope='popselect'][data-part='content'][data-state='open'] {
290
- animation: xh-pop-in var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
291
- }
292
-
293
- /* 退场:收起那一帧 hidden 由退场闸门押后,这里才播得出来。forwards 把末态钉住,
294
- 免得动画结束到真收起之间闪一下原样 */
295
- [data-scope='popselect'][data-part='content'][data-state='closed'] {
296
- animation: xh-pop-out var(--xh-motion-duration-exit) var(--xh-motion-ease-exit) forwards;
297
- }
298
-
299
- [data-scope='popselect'][data-part='item'] {
300
- display: flex;
301
- align-items: center;
302
- gap: var(--xh-popselect-item-gap, var(--xh-_popselect-gap));
303
- padding-block: var(--xh-popselect-item-py, var(--xh-_popselect-item-py));
304
- padding-inline: var(--xh-popselect-item-px, var(--xh-_popselect-item-px));
305
- border-radius: var(--xh-popselect-item-radius, var(--xh-shape-control));
306
- color: var(--xh-popselect-item-fg, var(--xh-fg-default));
307
- font-size: var(--xh-popselect-item-font-size, var(--xh-_popselect-font-size));
308
- /* 行高留出文字的上下伸展空间,行内那层 overflow:hidden 才不会把字削掉 */
309
- line-height: var(--xh-popselect-item-leading, var(--xh-leading-normal));
310
- white-space: nowrap;
311
- cursor: pointer;
312
- user-select: none;
313
- transition:
314
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
315
- color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
316
- }
317
-
318
- /* 悬停与键盘锚点共用中性灰轻档:条目本身承载焦点,不另画描边 */
319
- [data-scope='popselect'][data-part='item']:not([data-disabled]):is(:hover, [data-highlighted]) {
320
- background: var(--xh-popselect-item-bg-hover, var(--xh-bg-subtle));
321
- }
322
-
323
- /* 选中只换文字色与字重,配合行尾的 ✓ 标记;底色整条通道留给高亮,两者因此能同时看见 */
324
- [data-scope='popselect'][data-part='item'][data-state='checked'] {
325
- color: var(--xh-popselect-item-fg-selected, var(--xh-_popselect-item-selected-fg));
326
- font-weight: var(--xh-popselect-item-font-weight-selected, var(--xh-font-weight-medium));
327
- }
328
-
329
- /* 键盘走到条目上要画环:轻档底色对白底只有 1.1:1,够不上焦点指示器的对比度要求。
330
- 指针悬停走的是程序化聚焦,鼠标模态下 :focus-visible 不匹配,不会误画 */
331
- [data-scope='popselect'][data-part='item']:focus-visible {
332
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
333
- outline-offset: calc(-1 * var(--xh-ring-width));
334
- }
335
-
336
- [data-scope='popselect'][data-part='item']:focus:not(:focus-visible) {
337
- outline: none;
338
- }
339
-
340
- /* 禁用走 aria-disabled 而非原生 disabled,条目仍可聚焦,样式由 data-disabled 表达 */
341
- [data-scope='popselect'][data-part='item'][data-disabled] {
342
- color: var(--xh-fg-disabled);
343
- cursor: not-allowed;
344
- }
345
-
346
- [data-scope='popselect'][data-part='item-text'] {
347
- flex: 1;
348
- /* 弹性子项默认最小尺寸是内容尺寸,不归零则长文本把行撑破、省略号轮不上 */
349
- min-inline-size: 0;
350
- overflow: hidden;
351
- white-space: nowrap;
352
- text-overflow: ellipsis;
353
- }
354
-
355
- /* 勾选标记只在选中项上出现;未选中时占位不塌,切换选中不引起行宽抖动 */
356
- [data-scope='popselect'][data-part='item-indicator'] {
357
- display: inline-flex;
358
- flex: none;
359
- align-items: center;
360
- justify-content: center;
361
- inline-size: var(--xh-popselect-item-indicator-size, var(--xh-control-indicator-size));
362
- color: var(--xh-popselect-item-indicator-fg, var(--xh-_popselect-accent));
363
- visibility: hidden;
364
- }
365
-
366
- /* 没写内容就由皮肤画勾;作者往部件里塞了自己的图形,这条规则即不命中 */
367
- [data-scope='popselect'][data-part='item-indicator']:empty::before {
368
- content: '';
369
- display: inline-block;
370
- inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
371
- block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
372
- vertical-align: var(--xh-glyph-baseline-shift);
373
- background-color: currentColor;
374
- -webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
375
- mask: var(--xh-glyph-mark-check) center / contain no-repeat;
376
- }
377
-
378
- [data-scope='popselect'][data-part='item-indicator'][data-state='checked'] {
379
- visibility: visible;
380
- }
381
-
382
- /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
383
- 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
384
- [data-scope='popselect'][data-part='root'][hidden],
385
- [data-scope='popselect'][data-part='control'][hidden],
386
- [data-scope='popselect'][data-part='trigger'][hidden],
387
- [data-scope='popselect'][data-part='item'][hidden],
388
- [data-scope='popselect'][data-part='item-indicator'][hidden] {
389
- display: none;
390
- }
391
- }
package/css/qr-code.css DELETED
@@ -1,55 +0,0 @@
1
- @layer xihan.components {
2
- /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
- [data-scope='qr-code'] {
4
- --xh-qr-code-skin: 1;
5
- }
6
-
7
- /*
8
- * 根 <svg>。深浅两色取固定档而不是语义前景/背景:语义色跟着主题走,深色主题下整张码
9
- * 会翻成浅底深模块的反相图,一部分读码器不认反相码。要换配色改下面这三个覆盖槽。
10
- *
11
- * 换色只有一条硬约束:码点必须比底色深,且两者对比要足。反相(浅码点深底)与
12
- * 深浅相近都会让一部分读码器扫不出来,而这件事肉眼看不出来。
13
- *
14
- * --xh-qr-code-fg 码点色,同时经 currentColor 传给码眼
15
- * --xh-qr-code-bg 底色,挖空矩形也用它
16
- * --xh-qr-code-eye-fg 码眼色,缺省跟随码点色
17
- */
18
- [data-scope='qr-code'][data-part='root'] {
19
- display: block;
20
- border-radius: var(--xh-qr-code-radius, var(--xh-shape-control));
21
- background: var(--xh-qr-code-bg, var(--xh-color-neutral-0));
22
-
23
- /* 模块那条 path 不带自己的填充色,从这里继承下去 */
24
- color: var(--xh-qr-code-fg, var(--xh-color-neutral-950));
25
- fill: currentColor;
26
- }
27
-
28
- /* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
29
- [data-scope='qr-code'][data-part='root'][hidden] {
30
- display: none;
31
- }
32
-
33
- /* 码眼那条 path 恒在(与形状无关),没单独指定就退回 currentColor,跟码点同色 */
34
- [data-scope='qr-code'][data-part='root'] > [data-xh-geom='eyes'] {
35
- fill: var(--xh-qr-code-eye-fg, currentColor);
36
- }
37
-
38
- /*
39
- * logo 底下那块挖空:填的必须与根的背景逐字同一个表达式,两处一起改。
40
- * 差一点就会在 logo 四周露出一圈色差,读码器会把那圈当成模块边界。
41
- */
42
- [data-scope='qr-code'][data-part='root'] > [data-xh-geom='logo-clear'] {
43
- fill: var(--xh-qr-code-bg, var(--xh-color-neutral-0));
44
- }
45
-
46
- /*
47
- * 没有可编码的内容、以及内容超出容量:两种情形都一个模块不铺,留一块带描边的占位。
48
- * 占位用的是语义色——它是界面元素不是码面,跟着主题走才对。
49
- */
50
- [data-scope='qr-code'][data-part='root'][data-state='empty'],
51
- [data-scope='qr-code'][data-part='root'][data-state='error'] {
52
- background: var(--xh-qr-code-placeholder-bg, var(--xh-bg-subtle));
53
- box-shadow: inset 0 0 0 var(--xh-stroke-thin) var(--xh-qr-code-placeholder-border, var(--xh-border-default));
54
- }
55
- }
package/css/result.css DELETED
@@ -1,119 +0,0 @@
1
- @layer xihan.components {
2
- /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
- [data-scope='result'] {
4
- --xh-result-skin: 1;
5
- }
6
-
7
- [data-scope='result'][data-part='root'] {
8
- /* 三个尺寸档只换这几个私有槽,图标与标题都从 root 继承它们,
9
- 换档不必给每个部件各写一条选择器 */
10
- --xh-_result-gap: var(--xh-stack-gap-md);
11
- --xh-_result-py: var(--xh-section-py-md);
12
- --xh-_result-icon-size: var(--xh-glyph-size-3xl);
13
- --xh-_result-title-size: var(--xh-text-heading-3-size);
14
- /* 说明的读行宽度:整句话不收窄就会拉成一条难读的长行 */
15
- --xh-_result-measure: 32rem;
16
- /* 图标区的语气色,由 data-status 换掉;没写 status 就退成中性 */
17
- --xh-_result-accent: var(--xh-fg-subtle);
18
-
19
- display: flex;
20
- flex-direction: column;
21
- align-items: center;
22
- justify-content: center;
23
- gap: var(--xh-result-gap, var(--xh-_result-gap));
24
- padding-block: var(--xh-result-py, var(--xh-_result-py));
25
- padding-inline: var(--xh-result-px, var(--xh-space-6));
26
- color: var(--xh-result-fg, var(--xh-fg-default));
27
- text-align: center;
28
- }
29
-
30
- /* 上面声明了 display,会盖掉 UA 的 [hidden] 规则,收起态要在这里接回来 */
31
- [data-scope='result'][data-part='root'][hidden] {
32
- display: none;
33
- }
34
-
35
- /* —— 尺寸 —— */
36
- [data-scope='result'][data-part='root'][data-size='sm'] {
37
- --xh-_result-gap: var(--xh-stack-gap-sm);
38
- --xh-_result-py: var(--xh-section-py-sm);
39
- --xh-_result-icon-size: var(--xh-glyph-size-2xl);
40
- --xh-_result-title-size: var(--xh-control-font-lg);
41
- }
42
-
43
- [data-scope='result'][data-part='root'][data-size='lg'] {
44
- --xh-_result-gap: var(--xh-stack-gap-lg);
45
- --xh-_result-py: var(--xh-section-py-lg);
46
- --xh-_result-icon-size: var(--xh-glyph-size-4xl);
47
- --xh-_result-title-size: var(--xh-text-heading-2-size);
48
- }
49
-
50
- /* —— 语气 —— */
51
- /* 三个状态码各并进最接近的一族:找不到=提示,没权限=警示,服务出错=危险。
52
- 用 500 档而不是 600:500 是装饰性强调档,600 是给实心底与文字用的 */
53
- [data-scope='result'][data-part='root'][data-status='success'] {
54
- --xh-_result-accent: var(--xh-color-success-500);
55
- }
56
-
57
- [data-scope='result'][data-part='root'][data-status='warning'],
58
- [data-scope='result'][data-part='root'][data-status='403'] {
59
- --xh-_result-accent: var(--xh-color-warning-500);
60
- }
61
-
62
- [data-scope='result'][data-part='root'][data-status='error'],
63
- [data-scope='result'][data-part='root'][data-status='500'] {
64
- --xh-_result-accent: var(--xh-color-danger-500);
65
- }
66
-
67
- [data-scope='result'][data-part='root'][data-status='info'],
68
- [data-scope='result'][data-part='root'][data-status='404'] {
69
- --xh-_result-accent: var(--xh-color-info-500);
70
- }
71
-
72
- /* —— 各段 —— */
73
- [data-scope='result'][data-part='icon'] {
74
- display: inline-flex;
75
- align-items: center;
76
- justify-content: center;
77
- flex: none;
78
- /* 作者塞进图标槽的 XhIcon 与皮肤画的字形同一把尺,都按展示档的图标框量 */
79
- --xh-icon-size: var(--xh-result-icon-size, var(--xh-_result-icon-size));
80
-
81
- block-size: var(--xh-result-icon-size, var(--xh-_result-icon-size));
82
- inline-size: var(--xh-result-icon-size, var(--xh-_result-icon-size));
83
- color: var(--xh-result-icon-fg, var(--xh-_result-accent));
84
- /* 图标常是一个字形,字号跟着图标框走,line-height 不再另占高度 */
85
- font-size: var(--xh-result-icon-font-size, var(--xh-_result-icon-size));
86
- line-height: var(--xh-leading-none);
87
- }
88
-
89
- [data-scope='result'][data-part='title'] {
90
- margin: 0;
91
- color: var(--xh-result-title-fg, var(--xh-fg-default));
92
- font-size: var(--xh-result-title-font-size, var(--xh-_result-title-size));
93
- font-weight: var(--xh-result-title-font-weight, var(--xh-font-weight-semibold));
94
- line-height: var(--xh-result-title-leading, var(--xh-leading-tight));
95
- }
96
-
97
- [data-scope='result'][data-part='description'] {
98
- margin: 0;
99
- max-inline-size: var(--xh-result-description-max-w, var(--xh-_result-measure));
100
- color: var(--xh-result-description-fg, var(--xh-fg-muted));
101
- font-size: var(--xh-result-description-font-size, var(--xh-text-body-size));
102
- line-height: var(--xh-result-description-leading, var(--xh-text-body-leading));
103
- }
104
-
105
- [data-scope='result'][data-part='action'] {
106
- display: flex;
107
- flex-wrap: wrap;
108
- align-items: center;
109
- justify-content: center;
110
- gap: var(--xh-result-action-gap, var(--xh-space-2));
111
- }
112
-
113
- /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
114
- 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
115
- [data-scope='result'][data-part='icon'][hidden],
116
- [data-scope='result'][data-part='action'][hidden] {
117
- display: none;
118
- }
119
- }
package/css/space.css DELETED
@@ -1,117 +0,0 @@
1
- @layer xihan.components {
2
- /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
- [data-scope='space'] {
4
- --xh-space-skin: 1;
5
- }
6
-
7
- [data-scope='space'][data-part='root'] {
8
- display: flex;
9
- flex-wrap: nowrap;
10
- /* 不写档位也按 md 留白,这是与裸弹性容器的分野;使用者槽位排在档位之前,写死一个值即盖过所有档 */
11
- gap: var(--xh-space-gap, var(--xh-layout-gap-md));
12
- }
13
-
14
- /* 声明了 display 就盖掉了 UA 的 [hidden] 规则,这里还回去 */
15
- [data-scope='space'][data-part='root'][hidden] {
16
- display: none;
17
- }
18
-
19
- /* 行内盒:宽度收到内容,能和文字排在同一行 */
20
- [data-scope='space'][data-part='root'][data-inline]:not([hidden]) {
21
- display: inline-flex;
22
- }
23
-
24
- /* 分隔符:夹在两个子项之间的装饰件,样子由放进去的内容决定。
25
- 这里只兜住两件事——不被主轴挤扁(一条 1px 的竖线会被弹性收缩吃没),
26
- 交叉轴上不单独发话,跟着容器的对齐走:横排随中线、竖排随拉伸 */
27
- [data-scope='space'][data-part='split'] {
28
- flex: none;
29
- }
30
-
31
- /* —— 方向与缺省对齐 —— */
32
- /* 横排时按中线对齐:一排里混着文字、按钮、标签,高度本就不齐,居中最不容易看出错位 */
33
- [data-scope='space'][data-part='root'][data-orientation='horizontal'] {
34
- flex-direction: row;
35
- align-items: center;
36
- }
37
-
38
- /* 竖排时拉伸:一列里的块级子项该占满容器宽度 */
39
- [data-scope='space'][data-part='root'][data-orientation='vertical'] {
40
- flex-direction: column;
41
- align-items: stretch;
42
- }
43
-
44
- /* —— 折行 —— */
45
- [data-scope='space'][data-part='root'][data-wrap] {
46
- flex-wrap: wrap;
47
- }
48
-
49
- /* —— 交叉轴对齐 —— */
50
- /* 排在方向之后:两者特指度相同,写了 align 就该压过随方向来的那份缺省 */
51
- [data-scope='space'][data-part='root'][data-align='start'] {
52
- align-items: flex-start;
53
- }
54
-
55
- [data-scope='space'][data-part='root'][data-align='center'] {
56
- align-items: center;
57
- }
58
-
59
- [data-scope='space'][data-part='root'][data-align='end'] {
60
- align-items: flex-end;
61
- }
62
-
63
- [data-scope='space'][data-part='root'][data-align='stretch'] {
64
- align-items: stretch;
65
- }
66
-
67
- [data-scope='space'][data-part='root'][data-align='baseline'] {
68
- align-items: baseline;
69
- }
70
-
71
- /* —— 主轴分布 —— */
72
- [data-scope='space'][data-part='root'][data-justify='start'] {
73
- justify-content: flex-start;
74
- }
75
-
76
- [data-scope='space'][data-part='root'][data-justify='center'] {
77
- justify-content: center;
78
- }
79
-
80
- [data-scope='space'][data-part='root'][data-justify='end'] {
81
- justify-content: flex-end;
82
- }
83
-
84
- [data-scope='space'][data-part='root'][data-justify='between'] {
85
- justify-content: space-between;
86
- }
87
-
88
- [data-scope='space'][data-part='root'][data-justify='around'] {
89
- justify-content: space-around;
90
- }
91
-
92
- [data-scope='space'][data-part='root'][data-justify='evenly'] {
93
- justify-content: space-evenly;
94
- }
95
-
96
- /* —— 间距档位 —— */
97
- /* 每一档指向一个间距令牌,折行时行与行之间也吃这份间距 */
98
- [data-scope='space'][data-part='root'][data-gap='xs'] {
99
- gap: var(--xh-space-gap, var(--xh-layout-gap-xs));
100
- }
101
-
102
- [data-scope='space'][data-part='root'][data-gap='sm'] {
103
- gap: var(--xh-space-gap, var(--xh-layout-gap-sm));
104
- }
105
-
106
- [data-scope='space'][data-part='root'][data-gap='md'] {
107
- gap: var(--xh-space-gap, var(--xh-layout-gap-md));
108
- }
109
-
110
- [data-scope='space'][data-part='root'][data-gap='lg'] {
111
- gap: var(--xh-space-gap, var(--xh-layout-gap-lg));
112
- }
113
-
114
- [data-scope='space'][data-part='root'][data-gap='xl'] {
115
- gap: var(--xh-space-gap, var(--xh-layout-gap-xl));
116
- }
117
- }