@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.
- package/CHANGELOG.md +5146 -6
- package/README.md +22 -2
- package/component-tokens.d.ts +4212 -0
- package/component-tokens.js +2 -0
- package/components.tokens.json +80116 -0
- package/css/accordion.css +131 -75
- package/css/affix.css +16 -1
- package/css/alert.css +114 -67
- package/css/anchor.css +99 -27
- package/css/approval.css +461 -0
- package/css/avatar-group.css +14 -6
- package/css/avatar.css +33 -9
- package/css/back-top.css +103 -48
- package/css/badge.css +42 -14
- package/css/bar-code.css +62 -0
- package/css/breadcrumb.css +40 -21
- package/css/button-group.css +146 -24
- package/css/button.css +116 -99
- package/css/calendar-picker.css +448 -0
- package/css/calendar-range-picker.css +517 -0
- package/css/card.css +54 -77
- package/css/carousel.css +412 -68
- package/css/cascader.css +429 -246
- package/css/checkbox-group.css +225 -77
- package/css/checkbox.css +174 -37
- package/css/clipboard.css +266 -47
- package/css/code-view.css +279 -0
- package/css/collapsible.css +108 -63
- package/css/color-field.css +158 -0
- package/css/color-picker.css +172 -184
- package/css/color-slider.css +274 -0
- package/css/color-swatch-picker.css +243 -0
- package/css/color-swatch.css +35 -0
- package/css/combobox.css +267 -273
- package/css/command.css +399 -0
- package/css/context-menu.css +183 -108
- package/css/date-field.css +94 -121
- package/css/date-picker.css +486 -249
- package/css/date-range-picker.css +559 -0
- package/css/description.css +51 -0
- package/css/descriptions.css +133 -87
- package/css/dialog.css +247 -68
- package/css/diff-view.css +428 -0
- package/css/download-trigger.css +155 -46
- package/css/drawer.css +194 -111
- package/css/editable.css +172 -152
- package/css/empty-state.css +80 -11
- package/css/field-array.css +190 -0
- package/css/field.css +84 -31
- package/css/fieldset.css +51 -18
- package/css/file-upload.css +134 -36
- package/css/flex.css +20 -1
- package/css/float-button.css +238 -57
- package/css/floating-panel.css +173 -92
- package/css/focus.css +46 -0
- package/css/forced-colors.css +93 -0
- package/css/form.css +254 -77
- package/css/gradient-text.css +34 -10
- package/css/grid.css +516 -5
- package/css/heatmap.css +87 -29
- package/css/highlight.css +20 -5
- package/css/hover-card.css +97 -47
- package/css/icon-wrapper.css +15 -3
- package/css/icon.css +74 -8
- package/css/image-cropper.css +143 -29
- package/css/image-viewer.css +150 -89
- package/css/image.css +30 -1
- package/css/infinite-scroll.css +51 -1
- package/css/input-group.css +277 -0
- package/css/json-viewer.css +102 -45
- package/css/kbd.css +72 -0
- package/css/label.css +78 -0
- package/css/layers.css +5 -0
- package/css/layout.css +175 -31
- package/css/list.css +24 -3
- package/css/listbox.css +208 -67
- package/css/loading-bar.css +52 -3
- package/css/log.css +144 -9
- package/css/markdown-stream.css +149 -0
- package/css/marquee.css +27 -1
- package/css/masonry.css +7 -0
- package/css/matrix-code.css +67 -0
- package/css/mention.css +234 -152
- package/css/menu.css +180 -83
- package/css/menubar.css +204 -136
- package/css/message-feed.css +197 -0
- package/css/navigation-menu.css +144 -90
- package/css/notification.css +178 -100
- package/css/number-animation.css +7 -0
- package/css/number-field.css +120 -277
- package/css/overlay-arrow.css +12 -7
- package/css/page-header.css +99 -14
- package/css/pagination.css +175 -135
- package/css/password-input.css +222 -219
- package/css/pin-input.css +101 -67
- package/css/pointer.css +36 -0
- package/css/popconfirm.css +185 -94
- package/css/popover.css +121 -77
- package/css/progress.css +60 -12
- package/css/prompt-input.css +224 -0
- package/css/question-flow.css +513 -0
- package/css/radio-group.css +147 -30
- package/css/rating.css +193 -43
- package/css/reasoning.css +336 -0
- package/css/reset.css +84 -6
- package/css/resizable.css +237 -0
- package/css/scroll-area.css +68 -7
- package/css/scrollbar.css +47 -13
- package/css/segmented.css +94 -29
- package/css/select.css +288 -274
- package/css/separator.css +101 -1
- package/css/side-nav.css +133 -75
- package/css/signature-pad.css +74 -54
- package/css/skeleton.css +84 -11
- package/css/slider.css +132 -39
- package/css/sortable.css +198 -0
- package/css/spinner.css +126 -12
- package/css/splitter.css +29 -8
- package/css/statistic.css +55 -0
- package/css/steps.css +206 -72
- package/css/switch.css +268 -36
- package/css/table.css +695 -118
- package/css/tabs.css +604 -42
- package/css/tag-group.css +219 -0
- package/css/tag.css +118 -28
- package/css/tags-input.css +156 -274
- package/css/text-field.css +101 -249
- package/css/time-field.css +100 -128
- package/css/time-picker.css +323 -252
- package/css/time-range-picker.css +719 -0
- package/css/timeline.css +202 -68
- package/css/timer.css +56 -52
- package/css/timestamp.css +34 -0
- package/css/toast.css +373 -144
- package/css/toggle-group.css +309 -76
- package/css/toggle.css +116 -85
- package/css/tone.css +47 -0
- package/css/tool-call.css +421 -0
- package/css/toolbar.css +181 -33
- package/css/tooltip.css +107 -36
- package/css/tour.css +183 -152
- package/css/transfer.css +351 -138
- package/css/tree-select.css +323 -216
- package/css/tree.css +294 -62
- package/css/truncate.css +65 -0
- package/css/typography.css +228 -5
- package/css/undefined.css +10 -1
- package/css/virtualizer.css +9 -10
- package/css/visually-hidden.css +7 -0
- package/css/watermark.css +7 -0
- package/family/action-control.css +487 -0
- package/family/collection-item.css +721 -0
- package/family/field-chrome.css +298 -0
- package/family/motion.css +166 -0
- package/family/swatch.css +59 -0
- package/index.css +41705 -126
- package/index.unlayered.css +33692 -17339
- package/package.json +51 -17
- package/css/calendar.css +0 -367
- package/css/code-block.css +0 -91
- package/css/composer.css +0 -134
- package/css/countdown.css +0 -26
- package/css/dynamic-input.css +0 -220
- package/css/ellipsis.css +0 -52
- package/css/hotkeys.css +0 -90
- package/css/popselect.css +0 -391
- package/css/qr-code.css +0 -55
- package/css/result.css +0 -119
- package/css/space.css +0 -117
- package/css/thread.css +0 -120
- package/css/time.css +0 -25
package/css/tree.css
CHANGED
|
@@ -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
|
+
/* 定义 tree 样式。 */
|
|
7
|
+
|
|
8
|
+
@import '../family/collection-item.css';
|
|
9
|
+
|
|
1
10
|
@layer xihan.components {
|
|
2
11
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
12
|
[data-scope='tree'] {
|
|
@@ -5,8 +14,11 @@
|
|
|
5
14
|
}
|
|
6
15
|
|
|
7
16
|
[data-scope='tree'][data-part='root'] {
|
|
8
|
-
/*
|
|
9
|
-
|
|
17
|
+
/* 行外的字形(空态 / 在途占位里作者塞的图标)按档取尺,树没有 size 轴、固定 md;
|
|
18
|
+
行内的由家族随 data-xh-collection-size 下发(§6.5)。这支只管作者放进行里的图标:
|
|
19
|
+
树自绘的状态字形(展开方向、叶子对号、勾选把手里的勾)是指示符,各部件在自己身上
|
|
20
|
+
把 --xh-icon-size 改接到 --xh-control-indicator-* 一族的盒尺 */
|
|
21
|
+
--xh-icon-size: var(--xh-tree-icon-size, var(--xh-glyph-size-md));
|
|
10
22
|
|
|
11
23
|
display: flex;
|
|
12
24
|
flex-direction: column;
|
|
@@ -17,6 +29,20 @@
|
|
|
17
29
|
display: none;
|
|
18
30
|
}
|
|
19
31
|
|
|
32
|
+
/* 淡底档:描边透明、底换成 subtle;outline 即基础规则。
|
|
33
|
+
形态由 root 的 data-variant 向容器下发,容器基础规则直接写 border-default / bg-surface,
|
|
34
|
+
与 list / descriptions 的 outline 面同源(列表容器族) */
|
|
35
|
+
[data-scope='tree'][data-part='root'][data-variant='subtle'] [data-scope='tree'][data-part='tree'] {
|
|
36
|
+
border-color: transparent;
|
|
37
|
+
background: var(--xh-tree-bg, var(--xh-bg-subtle));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* 无框档:边框留着但透明,去掉外框不会让行的位置跳一格 */
|
|
41
|
+
[data-scope='tree'][data-part='root'][data-variant='ghost'] [data-scope='tree'][data-part='tree'] {
|
|
42
|
+
border-color: transparent;
|
|
43
|
+
background: transparent;
|
|
44
|
+
}
|
|
45
|
+
|
|
20
46
|
[data-scope='tree'][data-part='label'] {
|
|
21
47
|
color: var(--xh-tree-label-fg, var(--xh-fg-muted));
|
|
22
48
|
font-size: var(--xh-tree-label-font-size, var(--xh-text-label-size));
|
|
@@ -50,6 +76,46 @@
|
|
|
50
76
|
display: none;
|
|
51
77
|
}
|
|
52
78
|
|
|
79
|
+
/* 空态占位:待在 root 里、tree 的兄弟(role=tree 只许拥有 treeitem 与 group)。
|
|
80
|
+
盒归 tree,这里只画一句居中的次要文字 */
|
|
81
|
+
[data-scope='tree'][data-part='empty'] {
|
|
82
|
+
display: block;
|
|
83
|
+
padding-block: var(--xh-tree-empty-py, var(--xh-space-3));
|
|
84
|
+
padding-inline: var(--xh-tree-empty-px, var(--xh-space-3));
|
|
85
|
+
color: var(--xh-tree-empty-fg, var(--xh-fg-subtle));
|
|
86
|
+
font-size: var(--xh-tree-empty-font-size, var(--xh-text-body-size));
|
|
87
|
+
line-height: var(--xh-leading-none);
|
|
88
|
+
text-align: center;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* 上面给了 display,UA 的 [hidden]{display:none} 已被盖掉,这里补回来 */
|
|
92
|
+
[data-scope='tree'][data-part='empty'][hidden] {
|
|
93
|
+
display: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
[data-scope='tree'][data-part='empty'][data-disabled] {
|
|
97
|
+
color: var(--xh-fg-disabled);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* 在途占位:与空态占位同一个位置、同一副观感,两者不同屏 */
|
|
101
|
+
[data-scope='tree'][data-part='loading'] {
|
|
102
|
+
display: block;
|
|
103
|
+
padding-block: var(--xh-tree-loading-py, var(--xh-space-3));
|
|
104
|
+
padding-inline: var(--xh-tree-loading-px, var(--xh-space-3));
|
|
105
|
+
color: var(--xh-tree-loading-fg, var(--xh-fg-subtle));
|
|
106
|
+
font-size: var(--xh-tree-loading-font-size, var(--xh-text-body-size));
|
|
107
|
+
line-height: var(--xh-leading-none);
|
|
108
|
+
text-align: center;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[data-scope='tree'][data-part='loading'][hidden] {
|
|
112
|
+
display: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
[data-scope='tree'][data-part='loading'][data-disabled] {
|
|
116
|
+
color: var(--xh-fg-disabled);
|
|
117
|
+
}
|
|
118
|
+
|
|
53
119
|
/* 焦点在树外时容器自己进 Tab 序列兜底,落焦不画环:高亮永远长在行上 */
|
|
54
120
|
[data-scope='tree'][data-part='tree']:focus-visible {
|
|
55
121
|
outline: none;
|
|
@@ -76,59 +142,112 @@
|
|
|
76
142
|
|
|
77
143
|
[data-scope='tree'][data-part='branch']:focus-visible > [data-scope='tree'][data-part='branch-control'] {
|
|
78
144
|
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
79
|
-
|
|
80
|
-
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
145
|
+
outline-offset: var(--xh-ring-offset);
|
|
81
146
|
}
|
|
82
147
|
|
|
83
|
-
/*
|
|
148
|
+
/* 行:叶子与分支共用同一套盒子,两种行在视觉上必须齐平。
|
|
149
|
+
行走 Collection Item 的 page 语境(页内持久集合,§7.3):悬停 / 高亮 / 按下面(白底承载 hover 100 →
|
|
150
|
+
pressed 200)与选中面(品牌淡底 + 淡底前景 + 前导标记,selected+hover 20% / +pressed 28%)都由家族按
|
|
151
|
+
aria-selected / data-selected 与 aria-disabled / data-disabled 给出;这里只把公开槽映射到桥接槽。
|
|
152
|
+
布局保持 flex 而不用家族网格:一行里可以并排多个前导部件(箭头、勾选把手、拖拽把手)与作者自己的图标、
|
|
153
|
+
按钮,单列的 prefix 放不下;间距统一由行的 gap 给,家族按槽下发的外边距(--xh-collection-gap)归零 */
|
|
84
154
|
[data-scope='tree'][data-part='item'],
|
|
85
155
|
[data-scope='tree'][data-part='branch-control'] {
|
|
156
|
+
--xh-collection-block-padding: var(--xh-tree-row-py, var(--xh-list-option-py-md));
|
|
157
|
+
--xh-collection-inline-padding: var(--xh-tree-row-px, var(--xh-control-px-md));
|
|
158
|
+
--xh-collection-gap: 0;
|
|
159
|
+
--xh-collection-font-size: var(--xh-tree-row-font-size, var(--xh-text-body-size));
|
|
160
|
+
--xh-collection-radius: var(--xh-tree-row-radius, var(--xh-shape-control));
|
|
161
|
+
/* 作者的图标尺槽经桥接槽下发到行,家族缺省按 md 档 */
|
|
162
|
+
--xh-collection-glyph-size: var(--xh-tree-icon-size, var(--xh-_collection-glyph-size));
|
|
163
|
+
/* 箭头 / 对号盒与叶子的占位同一把尺:指示符档(§6.5),与同一行里的勾选把手、拖拽把手同走
|
|
164
|
+
--xh-control-indicator-size(comfortable 16 / compact 14)。不读家族按档下发的 --xh-icon-size——
|
|
165
|
+
那支只管作者放进行里的图标,按图标档取的 20px 会比 16px 的勾选把手大一圈 */
|
|
166
|
+
--xh-_tree-indicator-size: var(--xh-tree-indicator-size, var(--xh-control-indicator-size));
|
|
167
|
+
--xh-collection-fg-rest: var(--xh-tree-row-fg, var(--xh-fg-default));
|
|
168
|
+
--xh-collection-fg-hover: var(--xh-tree-row-fg, var(--xh-fg-default));
|
|
169
|
+
--xh-collection-fg-keyboard-highlight: var(--xh-tree-row-fg, var(--xh-fg-default));
|
|
170
|
+
--xh-collection-fg-pressed: var(--xh-tree-row-fg, var(--xh-fg-default));
|
|
171
|
+
--xh-collection-fg-selected: var(--xh-tree-row-fg-selected, var(--xh-fg-on-brand-subtle));
|
|
172
|
+
--xh-collection-fg-selected-hover: var(--xh-tree-row-fg-selected, var(--xh-fg-on-brand-subtle));
|
|
173
|
+
--xh-collection-fg-selected-highlight: var(--xh-tree-row-fg-selected, var(--xh-fg-on-brand-subtle));
|
|
174
|
+
--xh-collection-fg-selected-pressed: var(--xh-tree-row-fg-selected, var(--xh-fg-on-brand-subtle));
|
|
175
|
+
--xh-collection-font-weight-selected: var(--xh-tree-row-selected-font-weight, var(--xh-font-weight-regular));
|
|
176
|
+
--xh-collection-font-weight-selected-hover: var(--xh-tree-row-selected-font-weight, var(--xh-font-weight-regular));
|
|
177
|
+
--xh-collection-font-weight-selected-highlight: var(--xh-tree-row-selected-font-weight, var(--xh-font-weight-regular));
|
|
178
|
+
--xh-collection-font-weight-selected-pressed: var(--xh-tree-row-selected-font-weight, var(--xh-font-weight-regular));
|
|
179
|
+
--xh-collection-bg-hover: var(--xh-tree-row-bg-hover, var(--xh-bg-subtle));
|
|
180
|
+
--xh-collection-bg-keyboard-highlight: var(--xh-tree-row-bg-hover, var(--xh-bg-subtle));
|
|
181
|
+
--xh-collection-bg-pressed: var(--xh-tree-row-bg-pressed, var(--xh-bg-subtle-hover));
|
|
182
|
+
--xh-collection-bg-selected: var(--xh-tree-row-bg-selected, var(--xh-bg-brand-subtle));
|
|
183
|
+
/* data-highlighted 跟的是连接层记的焦点行(指针点选也会落焦):只换面,焦点环在 :focus-visible 下再接回 */
|
|
184
|
+
--xh-collection-outline-keyboard-highlight: transparent;
|
|
185
|
+
--xh-collection-outline-selected-highlight: transparent;
|
|
186
|
+
/* 叶子的对号:槽按本部件取名(item-check-fg),标记部件的旧槽留在兜底位 */
|
|
187
|
+
--xh-collection-indicator-fg-rest: var(--xh-tree-item-check-fg, var(--xh-tree-item-indicator-fg, var(--xh-fg-brand)));
|
|
188
|
+
--xh-collection-indicator-fg-checked: var(--xh-tree-item-check-fg, var(--xh-tree-item-indicator-fg, var(--xh-fg-brand)));
|
|
189
|
+
--xh-collection-indicator-fg-selected: var(--xh-tree-item-check-fg, var(--xh-tree-item-indicator-fg, var(--xh-fg-brand)));
|
|
190
|
+
--xh-collection-indicator-fg-selected-hover: var(--xh-tree-item-check-fg, var(--xh-tree-item-indicator-fg, var(--xh-fg-brand)));
|
|
191
|
+
--xh-collection-indicator-fg-selected-highlight: var(--xh-tree-item-check-fg, var(--xh-tree-item-indicator-fg, var(--xh-fg-brand)));
|
|
192
|
+
--xh-collection-indicator-fg-selected-pressed: var(--xh-tree-item-check-fg, var(--xh-tree-item-indicator-fg, var(--xh-fg-brand)));
|
|
193
|
+
|
|
86
194
|
display: flex;
|
|
87
195
|
align-items: center;
|
|
88
196
|
gap: var(--xh-tree-row-gap, var(--xh-control-gap-md));
|
|
89
|
-
padding-block: var(--xh-tree-row-py, var(--xh-list-option-py-md));
|
|
90
|
-
padding-inline: var(--xh-tree-row-px, var(--xh-control-px-md));
|
|
91
|
-
border-radius: var(--xh-tree-row-radius, var(--xh-shape-control));
|
|
92
|
-
color: var(--xh-tree-row-fg, var(--xh-fg-default));
|
|
93
|
-
font-size: var(--xh-tree-row-font-size, var(--xh-text-body-size));
|
|
94
197
|
/* 行高留出文字的上下伸展空间,行内那层 overflow:hidden 才不会把字削掉 */
|
|
95
198
|
line-height: var(--xh-tree-row-leading, var(--xh-leading-normal));
|
|
96
199
|
white-space: nowrap;
|
|
97
|
-
cursor: pointer;
|
|
98
200
|
user-select: none;
|
|
201
|
+
/* 换面走家族的按下 / 释放时间线(与家族基础块同一份,描边色同样不进过渡);box-shadow 一并接过渡:
|
|
202
|
+
换父落点那圈内描边挂在行自己身上,跟着 data-drop 在行间移动 */
|
|
99
203
|
transition:
|
|
100
|
-
background var(--xh-motion-duration-
|
|
101
|
-
color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter)
|
|
204
|
+
background-color var(--xh-motion-duration-release) var(--xh-motion-ease-release),
|
|
205
|
+
color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
206
|
+
box-shadow var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
102
207
|
}
|
|
103
208
|
|
|
104
209
|
/* 分支行的首格是展开箭头,叶子行没有这一格。作者摆了 item-indicator 时由它顶着,
|
|
105
210
|
没摆(如勾选档首位直接是 item-checkbox)就由行盒自己补出来,
|
|
106
|
-
|
|
211
|
+
否则叶子会比同级分支往行首缩一格,层级关系读不出来。占位宽度与箭头 / 对号盒同一把尺 */
|
|
107
212
|
[data-orientation='vertical'] > [data-scope='tree'][data-part='item']:not(
|
|
108
213
|
:has(> [data-scope='tree'][data-part='item-indicator'])
|
|
109
214
|
) {
|
|
110
215
|
padding-inline-start: calc(
|
|
111
216
|
var(--xh-tree-row-px, var(--xh-control-px-md)) +
|
|
112
|
-
var(--xh-
|
|
217
|
+
var(--xh-_tree-indicator-size) +
|
|
113
218
|
var(--xh-tree-row-gap, var(--xh-control-gap-md))
|
|
114
219
|
);
|
|
115
220
|
}
|
|
116
221
|
|
|
222
|
+
/* 家族给了 display,UA 的 [hidden]{display:none} 已被盖掉 */
|
|
117
223
|
[data-scope='tree'][data-part='item'][hidden],
|
|
118
224
|
[data-scope='tree'][data-part='branch-control'][hidden] {
|
|
119
225
|
display: none;
|
|
120
226
|
}
|
|
121
227
|
|
|
122
|
-
/*
|
|
123
|
-
|
|
124
|
-
[data-scope='tree'][data-part='item']:
|
|
125
|
-
|
|
126
|
-
|
|
228
|
+
/* 键盘焦点出现时环才接回并立即到位,不压在背景过渡的中间帧上:叶子自己承载焦点;
|
|
229
|
+
分支的焦点在 branch 上、环画在它那一行(见上面 branch:focus-visible 那条) */
|
|
230
|
+
[data-scope='tree'][data-part='item']:focus-visible:not(:hover) {
|
|
231
|
+
--xh-collection-outline-keyboard-highlight: var(--xh-ring-focus);
|
|
232
|
+
--xh-collection-outline-selected-highlight: var(--xh-ring-focus);
|
|
233
|
+
|
|
234
|
+
transition: none;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* 禁用走 aria-disabled 而非原生 disabled:叶子的禁用面由家族按 aria-disabled 给;
|
|
238
|
+
分支行不是 treeitem 本体(aria-disabled 在 branch 上),按连接层的 data-disabled 映射到家族槽:
|
|
239
|
+
字色降级、光标 not-allowed,悬停 / 高亮 / 按下由家族守卫拦掉 */
|
|
240
|
+
[data-scope='tree'][data-part='branch-control'][data-disabled] {
|
|
241
|
+
--xh-collection-fg-rest: var(--xh-fg-disabled);
|
|
242
|
+
--xh-collection-cursor-rest: not-allowed;
|
|
127
243
|
}
|
|
128
244
|
|
|
129
245
|
/* 勾选把手:勾选态只画在它身上,不碰行底色——底色那条通道归高亮 */
|
|
130
246
|
[data-scope='tree'][data-part='item-checkbox'],
|
|
131
247
|
[data-scope='tree'][data-part='branch-checkbox'] {
|
|
248
|
+
/* 方框里的勾按边长的比例取尺(与 Checkbox 同一比例),不吃家族按档下发的行内字形尺 */
|
|
249
|
+
--xh-icon-size: calc(var(--xh-tree-checkbox-size, var(--xh-control-indicator-size)) * 0.75);
|
|
250
|
+
|
|
132
251
|
display: inline-grid;
|
|
133
252
|
place-items: center;
|
|
134
253
|
flex: none;
|
|
@@ -136,7 +255,7 @@
|
|
|
136
255
|
block-size: var(--xh-tree-checkbox-size, var(--xh-control-indicator-size));
|
|
137
256
|
border: var(--xh-stroke-thin) solid var(--xh-tree-checkbox-border, var(--xh-border-control));
|
|
138
257
|
border-radius: var(--xh-tree-checkbox-radius, var(--xh-shape-inset));
|
|
139
|
-
background: var(--xh-tree-checkbox-bg,
|
|
258
|
+
background: var(--xh-tree-checkbox-bg, transparent);
|
|
140
259
|
color: var(--xh-tree-checkbox-fg, var(--xh-fg-on-brand));
|
|
141
260
|
}
|
|
142
261
|
|
|
@@ -146,6 +265,16 @@
|
|
|
146
265
|
background: var(--xh-tree-checkbox-bg-checked, var(--xh-bg-brand));
|
|
147
266
|
}
|
|
148
267
|
|
|
268
|
+
/* 面是实心的,环色与面同族,画在面里就看不出来;环改取面自己的前景色——
|
|
269
|
+
那一族色本来就要在这块面上把字读清楚,与面的对比是按可读性定的。
|
|
270
|
+
勾满与半选铺的是同一块实心底,两态一起收 */
|
|
271
|
+
[data-scope='tree'][data-part='item-checkbox'][data-selected]:focus-visible,
|
|
272
|
+
[data-scope='tree'][data-part='item-checkbox'][data-indeterminate]:focus-visible,
|
|
273
|
+
[data-scope='tree'][data-part='branch-checkbox'][data-selected]:focus-visible,
|
|
274
|
+
[data-scope='tree'][data-part='branch-checkbox'][data-indeterminate]:focus-visible {
|
|
275
|
+
--xh-_ring-color: currentColor;
|
|
276
|
+
}
|
|
277
|
+
|
|
149
278
|
/* 半选:级联勾选下「子树勾了一部分」的第三态,此前发了 data-indeterminate 却没人画 */
|
|
150
279
|
[data-scope='tree'][data-part='item-checkbox'][data-indeterminate]:not([data-selected]),
|
|
151
280
|
[data-scope='tree'][data-part='branch-checkbox'][data-indeterminate]:not([data-selected]) {
|
|
@@ -180,29 +309,7 @@
|
|
|
180
309
|
|
|
181
310
|
[data-scope='tree'][data-part='item-checkbox'][data-disabled],
|
|
182
311
|
[data-scope='tree'][data-part='branch-checkbox'][data-disabled] {
|
|
183
|
-
border-color: var(--xh-tree-checkbox-border-disabled, var(--xh-border-
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/* 选中只换文字色与字重,配合行尾的 ✓ 标记;底色整条通道留给高亮,
|
|
187
|
-
两者因此能同时看见 */
|
|
188
|
-
[data-scope='tree'][data-part='item'][data-selected],
|
|
189
|
-
[data-scope='tree'][data-part='branch-control'][data-selected] {
|
|
190
|
-
color: var(--xh-tree-row-fg-selected, var(--xh-fg-brand-strong));
|
|
191
|
-
font-weight: var(--xh-tree-row-selected-font-weight, var(--xh-font-weight-medium));
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/* 叶子自己就是 treeitem,环直接画在它身上 */
|
|
195
|
-
[data-scope='tree'][data-part='item']:focus-visible {
|
|
196
|
-
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
197
|
-
outline-offset: calc(-1 * var(--xh-ring-width));
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/* 禁用走 aria-disabled 而非原生 disabled:节点仍要可聚焦(它还得当方向键的起点),
|
|
201
|
-
所以只能靠 data-disabled 表达,写 :disabled 永远不命中 */
|
|
202
|
-
[data-scope='tree'][data-part='item'][data-disabled],
|
|
203
|
-
[data-scope='tree'][data-part='branch-control'][data-disabled] {
|
|
204
|
-
color: var(--xh-fg-disabled);
|
|
205
|
-
cursor: not-allowed;
|
|
312
|
+
border-color: var(--xh-tree-checkbox-border-disabled, var(--xh-border-default));
|
|
206
313
|
}
|
|
207
314
|
|
|
208
315
|
[data-scope='tree'][data-part='item-text'],
|
|
@@ -215,40 +322,37 @@
|
|
|
215
322
|
text-overflow: ellipsis;
|
|
216
323
|
}
|
|
217
324
|
|
|
218
|
-
/*
|
|
325
|
+
/* 勾选标记是 page 语境的前导对号:显隐与颜色由家族按行的选中态给;
|
|
326
|
+
未选中时占位不塌,切换选中不引起行宽抖动。盒尺取指示符档;盒里的对号是指示符(§6.5),
|
|
327
|
+
在自己身上把 --xh-icon-size 改接到盒的尺,兜底对号与作者塞进盒里的 XhIcon 读同一把尺、与盒同边长 */
|
|
219
328
|
[data-scope='tree'][data-part='item-indicator'] {
|
|
329
|
+
--xh-icon-size: var(--xh-_tree-indicator-size);
|
|
330
|
+
|
|
220
331
|
display: inline-flex;
|
|
221
332
|
flex: none;
|
|
222
333
|
align-items: center;
|
|
223
334
|
justify-content: center;
|
|
224
|
-
inline-size: var(--xh-
|
|
225
|
-
color: var(--xh-tree-indicator-fg, var(--xh-fg-brand));
|
|
226
|
-
visibility: hidden;
|
|
335
|
+
inline-size: var(--xh-_tree-indicator-size);
|
|
227
336
|
}
|
|
228
337
|
|
|
229
338
|
[data-scope='tree'][data-part='item-indicator'][hidden] {
|
|
230
339
|
display: none;
|
|
231
340
|
}
|
|
232
341
|
|
|
233
|
-
[data-scope='tree'][data-part='item-indicator'][data-selected] {
|
|
234
|
-
visibility: visible;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
[data-scope='tree'][data-part='item-indicator'][data-disabled] {
|
|
238
|
-
color: var(--xh-fg-disabled);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
342
|
/* 展开箭头与方向指示符:两者都可能被作者用作"点这里展开"的把手,
|
|
242
|
-
|
|
343
|
+
所以尺寸与叶子的勾选标记一致,两种行的文字起点才对得齐。
|
|
344
|
+
盒里的 chevron 是指示符(§6.5):与盒同边长,--xh-icon-size 在自己身上改接到盒的尺 */
|
|
243
345
|
[data-scope='tree'][data-part='branch-trigger'],
|
|
244
346
|
[data-scope='tree'][data-part='branch-indicator'] {
|
|
347
|
+
--xh-icon-size: var(--xh-_tree-indicator-size);
|
|
348
|
+
|
|
245
349
|
display: inline-flex;
|
|
246
350
|
flex: none;
|
|
247
351
|
align-items: center;
|
|
248
352
|
justify-content: center;
|
|
249
|
-
inline-size: var(--xh-
|
|
353
|
+
inline-size: var(--xh-_tree-indicator-size);
|
|
250
354
|
color: var(--xh-tree-branch-indicator-fg, var(--xh-fg-subtle));
|
|
251
|
-
transition: rotate var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
355
|
+
transition: rotate var(--xh-motion-duration-micro) var(--xh-motion-ease-enter-strong);
|
|
252
356
|
}
|
|
253
357
|
|
|
254
358
|
[data-scope='tree'][data-part='branch-trigger'][hidden],
|
|
@@ -301,12 +405,15 @@
|
|
|
301
405
|
flex: none;
|
|
302
406
|
}
|
|
303
407
|
|
|
304
|
-
/* 收起态的唯一开关:display 会盖掉 hidden 属性的 UA
|
|
305
|
-
|
|
408
|
+
/* 收起态的唯一开关:display 会盖掉 hidden 属性的 UA 规则,漏了这条整棵子树就收不起来。
|
|
409
|
+
作者写的 hidden 与连接层发的 data-state=closed 都收在这里 */
|
|
410
|
+
[data-scope='tree'][data-part='branch-content'][hidden],
|
|
411
|
+
[data-scope='tree'][data-part='branch-content'][data-state='closed'] {
|
|
306
412
|
display: none;
|
|
307
413
|
}
|
|
308
414
|
|
|
309
|
-
/*
|
|
415
|
+
/* 没写内容就由皮肤画兜底字形;作者往部件里塞了自己的图形,这几条即不命中。
|
|
416
|
+
尺寸读部件自己改接过的 --xh-icon-size:chevron 与对号都与盒同边长(见上面两块) */
|
|
310
417
|
[data-scope='tree'][data-part='branch-trigger']:empty::before,
|
|
311
418
|
[data-scope='tree'][data-part='branch-indicator']:empty::before {
|
|
312
419
|
content: '';
|
|
@@ -330,8 +437,133 @@
|
|
|
330
437
|
mask: var(--xh-glyph-mark-check) center / contain no-repeat;
|
|
331
438
|
}
|
|
332
439
|
|
|
440
|
+
/* —— 节点拖拽搬家 —— */
|
|
441
|
+
/* 整行都是拖动源,光标换成抓手告诉人这一行按得动。
|
|
442
|
+
这条不写 touch-action:整行关掉纵向手势,树容器自己就滚不动了;
|
|
443
|
+
触屏那一路交给下面那块专属把手 */
|
|
444
|
+
[data-scope='tree'][data-part='item'][data-draggable],
|
|
445
|
+
[data-scope='tree'][data-part='branch-control'][data-draggable] {
|
|
446
|
+
cursor: grab;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* 节点拖拽把手:行里的一小块专属拖动区,按下即拖。触屏靠它起手,
|
|
450
|
+
代价只是这一小块地方不再跟着树滚。整行起手那一路原样保留,把手是叠加的第二个入口。
|
|
451
|
+
touch-action 不在这儿写:连接层按「拖不动就不写」把它写进了内联 style,
|
|
452
|
+
皮肤再写一遍会盖掉那份条件判断,让不可拖的节点也白白让出滚动 */
|
|
453
|
+
[data-scope='tree'][data-part='node-drag-trigger'] {
|
|
454
|
+
display: inline-flex;
|
|
455
|
+
flex: none;
|
|
456
|
+
align-items: center;
|
|
457
|
+
justify-content: center;
|
|
458
|
+
inline-size: var(--xh-tree-drag-size, var(--xh-control-indicator-size));
|
|
459
|
+
block-size: var(--xh-tree-drag-size, var(--xh-control-indicator-size));
|
|
460
|
+
border-radius: var(--xh-tree-drag-radius, var(--xh-shape-control));
|
|
461
|
+
color: var(--xh-tree-drag-fg, var(--xh-fg-subtle));
|
|
462
|
+
cursor: grab;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
[data-scope='tree'][data-part='node-drag-trigger'][hidden] {
|
|
466
|
+
display: none;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/* 抓手是两条横线:盒子取边框盒,块向两侧的描边就是那两条线,宽高与线宽都走令牌。
|
|
470
|
+
线的走向与能拖的方向垂直——节点沿块向上下排,画的就是横线。
|
|
471
|
+
用逻辑属性写,书写模式一换,线跟着排列轴自己转过去。
|
|
472
|
+
:empty 守卫让作者塞进来的图标整个顶掉它,而不是两份叠在一起 */
|
|
473
|
+
[data-scope='tree'][data-part='node-drag-trigger']:empty::after {
|
|
474
|
+
content: '';
|
|
475
|
+
display: block;
|
|
476
|
+
inline-size: var(--xh-tree-drag-grip-long, var(--xh-space-2));
|
|
477
|
+
block-size: var(--xh-tree-drag-grip-short, var(--xh-space-1));
|
|
478
|
+
border-block: var(--xh-stroke-thin) solid currentColor;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
[data-scope='tree'][data-part='node-drag-trigger']:not([data-disabled]):hover,
|
|
482
|
+
[data-scope='tree'][data-part='node-drag-trigger'][data-dragging] {
|
|
483
|
+
color: var(--xh-tree-drag-fg-active, var(--xh-fg-default));
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
[data-scope='tree'][data-part='node-drag-trigger'][data-dragging] {
|
|
487
|
+
cursor: grabbing;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/* 不可拖的节点照样带一个把手,这里保住它的位置、只把它压到禁用色。
|
|
491
|
+
收成 display: none 是不行的:把手占着行首那一格,藏掉之后同一层里能拖与不能拖的两个节点,
|
|
492
|
+
文字起点会错开一格,层级关系跟着读歪 */
|
|
493
|
+
[data-scope='tree'][data-part='node-drag-trigger'][data-disabled] {
|
|
494
|
+
color: var(--xh-tree-drag-fg-disabled, var(--xh-fg-disabled));
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/* 被拖的那一行压暗,让人看得出正在搬的是它。这里只动 opacity、cursor 与 user-select,
|
|
498
|
+
一个 transform 都不写:行原地不动,要落到哪儿全交给落点指示 */
|
|
499
|
+
[data-scope='tree'][data-part='item'][data-dragging],
|
|
500
|
+
[data-scope='tree'][data-part='branch-control'][data-dragging] {
|
|
501
|
+
opacity: var(--xh-tree-dragging-opacity, var(--xh-state-dragging-opacity));
|
|
502
|
+
cursor: grabbing;
|
|
503
|
+
user-select: none;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/* 落点指示线:插到哪一行的哪一侧,横线就画在那一行的那条边上。
|
|
507
|
+
定位上下文只给要画线的那一行:行平时都不定位,缺了它伪元素会一路上溯到最近的定位祖先,
|
|
508
|
+
线就画到树外面去;写到所有行上则是给每一行都多担一份,而落点同一时刻只有一个。
|
|
509
|
+
整块高亮那一档不在此列:它不靠伪元素,用不着这层上下文 */
|
|
510
|
+
[data-scope='tree'][data-part='item']:is([data-drop='before'], [data-drop='after']),
|
|
511
|
+
[data-scope='tree'][data-part='branch-control']:is([data-drop='before'], [data-drop='after']) {
|
|
512
|
+
position: relative;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/* 线贯穿整行宽度。行自身不收 overflow,线不会被行裁掉;
|
|
516
|
+
但仍整条画在行内不压着边——压着边画的话,首行那条上沿线会被树容器的圆角与滚动裁掉半条 */
|
|
517
|
+
[data-scope='tree'][data-part='item']:is([data-drop='before'], [data-drop='after'])::after,
|
|
518
|
+
[data-scope='tree'][data-part='branch-control']:is([data-drop='before'], [data-drop='after'])::after {
|
|
519
|
+
content: '';
|
|
520
|
+
position: absolute;
|
|
521
|
+
inset-inline: 0;
|
|
522
|
+
block-size: var(--xh-tree-drop-line, var(--xh-stroke-thick));
|
|
523
|
+
background: var(--xh-tree-drop-fg, var(--xh-border-control-focus));
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/* 落在上沿还是下沿走逻辑属性,块向跟着书写模式走。
|
|
527
|
+
换成 box-shadow 的偏移量则是物理的,写不出逻辑方向 */
|
|
528
|
+
[data-scope='tree'][data-part='item'][data-drop='before']::after,
|
|
529
|
+
[data-scope='tree'][data-part='branch-control'][data-drop='before']::after {
|
|
530
|
+
inset-block-start: 0;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
[data-scope='tree'][data-part='item'][data-drop='after']::after,
|
|
534
|
+
[data-scope='tree'][data-part='branch-control'][data-drop='after']::after {
|
|
535
|
+
inset-block-end: 0;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/* 放进这个节点里面:整行淡底加一圈内描边,与上下沿那条横线一眼分得开。
|
|
539
|
+
描边走零偏移的内投影,四边同时着色、不涉及方向,也跟着行的圆角走。
|
|
540
|
+
选择器里那条 :not([data-disabled]) 是把特指度补到与悬停那条齐平,再靠排在它之后压过它:
|
|
541
|
+
指针本来就停在落点这一行上,少了这一段,落点底色会被悬停那档灰盖掉。
|
|
542
|
+
禁用的节点从来不做落点,这一段因此不会漏画任何一处高亮 */
|
|
543
|
+
[data-scope='tree'][data-part='item'][data-drop='inside']:not([data-disabled]),
|
|
544
|
+
[data-scope='tree'][data-part='branch-control'][data-drop='inside']:not([data-disabled]) {
|
|
545
|
+
/* 落点不是选中:品牌淡底专属选中 / 当前(§7.1),落点面取悬停之上一档的中性面 */
|
|
546
|
+
background: var(--xh-tree-drop-inside-bg, var(--xh-bg-subtle-hover));
|
|
547
|
+
box-shadow: inset 0 0 0 var(--xh-tree-drop-line, var(--xh-stroke-thick))
|
|
548
|
+
var(--xh-tree-drop-fg, var(--xh-border-control-focus));
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/* 活动区域只说给读屏听,不占版面。声明与 shared/visually-hidden.ts 逐条同值。 */
|
|
552
|
+
[data-scope='tree'][data-part='live-region'] {
|
|
553
|
+
position: absolute;
|
|
554
|
+
inline-size: 1px;
|
|
555
|
+
block-size: 1px;
|
|
556
|
+
padding: 0;
|
|
557
|
+
margin: -1px;
|
|
558
|
+
overflow: hidden;
|
|
559
|
+
clip-path: inset(50%);
|
|
560
|
+
white-space: nowrap;
|
|
561
|
+
border: 0;
|
|
562
|
+
}
|
|
563
|
+
|
|
333
564
|
/* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
|
|
334
565
|
写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
|
|
566
|
+
[data-scope='tree'][data-part='item-checkbox'][hidden],
|
|
335
567
|
[data-scope='tree'][data-part='branch-checkbox'][hidden] {
|
|
336
568
|
display: none;
|
|
337
569
|
}
|
package/css/truncate.css
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
/* 定义 truncate 样式。 */
|
|
7
|
+
|
|
8
|
+
@layer xihan.components {
|
|
9
|
+
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
10
|
+
[data-scope='truncate'] {
|
|
11
|
+
--xh-truncate-skin: 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* 单行:一行装不下就收成省略号。
|
|
15
|
+
行数由连接层写进这个盒子的内联 style,样式表这一行只是它缺席时的落点 */
|
|
16
|
+
[data-scope='truncate'][data-part='root'] {
|
|
17
|
+
--xh-_truncate-lines: 1;
|
|
18
|
+
|
|
19
|
+
display: block;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
white-space: nowrap;
|
|
22
|
+
text-overflow: ellipsis;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* 多行:按行数裁,裁掉的那一行末尾收省略号 */
|
|
26
|
+
[data-scope='truncate'][data-part='root'][data-multiline] {
|
|
27
|
+
display: -webkit-box;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
-webkit-box-orient: vertical;
|
|
30
|
+
/* 使用者槽排在前面:连接层把行数写成根上的内联私有槽,
|
|
31
|
+
在外层写一句 --xh-truncate-lines 即可整片改档,不必逐处改标记 */
|
|
32
|
+
-webkit-line-clamp: var(--xh-truncate-lines, var(--xh-_truncate-lines));
|
|
33
|
+
white-space: normal;
|
|
34
|
+
/* 一长串没有断点的字符(网址、编号)也得断开,否则它一路撑出去,裁不住 */
|
|
35
|
+
overflow-wrap: break-word;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* 铺开:裁剪整个撤掉。写在两档之后,压得住上面同权重的那两条 */
|
|
39
|
+
[data-scope='truncate'][data-part='root'][data-state='open'] {
|
|
40
|
+
display: block;
|
|
41
|
+
overflow: visible;
|
|
42
|
+
white-space: normal;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* 真被裁了才是那颗按钮:装得下的短文本按下去什么都不变,摆出手型等于许一个按不动的按钮。
|
|
46
|
+
铺开态另收一条——那一档量不出"被裁",但收回去的入口必须留着 */
|
|
47
|
+
[data-scope='truncate'][data-part='root'][data-expandable][data-overflowing],
|
|
48
|
+
[data-scope='truncate'][data-part='root'][data-expandable][data-state='open'] {
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
transition: color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* 是按钮的那一档才提亮:指针停在上面时这段文字与正文分开,
|
|
54
|
+
按不动的短文本不给这个反馈 */
|
|
55
|
+
[data-scope='truncate'][data-part='root'][data-expandable][data-overflowing]:hover,
|
|
56
|
+
[data-scope='truncate'][data-part='root'][data-expandable][data-state='open']:hover {
|
|
57
|
+
color: var(--xh-fg-default);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
|
|
61
|
+
写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
|
|
62
|
+
[data-scope='truncate'][data-part='root'][hidden] {
|
|
63
|
+
display: none;
|
|
64
|
+
}
|
|
65
|
+
}
|