@xihan-ui/styles 1.0.0-alpha.3 → 1.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 (96) hide show
  1. package/CHANGELOG.md +1730 -0
  2. package/css/accordion.css +25 -2
  3. package/css/alert.css +13 -9
  4. package/css/anchor.css +1 -1
  5. package/css/avatar-group.css +5 -1
  6. package/css/avatar.css +6 -0
  7. package/css/back-top.css +6 -0
  8. package/css/badge.css +94 -36
  9. package/css/breadcrumb.css +1 -1
  10. package/css/button-group.css +4 -0
  11. package/css/button.css +6 -0
  12. package/css/calendar.css +39 -13
  13. package/css/card.css +15 -6
  14. package/css/cascader.css +29 -23
  15. package/css/checkbox-group.css +38 -10
  16. package/css/checkbox.css +21 -10
  17. package/css/collapsible.css +7 -1
  18. package/css/color-picker.css +22 -2
  19. package/css/combobox.css +18 -7
  20. package/css/context-menu.css +17 -6
  21. package/css/date-field.css +2 -2
  22. package/css/date-picker.css +27 -17
  23. package/css/descriptions.css +9 -3
  24. package/css/dialog.css +7 -1
  25. package/css/drawer.css +15 -5
  26. package/css/dynamic-input.css +7 -0
  27. package/css/ellipsis.css +6 -0
  28. package/css/empty-state.css +16 -6
  29. package/css/field.css +7 -0
  30. package/css/file-upload.css +1 -1
  31. package/css/flex.css +13 -7
  32. package/css/float-button.css +7 -0
  33. package/css/floating-panel.css +6 -0
  34. package/css/grid.css +11 -5
  35. package/css/heatmap.css +3 -2
  36. package/css/highlight.css +1 -1
  37. package/css/hotkeys.css +1 -1
  38. package/css/hover-card.css +3 -0
  39. package/css/image-cropper.css +4 -2
  40. package/css/image-viewer.css +18 -5
  41. package/css/json-viewer.css +34 -1
  42. package/css/layout.css +15 -7
  43. package/css/list.css +14 -5
  44. package/css/listbox.css +4 -2
  45. package/css/loading-bar.css +5 -4
  46. package/css/log.css +6 -2
  47. package/css/masonry.css +5 -5
  48. package/css/mention.css +13 -3
  49. package/css/menu.css +16 -5
  50. package/css/menubar.css +14 -6
  51. package/css/navigation-menu.css +2 -2
  52. package/css/notification.css +377 -0
  53. package/css/number-field.css +9 -3
  54. package/css/page-header.css +7 -0
  55. package/css/pagination.css +158 -1
  56. package/css/password-input.css +4 -4
  57. package/css/pin-input.css +2 -2
  58. package/css/popconfirm.css +9 -2
  59. package/css/popover.css +3 -0
  60. package/css/popselect.css +24 -4
  61. package/css/progress.css +8 -2
  62. package/css/radio-group.css +17 -6
  63. package/css/rating.css +2 -2
  64. package/css/result.css +15 -5
  65. package/css/scrollbar.css +3 -0
  66. package/css/segmented.css +1 -1
  67. package/css/select.css +25 -7
  68. package/css/side-nav.css +16 -5
  69. package/css/slider.css +4 -2
  70. package/css/space.css +6 -6
  71. package/css/steps.css +6 -6
  72. package/css/switch.css +9 -2
  73. package/css/table.css +16 -8
  74. package/css/tabs.css +9 -1
  75. package/css/tag.css +3 -1
  76. package/css/tags-input.css +3 -3
  77. package/css/text-field.css +3 -3
  78. package/css/thread.css +10 -2
  79. package/css/time-field.css +2 -2
  80. package/css/time-picker.css +6 -6
  81. package/css/timeline.css +7 -7
  82. package/css/toast.css +103 -53
  83. package/css/toggle-group.css +30 -4
  84. package/css/toggle.css +6 -0
  85. package/css/tone.css +47 -17
  86. package/css/tooltip.css +7 -1
  87. package/css/tour.css +9 -3
  88. package/css/transfer.css +38 -12
  89. package/css/tree-select.css +30 -5
  90. package/css/tree.css +46 -4
  91. package/css/typography.css +1 -1
  92. package/css/undefined.css +1 -0
  93. package/index.css +1 -1
  94. package/index.unlayered.css +1746 -505
  95. package/package.json +3 -3
  96. package/css/toaster.css +0 -74
@@ -8,7 +8,7 @@
8
8
  /* 三个尺寸档只换这几个私有槽,图标与标题都从 root 继承它们,
9
9
  换档不必给每个部件各写一条选择器 */
10
10
  --xh-_empty-state-gap: var(--xh-stack-gap-md);
