@q1travel/design-system 0.16.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/README.md CHANGED
@@ -12,7 +12,7 @@ q1travel 产品家族的设计权威上游仓,三件事集于一处:`@q1trav
12
12
  - Generated mirrors(生成镜像,勿手改):`public/design.md`、`public/design.dark.md` 由 `scripts/sync-design-contracts.mjs` 从契约源逐字节复制;`public/design.css` 由 `scripts/build-design-css.mjs` 把两份契约 frontmatter 的取值注入 `contracts/design.css` 的类词汇后生成,因而自足、可被独立 HTML 页面直接加载。
13
13
  - Runtime tokens:`src/styles/tokens.css`(canonical `--q1-*`,仅 `:root` 与 `:root[data-theme='dark']` 两个扁平 selector)。
14
14
  - 发布台账:`contracts/releases/`(仅存于仓库,不进 npm 包)。
15
- - npm 发布与下游自动更新:[发布操作说明](docs/npm-release.md)。
15
+ - npm 发布与下游自动更新:版本 tag 触发 GitHub Actions OIDC 免令牌发布,详见[发布操作说明](docs/npm-release.md)。
16
16
 
17
17
  ## Getting Started
18
18
 
@@ -35,6 +35,9 @@ npm run dev
35
35
  | `npm run check:browser` | 基于 CDP 的浏览器行为契约(含 StrictMode 前置轮) |
36
36
  | `npm run check:package-api` | 已构建包的声明与运行时 API + 组件契约 `node --test` 套件 |
37
37
  | `npm run check:release-provenance` | 发布台账 vs `CHANGELOG.md`、origin tag 与 npm registry |
38
+ | `npm run check:release-sync` | 发布后 registry 完整性与四仓 Renovate 通知脚本测试 |
39
+ | `npm run release:verify -- <tarball>` | 只校验 workflow tarball 与 npm registry 完整性 |
40
+ | `npm run release:sync -- <tarball>` | 校验 registry 后通知四仓 Renovate;不具备发布能力 |
38
41
  | `npm run build:pkg` | 库构建(产物 `dist-pkg/`)+ CSS 拼装 + 包 API 检查(`prepack` 同款) |
39
42
 
40
43
  本仓没有独立的 test / lint script——规范由 `scripts/` 下的契约门禁脚本守护。
@@ -120,20 +120,30 @@ semantic-colors:
120
120
  action-primary-hover: "{colors.primary-hover}"
121
121
  action-primary-press: "{colors.primary-press}"
122
122
  action-on-primary: "#ffffff"
123
+ action-text: "{colors.primary-900}"
123
124
  surface-canvas: "{colors.background-100}"
124
125
  surface-subtle: "{colors.gray-100}"
125
126
  surface-panel: "{colors.background-100}"
127
+ surface-media: "#0a0a0a"
128
+ text-on-media: "#ffffff"
126
129
  border: "{colors.gray-200}"
127
130
  border-strong: "{colors.gray-400}"
131
+ border-subtle: "#1f1f1f"
128
132
  text-primary: "{colors.text-primary}"
129
133
  text-secondary: "{colors.text-secondary}"
130
134
  text-muted: "{colors.text-muted}"
135
+ text-soft: "#9a9a9c"
136
+ overlay-scrim: "rgba(2, 6, 23, 0.44)"
131
137
  selection-background: "{colors.text-primary}"
132
138
  selection-foreground: "{colors.background-100}"
133
139
  focus-ring: "{colors.primary}"
140
+ focus: "{colors.primary-700}"
134
141
  status-success: "{colors.green-900}"
135
142
  status-warning: "{colors.amber-700}"
136
143
  status-danger: "{colors.red-900}"
144
+ status-danger-text: "#ef5350"
145
+ status-danger-surface: "{colors.red-100}"
146
+ status-danger-border: "#ef5350"
137
147
  typography:
138
148
  heading-72:
139
149
  fontFamily: Noto Sans SC
@@ -385,8 +395,8 @@ These components ship in the package. Compose from this list before writing new
385
395
 
386
396
  **Option fields.** ControlOption, Checkbox, Radio, Choicebox, Combobox, MultiSelect, Switch, Toggle, Slider, RangeSlider.
387
397
 
388
- - Switch commits immediately. Checkbox stages a change that a submit applies. Choosing the wrong one misstates when the change takes effect.
389
- - Toggle selects among mutually exclusive views. It is not a Switch with more entries.
398
+ - Toggle represents one on/off setting and reports a requested change immediately. Checkbox stages a change that a submit applies. Choosing the wrong one misstates when the change takes effect.
399
+ - Switch selects among mutually exclusive views or modes.
390
400
  - RangeSlider is two thumbs over one interval, paired with numeric inputs; Slider is a single value.
391
401
 
392
402
  **Dates and ranges.** CalendarGrid, RangeInputs, RangeField, PeriodCombobox, addDays.
@@ -120,20 +120,30 @@ semantic-colors:
120
120
  action-primary-hover: "{colors.primary-hover}"
121
121
  action-primary-press: "{colors.primary-press}"
122
122
  action-on-primary: "#ffffff"
123
+ action-text: "{colors.primary-700}"
123
124
  surface-canvas: "{colors.background-100}"
124
125
  surface-subtle: "{colors.background-200}"
125
126
  surface-panel: "{colors.background-100}"
127
+ surface-media: "#0a0a0a"
128
+ text-on-media: "#ffffff"
126
129
  border: "{colors.gray-400}"
127
130
  border-strong: "{colors.gray-500}"
131
+ border-subtle: "rgba(203, 213, 225, 0.82)"
128
132
  text-primary: "{colors.text-primary}"
129
133
  text-secondary: "{colors.text-secondary}"
130
134
  text-muted: "{colors.text-muted}"
135
+ text-soft: "#6e6e73"
136
+ overlay-scrim: "rgba(2, 6, 23, 0.44)"
131
137
  selection-background: "{colors.text-primary}"
132
138
  selection-foreground: "{colors.background-100}"
133
139
  focus-ring: "{colors.primary}"
140
+ focus: "{colors.primary-700}"
134
141
  status-success: "{colors.green-700}"
135
142
  status-warning: "{colors.amber-900}"
136
143
  status-danger: "{colors.red-700}"
144
+ status-danger-text: "#d32f2f"
145
+ status-danger-surface: "{colors.red-100}"
146
+ status-danger-border: "#d32f2f"
137
147
  typography:
138
148
  heading-72:
139
149
  fontFamily: Noto Sans SC
@@ -385,8 +395,8 @@ These components ship in the package. Compose from this list before writing new
385
395
 
386
396
  **Option fields.** ControlOption, Checkbox, Radio, Choicebox, Combobox, MultiSelect, Switch, Toggle, Slider, RangeSlider.
387
397
 
388
- - Switch commits immediately. Checkbox stages a change that a submit applies. Choosing the wrong one misstates when the change takes effect.
389
- - Toggle selects among mutually exclusive views. It is not a Switch with more entries.
398
+ - Toggle represents one on/off setting and reports a requested change immediately. Checkbox stages a change that a submit applies. Choosing the wrong one misstates when the change takes effect.
399
+ - Switch selects among mutually exclusive views or modes.
390
400
  - RangeSlider is two thumbs over one interval, paired with numeric inputs; Slider is a single value.
391
401
 
392
402
  **Dates and ranges.** CalendarGrid, RangeInputs, RangeField, PeriodCombobox, addDays.
@@ -33,7 +33,7 @@ README owns the repository inventory and generated-file boundary. This file owns
33
33
 
34
34
  Two component-page sections are q1travel supersets with no external counterpart, so their scope is defined here rather than inferred page by page.
35
35
 
36
- - **设计 Token** — every Tier B native-semantic control page (Button, Input, Textarea, Select, Checkbox, Radio, Switch) MUST carry this section. Those controls take their whole surface from semantic tokens, so the role/token/usage table is the only place a consumer can see which tokens to override. Tier A and Tier C pages MUST NOT add it by default: their appearance comes mostly from structure, and a token table there restates the global palette without telling the reader anything component-specific. **Tabs is the one recorded exception** — a Tier A component whose surface is likewise entirely token-driven; it keeps its table, and it does not license other Tier A pages to add one.
36
+ - **设计 Token** — every Tier B native-semantic control page (Button, Input, Textarea, Select, Checkbox, Radio, Toggle) MUST carry this section. Those controls take their whole surface from semantic tokens, so the role/token/usage table is the only place a consumer can see which tokens to override. Tier A and Tier C pages MUST NOT add it by default: their appearance comes mostly from structure, and a token table there restates the global palette without telling the reader anything component-specific. **Switch and Tabs are the two recorded exceptions** — these Tier A components are likewise entirely token-driven; they keep their tables, and they do not license other Tier A pages to add one.
37
37
  - **API 与行为矩阵** — reserved for composite host components that the consumer assembles while the host owns the state (ContextSwitcher, Navigation, Sidebar). The table exists to state who owns what; a component that owns its own state does not need it.
38
38
 
39
39
  Rows in these tables reference semantic tokens (`--q1-color-*`, `--q1-shadow-*`, `--q1-radius-*`), not component-private custom properties. Component-private properties driven by props (for example an avatar diameter) are implementation detail and MUST NOT be documented as a consumer-facing token contract.
@@ -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
- - 不改动 `--q1-shadow-focus`。
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. The sort icon is decorative and is not the only state cue.
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-shadow-focus-danger` is the ring the field family already draws on an invalid control, now named: one step wider and one step lighter than `--q1-shadow-focus`, because red at the same opacity swallows the 1px red border it sits on. Both rings resolve their color through a semantic token, so light and dark need no separate declaration.
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