@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
@@ -1,3 +1,12 @@
1
+ /*
2
+ * Copyright (c) 2021-Present XiHanFun and contributors.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ */
5
+
6
+ /* 定义 checkbox group 样式。 */
7
+
8
+ @import '../family/action-control.css';
9
+
1
10
  @layer xihan.components {
2
11
  /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
3
12
  [data-scope='checkbox-group'] {
@@ -7,11 +16,45 @@
7
16
  /* 组容器:label、trigger、条目都是它的直接子节点,排布方式只能读 data-orientation——
8
17
  连接层明说了 role=group 不接受 aria-orientation,那个属性它根本没输出 */
9
18
  [data-scope='checkbox-group'][data-part='root'] {
10
- /* 作者塞进指示符槽的图标跟着字号走,与皮肤画的兜底字形同一把尺 */
11
- --xh-icon-size: var(--xh-checkbox-group-icon-size, var(--xh-glyph-size-text));
19
+ /* 尺寸档只换这四个私有槽,条目、方框与全选格都从 root 继承它们,
20
+ 换档不必给每个部件各写一条选择器。方框与字形照 checkbox 的档位走,
21
+ 单体与集合里的同一枚方框必须一样大;条目文字是控件文字,随档取 --xh-control-font-*(§6.4) */
22
+ --xh-_checkbox-group-box: var(--xh-control-indicator-md);
23
+ --xh-_checkbox-group-glyph: calc(var(--xh-_checkbox-group-box) * 0.75);
24
+ --xh-_checkbox-group-gap: var(--xh-control-gap-md);
25
+ --xh-_checkbox-group-font-size: var(--xh-control-font-md);
26
+ /* 作者塞进指示符槽的图标和皮肤画的兜底字形共用盒比例(与 checkbox 同一把尺);显式 icon-size 仍可覆盖 */
27
+ --xh-icon-size: var(--xh-checkbox-group-icon-size, var(--xh-_checkbox-group-glyph));
12
28
 
29
+ /* 勾中的填色随语气走;没写 data-tone 时退回品牌色 */
30
+ --xh-_checkbox-group-accent: var(--xh-_tone, var(--xh-bg-brand));
31
+ --xh-_checkbox-group-on-accent: var(--xh-_tone-on, var(--xh-fg-on-brand));
32
+ /* 方框是字段家族的控制盒(§8.3 字段静息形态):透明底 + --xh-border-control 描边 + 无影,不消费海拔与顶光 */
33
+ --xh-_checkbox-group-bg: var(--xh-checkbox-group-indicator-bg, transparent);
34
+ /* 条目与全选格是方框的承载面:行自己坐画布走 100 → 200,行面上的方框按淡底容器阶梯再上一档(200 → 300)。
35
+ 两支私有槽是这一档的唯一来源——宿主拿它们给 --xh-action-host-bg-* 赋值(桥接槽只写不读),
36
+ 方框按下读同一支私有槽,即与宿主的 host 槽同源 */
37
+ --xh-_checkbox-group-host-bg-hover: var(--xh-bg-subtle-hover);
38
+ --xh-_checkbox-group-host-bg-pressed: var(--xh-bg-subtle-active);
39
+
40
+ /* 标题与条目都是根的直接子节点,一支 gap 同时管「标题到集合」与「条目之间」:
41
+ 集合标题与集合隔 --xh-space-2(§6.4),同组条目之间也是同一档紧密关系 */
13
42
  display: flex;
14
- gap: var(--xh-checkbox-group-gap, var(--xh-stack-gap-md));
43
+ gap: var(--xh-checkbox-group-gap, var(--xh-space-2));
44
+ }
45
+
46
+ /* —— 尺寸 —— */
47
+ /* 缺省档写在上面的基础规则里 */
48
+ [data-scope='checkbox-group'][data-part='root'][data-size='sm'] {
49
+ --xh-_checkbox-group-box: var(--xh-control-indicator-sm);
50
+ --xh-_checkbox-group-gap: var(--xh-control-gap-sm);
51
+ --xh-_checkbox-group-font-size: var(--xh-control-font-sm);
52
+ }
53
+
54
+ [data-scope='checkbox-group'][data-part='root'][data-size='lg'] {
55
+ --xh-_checkbox-group-box: var(--xh-control-indicator-lg);
56
+ --xh-_checkbox-group-gap: var(--xh-control-gap-lg);
57
+ --xh-_checkbox-group-font-size: var(--xh-control-font-lg);
15
58
  }
16
59
 
17
60
  /* 两种取值各写一条:连接层缺省给的是 vertical,但受控写 horizontal 时不能靠默认值兜底 */
@@ -28,6 +71,7 @@
28
71
  align-items: center;
29
72
  }
30
73
 
74
+ /* 集合标题(§6.4):14 / 500 / fg-muted,字号不随 size 档 */
31
75
  [data-scope='checkbox-group'][data-part='label'] {
32
76
  color: var(--xh-checkbox-group-label-fg, var(--xh-fg-muted));
33
77
  font-size: var(--xh-checkbox-group-label-font-size, var(--xh-text-label-size));
@@ -41,79 +85,122 @@
41
85
  color: var(--xh-checkbox-group-label-fg-disabled, var(--xh-fg-subtle));
42
86
  }
43
87
 
44
- /* position 是给条目内那份视觉隐藏的原生输入当定位基准:连接层给它写死了 position:absolute,
88
+ /* 条目是「方框 + 文案」的整行命中区(§9.2):接 Action Control row 档、ghost 形态,悬停 / 按下 / 禁用面、手型、
89
+ 过渡与焦点环由家族给,按下只换面不缩放(row 档专属按压块 scale: none);这里只把使用者槽映射到桥接槽。
90
+ 行自己坐画布走 100 → 200(--xh-action-bg-* 钉住自己的面),行面上的方框按淡底容器阶梯再上一档
91
+ (--xh-action-host-bg-* 向内声明自己是方框的承载面,host 槽只对后代生效——自己的面已由 --xh-action-bg-* 钉住;
92
+ 也因此 root 带 data-tone 时 --xh-_tone-subtle 不会把整行染色)。
93
+ xs 的 24px 是命中地板,方框 12 / 16 / 20px 居中其间;字号与间距按组档位从 root 的私有槽映射。
94
+ 条目禁用一律走 aria-disabled(原生 disabled 会让它从键盘用户眼里消失),家族的禁用块读 data-disabled。
95
+ position 是给条目内那份视觉隐藏的原生输入当定位基准:连接层给它写死了 position:absolute,
45
96
  这里不立基准的话,原生校验气泡会飘到页面上离该条目很远的地方 */
46
97
  [data-scope='checkbox-group'][data-part='item'] {
47
- position: relative;
48
- display: inline-flex;
49
- align-items: center;
50
- gap: var(--xh-checkbox-group-item-gap, var(--xh-control-gap-md));
51
- border-radius: var(--xh-checkbox-group-item-radius, var(--xh-shape-control));
52
- color: var(--xh-checkbox-group-item-fg, var(--xh-fg-default));
53
- font-size: var(--xh-checkbox-group-item-font-size, var(--xh-text-label-size));
54
- line-height: var(--xh-leading-none);
55
- cursor: pointer;
56
- }
57
-
58
- [data-scope='checkbox-group'][data-part='item']:focus-visible {
59
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
60
- outline-offset: var(--xh-ring-offset);
61
- }
98
+ --xh-action-gap: var(--xh-checkbox-group-item-gap, var(--xh-_checkbox-group-gap));
99
+ --xh-action-radius: var(--xh-checkbox-group-item-radius, var(--xh-shape-control));
100
+ --xh-action-font-size: var(--xh-checkbox-group-item-font-size, var(--xh-_checkbox-group-font-size));
101
+ --xh-action-padding-inline: 0;
102
+ --xh-action-padding-block: 0;
103
+ --xh-action-fg-rest: var(--xh-checkbox-group-item-fg, var(--xh-fg-default));
104
+ --xh-action-fg-hover: var(--xh-checkbox-group-item-fg, var(--xh-fg-default));
105
+ --xh-action-fg-pressed: var(--xh-checkbox-group-item-fg, var(--xh-fg-default));
106
+ --xh-action-fg-focus-visible: var(--xh-checkbox-group-item-fg, var(--xh-fg-default));
107
+ --xh-action-fg-disabled: var(--xh-checkbox-group-item-fg-disabled, var(--xh-fg-disabled));
108
+ --xh-action-bg-hover: var(--xh-checkbox-group-item-bg-hover, var(--xh-bg-subtle));
109
+ --xh-action-bg-pressed: var(--xh-checkbox-group-item-bg-pressed, var(--xh-bg-subtle-hover));
110
+ --xh-action-host-bg-hover: var(--xh-_checkbox-group-host-bg-hover);
111
+ --xh-action-host-bg-pressed: var(--xh-_checkbox-group-host-bg-pressed);
62
112
 
63
- /* 条目禁用一律走 aria-disabled(原生 disabled 会让它从键盘用户眼里消失),
64
- 所以样式只能读 data-disabled,写 :disabled 永远不命中 */
65
- [data-scope='checkbox-group'][data-part='item'][data-disabled] {
66
- color: var(--xh-checkbox-group-item-fg-disabled, var(--xh-fg-disabled));
67
- cursor: not-allowed;
113
+ position: relative;
114
+ /* row 档铺满容器(inline-size: 100%)会把竖排的命中区拉到整行空白处、横排 wrap 也塌:
115
+ 沿用「条目按内容收宽」的既有决定 */
116
+ inline-size: auto;
117
+ /* ghost 的 1px 透明边位会把方框列相对组标题错开 1px:边归零,几何保持不变 */
118
+ border-width: 0;
68
119
  }
69
120
 
70
- /* 只读整组都改不动,但不是禁用:颜色照常,只把"可点"这个暗示收回来。
71
- 排掉禁用项是因为这条选择器权重高过上面那条,不排就会把 not-allowed 覆盖回 default */
121
+ /* 只读整组都改不动,但不是禁用:颜色照常,把整行的悬停 / 按下面与"可点"这个暗示一起收回来。
122
+ 家族的 :hover / 按压块不排 readonly,只能从槽上收回;排掉禁用项是因为这条选择器权重高过家族的禁用块,
123
+ 不排就会把 not-allowed 覆盖回 default */
72
124
  [data-scope='checkbox-group'][data-part='root'][data-readonly]
73
125
  [data-scope='checkbox-group'][data-part='item']:not([data-disabled]) {
74
- cursor: default;
126
+ --xh-action-bg-hover: transparent;
127
+ --xh-action-bg-pressed: transparent;
128
+ --xh-action-cursor-rest: default;
129
+ --xh-action-cursor-hover: default;
130
+ --xh-action-cursor-pressed: default;
131
+ --xh-action-cursor-focus-visible: default;
75
132
  }
76
133
 
77
134
  /* 全选格与条目格共用同一套盒子,并成一条规则写:分开写迟早只改到一半,两个方框就此走形。
78
135
  尺寸与选中态照 checkbox 的 root 搬,同一份视觉语言在单体与集合里必须一致。
79
136
  trigger 那格没有对应的角色节点(anatomy 到 trigger 为止),只能由伪元素补出来 */
80
137
  [data-scope='checkbox-group'][data-part='indicator'],
81
- [data-scope='checkbox-group'][data-part='trigger']::before {
138
+ [data-scope='checkbox-group'][data-part='select-all-trigger']::before {
82
139
  display: inline-flex;
83
140
  flex: none;
84
141
  align-items: center;
85
142
  justify-content: center;
86
- inline-size: var(--xh-checkbox-group-indicator-size, var(--xh-control-indicator-size));
87
- block-size: var(--xh-checkbox-group-indicator-size, var(--xh-control-indicator-size));
143
+ inline-size: var(--xh-checkbox-group-indicator-size, var(--xh-_checkbox-group-box));
144
+ block-size: var(--xh-checkbox-group-indicator-size, var(--xh-_checkbox-group-box));
88
145
  border: var(--xh-stroke-thin) solid var(--xh-checkbox-group-indicator-border, var(--xh-border-control));
89
146
  border-radius: var(--xh-checkbox-group-indicator-radius, var(--xh-shape-inset));
90
- background: var(--xh-checkbox-group-indicator-bg, var(--xh-bg-canvas));
91
- color: var(--xh-checkbox-group-indicator-fg, var(--xh-fg-on-brand));
92
- font-size: var(--xh-checkbox-group-indicator-font-size, calc(var(--xh-control-indicator-size) * 0.75));
147
+ background-color: var(--xh-_checkbox-group-bg);
148
+ color: var(--xh-checkbox-group-indicator-fg, var(--xh-_checkbox-group-on-accent));
149
+ box-shadow: var(--xh-checkbox-group-indicator-shadow, none);
150
+ font-size: var(--xh-checkbox-group-indicator-font-size, var(--xh-_checkbox-group-glyph));
93
151
  line-height: var(--xh-leading-none);
152
+ /* 方框不缩放(§9.2 行级只换面),过渡只有底与描边;按下走 press 时间线、释放同走 micro */
94
153
  transition:
95
- background var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
154
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
96
155
  border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
97
156
  }
98
157
 
99
158
  /* content 只能给伪元素,绝不能并进上面那条:content 落在普通元素上会顶掉它的全部子节点,
100
159
  indicator 里作者写的图标就此消失 */
101
- [data-scope='checkbox-group'][data-part='trigger']::before {
160
+ [data-scope='checkbox-group'][data-part='select-all-trigger']::before {
102
161
  content: '';
103
162
  }
104
163
 
105
- /* 悬停只加深空方框的描边。已选中的那一格必须排除:这条选择器的权重高过下面那条填色规则,
106
- 不排除就会在悬停时把 brand 描边换回灰色,方框看起来"缺了一圈" */
107
- [data-scope='checkbox-group'][data-part='item']:not([data-disabled]):hover
108
- [data-scope='checkbox-group'][data-part='indicator']:not([data-state='checked']) {
109
- border-color: var(--xh-checkbox-group-indicator-border-hover, var(--xh-border-control-hover));
164
+ /* 悬停整行时未勾选的方框描边升一档(字段静息 → hover 的同一条阶梯,§8.3);
165
+ 勾中的方框描边与底同色,悬停不换描边——填色本身已经在表达状态 */
166
+ @media (hover: hover) {
167
+ [data-scope='checkbox-group'][data-part='root']:not([data-disabled]):not([data-readonly]):not([data-invalid])
168
+ [data-scope='checkbox-group'][data-part='item']:not([data-disabled]):hover
169
+ [data-scope='checkbox-group'][data-part='indicator']:not([data-state='checked']),
170
+ [data-scope='checkbox-group'][data-part='root']:not([data-disabled]):not([data-readonly]):not([data-invalid])
171
+ [data-scope='checkbox-group'][data-part='select-all-trigger']:not([data-disabled]):not([data-state='checked']):not([data-state='indeterminate']):hover::before {
172
+ border-color: var(--xh-checkbox-group-indicator-border-hover, var(--xh-border-control-hover));
173
+ }
110
174
  }
111
175
 
112
176
  /* 选中即填色:条目是二态,全选格三态里 checked 与 indeterminate 都算"有值",共用同一副填色 */
113
177
  [data-scope='checkbox-group'][data-part='indicator'][data-state='checked'],
114
- [data-scope='checkbox-group'][data-part='trigger']:is([data-state='checked'], [data-state='indeterminate'])::before {
115
- border-color: var(--xh-checkbox-group-indicator-border-checked, var(--xh-bg-brand));
116
- background: var(--xh-checkbox-group-indicator-bg-checked, var(--xh-bg-brand));
178
+ [data-scope='checkbox-group'][data-part='select-all-trigger']:is([data-state='checked'], [data-state='indeterminate'])::before {
179
+ --xh-_checkbox-group-bg: var(--xh-checkbox-group-indicator-bg-checked, var(--xh-_checkbox-group-accent));
180
+
181
+ border-color: var(--xh-checkbox-group-indicator-border-checked, var(--xh-_checkbox-group-accent));
182
+ }
183
+
184
+ /* 按下去要有回应。方框不是激活宿主:宿主是投影了 row 档的整行(条目 / 全选格),方框在宿主的
185
+ :hover / :is(:active, [data-pressed]) 下读宿主 host 槽的同一来源换面、不缩放(§9.2)——行按下是 200,
186
+ 坐在上面的方框到 300(行以 --xh-action-host-bg-pressed 声明自己是方框的承载面,桥接槽只写不读,
187
+ 方框读的是喂给它的那支私有槽),勾中的换到语气的 active 档;
188
+ 与家族按压块同一时间线(按下 --xh-motion-duration-press,释放同走 micro) */
189
+ [data-scope='checkbox-group'][data-part='root']:not([data-readonly])
190
+ [data-scope='checkbox-group'][data-part='item']:not([data-disabled]):is(:active, [data-pressed])
191
+ [data-scope='checkbox-group'][data-part='indicator'],
192
+ [data-scope='checkbox-group'][data-part='select-all-trigger']:not([data-disabled]):not([data-readonly]):is(:active, [data-pressed])::before {
193
+ --xh-_checkbox-group-bg: var(--xh-checkbox-group-indicator-bg-pressed, var(--xh-_checkbox-group-host-bg-pressed));
194
+
195
+ transition-duration: var(--xh-motion-duration-press);
196
+ transition-timing-function: var(--xh-motion-ease-press);
197
+ }
198
+
199
+ [data-scope='checkbox-group'][data-part='root']:not([data-readonly])
200
+ [data-scope='checkbox-group'][data-part='item']:not([data-disabled]):is(:active, [data-pressed])
201
+ [data-scope='checkbox-group'][data-part='indicator'][data-state='checked'],
202
+ [data-scope='checkbox-group'][data-part='select-all-trigger']:not([data-disabled]):not([data-readonly]):is(:active, [data-pressed]):is([data-state='checked'], [data-state='indeterminate'])::before {
203
+ --xh-_checkbox-group-bg: var(--xh-checkbox-group-indicator-bg-checked-pressed, var(--xh-_tone-active, var(--xh-bg-brand-active)));
117
204
  }
118
205
 
119
206
  /* 勾号由皮肤补,作者不必自己往 indicator 里塞字符 */
@@ -138,7 +225,7 @@
138
225
  方框是行首那颗 ::before、宽度即指示符尺寸,所以字形按「盒与字形的宽度差之半」
139
226
  内推即落在圆心;纵向靠 inset-block: 0 + margin-block: auto 居中。
140
227
  font-size 与 ::before 同值,--xh-icon-size 的 1em 兜底才和条目那侧量得一样大 */
141
- [data-scope='checkbox-group'][data-part='trigger'][data-state='checked']::after {
228
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][data-state='checked']::after {
142
229
  content: '';
143
230
  position: absolute;
144
231
  inset-block: 0;
@@ -146,19 +233,19 @@
146
233
  margin-block: auto;
147
234
  margin-inline-start: calc(
148
235
  (
149
- var(--xh-checkbox-group-indicator-size, var(--xh-control-indicator-size)) -
236
+ var(--xh-checkbox-group-indicator-size, var(--xh-_checkbox-group-box)) -
150
237
  var(--xh-icon-size, var(--xh-glyph-size-text))
151
238
  ) / 2
152
239
  );
153
240
  inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
154
241
  block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
155
- background-color: var(--xh-checkbox-group-indicator-fg, var(--xh-fg-on-brand));
156
- font-size: var(--xh-checkbox-group-indicator-font-size, calc(var(--xh-control-indicator-size) * 0.75));
242
+ background-color: var(--xh-checkbox-group-indicator-fg, var(--xh-_checkbox-group-on-accent));
243
+ font-size: var(--xh-checkbox-group-indicator-font-size, var(--xh-_checkbox-group-glyph));
157
244
  -webkit-mask: var(--xh-glyph-mark-check) center / contain no-repeat;
158
245
  mask: var(--xh-glyph-mark-check) center / contain no-repeat;
159
246
  }
160
247
 
161
- [data-scope='checkbox-group'][data-part='trigger'][data-state='indeterminate']::after {
248
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][data-state='indeterminate']::after {
162
249
  content: '';
163
250
  position: absolute;
164
251
  inset-block: 0;
@@ -166,14 +253,14 @@
166
253
  margin-block: auto;
167
254
  margin-inline-start: calc(
168
255
  (
169
- var(--xh-checkbox-group-indicator-size, var(--xh-control-indicator-size)) -
256
+ var(--xh-checkbox-group-indicator-size, var(--xh-_checkbox-group-box)) -
170
257
  var(--xh-icon-size, var(--xh-glyph-size-text))
171
258
  ) / 2
172
259
  );
173
260
  inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
174
261
  block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
175
- background-color: var(--xh-checkbox-group-indicator-fg, var(--xh-fg-on-brand));
176
- font-size: var(--xh-checkbox-group-indicator-font-size, calc(var(--xh-control-indicator-size) * 0.75));
262
+ background-color: var(--xh-checkbox-group-indicator-fg, var(--xh-_checkbox-group-on-accent));
263
+ font-size: var(--xh-checkbox-group-indicator-font-size, var(--xh-_checkbox-group-glyph));
177
264
  -webkit-mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
178
265
  mask: var(--xh-glyph-mark-minus) center / contain no-repeat;
179
266
  }
@@ -184,42 +271,74 @@
184
271
  border-color: var(--xh-checkbox-group-indicator-border-invalid, var(--xh-border-invalid));
185
272
  }
186
273
 
274
+ /* 禁用(§7.2):--xh-border-default 描边 + --xh-bg-subtle 底 + --xh-fg-disabled 字形,不靠 opacity */
275
+ [data-scope='checkbox-group'][data-part='root'][data-disabled]
276
+ [data-scope='checkbox-group'][data-part='indicator'],
277
+ [data-scope='checkbox-group'][data-part='item'][data-disabled]
278
+ [data-scope='checkbox-group'][data-part='indicator'],
279
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][data-disabled]::before {
280
+ --xh-_checkbox-group-bg: var(--xh-checkbox-group-indicator-bg-disabled, var(--xh-bg-subtle));
281
+
282
+ border-color: var(--xh-checkbox-group-indicator-border-disabled, var(--xh-border-default));
283
+ color: var(--xh-checkbox-group-indicator-fg-disabled, var(--xh-fg-disabled));
284
+ }
285
+
187
286
  [data-scope='checkbox-group'][data-part='item-text'] {
188
287
  color: inherit;
189
288
  user-select: none;
190
289
  }
191
290
 
192
- /* 全选格与条目同形,但字重加一档,读起来才不像又一个普通选项。
193
- 它是普通元素而非原生控件(三态只有非原生控件表达得出),禁用态同样只能读 data-disabled。
194
- position 是给叠在方框上的那颗字形 ::after 当定位基准 */
195
- [data-scope='checkbox-group'][data-part='trigger'] {
291
+ /* 全选格与条目同形(接 Action Control row 档 ghost、xs 命中地板、按下只换面不缩放,方框读宿主 host 槽),
292
+ 但字重加一档,读起来才不像又一个普通选项。它是普通元素而非原生控件(三态只有非原生控件表达得出),
293
+ 家族的禁用块同样只读 data-disabled。position 是给叠在方框上的那颗字形 ::after 当定位基准 */
294
+ [data-scope='checkbox-group'][data-part='select-all-trigger'] {
295
+ --xh-action-gap: var(--xh-checkbox-group-select-all-trigger-gap, var(--xh-_checkbox-group-gap));
296
+ /* 全选格的身份是嵌在 control 内的小方框(§6.3 select-all 方框取 inset),与条目方框同一档 */
297
+ --xh-action-radius: var(--xh-checkbox-group-select-all-trigger-radius, var(--xh-shape-inset));
298
+ --xh-action-font-size: var(--xh-checkbox-group-select-all-trigger-font-size, var(--xh-_checkbox-group-font-size));
299
+ --xh-action-padding-inline: 0;
300
+ --xh-action-padding-block: 0;
301
+ --xh-action-fg-rest: var(--xh-checkbox-group-select-all-trigger-fg, var(--xh-fg-default));
302
+ --xh-action-fg-hover: var(--xh-checkbox-group-select-all-trigger-fg, var(--xh-fg-default));
303
+ --xh-action-fg-pressed: var(--xh-checkbox-group-select-all-trigger-fg, var(--xh-fg-default));
304
+ --xh-action-fg-focus-visible: var(--xh-checkbox-group-select-all-trigger-fg, var(--xh-fg-default));
305
+ --xh-action-fg-disabled: var(--xh-checkbox-group-select-all-trigger-fg-disabled, var(--xh-fg-disabled));
306
+ --xh-action-bg-hover: var(--xh-checkbox-group-select-all-trigger-bg-hover, var(--xh-bg-subtle));
307
+ --xh-action-bg-pressed: var(--xh-checkbox-group-select-all-trigger-bg-pressed, var(--xh-bg-subtle-hover));
308
+ /* 行自己的面已由上面两支钉住,host 槽只对方框(::before)生效:200 → 300 */
309
+ --xh-action-host-bg-hover: var(--xh-_checkbox-group-host-bg-hover);
310
+ --xh-action-host-bg-pressed: var(--xh-_checkbox-group-host-bg-pressed);
311
+
196
312
  position: relative;
197
- display: inline-flex;
198
- align-items: center;
199
- gap: var(--xh-checkbox-group-trigger-gap, var(--xh-control-gap-md));
200
- border-radius: var(--xh-checkbox-group-trigger-radius, var(--xh-shape-control));
201
- color: var(--xh-checkbox-group-trigger-fg, var(--xh-fg-default));
202
- font-size: var(--xh-checkbox-group-trigger-font-size, var(--xh-text-label-size));
203
- font-weight: var(--xh-checkbox-group-trigger-font-weight, var(--xh-font-weight-medium));
204
- line-height: var(--xh-leading-none);
205
- cursor: pointer;
206
- user-select: none;
313
+ inline-size: auto;
314
+ border-width: 0;
315
+ font-weight: var(--xh-checkbox-group-select-all-trigger-font-weight, var(--xh-font-weight-medium));
207
316
  }
208
317
 
209
- [data-scope='checkbox-group'][data-part='trigger']:focus-visible {
210
- outline: var(--xh-ring-width) solid var(--xh-ring-focus);
211
- outline-offset: var(--xh-ring-offset);
318
+ /* 只读与禁用会同时出现在 trigger 上(连接层两个属性各写各的):只读收回整行的悬停 / 按下面与手型,
319
+ 显式排掉禁用,否则禁用的 not-allowed 被只读的 default 盖掉 */
320
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][data-readonly]:not([data-disabled]) {
321
+ --xh-action-bg-hover: transparent;
322
+ --xh-action-bg-pressed: transparent;
323
+ --xh-action-cursor-rest: default;
324
+ --xh-action-cursor-hover: default;
325
+ --xh-action-cursor-pressed: default;
326
+ --xh-action-cursor-focus-visible: default;
212
327
  }
213
328
 
214
- [data-scope='checkbox-group'][data-part='trigger'][data-disabled] {
215
- color: var(--xh-checkbox-group-trigger-fg-disabled, var(--xh-fg-disabled));
216
- cursor: not-allowed;
217
- }
329
+ /* 家族 row 档在粗指针下用 ::after 把热区扩到 44px 高:条目按 24px 行 + 8px 间距密排,热区会压进相邻条目 2px、
330
+ 指针落错行,A 档 24px 由 xs 地板保住(两者都不在 coarse-target 的 B 档名单);勾中 / 半选时全选格的 ::after
331
+ 是叠在方框上的字形,家族的热区 translate 会把它拖走,钉回原位(同 transfer select-all-trigger) */
332
+ @media (pointer: coarse) {
333
+ [data-scope='checkbox-group'][data-part='item']::after,
334
+ [data-scope='checkbox-group'][data-part='select-all-trigger']::after {
335
+ min-block-size: 0;
336
+ }
218
337
 
219
- /* 只读与禁用会同时出现在 trigger 上(连接层两个属性各写各的),
220
- 同权重下后写的赢,所以这里必须显式排掉禁用,否则禁用的手势指示被只读盖掉 */
221
- [data-scope='checkbox-group'][data-part='trigger'][data-readonly]:not([data-disabled]) {
222
- cursor: default;
338
+ [data-scope='checkbox-group'][data-part='select-all-trigger']:is([data-state='checked'], [data-state='indeterminate'])::after {
339
+ min-block-size: 0;
340
+ translate: none;
341
+ }
223
342
  }
224
343
 
225
344
  /* 表单出口:连接层已经把整套视觉隐藏写进内联 style(absolute + 1px + clip-path),
@@ -234,7 +353,36 @@
234
353
  [data-scope='checkbox-group'][data-part='root'][hidden],
235
354
  [data-scope='checkbox-group'][data-part='item'][hidden],
236
355
  [data-scope='checkbox-group'][data-part='indicator'][hidden],
237
- [data-scope='checkbox-group'][data-part='trigger'][hidden] {
356
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][hidden] {
238
357
  display: none;
239
358
  }
359
+
360
+ @media (forced-colors: active) {
361
+ /* 真实描边保留方框,系统前景重绘状态字形。 */
362
+ [data-scope='checkbox-group'][data-part='indicator'][data-state='checked']:empty::before,
363
+ [data-scope='checkbox-group'][data-part='select-all-trigger']:is([data-state='checked'], [data-state='indeterminate'])::after {
364
+ background-color: CanvasText;
365
+ }
366
+
367
+ [data-scope='checkbox-group'][data-part='item'][data-disabled]
368
+ [data-scope='checkbox-group'][data-part='indicator'][data-state='checked']:empty::before,
369
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][data-disabled]:is(
370
+ [data-state='checked'],
371
+ [data-state='indeterminate']
372
+ )::after {
373
+ background-color: GrayText;
374
+ }
375
+ }
376
+
377
+ @media print {
378
+ [data-scope='checkbox-group'][data-part='indicator'][data-state='checked'],
379
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][data-state='checked']::before {
380
+ border-width: var(--xh-stroke-thick);
381
+ }
382
+
383
+ [data-scope='checkbox-group'][data-part='select-all-trigger'][data-state='indeterminate']::before {
384
+ border-width: var(--xh-stroke-thick);
385
+ border-style: dashed;
386
+ }
387
+ }
240
388
  }