11
- --xh-_empty-state-py: var(--xh-section-py);
11
+ --xh-_empty-state-py: var(--xh-section-py-md);
12
12
  --xh-_empty-state-icon-size: var(--xh-glyph-size-2xl);
13
13
  --xh-_empty-state-title-size: var(--xh-control-font-lg);
14
14
  /* 说明的读行宽度:整句话不收窄就会拉成一条难读的长行 */
@@ -31,15 +31,15 @@
31
31
  }
32
32
 
33
33
  [data-scope='empty-state'][data-part='root'][data-size='sm'] {
34
- --xh-_empty-state-gap: var(--xh-space-2);
35
- --xh-_empty-state-py: var(--xh-space-4);
34
+ --xh-_empty-state-gap: var(--xh-stack-gap-sm);
35
+ --xh-_empty-state-py: var(--xh-section-py-sm);
36
36
  --xh-_empty-state-icon-size: var(--xh-glyph-size-xl);
37
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
- --xh-_empty-state-gap: var(--xh-space-6);
42
- --xh-_empty-state-py: var(--xh-space-8);
41
+ --xh-_empty-state-gap: var(--xh-stack-gap-lg);
42
+ --xh-_empty-state-py: var(--xh-section-py-lg);
43
43
  --xh-_empty-state-icon-size: var(--xh-glyph-size-3xl);
44
44
  --xh-_empty-state-title-size: var(--xh-text-heading-3-size);
45
45
  }
@@ -49,11 +49,14 @@
49
49
  align-items: center;
50
50
  justify-content: center;
51
51
  flex: none;
52
+ /* 作者塞进图标槽的 XhIcon 与皮肤画的字形同一把尺,都按展示档的图标框量 */
53
+ --xh-icon-size: var(--xh-empty-state-icon-size, var(--xh-_empty-state-icon-size));
54
+
52
55
  block-size: var(--xh-empty-state-icon-size, var(--xh-_empty-state-icon-size));
53
56
  inline-size: var(--xh-empty-state-icon-size, var(--xh-_empty-state-icon-size));
54
57
  color: var(--xh-empty-state-icon-fg, var(--xh-fg-subtle));
55
58
  /* 图标常是一个字形,字号跟着图标框走,line-height 不再另占高度 */
56
- font-size: var(--xh-empty-state-icon-font-size, var(--xh-text-heading-1-size));
59
+ font-size: var(--xh-empty-state-icon-font-size, var(--xh-_empty-state-icon-size));
57
60
  line-height: var(--xh-leading-none);
58
61
  }
59
62
 
@@ -80,4 +83,11 @@
80
83
  justify-content: center;
81
84
  gap: var(--xh-empty-state-action-gap, var(--xh-space-2));
82
85
  }
86
+
87
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
88
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
89
+ [data-scope='empty-state'][data-part='icon'][hidden],
90
+ [data-scope='empty-state'][data-part='action'][hidden] {
91
+ display: none;
92
+ }
83
93
  }
package/css/field.css CHANGED
@@ -101,4 +101,11 @@
101
101
  font-size: var(--xh-field-error-font-size, var(--xh-text-secondary-size));
102
102
  line-height: var(--xh-leading-normal);
103
103
  }
104
+
105
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
106
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
107
+ [data-scope='field'][data-part='root'][hidden],
108
+ [data-scope='form'][data-part='root'][hidden] {
109
+ display: none;
110
+ }
104
111
  }
@@ -193,7 +193,7 @@
193
193
  只挑图标色不换底色:底色一换,一列文件里图片那几行会跳出来抢戏。
194
194
  取语义 token 而不是品牌色阶原值,深色主题才跟着走 */
195
195
  [data-scope='file-upload'][data-part='item-preview'][data-file-type^='image/'] {
196
- color: var(--xh-file-upload-preview-fg-image, var(--xh-bg-brand));
196
+ color: var(--xh-file-upload-preview-fg-image, var(--xh-fg-brand));
197
197
  }
198
198
 
199
199
  /* 塞进来的真缩略图撑满这个方框,长宽比不对就裁掉,不许把格子顶变形 */
package/css/flex.css CHANGED
@@ -17,11 +17,11 @@
17
17
  }
18
18
 
19
19
  /* —— 方向 —— */
