@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/radio-group.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
|
+
/* 定义 radio group 样式。 */
|
|
7
|
+
|
|
8
|
+
@import '../family/action-control.css';
|
|
9
|
+
|
|
1
10
|
@layer xihan.components {
|
|
2
11
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
12
|
[data-scope='radio-group'] {
|
|
@@ -11,17 +20,27 @@
|
|
|
11
20
|
--xh-_radio-group-indicator: var(--xh-control-indicator-md);
|
|
12
21
|
/* 选中色随语气走。没写 data-tone 时 --xh-_tone 没被声明,退回原来的品牌色 */
|
|
13
22
|
--xh-_radio-group-accent: var(--xh-_tone, var(--xh-bg-brand));
|
|
14
|
-
|
|
23
|
+
/* 条目是圆圈的承载面:行自己坐画布走 100 → 200,行面上的圆圈按淡底容器阶梯再上一档(200 → 300)。
|
|
24
|
+
两支私有槽是这一档的唯一来源——宿主拿它们给 --xh-action-host-bg-* 赋值(桥接槽只写不读),
|
|
25
|
+
圆圈按下读同一支私有槽,即与宿主的 host 槽同源 */
|
|
26
|
+
--xh-_radio-group-host-bg-hover: var(--xh-bg-subtle-hover);
|
|
27
|
+
--xh-_radio-group-host-bg-pressed: var(--xh-bg-subtle-active);
|
|
28
|
+
|
|
29
|
+
/* 标题与条目都是根的直接子节点,一支 gap 同时管「标题到集合」与「条目之间」:
|
|
30
|
+
集合标题与集合隔 --xh-space-2(§6.4),同组条目之间也是同一档紧密关系 */
|
|
15
31
|
display: flex;
|
|
16
|
-
gap: var(--xh-radio-group-gap, var(--xh-
|
|
32
|
+
gap: var(--xh-radio-group-gap, var(--xh-space-2));
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
[data-scope='radio-group'][data-part='root'][data-orientation='vertical'] {
|
|
20
36
|
flex-direction: column;
|
|
21
37
|
}
|
|
22
38
|
|
|
39
|
+
/* 横排一行摆不下时条目落到下一行。不换行的话它们只会被压窄,
|
|
40
|
+
文字逐字折行、每个条目变成一根竖条 */
|
|
23
41
|
[data-scope='radio-group'][data-part='root'][data-orientation='horizontal'] {
|
|
24
42
|
flex-direction: row;
|
|
43
|
+
flex-wrap: wrap;
|
|
25
44
|
align-items: center;
|
|
26
45
|
}
|
|
27
46
|
|
|
@@ -38,37 +57,65 @@
|
|
|
38
57
|
--xh-_radio-group-indicator: var(--xh-control-indicator-lg);
|
|
39
58
|
}
|
|
40
59
|
|
|
60
|
+
/* 集合标题(§6.4):14 / 500 / fg-muted,字号不随 size 档——随档的是条目文字 */
|
|
41
61
|
[data-scope='radio-group'][data-part='label'] {
|
|
42
62
|
color: var(--xh-radio-group-label-fg, var(--xh-fg-muted));
|
|
43
|
-
font-size: var(--xh-radio-group-label-font-size, var(--xh-
|
|
63
|
+
font-size: var(--xh-radio-group-label-font-size, var(--xh-text-label-size));
|
|
44
64
|
font-weight: var(--xh-radio-group-label-font-weight, var(--xh-text-label-weight));
|
|
45
65
|
line-height: var(--xh-leading-none);
|
|
46
66
|
}
|
|
47
67
|
|
|
48
|
-
/*
|
|
49
|
-
[data-scope='radio-group'][data-part='
|
|
50
|
-
|
|
51
|
-
display: inline-flex;
|
|
52
|
-
align-items: center;
|
|
53
|
-
gap: var(--xh-radio-group-item-gap, var(--xh-_radio-group-item-gap));
|
|
54
|
-
border-radius: var(--xh-radio-group-item-radius, var(--xh-shape-control));
|
|
55
|
-
color: var(--xh-radio-group-item-fg, var(--xh-fg-default));
|
|
56
|
-
font-size: var(--xh-radio-group-item-font-size, var(--xh-_radio-group-font-size));
|
|
57
|
-
line-height: var(--xh-leading-none);
|
|
58
|
-
cursor: pointer;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
[data-scope='radio-group'][data-part='item']:focus-visible {
|
|
62
|
-
outline: var(--xh-ring-width) solid var(--xh-ring-focus);
|
|
63
|
-
outline-offset: var(--xh-ring-offset);
|
|
68
|
+
/* label 自己不带状态属性,整组禁用只写在 root 上,禁用标签色统一 --xh-fg-subtle(§6.4) */
|
|
69
|
+
[data-scope='radio-group'][data-part='root'][data-disabled] [data-scope='radio-group'][data-part='label'] {
|
|
70
|
+
color: var(--xh-radio-group-label-fg-disabled, var(--xh-fg-subtle));
|
|
64
71
|
}
|
|
65
72
|
|
|
66
|
-
/*
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
/* 条目是「圆圈 + 文案」的整行命中区(§9.2):接 Action Control row 档、ghost 形态,悬停 / 按下 / 禁用面、手型、
|
|
74
|
+
过渡与焦点环由家族给,按下只换面不缩放(row 档专属按压块 scale: none);这里只把使用者槽映射到桥接槽。
|
|
75
|
+
行自己坐画布走 100 → 200(--xh-action-bg-* 钉住自己的面),行面上的圆圈按淡底容器阶梯再上一档
|
|
76
|
+
(--xh-action-host-bg-* 向内声明自己是圆圈的承载面,host 槽只对后代生效——自己的面已由 --xh-action-bg-* 钉住;
|
|
77
|
+
也因此 root 带 data-tone 时 --xh-_tone-subtle 不会把整行染色)。
|
|
78
|
+
xs 的 24px 是命中地板,圆圈 12 / 16 / 20px 居中其间;字号与间距按组档位从 root 的私有槽映射。
|
|
79
|
+
条目禁用走 aria-disabled 而非原生 disabled,条目仍可聚焦,家族的禁用块读 data-disabled。
|
|
80
|
+
position 是给条目内那份视觉隐藏的原生输入做定位基准,别去掉 */
|
|
81
|
+
[data-scope='radio-group'][data-part='item'] {
|
|
82
|
+
--xh-action-gap: var(--xh-radio-group-item-gap, var(--xh-_radio-group-item-gap));
|
|
83
|
+
--xh-action-radius: var(--xh-radio-group-item-radius, var(--xh-shape-control));
|
|
84
|
+
--xh-action-font-size: var(--xh-radio-group-item-font-size, var(--xh-_radio-group-font-size));
|
|
85
|
+
--xh-action-padding-inline: 0;
|
|
86
|
+
--xh-action-padding-block: 0;
|
|
87
|
+
--xh-action-fg-rest: var(--xh-radio-group-item-fg, var(--xh-fg-default));
|
|
88
|
+
--xh-action-fg-hover: var(--xh-radio-group-item-fg, var(--xh-fg-default));
|
|
89
|
+
--xh-action-fg-pressed: var(--xh-radio-group-item-fg, var(--xh-fg-default));
|
|
90
|
+
--xh-action-fg-focus-visible: var(--xh-radio-group-item-fg, var(--xh-fg-default));
|
|
91
|
+
--xh-action-fg-disabled: var(--xh-radio-group-item-fg-disabled, var(--xh-fg-disabled));
|
|
92
|
+
--xh-action-bg-hover: var(--xh-radio-group-item-bg-hover, var(--xh-bg-subtle));
|
|
93
|
+
--xh-action-bg-pressed: var(--xh-radio-group-item-bg-pressed, var(--xh-bg-subtle-hover));
|
|
94
|
+
--xh-action-host-bg-hover: var(--xh-_radio-group-host-bg-hover);
|
|
95
|
+
--xh-action-host-bg-pressed: var(--xh-_radio-group-host-bg-pressed);
|
|
71
96
|
|
|
97
|
+
position: relative;
|
|
98
|
+
/* row 档铺满容器(inline-size: 100%)会把竖排的命中区拉到整行空白处、横排 wrap 也塌:
|
|
99
|
+
沿用「条目按内容收宽」的既有决定,写法同 checkbox-group 条目 */
|
|
100
|
+
inline-size: auto;
|
|
101
|
+
/* ghost 的 1px 透明边位会把圆圈列相对组标题错开 1px:边归零,几何保持不变 */
|
|
102
|
+
border-width: 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* 只读整组都改不动,但不是禁用:颜色照常,把整行的悬停 / 按下面与"可点"这个暗示一起收回来。
|
|
106
|
+
家族的 :hover / 按压块不排 readonly,只能从槽上收回;排掉禁用项是因为这条选择器权重高过家族的禁用块,
|
|
107
|
+
不排就会把 not-allowed 覆盖回 default */
|
|
108
|
+
[data-scope='radio-group'][data-part='item'][data-readonly]:not([data-disabled]) {
|
|
109
|
+
--xh-action-bg-hover: transparent;
|
|
110
|
+
--xh-action-bg-pressed: transparent;
|
|
111
|
+
--xh-action-cursor-rest: default;
|
|
112
|
+
--xh-action-cursor-hover: default;
|
|
113
|
+
--xh-action-cursor-pressed: default;
|
|
114
|
+
--xh-action-cursor-focus-visible: default;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* 圆圈是字段家族的控制盒(§8.3 字段静息形态):透明底 + --xh-border-control 描边 + 无影。
|
|
118
|
+
不缩放(§9.2 行级只换面),过渡只有底与描边;按下走 press 时间线、释放同走 micro */
|
|
72
119
|
[data-scope='radio-group'][data-part='indicator'] {
|
|
73
120
|
display: inline-flex;
|
|
74
121
|
flex: none;
|
|
@@ -77,9 +124,30 @@
|
|
|
77
124
|
inline-size: var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator));
|
|
78
125
|
block-size: var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator));
|
|
79
126
|
border: var(--xh-stroke-thin) solid var(--xh-radio-group-indicator-border, var(--xh-border-control));
|
|
80
|
-
border-radius: var(--xh-radio-group-indicator-radius, var(--xh-shape-
|
|
81
|
-
background: var(--xh-radio-group-indicator-bg,
|
|
82
|
-
transition:
|
|
127
|
+
border-radius: var(--xh-radio-group-indicator-radius, var(--xh-shape-circle));
|
|
128
|
+
background: var(--xh-radio-group-indicator-bg, transparent);
|
|
129
|
+
transition:
|
|
130
|
+
border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
|
|
131
|
+
background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* 悬停整行时未选中的圆圈描边升一档(字段静息 → hover 的同一条阶梯,§8.3);
|
|
135
|
+
选中圈与校验失败的圈保住各自的描边——圈内的点 / 警示色本身已经在表达状态 */
|
|
136
|
+
[data-scope='radio-group'][data-part='item']:not([data-disabled]):not([data-readonly]):hover
|
|
137
|
+
> [data-scope='radio-group'][data-part='indicator']:not([data-state='checked']):not([data-invalid]) {
|
|
138
|
+
border-color: var(--xh-radio-group-indicator-border-hover, var(--xh-border-control-hover));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* 按下去要有回应。圆圈不是激活宿主:宿主是投影了 row 档的整行条目,圆圈在宿主的
|
|
142
|
+
:hover / :is(:active, [data-pressed]) 下读宿主 host 槽的同一来源换面、不缩放(§9.2)——行按下是 200,
|
|
143
|
+
坐在上面的圆圈到 300(行以 --xh-action-host-bg-pressed 声明自己是圆圈的承载面,桥接槽只写不读,
|
|
144
|
+
圆圈读的是喂给它的那支私有槽),描边不动、几何不动;
|
|
145
|
+
与家族按压块同一时间线(按下 --xh-motion-duration-press,释放同走 micro) */
|
|
146
|
+
[data-scope='radio-group'][data-part='item']:not([data-disabled]):not([data-readonly]):is(:active, [data-pressed])
|
|
147
|
+
> [data-scope='radio-group'][data-part='indicator'] {
|
|
148
|
+
background: var(--xh-radio-group-indicator-bg-pressed, var(--xh-_radio-group-host-bg-pressed));
|
|
149
|
+
transition-duration: var(--xh-motion-duration-press);
|
|
150
|
+
transition-timing-function: var(--xh-motion-ease-press);
|
|
83
151
|
}
|
|
84
152
|
|
|
85
153
|
[data-scope='radio-group'][data-part='indicator'][data-state='checked'] {
|
|
@@ -93,26 +161,53 @@
|
|
|
93
161
|
}
|
|
94
162
|
|
|
95
163
|
/* 圆点用 scale 收放,选中态切换不引起布局抖动。
|
|
96
|
-
|
|
164
|
+
直径取指示器的一半:换尺寸档时圈与点一起走,比例不散。
|
|
165
|
+
出现时略微涨过 1 再收回,过冲量落在圈内不碰描边 */
|
|
97
166
|
[data-scope='radio-group'][data-part='indicator']::before {
|
|
98
167
|
content: '';
|
|
99
168
|
inline-size: calc(var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator)) / 2);
|
|
100
169
|
block-size: calc(var(--xh-radio-group-indicator-size, var(--xh-_radio-group-indicator)) / 2);
|
|
101
|
-
border-radius: var(--xh-shape-
|
|
170
|
+
border-radius: var(--xh-shape-circle);
|
|
102
171
|
background: var(--xh-radio-group-indicator-dot, var(--xh-_radio-group-accent));
|
|
103
172
|
scale: 0;
|
|
104
|
-
transition: scale var(--xh-motion-duration-micro) var(--xh-motion-ease-
|
|
173
|
+
transition: scale var(--xh-motion-duration-micro) var(--xh-motion-ease-settle);
|
|
105
174
|
}
|
|
106
175
|
|
|
107
176
|
[data-scope='radio-group'][data-part='indicator'][data-state='checked']::before {
|
|
108
177
|
scale: 1;
|
|
109
178
|
}
|
|
110
179
|
|
|
180
|
+
/* 选中的圆点是这颗圈的「填色」:按下随行换到语气的 active 档(与 checkbox-group 勾中方框按下同档),
|
|
181
|
+
选中圈的描边保住不换 */
|
|
182
|
+
[data-scope='radio-group'][data-part='item']:not([data-disabled]):not([data-readonly]):is(:active, [data-pressed])
|
|
183
|
+
> [data-scope='radio-group'][data-part='indicator'][data-state='checked']::before {
|
|
184
|
+
background: var(--xh-radio-group-indicator-dot-pressed, var(--xh-_tone-active, var(--xh-bg-brand-active)));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* 禁用(§7.2):--xh-border-default 描边 + --xh-bg-subtle 底 + --xh-fg-disabled 圆点,不靠 opacity;
|
|
188
|
+
与 checkbox-group 方框、独立 checkbox 逐档一致。条目自己带 data-disabled(组禁用也逐条下放),圆圈读它 */
|
|
189
|
+
[data-scope='radio-group'][data-part='item'][data-disabled] > [data-scope='radio-group'][data-part='indicator'] {
|
|
190
|
+
border-color: var(--xh-radio-group-indicator-border-disabled, var(--xh-border-default));
|
|
191
|
+
background: var(--xh-radio-group-indicator-bg-disabled, var(--xh-bg-subtle));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
[data-scope='radio-group'][data-part='item'][data-disabled] > [data-scope='radio-group'][data-part='indicator']::before {
|
|
195
|
+
background: var(--xh-radio-group-indicator-dot-disabled, var(--xh-fg-disabled));
|
|
196
|
+
}
|
|
197
|
+
|
|
111
198
|
[data-scope='radio-group'][data-part='item-text'] {
|
|
112
199
|
color: inherit;
|
|
113
200
|
user-select: none;
|
|
114
201
|
}
|
|
115
202
|
|
|
203
|
+
/* 家族 row 档在粗指针下用 ::after 把热区扩到 44px 高:条目按 24px 行 + 8px 间距密排,热区会压进相邻条目、
|
|
204
|
+
指针落错行,A 档 24px 由 xs 地板保住(同 checkbox-group 条目) */
|
|
205
|
+
@media (pointer: coarse) {
|
|
206
|
+
[data-scope='radio-group'][data-part='item']::after {
|
|
207
|
+
min-block-size: 0;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
116
211
|
/* 声明过任何 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去。
|
|
117
212
|
写在文件末尾:兜底必须排在该部件所有 display 声明之后 */
|
|
118
213
|
[data-scope='radio-group'][data-part='root'][hidden],
|
|
@@ -120,4 +215,26 @@
|
|
|
120
215
|
[data-scope='radio-group'][data-part='indicator'][hidden] {
|
|
121
216
|
display: none;
|
|
122
217
|
}
|
|
218
|
+
|
|
219
|
+
@media (forced-colors: active) {
|
|
220
|
+
/* 按下:常态靠圆圈换底表出,这一档里底色被统一换成 Canvas;按住那一下把圈的描边换成系统高亮色 */
|
|
221
|
+
[data-scope='radio-group'][data-part='item']:not([data-disabled]):not([data-readonly]):is(:active, [data-pressed])
|
|
222
|
+
> [data-scope='radio-group'][data-part='indicator'] {
|
|
223
|
+
border-color: Highlight;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* 禁用的圆点跟随系统的置灰前景 */
|
|
227
|
+
[data-scope='radio-group'][data-part='item'][data-disabled]
|
|
228
|
+
> [data-scope='radio-group'][data-part='indicator'][data-state='checked']::before {
|
|
229
|
+
background: GrayText;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@media print {
|
|
234
|
+
/* 打印默认丢底色:选中那颗圆点是一块底,落到纸上整个消失,选中与没选中的圈一模一样。
|
|
235
|
+
圆点改画成一圈实边——边框印得出来,直径与圆心都不动(描边吃进盒里)。 */
|
|
236
|
+
[data-scope='radio-group'][data-part='indicator'][data-state='checked']::before {
|
|
237
|
+
border: var(--xh-stroke-thick) solid currentColor;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
123
240
|
}
|
package/css/rating.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
|
+
/* 定义 rating 样式。 */
|
|
7
|
+
|
|
8
|
+
@import '../family/action-control.css';
|
|
9
|
+
|
|
1
10
|
@layer xihan.components {
|
|
2
11
|
/* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
|
|
3
12
|
[data-scope='rating'] {
|
|
@@ -7,47 +16,45 @@
|
|
|
7
16
|
/* position 是给表单影子做定位基准的:那份输入被连接层内联写成绝对定位,
|
|
8
17
|
根上不留基准它就会贴到更外层的定位祖先上,原生校验提示跟着飘到页面别处。 */
|
|
9
18
|
[data-scope='rating'][data-part='root'] {
|
|
10
|
-
/*
|
|
19
|
+
/* 尺寸档只换这三个私有槽,星星与分值都从 root 继承它们,换档不必给每个部件各写一条选择器。
|
|
20
|
+
星是控件内的字形,按档取 --xh-glyph-size-sm / md / lg(§6.5);标签字号不随档 */
|
|
11
21
|
--xh-_rating-item-gap: var(--xh-control-gap-md);
|
|
12
|
-
--xh-_rating-item-size: var(--xh-
|
|
22
|
+
--xh-_rating-item-size: var(--xh-glyph-size-md);
|
|
23
|
+
--xh-_rating-item-box-size: var(--xh-control-action-size);
|
|
13
24
|
--xh-_rating-font-size: var(--xh-control-font-md);
|
|
25
|
+
--xh-icon-size: var(--xh-rating-item-font-size, var(--xh-_rating-item-size));
|
|
14
26
|
/* 点亮色随语气走。没写 data-tone 时 --xh-_tone 没被声明,退回原来的警示色 */
|
|
15
27
|
--xh-_rating-accent: var(--xh-_tone, var(--xh-color-warning-500));
|
|
16
28
|
|
|
17
29
|
position: relative;
|
|
18
30
|
display: inline-flex;
|
|
19
31
|
flex-direction: column;
|
|
20
|
-
|
|
32
|
+
/* 字段标签贴控件(§6.4 复合单字段) */
|
|
33
|
+
gap: var(--xh-rating-gap, var(--xh-space-1));
|
|
21
34
|
}
|
|
22
35
|
|
|
23
36
|
/* —— 尺寸 —— */
|
|
24
37
|
[data-scope='rating'][data-part='root'][data-size='sm'] {
|
|
25
38
|
--xh-_rating-item-gap: var(--xh-control-gap-sm);
|
|
26
|
-
--xh-_rating-item-size: var(--xh-
|
|
39
|
+
--xh-_rating-item-size: var(--xh-glyph-size-sm);
|
|
27
40
|
--xh-_rating-font-size: var(--xh-control-font-sm);
|
|
28
41
|
}
|
|
29
42
|
|
|
30
43
|
[data-scope='rating'][data-part='root'][data-size='lg'] {
|
|
31
44
|
--xh-_rating-item-gap: var(--xh-control-gap-lg);
|
|
32
|
-
--xh-_rating-item-size: var(--xh-
|
|
45
|
+
--xh-_rating-item-size: var(--xh-glyph-size-lg);
|
|
33
46
|
--xh-_rating-font-size: var(--xh-control-font-lg);
|
|
34
47
|
}
|
|
35
48
|
|
|
36
|
-
/*
|
|
37
|
-
[data-scope='rating'][data-part='root'][data-disabled] {
|
|
38
|
-
cursor: not-allowed;
|
|
39
|
-
opacity: var(--xh-state-disabled-opacity);
|
|
40
|
-
}
|
|
41
|
-
|
|
49
|
+
/* 字段标签:14 / 500 / fg-default(§6.4),禁用换到 --xh-fg-subtle;文字部件不叠 opacity */
|
|
42
50
|
[data-scope='rating'][data-part='label'] {
|
|
43
|
-
color: var(--xh-rating-label-fg, var(--xh-fg-
|
|
44
|
-
font-size: var(--xh-rating-label-font-size, var(--xh-
|
|
51
|
+
color: var(--xh-rating-label-fg, var(--xh-fg-default));
|
|
52
|
+
font-size: var(--xh-rating-label-font-size, var(--xh-text-label-size));
|
|
45
53
|
font-weight: var(--xh-rating-label-font-weight, var(--xh-text-label-weight));
|
|
46
|
-
line-height: var(--xh-leading-none);
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
[data-scope='rating'][data-part='label'][data-disabled] {
|
|
50
|
-
color: var(--xh-fg-subtle);
|
|
57
|
+
color: var(--xh-rating-label-fg-disabled, var(--xh-fg-subtle));
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
[data-scope='rating'][data-part='control'] {
|
|
@@ -56,46 +63,125 @@
|
|
|
56
63
|
gap: var(--xh-rating-item-gap, var(--xh-_rating-item-gap));
|
|
57
64
|
}
|
|
58
65
|
|
|
66
|
+
/* 禁用:星带是纯图形,整体压暗只做一次、落在星带上(星星逐颗再叠 opacity 会越叠越黑);
|
|
67
|
+
标签与分值是文字,各自换到禁用前景,不落在这层 opacity 之下 */
|
|
68
|
+
[data-scope='rating'][data-part='control'][data-disabled] {
|
|
69
|
+
opacity: var(--xh-state-disabled-opacity);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* 分值文本在场时根改成两列栅格:星星带与分值并排,标题仍独占一整行。
|
|
73
|
+
没写这个部件的评分不命中这条,还是原来的竖排 */
|
|
74
|
+
[data-scope='rating'][data-part='root']:has(> [data-part='value-text']) {
|
|
75
|
+
display: inline-grid;
|
|
76
|
+
grid-template-columns: auto auto;
|
|
77
|
+
align-items: center;
|
|
78
|
+
justify-content: start;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[data-scope='rating'][data-part='root']:has(> [data-part='value-text']) > [data-part='label'] {
|
|
82
|
+
grid-column: 1 / -1;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* 数字等宽:指针从一颗星划到另一颗时分值在原地变,不带着星星左右挪 */
|
|
86
|
+
[data-scope='rating'][data-part='value-text'] {
|
|
87
|
+
color: var(--xh-rating-value-text-fg, var(--xh-fg-muted));
|
|
88
|
+
font-size: var(--xh-rating-value-text-font-size, var(--xh-_rating-font-size));
|
|
89
|
+
font-variant-numeric: tabular-nums;
|
|
90
|
+
line-height: var(--xh-leading-none);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[data-scope='rating'][data-part='value-text'][data-disabled] {
|
|
94
|
+
color: var(--xh-rating-value-text-fg-disabled, var(--xh-fg-subtle));
|
|
95
|
+
}
|
|
96
|
+
|
|
59
97
|
/* 容器只是焦点域的兜底落点(焦点从带外进来先落在它身上,随即被转投给某颗星),
|
|
60
98
|
落焦不画环:高亮永远长在星星上,容器再画一圈只是重影。 */
|
|
61
99
|
[data-scope='rating'][data-part='control']:focus-visible {
|
|
62
100
|
outline: none;
|
|
63
101
|
}
|
|
64
102
|
|
|
65
|
-
[data-scope='rating'][data-part='control'][data-readonly] {
|
|
103
|
+
[data-scope='rating'][data-part='control'][data-readonly]:not([data-disabled]) {
|
|
66
104
|
cursor: default;
|
|
67
105
|
}
|
|
68
106
|
|
|
69
|
-
|
|
70
|
-
|
|
107
|
+
/* 条目固定成一枚方形图标盒:连接层用 clientWidth 判定指针落在左半还是右半,
|
|
108
|
+
固定盒能让半档分界与图形中心严格重合。
|
|
109
|
+
星接 Action Control icon 档(§9.1 定尺的星):盒型、按下 / 禁用面、0.97 缩放与换底、焦点环与过渡由家族配方给,
|
|
110
|
+
这里只把使用者槽映射到桥接槽。静息透明(ghost 形态);悬停不换底——悬停预览由点亮的星形(data-highlighted)
|
|
111
|
+
表达,再给盒换面是重复的通道;按下换到 200 档中性面(白底承载)。前景五态映射同一个值:点亮时五态一起换到
|
|
112
|
+
点亮色,家族的悬停 / 按下块才不会把点亮色换回静息色;禁用不换前景,星带整体的压暗落在 control 的 opacity 上 */
|
|
113
|
+
[data-scope='rating'][data-part='item'] {
|
|
114
|
+
--xh-_rating-item-bg-pressed: var(--xh-rating-item-bg-pressed, var(--xh-bg-subtle-hover));
|
|
115
|
+
|
|
116
|
+
--xh-action-visual-size: var(--xh-_rating-item-box-size);
|
|
117
|
+
--xh-action-min-inline-size: var(--xh-_rating-item-box-size);
|
|
118
|
+
--xh-action-radius: var(--xh-rating-item-radius, var(--xh-shape-control));
|
|
119
|
+
--xh-action-font-size: var(--xh-rating-item-font-size, var(--xh-_rating-item-size));
|
|
120
|
+
--xh-action-bg-hover: transparent;
|
|
121
|
+
--xh-action-bg-pressed: var(--xh-_rating-item-bg-pressed);
|
|
122
|
+
--xh-action-fg-rest: var(--xh-rating-item-fg, var(--xh-fg-subtle));
|
|
123
|
+
--xh-action-fg-hover: var(--xh-rating-item-fg, var(--xh-fg-subtle));
|
|
124
|
+
--xh-action-fg-pressed: var(--xh-rating-item-fg, var(--xh-fg-subtle));
|
|
125
|
+
--xh-action-fg-focus-visible: var(--xh-rating-item-fg, var(--xh-fg-subtle));
|
|
126
|
+
--xh-action-fg-disabled: var(--xh-rating-item-fg, var(--xh-fg-subtle));
|
|
127
|
+
--xh-action-border-rest: transparent;
|
|
128
|
+
--xh-action-border-hover: transparent;
|
|
129
|
+
--xh-action-border-pressed: transparent;
|
|
130
|
+
--xh-action-border-focus-visible: transparent;
|
|
131
|
+
--xh-action-border-disabled: transparent;
|
|
71
132
|
}
|
|
72
133
|
|
|
73
|
-
/*
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
134
|
+
/* 家族 icon 档在粗指针下用 ::after 扩热区到 44px:五颗星密排,44px 热区会压住相邻的星,
|
|
135
|
+
连接层又按 currentTarget 的宽度判半颗,热区串到邻星上半档就判错;星本身仍是 24px 盒,热区不外扩。
|
|
136
|
+
空条目的 ::after 是点亮那层星形,下限归零才不会被撑成 44px */
|
|
137
|
+
@media (pointer: coarse) {
|
|
138
|
+
[data-scope='rating'][data-part='item']::after {
|
|
139
|
+
min-inline-size: 0;
|
|
140
|
+
min-block-size: 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* 空条目使用两层同源星形:底层保持中性轮廓,上层按完整或半档裁出强调色。 */
|
|
145
|
+
[data-scope='rating'][data-part='item']:empty::before,
|
|
146
|
+
[data-scope='rating'][data-part='item']:empty::after {
|
|
147
|
+
content: '';
|
|
148
|
+
position: absolute;
|
|
149
|
+
inset-block-start: 50%;
|
|
150
|
+
inset-inline-start: 50%;
|
|
151
|
+
inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
152
|
+
block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
|
|
153
|
+
translate: -50% -50%;
|
|
154
|
+
background-color: var(--xh-rating-item-fg, var(--xh-fg-subtle));
|
|
155
|
+
-webkit-mask: var(--xh-glyph-mark-star) center / contain no-repeat;
|
|
156
|
+
mask: var(--xh-glyph-mark-star) center / contain no-repeat;
|
|
157
|
+
pointer-events: none;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[data-scope='rating'][data-part='item']:empty::after {
|
|
161
|
+
background-color: var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent));
|
|
162
|
+
clip-path: inset(0 100% 0 0);
|
|
163
|
+
transition: clip-path var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
|
|
86
164
|
}
|
|
87
165
|
|
|
88
166
|
/* 点亮的判据是 data-highlighted,不是 aria-checked:
|
|
89
167
|
aria-checked 只认落定的值,而悬停预览要求手划过去当场就亮。
|
|
90
168
|
两者共用同一档颜色,预览与选中因此看不出差别——这正是"预览"该有的样子。 */
|
|
91
169
|
[data-scope='rating'][data-part='item'][data-highlighted] {
|
|
92
|
-
|
|
170
|
+
--xh-action-fg-rest: var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent));
|
|
171
|
+
--xh-action-fg-hover: var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent));
|
|
172
|
+
--xh-action-fg-pressed: var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent));
|
|
173
|
+
--xh-action-fg-focus-visible: var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent));
|
|
174
|
+
--xh-action-fg-disabled: var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
[data-scope='rating'][data-part='item'][data-highlighted]:empty::after {
|
|
178
|
+
clip-path: inset(0);
|
|
93
179
|
}
|
|
94
180
|
|
|
95
181
|
/* 半颗:一道 50% 硬边渐变裁到字形上,左半亮右半灰。
|
|
96
182
|
必须排在 data-highlighted 之后:半颗那颗星同时带着 data-highlighted,两条选择器特异度相同,
|
|
97
183
|
顺序一反 color 就把 transparent 覆盖回实色,渐变整个看不见。 */
|
|
98
|
-
[data-scope='rating'][data-part='item'][data-half] {
|
|
184
|
+
[data-scope='rating'][data-part='item'][data-half]:not(:empty) {
|
|
99
185
|
background-image: linear-gradient(
|
|
100
186
|
to right,
|
|
101
187
|
var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent)) 50%,
|
|
@@ -108,7 +194,7 @@
|
|
|
108
194
|
|
|
109
195
|
/* rtl 下"半颗"落在星的右半边(连接层按 1 - offsetX/width 判),亮的那半得跟着掉头。
|
|
110
196
|
渐变方向没有逻辑关键字可用,只能靠 :dir() 分流,不能指望逻辑属性自动换向。 */
|
|
111
|
-
[data-scope='rating'][data-part='item'][data-half]:dir(rtl) {
|
|
197
|
+
[data-scope='rating'][data-part='item'][data-half]:not(:empty):dir(rtl) {
|
|
112
198
|
background-image: linear-gradient(
|
|
113
199
|
to left,
|
|
114
200
|
var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent)) 50%,
|
|
@@ -116,19 +202,23 @@
|
|
|
116
202
|
);
|
|
117
203
|
}
|
|
118
204
|
|
|
119
|
-
[data-scope='rating'][data-part='item']:
|
|
120
|
-
|
|
121
|
-
outline-offset: var(--xh-ring-offset);
|
|
205
|
+
[data-scope='rating'][data-part='item'][data-half]:empty::after {
|
|
206
|
+
clip-path: inset(0 50% 0 0);
|
|
122
207
|
}
|
|
123
208
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
cursor: default;
|
|
209
|
+
[data-scope='rating'][data-part='item'][data-half]:empty:dir(rtl)::after {
|
|
210
|
+
clip-path: inset(0 0 0 50%);
|
|
127
211
|
}
|
|
128
212
|
|
|
129
|
-
/*
|
|
130
|
-
|
|
131
|
-
|
|
213
|
+
/* 只读仍进得了 Tab 序列、读屏也念得出,只是改不动:收掉手型,别暗示"点这儿能改";
|
|
214
|
+
家族的按压块由这里的映射钉回静息面——按下不缩放、不换底 */
|
|
215
|
+
[data-scope='rating'][data-part='item'][data-readonly]:not([data-disabled]) {
|
|
216
|
+
--xh-_rating-item-bg-pressed: transparent;
|
|
217
|
+
--xh-action-scale-pressed: none;
|
|
218
|
+
--xh-action-cursor-rest: default;
|
|
219
|
+
--xh-action-cursor-hover: default;
|
|
220
|
+
--xh-action-cursor-pressed: default;
|
|
221
|
+
--xh-action-cursor-focus-visible: default;
|
|
132
222
|
}
|
|
133
223
|
|
|
134
224
|
/* 表单影子的视觉隐藏(绝对定位 + 1px + clip-path)连接层内联给全了,这里不重复也不覆盖,
|
|
@@ -143,4 +233,64 @@
|
|
|
143
233
|
[data-scope='rating'][data-part='item'][hidden] {
|
|
144
234
|
display: none;
|
|
145
235
|
}
|
|
236
|
+
|
|
237
|
+
/*
|
|
238
|
+
* 高对比档:点亮与没点亮只差一档字色,这一档里两档一起被换成同一个系统前景色,
|
|
239
|
+
* 整条星带看上去全是亮的。改用系统自己的两个角色分开:亮的取高亮色、没亮的取不可用色。
|
|
240
|
+
* 半颗那道裁到字形上的渐变在这一档里被丢弃,留着透明填充整颗星会消失,
|
|
241
|
+
* 把填充还回去并按点亮那一档画。
|
|
242
|
+
*/
|
|
243
|
+
@media (forced-colors: active) {
|
|
244
|
+
[data-scope='rating'][data-part='item'] {
|
|
245
|
+
color: GrayText;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
[data-scope='rating'][data-part='item']:empty::before {
|
|
249
|
+
background-color: GrayText;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
[data-scope='rating'][data-part='item']:empty::after {
|
|
253
|
+
background-color: Highlight;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
[data-scope='rating'][data-part='item'][data-highlighted],
|
|
257
|
+
[data-scope='rating'][data-part='item'][data-half]:not(:empty) {
|
|
258
|
+
background-image: none;
|
|
259
|
+
-webkit-background-clip: border-box;
|
|
260
|
+
background-clip: border-box;
|
|
261
|
+
color: Highlight;
|
|
262
|
+
/* 亮档已经由字色表出,公共层那圈锚点虚线在这里只是重影 */
|
|
263
|
+
outline: none;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* 家族在这一档把悬停 / 按下的盒填成 Highlight、字换 HighlightText:点亮的那层星形也是 Highlight,
|
|
267
|
+
填了盒就把它吞掉。盒保持 Canvas 底,字色仍按点亮与否取 GrayText / Highlight;
|
|
268
|
+
按住那一下给盒画一圈系统高亮环表出按下 */
|
|
269
|
+
[data-scope='rating'][data-part='item']:not([data-disabled]):not([data-loading]):hover,
|
|
270
|
+
[data-scope='rating'][data-part='item']:not([data-disabled]):not([data-loading]):is(:active, [data-pressed]) {
|
|
271
|
+
background-color: Canvas;
|
|
272
|
+
color: GrayText;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
[data-scope='rating'][data-part='item'][data-highlighted]:not([data-disabled]):not([data-loading]):hover,
|
|
276
|
+
[data-scope='rating'][data-part='item'][data-highlighted]:not([data-disabled]):not([data-loading]):is(:active, [data-pressed]) {
|
|
277
|
+
color: Highlight;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
[data-scope='rating'][data-part='item']:not([data-disabled]):not([data-readonly]):is(:active, [data-pressed]) {
|
|
281
|
+
outline: var(--xh-stroke-thick) solid Highlight;
|
|
282
|
+
outline-offset: calc(-1 * var(--xh-stroke-thick));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
@media print {
|
|
287
|
+
/* 打印默认丢底图:半颗那道裁到字形上的渐变整个消失,星上只剩 color: transparent,
|
|
288
|
+
那颗星在纸上什么都不剩。把填充还回去并按点亮那一档画整颗。 */
|
|
289
|
+
[data-scope='rating'][data-part='item'][data-half]:not(:empty) {
|
|
290
|
+
background-image: none;
|
|
291
|
+
-webkit-background-clip: border-box;
|
|
292
|
+
background-clip: border-box;
|
|
293
|
+
color: var(--xh-rating-item-fg-highlighted, var(--xh-_rating-accent));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
146
296
|
}
|