@q1travel/design-system 0.19.0 → 0.20.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/contracts/design.dark.md
CHANGED
|
@@ -450,7 +450,7 @@ These components ship in the package. Compose from this list before writing new
|
|
|
450
450
|
|
|
451
451
|
**Identity and media.** Avatar, AvatarGroup, Book, Browser, BrowserDots, BrowserControls, BrowserAddress, BrowserTabs, BrowserPlaceholder, Phone, Video, ThemeSwitcher, ProductLockup, Q1travelSymbol.
|
|
452
452
|
|
|
453
|
-
- ProductLockup combines a product icon, product name, and brand endorsement into one identity mark. The endorsement is smaller and uses secondary text color.
|
|
453
|
+
- ProductLockup combines a product icon, product name, and brand endorsement into one identity mark. The endorsement is smaller and uses secondary text color. Pass only the brand name through `brand`; the component renders "by" itself.
|
|
454
454
|
|
|
455
455
|
**Text utilities.** Code, CodeInline, CodeTokens, CodeBlock, Snippet, Kbd, MiddleTruncate, TextWithCopyButton.
|
|
456
456
|
|
package/contracts/design.md
CHANGED
|
@@ -450,7 +450,7 @@ These components ship in the package. Compose from this list before writing new
|
|
|
450
450
|
|
|
451
451
|
**Identity and media.** Avatar, AvatarGroup, Book, Browser, BrowserDots, BrowserControls, BrowserAddress, BrowserTabs, BrowserPlaceholder, Phone, Video, ThemeSwitcher, ProductLockup, Q1travelSymbol.
|
|
452
452
|
|
|
453
|
-
- ProductLockup combines a product icon, product name, and brand endorsement into one identity mark. The endorsement is smaller and uses secondary text color.
|
|
453
|
+
- ProductLockup combines a product icon, product name, and brand endorsement into one identity mark. The endorsement is smaller and uses secondary text color. Pass only the brand name through `brand`; the component renders "by" itself.
|
|
454
454
|
|
|
455
455
|
**Text utilities.** Code, CodeInline, CodeTokens, CodeBlock, Snippet, Kbd, MiddleTruncate, TextWithCopyButton.
|
|
456
456
|
|
|
@@ -118,6 +118,24 @@ Examples:
|
|
|
118
118
|
Shipped today for the `.form-control` skin: `--q1-input-bg`, `--q1-input-border`,
|
|
119
119
|
`--q1-input-fg`, `--q1-input-border-focus`, `--q1-input-focus-ring`.
|
|
120
120
|
|
|
121
|
+
Shipped for `Table` rows, defined in `tokens.css` for both themes:
|
|
122
|
+
|
|
123
|
+
| Token | Light | Dark | Derivation |
|
|
124
|
+
| --- | --- | --- | --- |
|
|
125
|
+
| `--q1-table-row-bg` | `#ffffff` | `#121212` | `var(--q1-color-bg-canvas)` |
|
|
126
|
+
| `--q1-table-row-bg-hover` | `#f6f6f6` | `#1f1f1f` | `--q1-color-bg-hover` flattened onto the canvas (text-primary at 4% light, 6% dark) |
|
|
127
|
+
| `--q1-table-row-bg-selected` | `#f1efff` | `#1f1e38` | `var(--q1-color-bg-selected)` |
|
|
128
|
+
| `--q1-table-row-bg-selected-hover` | `#edebfa` | `#25243d` | text-primary at half the hover strength (2% light, 3% dark) over the selected surface |
|
|
129
|
+
|
|
130
|
+
Every value is opaque. Table cells, not rows, carry the background and read it from the row, so a
|
|
131
|
+
sticky column always paints the same color as the rest of its row and never lets scrolled content
|
|
132
|
+
show through; row states swap the value instead of stacking a translucent layer. The half-strength
|
|
133
|
+
selected hover keeps `--q1-color-text-muted` at or above 4.5:1. `check-contrast-contract` recomputes
|
|
134
|
+
each derivation and checks the three text levels against all four values. Unlike the input tokens they
|
|
135
|
+
ship with values, because the pre-mixed colors exist nowhere else; `Table` still reads each one with
|
|
136
|
+
a fallback (`bg-canvas`, `bg-subtle`, `bg-selected`) so a stylesheet without them keeps an opaque
|
|
137
|
+
row. A table on a surface other than the canvas overrides all four on the table or its container.
|
|
138
|
+
|
|
121
139
|
Every component token MUST declare a fallback to the semantic token it replaces, so a
|
|
122
140
|
consumer that defines none of them sees no change. A component token without a fallback
|
|
123
141
|
turns an opt-in customisation surface into a required one: the first consumer to upgrade
|
|
@@ -1381,15 +1381,15 @@ export declare type PillProps = {
|
|
|
1381
1381
|
|
|
1382
1382
|
export declare type PopoverLayout = 'vertical' | 'horizontal';
|
|
1383
1383
|
|
|
1384
|
-
export declare function ProductLockup({ name, icon,
|
|
1384
|
+
export declare function ProductLockup({ name, icon, brand, size, className, 'aria-label': ariaLabel, ...rest }: ProductLockupProps): JSX.Element;
|
|
1385
1385
|
|
|
1386
1386
|
export declare type ProductLockupProps = {
|
|
1387
1387
|
/** 产品名称,以文字渲染,随主题承色。 */
|
|
1388
1388
|
name: string;
|
|
1389
1389
|
/** 产品图标,视为装饰,不参与朗读。默认为品牌符号。 */
|
|
1390
1390
|
icon?: ReactNode;
|
|
1391
|
-
/**
|
|
1392
|
-
|
|
1391
|
+
/** 背书品牌名,渲染为「by {brand}」。 */
|
|
1392
|
+
brand?: string;
|
|
1393
1393
|
size?: ProductLockupSize;
|
|
1394
1394
|
} & Omit<HTMLAttributes<HTMLSpanElement>, 'children' | 'role'>;
|
|
1395
1395
|
|
|
@@ -4664,24 +4664,25 @@ function hi(e) {
|
|
|
4664
4664
|
function Bs({
|
|
4665
4665
|
name: e,
|
|
4666
4666
|
icon: t,
|
|
4667
|
-
|
|
4667
|
+
brand: r = "奇异旅行",
|
|
4668
4668
|
size: o = "md",
|
|
4669
4669
|
className: i,
|
|
4670
4670
|
"aria-label": s,
|
|
4671
4671
|
...a
|
|
4672
4672
|
}) {
|
|
4673
|
+
const l = `by ${r}`;
|
|
4673
4674
|
return /* @__PURE__ */ w(
|
|
4674
4675
|
"span",
|
|
4675
4676
|
{
|
|
4676
4677
|
...a,
|
|
4677
4678
|
role: "img",
|
|
4678
|
-
"aria-label": s ?? `${e} ${
|
|
4679
|
+
"aria-label": s ?? `${e} ${l}`,
|
|
4679
4680
|
className: ie("q1-product-lockup", `q1-product-lockup--${o}`, i ?? ""),
|
|
4680
4681
|
children: [
|
|
4681
4682
|
/* @__PURE__ */ n("span", { className: "q1-product-lockup__icon", "aria-hidden": "true", children: t ?? /* @__PURE__ */ n(hi, {}) }),
|
|
4682
4683
|
/* @__PURE__ */ n("span", { className: "q1-product-lockup__name", children: e }),
|
|
4683
4684
|
/* @__PURE__ */ n(mi, { orientation: "vertical", className: "q1-product-lockup__divider" }),
|
|
4684
|
-
/* @__PURE__ */ n("span", { className: "q1-product-lockup__endorsement", children:
|
|
4685
|
+
/* @__PURE__ */ n("span", { className: "q1-product-lockup__endorsement", children: l })
|
|
4685
4686
|
]
|
|
4686
4687
|
}
|
|
4687
4688
|
);
|
package/dist-pkg/style.css
CHANGED
|
@@ -125,6 +125,15 @@
|
|
|
125
125
|
--q1-color-bg-overlay: var(--q1-color-background-100);
|
|
126
126
|
--q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 4%, transparent);
|
|
127
127
|
--q1-color-bg-selected: var(--q1-color-primary-100);
|
|
128
|
+
/* 表格行底色:单元格自带不透明底色,行状态只换取值,固定列与普通列同色、永不透出下层。
|
|
129
|
+
半透明的 bg-hover 不能直接用于固定列——叠在已有底色的行上会双层加深。以下取值为预混结果:
|
|
130
|
+
hover = bg-hover(text-primary 4%)叠在 bg-canvas 上;selected = bg-selected(本身不透明);
|
|
131
|
+
selected-hover = bg-hover 半强度(2%)叠在 bg-selected 上,整强度会把 text-muted 压到 AA 以下。
|
|
132
|
+
推导与对比度由 check-contrast-contract 锁定;改表面色或悬停强度须同步重算。 */
|
|
133
|
+
--q1-table-row-bg: var(--q1-color-bg-canvas);
|
|
134
|
+
--q1-table-row-bg-hover: #f6f6f6;
|
|
135
|
+
--q1-table-row-bg-selected: var(--q1-color-bg-selected);
|
|
136
|
+
--q1-table-row-bg-selected-hover: #edebfa;
|
|
128
137
|
--q1-color-bg-inverse: var(--q1-color-gray-1000);
|
|
129
138
|
--q1-color-text-on-inverse: var(--q1-color-background-100);
|
|
130
139
|
--q1-color-bg-media: #0a0a0a;
|
|
@@ -406,6 +415,9 @@
|
|
|
406
415
|
--q1-color-bg-overlay: var(--q1-color-gray-300);
|
|
407
416
|
--q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 6%, transparent);
|
|
408
417
|
--q1-color-bg-selected: #1f1e38;
|
|
418
|
+
/* 暗色预混:hover = text-primary 6% 叠在 bg-canvas 上;selected-hover 取半强度 3%。 */
|
|
419
|
+
--q1-table-row-bg-hover: #1f1f1f;
|
|
420
|
+
--q1-table-row-bg-selected-hover: #25243d;
|
|
409
421
|
--q1-color-bg-inverse: var(--q1-color-gray-1000);
|
|
410
422
|
--q1-color-text-on-inverse: #0a0a0a;
|
|
411
423
|
--q1-color-bg-media: #0a0a0a;
|
|
@@ -1909,6 +1921,21 @@
|
|
|
1909
1921
|
font-weight: var(--q1-font-weight-medium);
|
|
1910
1922
|
}
|
|
1911
1923
|
|
|
1924
|
+
/* 底色落在单元格上而不是行上:消费方把某列设为 position: sticky 时,它与同行其余单元格读同一个
|
|
1925
|
+
不透明值,横向滚动不透底,悬停也不会在行底色之上再叠一层。行状态只改 --table-cell-bg。 */
|
|
1926
|
+
.table tbody tr {
|
|
1927
|
+
--table-cell-bg: var(--q1-table-row-bg, var(--q1-color-bg-canvas));
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
.table tbody td,
|
|
1931
|
+
.table tbody th {
|
|
1932
|
+
background: var(--table-cell-bg);
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
.table tbody tr:has(.table__checkbox-control input:checked) {
|
|
1936
|
+
--table-cell-bg: var(--q1-table-row-bg-selected, var(--q1-color-bg-selected));
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1912
1939
|
.table__head--hidden {
|
|
1913
1940
|
position: absolute;
|
|
1914
1941
|
width: 1px;
|
|
@@ -1942,7 +1969,7 @@
|
|
|
1942
1969
|
position: sticky;
|
|
1943
1970
|
top: 0;
|
|
1944
1971
|
z-index: 1;
|
|
1945
|
-
background: var(--q1-color-bg-canvas);
|
|
1972
|
+
background: var(--q1-table-row-bg, var(--q1-color-bg-canvas));
|
|
1946
1973
|
}
|
|
1947
1974
|
|
|
1948
1975
|
.table__sort {
|
|
@@ -1994,8 +2021,35 @@
|
|
|
1994
2021
|
cursor: not-allowed;
|
|
1995
2022
|
}
|
|
1996
2023
|
|
|
2024
|
+
/* 焦点环画在单元格上:单元格自带不透明底色,行上的阴影或 outline 会被单元格底色、
|
|
2025
|
+
以及消费方的 sticky 列盖住。每格画上下两边,首末格补外侧一边,拼成整行的一圈。 */
|
|
1997
2026
|
.table tbody tr[tabindex='0']:focus-visible {
|
|
1998
2027
|
outline: none;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
.table tbody tr[tabindex='0']:focus-visible > * {
|
|
2031
|
+
--table-focus-edge: inset 0 2px 0 var(--q1-color-action-primary), inset 0 -2px 0 var(--q1-color-action-primary);
|
|
2032
|
+
box-shadow: var(--table-focus-edge);
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
.table tbody tr[tabindex='0']:focus-visible > :first-child {
|
|
2036
|
+
box-shadow: var(--table-focus-edge), inset 2px 0 0 var(--q1-color-action-primary);
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
.table tbody tr[tabindex='0']:focus-visible > :last-child {
|
|
2040
|
+
box-shadow: var(--table-focus-edge), inset -2px 0 0 var(--q1-color-action-primary);
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
.table tbody tr[tabindex='0']:focus-visible > :first-child:dir(rtl) {
|
|
2044
|
+
box-shadow: var(--table-focus-edge), inset -2px 0 0 var(--q1-color-action-primary);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
.table tbody tr[tabindex='0']:focus-visible > :last-child:dir(rtl) {
|
|
2048
|
+
box-shadow: var(--table-focus-edge), inset 2px 0 0 var(--q1-color-action-primary);
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
/* 整行只有一格(跨列的空态、加载行)时首末是同一格,四边都要画。 */
|
|
2052
|
+
.table tbody tr[tabindex='0']:focus-visible > :first-child:last-child {
|
|
1999
2053
|
box-shadow: inset 0 0 0 2px var(--q1-color-action-primary);
|
|
2000
2054
|
}
|
|
2001
2055
|
|
|
@@ -2005,12 +2059,26 @@
|
|
|
2005
2059
|
}
|
|
2006
2060
|
|
|
2007
2061
|
.table tbody tr.table__row--interactive:hover {
|
|
2008
|
-
|
|
2062
|
+
--table-cell-bg: var(--q1-table-row-bg-hover, var(--q1-color-bg-subtle));
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
.table tbody tr.table__row--interactive:hover:has(.table__checkbox-control input:checked) {
|
|
2066
|
+
--table-cell-bg: var(--q1-table-row-bg-selected-hover, var(--q1-color-bg-selected));
|
|
2009
2067
|
}
|
|
2010
2068
|
}
|
|
2011
2069
|
|
|
2070
|
+
/* 按压在悬停值上再加深:两个输入都不透明,混出来的仍不透明。选中行另起一支,否则选中规则的
|
|
2071
|
+
特异度更高,按压没有反馈。 */
|
|
2012
2072
|
.table tbody tr.table__row--interactive:active {
|
|
2013
|
-
|
|
2073
|
+
--table-cell-bg: color-mix(in srgb, var(--q1-table-row-bg-hover, var(--q1-color-bg-subtle)), var(--q1-color-text-primary) 8%);
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
.table tbody tr.table__row--interactive:active:has(.table__checkbox-control input:checked) {
|
|
2077
|
+
--table-cell-bg: color-mix(
|
|
2078
|
+
in srgb,
|
|
2079
|
+
var(--q1-table-row-bg-selected-hover, var(--q1-color-bg-selected)),
|
|
2080
|
+
var(--q1-color-text-primary) 8%
|
|
2081
|
+
);
|
|
2014
2082
|
}
|
|
2015
2083
|
|
|
2016
2084
|
.table th[aria-sort='ascending'] .table__sort,
|
package/dist-pkg/tokens.css
CHANGED
|
@@ -121,6 +121,10 @@
|
|
|
121
121
|
--q1-color-bg-overlay: var(--q1-color-background-100);
|
|
122
122
|
--q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 4%, transparent);
|
|
123
123
|
--q1-color-bg-selected: var(--q1-color-primary-100);
|
|
124
|
+
--q1-table-row-bg: var(--q1-color-bg-canvas);
|
|
125
|
+
--q1-table-row-bg-hover: #f6f6f6;
|
|
126
|
+
--q1-table-row-bg-selected: var(--q1-color-bg-selected);
|
|
127
|
+
--q1-table-row-bg-selected-hover: #edebfa;
|
|
124
128
|
--q1-color-bg-inverse: var(--q1-color-gray-1000);
|
|
125
129
|
--q1-color-text-on-inverse: var(--q1-color-background-100);
|
|
126
130
|
--q1-color-bg-media: #0a0a0a;
|
|
@@ -389,6 +393,10 @@
|
|
|
389
393
|
--q1-color-bg-overlay: var(--q1-color-gray-300);
|
|
390
394
|
--q1-color-bg-hover: color-mix(in srgb, var(--q1-color-text-primary) 6%, transparent);
|
|
391
395
|
--q1-color-bg-selected: #1f1e38;
|
|
396
|
+
--q1-table-row-bg: var(--q1-color-bg-canvas);
|
|
397
|
+
--q1-table-row-bg-hover: #1f1f1f;
|
|
398
|
+
--q1-table-row-bg-selected: var(--q1-color-bg-selected);
|
|
399
|
+
--q1-table-row-bg-selected-hover: #25243d;
|
|
392
400
|
--q1-color-bg-inverse: var(--q1-color-gray-1000);
|
|
393
401
|
--q1-color-text-on-inverse: #0a0a0a;
|
|
394
402
|
--q1-color-bg-media: #0a0a0a;
|