20
- [data-scope='flex'][data-part='root'][data-direction='row'] {
20
+ [data-scope='flex'][data-part='root'][data-orientation='horizontal'] {
21
21
  flex-direction: row;
22
22
  }
23
23
 
24
- [data-scope='flex'][data-part='root'][data-direction='column'] {
24
+ [data-scope='flex'][data-part='root'][data-orientation='vertical'] {
25
25
  flex-direction: column;
26
26
  }
27
27
 
@@ -79,22 +79,28 @@
79
79
  /* —— 间距档位 —— */
80
80
  /* 每一档指向一个间距令牌,折行时行与行之间也吃这份间距 */
81
81
  [data-scope='flex'][data-part='root'][data-gap='xs'] {
82
- gap: var(--xh-flex-gap, var(--xh-space-1));
82
+ gap: var(--xh-flex-gap, var(--xh-layout-gap-xs));
83
83
  }
84
84
 
85
85
  [data-scope='flex'][data-part='root'][data-gap='sm'] {
86
- gap: var(--xh-flex-gap, var(--xh-space-2));
86
+ gap: var(--xh-flex-gap, var(--xh-layout-gap-sm));
87
87
  }
88
88
 
89
89
  [data-scope='flex'][data-part='root'][data-gap='md'] {
90
- gap: var(--xh-flex-gap, var(--xh-space-3));
90
+ gap: var(--xh-flex-gap, var(--xh-layout-gap-md));
91
91
  }
92
92
 
93
93
  [data-scope='flex'][data-part='root'][data-gap='lg'] {
94
- gap: var(--xh-flex-gap, var(--xh-space-4));
94
+ gap: var(--xh-flex-gap, var(--xh-layout-gap-lg));
95
95
  }
96
96
 
97
97
  [data-scope='flex'][data-part='root'][data-gap='xl'] {
98
- gap: var(--xh-flex-gap, var(--xh-space-6));
98
+ gap: var(--xh-flex-gap, var(--xh-layout-gap-xl));
99
+ }
100
+
101
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
102
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
103
+ [data-scope='flex'][data-part='root'][hidden] {
104
+ display: none;
99
105
  }
100
106
  }
@@ -138,4 +138,11 @@
138
138
  -webkit-mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
139
139
  mask: var(--xh-glyph-mark-plus) center / contain no-repeat;
140
140
  }
141
+
142
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
143
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
144
+ [data-scope='float-button'][data-part='root'][hidden],
145
+ [data-scope='float-button'][data-part='trigger'][hidden] {
146
+ display: none;
147
+ }
141
148
  }
@@ -17,6 +17,12 @@
17
17
  display: contents;
18
18
  }
19
19
 
20
+ /* 浮层被搬到 portal 落点,继承不到 root 上的槽:这把尺在被搬走的那一侧再声明一次,
21
+ 关闭钮与条目里作者塞的图标才和皮肤画的兜底字形一样大 */
22
+ [data-scope='floating-panel'][data-part='content'] {
23
+ --xh-icon-size: var(--xh-floating-panel-icon-size, var(--xh-glyph-size-text));
24
+ }
25
+
20
26
  [data-scope='floating-panel'][data-part='root'][hidden] {
21
27
  display: none;
22
28
  }
package/css/grid.css CHANGED
@@ -269,23 +269,23 @@
269
269
  /* —— 间距档位 —— */
270
270
  /* 每一档指向一个间距令牌,行与行之间也吃这同一份间距 */
271
271
  [data-scope='grid'][data-part='root'][data-gap='xs'] {
272
- gap: var(--xh-grid-gap, var(--xh-space-1));
272
+ gap: var(--xh-grid-gap, var(--xh-layout-gap-xs));
273
273
  }
274
274
 
275
275
  [data-scope='grid'][data-part='root'][data-gap='sm'] {
276
- gap: var(--xh-grid-gap, var(--xh-space-2));
276
+ gap: var(--xh-grid-gap, var(--xh-layout-gap-sm));
277
277
  }
278
278
 
279
279
  [data-scope='grid'][data-part='root'][data-gap='md'] {
280
- gap: var(--xh-grid-gap, var(--xh-space-3));
280
+ gap: var(--xh-grid-gap, var(--xh-layout-gap-md));
281
281
  }
282
282
 
283
283
  [data-scope='grid'][data-part='root'][data-gap='lg'] {
284
- gap: var(--xh-grid-gap, var(--xh-space-4));
284
+ gap: var(--xh-grid-gap, var(--xh-layout-gap-lg));
285
285
  }
286
286
 
287
287
  [data-scope='grid'][data-part='root'][data-gap='xl'] {
288
- gap: var(--xh-grid-gap, var(--xh-space-6));
288
+ gap: var(--xh-grid-gap, var(--xh-layout-gap-xl));
289
289
  }
290
290
 
291
291
  /* —— 块向对齐 —— */
@@ -430,4 +430,10 @@
430
430
  [data-scope='grid'][data-part='item'][data-offset='11'] {
431
431
  --xh-_grid-start: 12;
432
432
  }
433
+
434
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
435
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
436
+ [data-scope='grid'][data-part='root'][hidden] {
437
+ display: none;
438
+ }
433
439
  }
