@q1travel/design-system 0.17.0 → 0.17.1
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/contracts/design.dark.md +7 -0
- package/contracts/design.md +7 -0
- package/contracts/overlay-shadow-migration.md +2 -2
- package/contracts/table-migration.md +5 -1
- package/contracts/token-naming.md +3 -1
- package/dist-pkg/design-system.d.ts +2 -0
- package/dist-pkg/design-system.js +10 -7
- package/dist-pkg/style.css +17 -2
- package/dist-pkg/tokens.css +16 -2
- package/package.json +1 -1
package/contracts/design.dark.md
CHANGED
|
@@ -128,15 +128,22 @@ semantic-colors:
|
|
|
128
128
|
text-on-media: "#ffffff"
|
|
129
129
|
border: "{colors.gray-200}"
|
|
130
130
|
border-strong: "{colors.gray-400}"
|
|
131
|
+
border-subtle: "#1f1f1f"
|
|
131
132
|
text-primary: "{colors.text-primary}"
|
|
132
133
|
text-secondary: "{colors.text-secondary}"
|
|
133
134
|
text-muted: "{colors.text-muted}"
|
|
135
|
+
text-soft: "#9a9a9c"
|
|
136
|
+
overlay-scrim: "rgba(2, 6, 23, 0.44)"
|
|
134
137
|
selection-background: "{colors.text-primary}"
|
|
135
138
|
selection-foreground: "{colors.background-100}"
|
|
136
139
|
focus-ring: "{colors.primary}"
|
|
140
|
+
focus: "{colors.primary-700}"
|
|
137
141
|
status-success: "{colors.green-900}"
|
|
138
142
|
status-warning: "{colors.amber-700}"
|
|
139
143
|
status-danger: "{colors.red-900}"
|
|
144
|
+
status-danger-text: "#ef5350"
|
|
145
|
+
status-danger-surface: "{colors.red-100}"
|
|
146
|
+
status-danger-border: "#ef5350"
|
|
140
147
|
typography:
|
|
141
148
|
heading-72:
|
|
142
149
|
fontFamily: Noto Sans SC
|
package/contracts/design.md
CHANGED
|
@@ -128,15 +128,22 @@ semantic-colors:
|
|
|
128
128
|
text-on-media: "#ffffff"
|
|
129
129
|
border: "{colors.gray-400}"
|
|
130
130
|
border-strong: "{colors.gray-500}"
|
|
131
|
+
border-subtle: "rgba(203, 213, 225, 0.82)"
|
|
131
132
|
text-primary: "{colors.text-primary}"
|
|
132
133
|
text-secondary: "{colors.text-secondary}"
|
|
133
134
|
text-muted: "{colors.text-muted}"
|
|
135
|
+
text-soft: "#6e6e73"
|
|
136
|
+
overlay-scrim: "rgba(2, 6, 23, 0.44)"
|
|
134
137
|
selection-background: "{colors.text-primary}"
|
|
135
138
|
selection-foreground: "{colors.background-100}"
|
|
136
139
|
focus-ring: "{colors.primary}"
|
|
140
|
+
focus: "{colors.primary-700}"
|
|
137
141
|
status-success: "{colors.green-700}"
|
|
138
142
|
status-warning: "{colors.amber-900}"
|
|
139
143
|
status-danger: "{colors.red-700}"
|
|
144
|
+
status-danger-text: "#d32f2f"
|
|
145
|
+
status-danger-surface: "{colors.red-100}"
|
|
146
|
+
status-danger-border: "#d32f2f"
|
|
140
147
|
typography:
|
|
141
148
|
heading-72:
|
|
142
149
|
fontFamily: Noto Sans SC
|
|
@@ -27,7 +27,7 @@ Decision date: 2026-08-26
|
|
|
27
27
|
|
|
28
28
|
**为什么环境层要降不透明度**:新增的接触层已经补上了元件根部的密度。若环境层沿用原不透明度,两层叠加后整体偏重,浮层看起来像是"脏"了而不是"浮起来"。popover 16%→14%、modal 32%→28% 是为抵消这部分叠加。
|
|
29
29
|
|
|
30
|
-
`--q1-shadow-focus`
|
|
30
|
+
`--q1-shadow-focus` 不在本次浮层阴影迁移范围内:焦点环是独立语义,不参与光照模型。其后续双层对比环见 `contracts/token-naming.md`。
|
|
31
31
|
|
|
32
32
|
方向性面板(Drawer / Sheet)的阴影在组件内自持,不消费这两个 token,因此不受影响。
|
|
33
33
|
|
|
@@ -78,5 +78,5 @@ q1travel-web 当前停留在 0.7.3,与本仓 0.9.0 之间还隔着其他变更
|
|
|
78
78
|
|
|
79
79
|
- 不修改 q1travel-web,不代下游提交。
|
|
80
80
|
- 不新增第三档阴影,不为 Drawer / Sheet 引入共享阴影 token。
|
|
81
|
-
-
|
|
81
|
+
- 本次浮层阴影迁移不改动 `--q1-shadow-focus`;后续焦点环调整独立进行。
|
|
82
82
|
- 不在本合同内处理 `contracts/interface-guidelines.md` Design 章节的其余条款(嵌套圆角见 #141,色相一致见 #142)。
|
|
@@ -95,7 +95,11 @@ requires each capability.
|
|
|
95
95
|
receives the sort-change event, and owns data ordering or server requests.
|
|
96
96
|
- A sortable heading is a native button inside the heading cell. The heading
|
|
97
97
|
exposes `aria-sort` with the applicable `none`, `ascending`, or `descending`
|
|
98
|
-
value
|
|
98
|
+
value for the current state. Its button name describes the direction after
|
|
99
|
+
activation. A column may provide `nextSortDirection` when the consumer's
|
|
100
|
+
sorting policy differs from the default ascending-first toggle; that same
|
|
101
|
+
direction is sent to `onSortChange`. The sort icon is decorative and is not
|
|
102
|
+
the only state cue.
|
|
99
103
|
- Table does not silently sort data, fetch a new page, mutate URL/query state,
|
|
100
104
|
or fabricate a total while sorting.
|
|
101
105
|
|
|
@@ -94,7 +94,9 @@ Examples:
|
|
|
94
94
|
- `--q1-shadow-focus`
|
|
95
95
|
- `--q1-shadow-focus-danger`
|
|
96
96
|
|
|
97
|
-
`--q1-
|
|
97
|
+
`--q1-color-status-danger` is the bright red for fills and strokes only; use `--q1-color-status-danger-text` for text and weak notices without an underline. `--q1-color-status-danger-surface` and `--q1-color-status-danger-border` keep the background and stroke roles separate. `--q1-color-text-soft`, `--q1-color-border-subtle`, and `--q1-color-overlay-scrim` cover tertiary text, quiet separators, and overlay scrims.
|
|
98
|
+
|
|
99
|
+
`--q1-color-focus` resolves to `--q1-color-primary-700`. `--q1-shadow-focus` draws a 1px canvas contrast ring and a 3px focus color ring, keeping keyboard focus visible against a purple control or dark surface. `--q1-shadow-focus-danger` remains the field family's invalid-control ring and does not change with this focus-ring migration.
|
|
98
100
|
|
|
99
101
|
### Component Tokens
|
|
100
102
|
|
|
@@ -1781,6 +1781,8 @@ export declare type TableColumn<T> = {
|
|
|
1781
1781
|
render: (row: T, rowIndex: number) => ReactNode;
|
|
1782
1782
|
sortable?: boolean;
|
|
1783
1783
|
sortLabel?: string;
|
|
1784
|
+
/** 下次点击此列时的排序方向;未提供时沿用默认的升序优先切换。 */
|
|
1785
|
+
nextSortDirection?: TableSortDirection;
|
|
1784
1786
|
/**
|
|
1785
1787
|
* 横向对齐,默认 `start`。数值列用 `end`——个位对齐个位,一眼可比大小与位数;
|
|
1786
1788
|
* 左对齐的数字列要逐行数位数才知道谁大。表头随单元格一起对齐,否则列会读成两栏。
|
|
@@ -3447,8 +3447,11 @@ function Is({
|
|
|
3447
3447
|
}, []);
|
|
3448
3448
|
Z(() => {
|
|
3449
3449
|
const R = D.current !== r;
|
|
3450
|
-
D.current = r, k((j) =>
|
|
3451
|
-
|
|
3450
|
+
D.current = r, k((j) => {
|
|
3451
|
+
if (e)
|
|
3452
|
+
return R ? r.trim() ? x[0]?.key : void 0 : x.some((G) => G.key === j) ? j : r.trim() ? x[0]?.key : void 0;
|
|
3453
|
+
});
|
|
3454
|
+
}, [x, e, r]), Z(() => {
|
|
3452
3455
|
if (!e || !I) return;
|
|
3453
3456
|
p.current?.querySelector('[data-search-dialog-active="true"]')?.scrollIntoView({ block: "nearest" });
|
|
3454
3457
|
}, [e, I]), Z(() => {
|
|
@@ -8106,10 +8109,10 @@ function bc({
|
|
|
8106
8109
|
!E || Wn(A.target, A.currentTarget) || A.key !== "Enter" && A.key !== " " || (A.preventDefault(), E.onActivate(T.row, T.rowIndex));
|
|
8107
8110
|
}
|
|
8108
8111
|
function j(T) {
|
|
8109
|
-
return f === T && _ === "asc" ? "desc" : "asc";
|
|
8112
|
+
return T.nextSortDirection ?? (f === T.key && _ === "asc" ? "desc" : "asc");
|
|
8110
8113
|
}
|
|
8111
8114
|
function G(T) {
|
|
8112
|
-
N && N(T, j(T));
|
|
8115
|
+
N && N(T.key, j(T));
|
|
8113
8116
|
}
|
|
8114
8117
|
function ee(T) {
|
|
8115
8118
|
if (T.sortable)
|
|
@@ -8134,14 +8137,14 @@ function bc({
|
|
|
8134
8137
|
}
|
|
8135
8138
|
) }) }) : null,
|
|
8136
8139
|
t.map((T) => {
|
|
8137
|
-
const A = ee(T), Y = T.sortable && f === T.key && _ ? _ === "asc" ? "升序" : "降序" : null, J = j(T
|
|
8140
|
+
const A = ee(T), Y = T.sortable && f === T.key && _ ? _ === "asc" ? "升序" : "降序" : null, J = j(T) === "asc" ? "升序" : "降序", te = Y ? /* @__PURE__ */ n("span", { className: "table__sort-state", children: Y }) : null, B = T.sortLabel ?? (typeof T.header == "string" ? T.header : T.key), H = T.sortable ? /* @__PURE__ */ w(
|
|
8138
8141
|
"button",
|
|
8139
8142
|
{
|
|
8140
8143
|
type: "button",
|
|
8141
8144
|
className: "table__sort",
|
|
8142
|
-
"aria-label":
|
|
8145
|
+
"aria-label": `点击后将按${B}${J}排序`,
|
|
8143
8146
|
disabled: !N,
|
|
8144
|
-
onClick: N ? () => G(T
|
|
8147
|
+
onClick: N ? () => G(T) : void 0,
|
|
8145
8148
|
children: [
|
|
8146
8149
|
T.header,
|
|
8147
8150
|
te
|
package/dist-pkg/style.css
CHANGED
|
@@ -122,15 +122,23 @@
|
|
|
122
122
|
--q1-color-bg-media: #0a0a0a;
|
|
123
123
|
--q1-color-text-on-media: #ffffff;
|
|
124
124
|
--q1-color-border: var(--q1-color-gray-400);
|
|
125
|
+
--q1-color-border-subtle: rgba(203, 213, 225, 0.82);
|
|
125
126
|
--q1-color-border-strong: var(--q1-color-gray-500);
|
|
126
127
|
--q1-color-text-primary: var(--q1-color-gray-1000);
|
|
127
128
|
--q1-color-text-secondary: var(--q1-color-gray-900);
|
|
128
129
|
--q1-color-text-muted: #6b6b6b;
|
|
130
|
+
--q1-color-text-soft: #6e6e73;
|
|
131
|
+
--q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
|
|
132
|
+
--q1-color-focus: var(--q1-color-primary-700);
|
|
129
133
|
--q1-color-selection-bg: var(--q1-color-text-primary);
|
|
130
134
|
--q1-color-selection-fg: var(--q1-color-bg-canvas);
|
|
131
135
|
--q1-color-status-success: var(--q1-color-green-700);
|
|
132
136
|
--q1-color-status-warning: var(--q1-color-amber-900);
|
|
133
137
|
--q1-color-status-danger: var(--q1-color-red-700);
|
|
138
|
+
/* status-danger 是亮红,只用于填充和描边;文字或无下划线弱提示使用 danger-text。 */
|
|
139
|
+
--q1-color-status-danger-text: #d32f2f;
|
|
140
|
+
--q1-color-status-danger-surface: var(--q1-color-red-100);
|
|
141
|
+
--q1-color-status-danger-border: #d32f2f;
|
|
134
142
|
--q1-color-status-info: var(--q1-color-blue-700);
|
|
135
143
|
--q1-font-sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
|
|
136
144
|
--q1-font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
|
|
@@ -232,7 +240,7 @@
|
|
|
232
240
|
--q1-radius-5: 16px;
|
|
233
241
|
/* 胶囊:半径大于任何可能的半高即可,具体数值不参与计算。 */
|
|
234
242
|
--q1-radius-full: 9999px;
|
|
235
|
-
--q1-shadow-focus: 0 0 0
|
|
243
|
+
--q1-shadow-focus: 0 0 0 1px var(--q1-color-bg-canvas), 0 0 0 3px var(--q1-color-focus);
|
|
236
244
|
/* 危险态环:字段家族错误态与危险动作共用。比默认焦点环宽一档、淡一档——红色本身已经足够响,
|
|
237
245
|
同样浓度会盖过 1px 红描边。取值沿用字段错误态的既有标定,status-danger 明暗各有取值。 */
|
|
238
246
|
--q1-shadow-focus-danger: 0 0 0 4px color-mix(in srgb, var(--q1-color-status-danger) 16%, transparent);
|
|
@@ -374,15 +382,22 @@
|
|
|
374
382
|
--q1-color-bg-media: #0a0a0a;
|
|
375
383
|
--q1-color-text-on-media: #ffffff;
|
|
376
384
|
--q1-color-border: var(--q1-color-gray-200);
|
|
385
|
+
--q1-color-border-subtle: #1f1f1f;
|
|
377
386
|
/* 降档:控件描边不再泛白。 */
|
|
378
387
|
--q1-color-border-strong: var(--q1-color-gray-400);
|
|
379
388
|
--q1-color-border-overlay: color-mix(in srgb, #ffffff 14%, transparent);
|
|
380
389
|
--q1-color-text-primary: var(--q1-color-gray-1000);
|
|
381
390
|
--q1-color-text-secondary: var(--q1-color-gray-900);
|
|
382
391
|
--q1-color-text-muted: var(--q1-color-gray-700);
|
|
392
|
+
--q1-color-text-soft: #9a9a9c;
|
|
393
|
+
--q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
|
|
394
|
+
--q1-color-focus: var(--q1-color-primary-700);
|
|
383
395
|
--q1-color-status-success: var(--q1-color-green-900);
|
|
384
396
|
--q1-color-status-warning: var(--q1-color-amber-700);
|
|
385
397
|
--q1-color-status-danger: var(--q1-color-red-900);
|
|
398
|
+
--q1-color-status-danger-text: #ef5350;
|
|
399
|
+
--q1-color-status-danger-surface: var(--q1-color-red-100);
|
|
400
|
+
--q1-color-status-danger-border: #ef5350;
|
|
386
401
|
--q1-color-status-info: var(--q1-color-blue-900);
|
|
387
402
|
/* Override only the press state: the dark Primary ramp runs left-dark to
|
|
388
403
|
right-light, so Primary-900 is a light tint. Point action-press at a darker
|
|
@@ -6399,7 +6414,7 @@ a.q1-card:focus-visible {
|
|
|
6399
6414
|
}
|
|
6400
6415
|
.collapse__trigger:focus-visible {
|
|
6401
6416
|
outline: none;
|
|
6402
|
-
box-shadow: inset var(--q1-
|
|
6417
|
+
box-shadow: inset 0 0 0 1px var(--q1-color-bg-canvas), inset 0 0 0 3px var(--q1-color-focus);
|
|
6403
6418
|
}
|
|
6404
6419
|
.collapse__title {
|
|
6405
6420
|
font-size: 14px;
|
package/dist-pkg/tokens.css
CHANGED
|
@@ -118,15 +118,22 @@
|
|
|
118
118
|
--q1-color-bg-media: #0a0a0a;
|
|
119
119
|
--q1-color-text-on-media: #ffffff;
|
|
120
120
|
--q1-color-border: var(--q1-color-gray-400);
|
|
121
|
+
--q1-color-border-subtle: rgba(203, 213, 225, 0.82);
|
|
121
122
|
--q1-color-border-strong: var(--q1-color-gray-500);
|
|
122
123
|
--q1-color-text-primary: var(--q1-color-gray-1000);
|
|
123
124
|
--q1-color-text-secondary: var(--q1-color-gray-900);
|
|
124
125
|
--q1-color-text-muted: #6b6b6b;
|
|
126
|
+
--q1-color-text-soft: #6e6e73;
|
|
127
|
+
--q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
|
|
128
|
+
--q1-color-focus: var(--q1-color-primary-700);
|
|
125
129
|
--q1-color-selection-bg: var(--q1-color-text-primary);
|
|
126
130
|
--q1-color-selection-fg: var(--q1-color-bg-canvas);
|
|
127
131
|
--q1-color-status-success: var(--q1-color-green-700);
|
|
128
132
|
--q1-color-status-warning: var(--q1-color-amber-900);
|
|
129
133
|
--q1-color-status-danger: var(--q1-color-red-700);
|
|
134
|
+
--q1-color-status-danger-text: #d32f2f;
|
|
135
|
+
--q1-color-status-danger-surface: var(--q1-color-red-100);
|
|
136
|
+
--q1-color-status-danger-border: #d32f2f;
|
|
130
137
|
--q1-color-status-info: var(--q1-color-blue-700);
|
|
131
138
|
--q1-font-sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
|
|
132
139
|
--q1-font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
|
|
@@ -220,7 +227,7 @@
|
|
|
220
227
|
--q1-radius-4: 12px;
|
|
221
228
|
--q1-radius-5: 16px;
|
|
222
229
|
--q1-radius-full: 9999px;
|
|
223
|
-
--q1-shadow-focus: 0 0 0
|
|
230
|
+
--q1-shadow-focus: 0 0 0 1px var(--q1-color-bg-canvas), 0 0 0 3px var(--q1-color-focus);
|
|
224
231
|
--q1-shadow-focus-danger: 0 0 0 4px color-mix(in srgb, var(--q1-color-status-danger) 16%, transparent);
|
|
225
232
|
--q1-shadow-popover: 0 1px 3px color-mix(in srgb, var(--q1-color-shadow) 10%, transparent),
|
|
226
233
|
0 8px 28px color-mix(in srgb, var(--q1-color-shadow) 14%, transparent);
|
|
@@ -358,15 +365,22 @@
|
|
|
358
365
|
--q1-color-bg-media: #0a0a0a;
|
|
359
366
|
--q1-color-text-on-media: #ffffff;
|
|
360
367
|
--q1-color-border: var(--q1-color-gray-200);
|
|
368
|
+
--q1-color-border-subtle: #1f1f1f;
|
|
361
369
|
--q1-color-border-strong: var(--q1-color-gray-400);
|
|
362
370
|
--q1-color-text-primary: var(--q1-color-gray-1000);
|
|
363
371
|
--q1-color-text-secondary: var(--q1-color-gray-900);
|
|
364
372
|
--q1-color-text-muted: var(--q1-color-gray-700);
|
|
373
|
+
--q1-color-text-soft: #9a9a9c;
|
|
374
|
+
--q1-color-overlay-scrim: rgba(2, 6, 23, 0.44);
|
|
375
|
+
--q1-color-focus: var(--q1-color-primary-700);
|
|
365
376
|
--q1-color-selection-bg: var(--q1-color-text-primary);
|
|
366
377
|
--q1-color-selection-fg: var(--q1-color-bg-canvas);
|
|
367
378
|
--q1-color-status-success: var(--q1-color-green-900);
|
|
368
379
|
--q1-color-status-warning: var(--q1-color-amber-700);
|
|
369
380
|
--q1-color-status-danger: var(--q1-color-red-900);
|
|
381
|
+
--q1-color-status-danger-text: #ef5350;
|
|
382
|
+
--q1-color-status-danger-surface: var(--q1-color-red-100);
|
|
383
|
+
--q1-color-status-danger-border: #ef5350;
|
|
370
384
|
--q1-color-status-info: var(--q1-color-blue-900);
|
|
371
385
|
--q1-font-sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
|
|
372
386
|
--q1-font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
|
|
@@ -460,7 +474,7 @@
|
|
|
460
474
|
--q1-radius-4: 12px;
|
|
461
475
|
--q1-radius-5: 16px;
|
|
462
476
|
--q1-radius-full: 9999px;
|
|
463
|
-
--q1-shadow-focus: 0 0 0
|
|
477
|
+
--q1-shadow-focus: 0 0 0 1px var(--q1-color-bg-canvas), 0 0 0 3px var(--q1-color-focus);
|
|
464
478
|
--q1-shadow-focus-danger: 0 0 0 4px color-mix(in srgb, var(--q1-color-status-danger) 16%, transparent);
|
|
465
479
|
--q1-shadow-popover: 0 1px 3px color-mix(in srgb, var(--q1-color-shadow) 10%, transparent),
|
|
466
480
|
0 8px 28px color-mix(in srgb, var(--q1-color-shadow) 14%, transparent);
|