package/css/heatmap.css CHANGED
@@ -121,10 +121,11 @@
121
121
  gap: var(--xh-heatmap-grid-gap, var(--xh-_heatmap-gap));
122
122
  }
123
123
 
124
- /* 网格自己只在没有格子可落焦点时才占 Tab 位,那几帧里也该看得出焦点在哪 */
124
+ /* 网格自己只在没有格子可落焦点时才占 Tab 位,那几帧里也该看得出焦点在哪。
125
+ 环往内收:网格铺满 root,root 那层 overflow-x: auto 会把画在外沿的环裁掉 */
125
126
  [data-scope='heatmap'][data-part='grid']:focus-visible {
126
127
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
127
- outline-offset: var(--xh-ring-offset);
128
+ outline-offset: calc(-1 * var(--xh-ring-width));
128
129
  }
129
130
 
130
131
  [data-scope='heatmap'][data-part='row'] {
package/css/highlight.css CHANGED
@@ -13,7 +13,7 @@
13
13
  /* 浏览器给 mark 的默认底色是一个固定的亮黄,暗色主题下压在深底上刺眼、
14
14
  配的黑字也不随主题走;这里整份换成随主题走的品牌淡底 */
15
15
  [data-scope='highlight'][data-part='mark'] {
16
- padding-inline: var(--xh-space-0_5);
16
+ padding-inline: var(--xh-highlight-mark-px, var(--xh-space-0_5));
17
17
  border-radius: var(--xh-highlight-radius, var(--xh-shape-inset));
18
18
  background: var(--xh-highlight-bg, var(--xh-bg-brand-subtle));
19
19
  color: var(--xh-highlight-fg, var(--xh-fg-brand-strong));
package/css/hotkeys.css CHANGED
@@ -7,7 +7,7 @@
7
7
  /* 一排键帽连着连接符。整块不换行:一组组合被折成两行就读不出是一组了 */
8
8
  [data-scope='hotkeys'][data-part='root'] {
9
9
  /* 尺寸档只换这两个私有槽,键帽从 root 继承它们,换档不必给每个部件各写一条选择器 */
10
- --xh-_hotkeys-font-size: var(--xh-text-secondary-size);
10
+ --xh-_hotkeys-font-size: var(--xh-control-caption-md);
11
11
  --xh-_hotkeys-key-px: var(--xh-space-1);
12
12
 
13
13
  display: inline-flex;
@@ -67,6 +67,9 @@
67
67
  引擎没算(尚未落位 / 无引擎 / 贴边归零)时不额外限高 */
68
68
  --xh-_hover-card-available-h: 100vh;
69
69
 
70
+ /* 卡片内容的自绘条浮在内容之上:轨道不上底色,实色轨道会在卡片右缘糊一条竖灰带 */
71
+ --xh-scrollbar-track-bg: transparent;
72
+
70
73
  position: fixed;
71
74
  z-index: var(--xh-hover-card-layer, var(--xh-layer-popover));
72
75
  /* 空壳不吃指针:trigger 与 content 之间那段间隙要能点得穿,
@@ -69,9 +69,10 @@
69
69
  cursor: not-allowed;
70
70
  }
71
71
 
72
+ /* 环往内收:裁切框长在视口里,视口那层 overflow: hidden 会把画在外沿的环裁掉 */
72
73
  [data-scope='image-cropper'][data-part='crop-area']:focus-visible {
73
74
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
74
- outline-offset: var(--xh-ring-offset);
75
+ outline-offset: calc(-1 * var(--xh-ring-width));
75
76
  }
76
77
 
77
78
  /* 三分构图参考线:两条竖线、两条横线,落点写死在三分处,不占节点、不吃指针。
@@ -134,9 +135,10 @@
134
135
  content: '';
135
136
  }
136
137
 
138
+ /* 与裁切框同一口径:把手也在视口的 overflow: hidden 里,环画在外沿会被裁掉 */
137
139
  [data-scope='image-cropper'][data-part='crop-handle']:focus-visible {
138
140
  outline: var(--xh-ring-width) solid var(--xh-ring-focus);
139
- outline-offset: var(--xh-ring-offset);
141
+ outline-offset: calc(-1 * var(--xh-ring-width));
140
142
  }
141
143
 
142
144
  [data-scope='image-cropper'][data-part='crop-handle'][data-resizing] {
@@ -54,6 +54,10 @@
54
54
  }
55
55
 
56
56
  [data-scope='image-viewer'][data-part='content'] {
57
+ /* 组件内那几档层号只在自己人之间排序:建一个层叠上下文把它们关起来,
58
+ 既不让页面上的层号插进来,也不让它们漏出去压住别人 */
59
+ isolation: isolate;
60
+
57
61
  /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
58
62
  --xh-icon-size: var(--xh-image-viewer-icon-size, var(--xh-glyph-size-text));
59
63
 
@@ -114,7 +118,7 @@
114
118
  background: var(--xh-image-viewer-chrome-bg, color-mix(in oklab, var(--xh-color-neutral-950) 55%, transparent));
115
119
  color: inherit;
116
120
  border: none;
117
- border-radius: var(--xh-shape-pill);
121
+ border-radius: var(--xh-image-viewer-overlay-radius, var(--xh-shape-pill));
118
122
  }
119
123
 
120
124
  [data-scope='image-viewer'][data-part='toolbar'] {
@@ -123,8 +127,8 @@
123
127
  translate: -50% 0;
124
128
  display: flex;
125
129
  align-items: center;
126
- gap: var(--xh-space-1);
127
- padding: var(--xh-space-1_5) var(--xh-space-3);
130
+ gap: var(--xh-image-viewer-toolbar-gap, var(--xh-space-1));
131
+ padding: var(--xh-image-viewer-toolbar-padding, var(--xh-space-1_5) var(--xh-space-3));
128
132
  }
129
133
 
130
134
  /* 工具条里的按钮:底色交给工具条,本体只管命中区 */
@@ -137,7 +141,7 @@
137
141
  block-size: var(--xh-control-action-size);
138
142
  background: none;
139
143
  border: none;
140
- border-radius: var(--xh-shape-control);
144
+ border-radius: var(--xh-image-viewer-toolbar-radius, var(--xh-shape-control));
141
145
  color: inherit;
142
146
  font-size: var(--xh-glyph-size-sm);
143
147
  cursor: pointer;
@@ -147,7 +151,7 @@
147
151
  inset-block-start: var(--xh-space-6);
148
152
  inset-inline-start: 50%;
149
153
  translate: -50% 0;
150
- padding: var(--xh-space-1) var(--xh-space-3);
154
+ padding: var(--xh-image-viewer-counter-padding, var(--xh-space-1) var(--xh-space-3));
151
155
  font-size: var(--xh-text-secondary-size);
152
156
  }
153
157
 
@@ -318,4 +322,13 @@
318
322
  -webkit-mask: var(--xh-glyph-mark-close) center / contain no-repeat;
319
323
  mask: var(--xh-glyph-mark-close) center / contain no-repeat;
320
324
  }
325
+
326
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
327
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
328
+ [data-scope='image-viewer'][data-part='positioner'][hidden],
329
+ [data-scope='image-viewer'][data-part='viewport'][hidden],
330
+ [data-scope='image-viewer'][data-part='toolbar'][hidden],
331
+ [data-scope='image-viewer'][data-part='next-trigger'][hidden] {
332
+ display: none;
333
+ }
321
334
  }
@@ -10,7 +10,7 @@
10
10
  /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
11
11
  --xh-icon-size: var(--xh-json-viewer-icon-size, var(--xh-glyph-size-text));
12
12
 
13
- --xh-_json-viewer-font-size: var(--xh-text-secondary-size);
13
+ --xh-_json-viewer-font-size: var(--xh-control-caption-md);
14
14
  --xh-_json-viewer-row-py: var(--xh-space-0_5);
15
15
  --xh-_json-viewer-indent: var(--xh-space-4);
16
16
  --xh-json-viewer-key-fg: var(--xh-fg-brand-strong);
@@ -20,6 +20,11 @@
20
20
  --xh-json-viewer-number-fg: var(--xh-syntax-number);
21
21
  --xh-json-viewer-boolean-fg: var(--xh-syntax-keyword);
22
22
 
23
+ /* 两档的自绘条浮在内容之上:轨道不上底色,实色轨道会沿容器边缘糊出一条灰带 */
24
+ --xh-scrollbar-track-bg: transparent;
25
+
26
+ /* 自绘条绝对定位贴这一层的内边距盒,它得是定位盒 */
27
+ position: relative;
23
28
  display: block;
24
29
  color: var(--xh-json-viewer-fg, var(--xh-fg-default));
25
30
  font-family: var(--xh-json-viewer-font, var(--xh-font-family-mono));
@@ -58,6 +63,34 @@
58
63
  overflow: auto;
59
64
  }
60
65
 
66
+ /* 原文档:与树档共用同一套边框、内衬与高度令牌,两档切过去盒子不跳。
67
+ 整块可框选——这一档存在的理由就是把与后端一字不差的那份原文交到手上 */
68
+ [data-scope='json-viewer'][data-part='text'] {
69
+ margin: 0;
70
+ max-block-size: var(--xh-json-viewer-max-h, var(--xh-viewport-max-h));
71
+ padding-block: var(--xh-json-viewer-py, var(--xh-space-2));
72
+ padding-inline: var(--xh-json-viewer-px, var(--xh-space-2));
73
+ border: var(--xh-stroke-thin) solid var(--xh-json-viewer-border, var(--xh-border-default));
74
+ border-radius: var(--xh-json-viewer-radius, var(--xh-shape-surface));
75
+ background: var(--xh-json-viewer-bg, var(--xh-bg-surface));
76
+ color: var(--xh-json-viewer-text-fg, var(--xh-fg-default));
77
+ font-family: var(--xh-json-viewer-font, var(--xh-font-family-mono));
78
+ /* 缩进靠空格,行不折:折行会把层级读乱,横向给滚动条 */
79
+ white-space: pre;
80
+ tab-size: 2;
81
+ overflow: auto;
82
+ user-select: text;
83
+ }
84
+
85
+ [data-scope='json-viewer'][data-part='text'][hidden] {
86
+ display: none;
87
+ }
88
+
89
+ /* 这一档没有行可落焦,环画在整块上 */
90
+ [data-scope='json-viewer'][data-part='text']:focus-visible {
91
+ outline: var(--xh-ring-width) solid var(--xh-ring-focus);
92
+ outline-offset: calc(-1 * var(--xh-ring-width));
93
+ }
61
94
  [data-scope='json-viewer'][data-part='tree'][hidden] {
62
95
  display: none;
63
96
  }
package/css/layout.css CHANGED
@@ -40,9 +40,9 @@
40
40
  display: flex;
41
41
  grid-area: header;
42
42
  align-items: center;
43
- gap: var(--xh-space-3);
43
+ gap: var(--xh-layout-header-gap, var(--xh-space-3));
44
44
  block-size: var(--xh-_layout-header-h);
45
- padding-inline: var(--xh-space-4);
45
+ padding-inline: var(--xh-layout-header-px, var(--xh-space-4));
46
46
  background: var(--xh-layout-header-bg, var(--xh-bg-surface));
47
47
  }
48
48
 
@@ -51,7 +51,7 @@
51
51
  grid-area: sider;
52
52
  inline-size: var(--xh-_layout-sider-w);
53
53
  overflow: hidden;
54
- padding: var(--xh-space-3);
54
+ padding: var(--xh-layout-sider-padding, var(--xh-space-3));
55
55
  background: var(--xh-layout-sider-bg, var(--xh-bg-subtle));
56
56
  transition: inline-size var(--xh-motion-duration-enter) var(--xh-motion-ease-enter);
57
57
  }
@@ -66,12 +66,12 @@
66
66
  grid-area: content;
67
67
  /* 内容列已是 minmax(0, 1fr),这里再声明一次,宽表格与长串文本才撑不破列 */
68
68
  min-inline-size: 0;
69
- padding: var(--xh-space-4);
69
+ padding: var(--xh-layout-content-padding, var(--xh-space-4));
70
70
  }
71
71
 
72
72
  [data-scope='layout'][data-part='footer'] {
73
73
  grid-area: footer;
74
- padding: var(--xh-space-3) var(--xh-space-4);
74
+ padding: var(--xh-layout-footer-padding, var(--xh-space-3) var(--xh-space-4));
75
75
  background: var(--xh-layout-footer-bg, var(--xh-bg-surface));
76
76
  color: var(--xh-fg-muted);
77
77
  font-size: var(--xh-text-secondary-size);
@@ -82,9 +82,9 @@
82
82
  display: inline-flex;
83
83
  align-items: center;
84
84
  justify-content: center;
85
- gap: var(--xh-control-gap-sm);
85
+ gap: var(--xh-layout-sider-trigger-gap, var(--xh-control-gap-sm));
86
86
  block-size: var(--xh-control-h-sm);
87
- padding-inline: var(--xh-control-px-sm);
87
+ padding-inline: var(--xh-layout-sider-trigger-px, var(--xh-control-px-sm));
88
88
  border: 0;
89
89
  border-radius: var(--xh-layout-sider-trigger-radius, var(--xh-shape-control));
90
90
  background: var(--xh-layout-sider-trigger-bg, transparent);
@@ -167,4 +167,12 @@
167
167
  max-block-size: calc(var(--xh-layout-scrollport-h, 100dvh) - var(--xh-_layout-sider-offset));
168
168
  overflow-y: auto;
169
169
  }
170
+
171
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
172
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
173
+ [data-scope='layout'][data-part='root'][hidden],
174
+ [data-scope='layout'][data-part='header'][hidden],
175
+ [data-scope='layout'][data-part='sider-trigger'][hidden] {
176
+ display: none;
177
+ }
170
178
  }
package/css/list.css CHANGED
@@ -8,7 +8,7 @@
8
8
  /* 一个尺寸档只换这几个私有槽,条目与两行文字都从根上继承它们,
9
9
  换档不必给每个部件各写一条选择器 */
10
10
  --xh-_list-item-py: var(--xh-list-item-py-md);
11
- --xh-_list-item-px: var(--xh-space-4);
11
+ --xh-_list-item-px: var(--xh-list-item-px-md);
12
12
  --xh-_list-item-gap: var(--xh-space-3);
13
13
  --xh-_list-title-size: var(--xh-control-font-md);
14
14
  --xh-_list-description-size: var(--xh-control-caption-md);
@@ -30,7 +30,7 @@
30
30
  /* —— 尺寸 —— */
31
31
  [data-scope='list'][data-part='root'][data-size='sm'] {
32
32
  --xh-_list-item-py: var(--xh-list-item-py-sm);
33
- --xh-_list-item-px: var(--xh-space-3);
33
+ --xh-_list-item-px: var(--xh-list-item-px-sm);
34
34
  --xh-_list-item-gap: var(--xh-space-2);
35
35
  --xh-_list-title-size: var(--xh-control-font-sm);
36
36
  --xh-_list-description-size: var(--xh-control-caption-sm);
@@ -38,7 +38,7 @@
38
38
 
39
39
  [data-scope='list'][data-part='root'][data-size='lg'] {
40
40
  --xh-_list-item-py: var(--xh-list-item-py-lg);
41
- --xh-_list-item-px: var(--xh-space-5);
41
+ --xh-_list-item-px: var(--xh-list-item-px-lg);
42
42
  --xh-_list-item-gap: var(--xh-space-4);
43
43
  --xh-_list-title-size: var(--xh-control-font-lg);
44
44
  }
@@ -66,11 +66,11 @@
66
66
  [data-scope='list'][data-part='root'][data-split]
67
67
  > [data-scope='list'][data-part='item']
68
68
  + [data-scope='list'][data-part='item'] {
69
- border-block-start: var(--xh-stroke-thin) solid var(--xh-list-border, var(--xh-border-subtle));
69
+ border-block-start: var(--xh-stroke-thin) solid var(--xh-list-divider, var(--xh-border-subtle));
70
70
  }
71
71
 
72
72
  [data-scope='list'][data-part='root'][data-hoverable] > [data-scope='list'][data-part='item'] {
73
- transition: background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
73
+ transition: background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
74
74
  }
75
75
 
76
76
  /* 悬停换底色:只在能用指针的设备上生效,触摸端不留一个按不掉的悬停态 */
@@ -119,4 +119,13 @@
119
119
  gap: var(--xh-list-action-gap, var(--xh-space-2));
120
120
  margin-inline-start: auto;
121
121
  }
122
+
123
+ /* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
124
+ 写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
125
+ [data-scope='list'][data-part='item'][hidden],
126
+ [data-scope='list'][data-part='item-media'][hidden],
127
+ [data-scope='list'][data-part='item-content'][hidden],
128
+ [data-scope='list'][data-part='item-action'][hidden] {
129
+ display: none;
130
+ }
122
131
  }
package/css/listbox.css CHANGED
@@ -34,6 +34,7 @@
34
34
  [data-scope='listbox'][data-part='content'] {
35
35
  display: flex;
36
36
  flex-direction: column;
37
+ gap: var(--xh-listbox-content-gap, var(--xh-list-option-gap));
37
38
  max-block-size: var(--xh-listbox-content-max-h, var(--xh-viewport-h-md));
38
39
  padding-block: var(--xh-listbox-content-py, var(--xh-space-1));
39
40
  padding-inline: var(--xh-listbox-content-px, var(--xh-space-1));
@@ -66,6 +67,7 @@
66
67
  [data-scope='listbox'][data-part='item-group'] {
67
68
  display: flex;
68
69
  flex-direction: column;
70
+ gap: var(--xh-listbox-item-group-gap, var(--xh-list-option-gap));
69
71
  }
70
72
 
71
73
  [data-scope='listbox'][data-part='item-group'][hidden] {
@@ -74,7 +76,7 @@
74
76
 
75
77
  /* 组间留白只加在后继分组上:首组顶上已经有 content 的内边距,再加一层会显得头重 */
76
78
  [data-scope='listbox'][data-part='item-group'] + [data-scope='listbox'][data-part='item-group'] {
77
- margin-block-start: var(--xh-listbox-group-gap, var(--xh-space-2));
79
+ margin-block-start: var(--xh-listbox-group-gap, var(--xh-space-1_5));
78
80
  }
79
81
 
80
82
  /* 分组标题不是选项、进不了导航,画成小号次要文字,
@@ -168,7 +170,7 @@
168
170
  align-items: center;
169
171
  justify-content: center;
170
172
  inline-size: var(--xh-listbox-item-indicator-size, var(--xh-control-indicator-size));
171
- color: var(--xh-listbox-item-indicator-fg, var(--xh-bg-brand));
173
+ color: var(--xh-listbox-item-indicator-fg, var(--xh-fg-brand));
172
174
  visibility: hidden;
173
175
  }
174
176
 
@@ -31,8 +31,9 @@
31
31
  display: none;
32
32
  }
33
33
 
34
- /* 冲到 100 之后进入淡出:机器会在淡出窗口走完之前一直停在 finishing
35
- 这段过渡才有时间跑完;窗口与时长两处默认值都是 200ms,改一处记得对齐另一处 */
34
+ /* 冲到 100 之后进入淡出:机器会在淡出窗口走完之前一直停在 finishing,这段过渡才有时间跑完。
35
+ 窗口(machine 的 LOADING_BAR_FADE_DURATION,200ms)比过渡本身(motion-duration-exit,120ms)
36
+ 宽出一截是有意的余量;两者不是同一个数,改窗口时只要保证它仍不短于过渡 */
36
37
  [data-scope='loading-bar'][data-part='root'][data-state='finishing'] {
37
38
  opacity: 0;
38
39
  }
@@ -50,8 +51,8 @@
50
51
  * 进度段。宽度那条轴(inline-size)由连接层写进内联样式,这里绝不重复写。
51
52
  * 背景色同理:给了 color 就走内联,盖过下面这条。
52
53
  *
53
- * 语气取柔和档 --xh-_tone-soft(500)而不是 --xh-_tone(600):600 是给实心底与
54
- * 文字用的强调档,压在这么一条细带上偏重。槽位由 root 上的 data-tone 声明,继承下来。
54
+ * 语气取装饰档 --xh-_tone-soft:那一档压在画布上够 3:1,细带才看得出来。
55
+ * 槽位由 root 上的 data-tone 声明,继承下来。
55
56
  * 没写 data-tone 时该槽没被声明,退回原来的品牌色。
56
57
  */
57
58
  [data-scope='loading-bar'][data-part='range'] {
package/css/log.css CHANGED
@@ -28,14 +28,18 @@
28
28
  flex-basis 取 auto,连接层写的按行数高度才算数,同时外层给了高度时还能撑满;
29
29
  min-block-size: 0 让它在弹性父级里能被压缩从而真的溢出;
30
30
  两个轴都 auto:长行不折,横向也要能滚;
31
- overscroll-behavior: contain 阻止滚动量传给页面;
32
- scrollbar-gutter: stable 避免滚动条出现与消失时推动文字。 */
31
+ overscroll-behavior: contain 阻止滚动量传给页面。 */
33
32
  [data-scope='log'][data-part='viewport'] {
34
33
  flex: 1 1 auto;
35
34
  min-block-size: 0;
36
35
  block-size: calc(var(--xh-_log-line-h) * var(--xh-log-rows, 16));
37
36
  overflow: auto;
38
37
  overscroll-behavior: contain;
38
+ }
39
+
40
+ /* 还在用原生滚动条的视口留一条空道,滚动条出现与消失时不推动文字。
41
+ 带 data-xh-scrollbar 的容器已经把原生条藏成零宽,这条空道对它没有布局作用,排除掉 */
42
+ [data-scope='log'][data-part='viewport']:not([data-xh-scrollbar]) {
39
43
  scrollbar-gutter: stable;
40
44
  }
41
45
 
package/css/masonry.css CHANGED
@@ -42,22 +42,22 @@
42
42
  /* —— 间距档位 —— */
43
43
  /* 每一档指向一个间距令牌,列之间与列内项之间吃同一份间距 */
44
44
  [data-scope='masonry'][data-part='root'][data-gap='xs'] {
45
- --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-space-1));
45
+ --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-layout-gap-xs));
46
46
  }
47
47
 
48
48
  [data-scope='masonry'][data-part='root'][data-gap='sm'] {
49
- --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-space-2));
49
+ --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-layout-gap-sm));
50
50
  }
51
51
 
52
52
  [data-scope='masonry'][data-part='root'][data-gap='md'] {
53
- --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-space-3));
53
+ --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-layout-gap-md));
54
54
  }
55
55
 
56
56
  [data-scope='masonry'][data-part='root'][data-gap='lg'] {
57
- --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-space-4));
57
+ --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-layout-gap-lg));
58
58
  }
59
59
 
60
60
  [data-scope='masonry'][data-part='root'][data-gap='xl'] {
61
- --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-space-6));
61
+ --xh-_masonry-gap: var(--xh-masonry-gap, var(--xh-layout-gap-xl));
62
62
  }
63
63
  }