@q1travel/design-system 0.30.11 → 0.30.12

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
@@ -129,8 +129,9 @@ npm run dev
129
129
  | `npm run check:shell` | 结构与源码契约断言 + token 包检查 + 发布溯源检查 |
130
130
  | `npm run check:browser` | 基于 CDP 的浏览器行为契约(含 StrictMode 前置轮) |
131
131
  | `npm run check:package-api` | 已构建包的声明与运行时 API + 组件契约 `node --test` 套件 + `check:release-diff` |
132
+ | `npm run changelog:assemble -- --version <x.y.z>` | 正式候选汇编 `.changes/*.md`,锁定版本段并消费片段;普通 PR 只加片段 |
132
133
  | `npm run check:release-provenance` | 发布记录 vs `CHANGELOG.md`、origin tag 与 npm registry |
133
- | `npm run check:release-diff` | 与 registry 上一已发布版本比对 `dist-pkg` 的类名、导出、声明与 token;类名变化未写入 CHANGELOG 时失败 |
134
+ | `npm run check:release-diff` | 与 registry 上一已发布版本比对 `dist-pkg` 的类名、导出、声明与 token;类名变化未写入 `.changes/*.md` 片段或候选版本段时失败 |
134
135
  | `npm run check:release-sync` | 发布后 registry 完整性校验与依赖更新通知脚本测试 |
135
136
  | `npm run release:verify -- <tarball>` | 只校验 workflow tarball 与 npm registry 完整性 |
136
137
  | `npm run release:sync -- <tarball>` | 校验 registry 后发送依赖更新通知;不具备发布能力 |
@@ -39,3 +39,13 @@ Popover 为非模态 dialog,无锁滚动或焦点陷阱。footer 独立于列
39
39
  公开类名:q1-cascader;__label、__control、__trigger、__placeholder、__tags、__tag、__remove、__popup、__panel、__search、__columns、__column、__list、__option、__copy、__path、__forward、__results、__back、__status、__footer、__error。只使用既有 token,不新增刻度。每列优选 space-10 × 6,高度上限 min(space-10 × 6, 40dvh);视口低于 space-10 × 12 + space-6 时同一 Popover 单列钻取,有完整父路径和返回,隐藏列带 hidden,SSR 默认单列。亮暗继承 anchor 局部主题。
40
40
 
41
41
  新增导出 Cascader、CascaderProps、CascaderNode、CascaderPathItem、CascaderPath、CascaderSearchResult、CascaderAsyncState、CascaderBranchStates 与 /components/cascader 文档入口。没有使用端迁移,既有选择器默认行为不变。接入时适配业务规则为标准节点,输出在 onChange 转换;回滚先撤新增调用和路由再撤导出,发布另行授权。
42
+
43
+ ## 可选分支确认、路径回显与空树说明
44
+
45
+ `branchSelection?: 'immediate' | 'confirm'` 仅 single 允许,默认 immediate,省略时上述指针和键盘行为不变。confirm 模式下,可选分支的点击、触屏、Enter/Space 只进入子级,不通知 onChange;下一列 listbox 外列头使用既有 DS Button secondary/sm,无勾选图形,名称「选择“<label>”」。确认后提交分支并关闭回焦;分支已经是当前值时名称「已选择“<label>”」,激活只关闭回焦,不重复通知 onChange。窄屏列头在返回行下方。叶子与搜索结果仍直接提交,disabled/selectable 约束不变。
46
+
47
+ `displayPath?: boolean` 默认 false;true 时单选触发器和多选标签把已知路径 label 以 ` / ` 连接,沿用标签换行。路径来源仍为 selectedPaths、已加载节点、存活快照;未知路径回退既有末项或 value。移除名称及读屏数量与路径摘要不变。
48
+
49
+ `emptyTreeText?: ReactNode` 默认「没有可选项」,只影响非搜索根列在 idle 且 nodes 为空时的说明;搜索继续使用 emptyText,子级空列保持默认,加载与错误不变。内容替换默认说明且容器仅一个 role=status;交互操作使用 footer,不在说明中嵌套操作。
50
+
51
+ 三个属性均为可选新增,无使用端迁移;回滚调用方先删除属性,再撤新增实现。不改变公开类名、token、默认渲染或默认选择策略。
@@ -149,6 +149,7 @@ semantic-colors:
149
149
  text-soft: "#9a9a9c"
150
150
  text-disabled: "{colors.gray-500}"
151
151
  overlay-scrim: "rgba(2, 6, 23, 0.44)"
152
+ media-scrim: "rgba(2, 6, 23, 0.56)"
152
153
  selection-background: "{colors.text-primary}"
153
154
  selection-foreground: "{colors.background-100}"
154
155
  focus-ring: "#ffffff"
@@ -676,3 +677,9 @@ In this repository, `npm run check` is the full gate; a partial run is not a pas
676
677
  ## Cascader 层级选择
677
678
 
678
679
  Cascader 用于已知层级中的节点选择,采用关联 listbox + 搜索 combobox,值完全受控、父子独立多选,默认 selectable=true、clearable=false、关闭保留查询。节点可选规则、异步请求与输出转换归调用方。字段、键盘、默认省略、公开类名和加法迁移见 [Cascader 契约](./cascader.md)。无新增 token,既有选择组件默认行为不变。
680
+
681
+ ### Menu 锁定原因
682
+
683
+ 锁定项的 `lockedReason` 固定在标签下方,以 `--q1-font-size-label-13` 和次级文字色完整换行,不使用省略号,不撑破默认最大宽度;锁图标对齐标签首行。锁定原因仍并入 menuitem 的 `aria-label`,可见原因节点 `aria-hidden="true"` 避免重复播报;键盘可发现但不可激活。普通后缀与快捷键保持原有行为。
684
+
685
+ 新增公开类名:`menu__item-content`(锁定项标签与原因容器)、`menu__item-reason`(完整原因)。仅锁定项新增这两层 DOM,非锁定项结构不变;不新增 props 或 token,调用方无需迁移。
@@ -149,6 +149,7 @@ semantic-colors:
149
149
  text-soft: "#6e6e73"
150
150
  text-disabled: "#b7b7b7"
151
151
  overlay-scrim: "rgba(2, 6, 23, 0.44)"
152
+ media-scrim: "rgba(2, 6, 23, 0.56)"
152
153
  selection-background: "{colors.text-primary}"
153
154
  selection-foreground: "{colors.background-100}"
154
155
  focus-ring: "#000000"
@@ -676,3 +677,9 @@ In this repository, `npm run check` is the full gate; a partial run is not a pas
676
677
  ## Cascader 层级选择
677
678
 
678
679
  Cascader 用于已知层级中的节点选择,采用关联 listbox + 搜索 combobox,值完全受控、父子独立多选,默认 selectable=true、clearable=false、关闭保留查询。节点可选规则、异步请求与输出转换归调用方。字段、键盘、默认省略、公开类名和加法迁移见 [Cascader 契约](./cascader.md)。无新增 token,既有选择组件默认行为不变。
680
+
681
+ ### Menu 锁定原因
682
+
683
+ 锁定项的 `lockedReason` 固定在标签下方,以 `--q1-font-size-label-13` 和次级文字色完整换行,不使用省略号,不撑破默认最大宽度;锁图标对齐标签首行。锁定原因仍并入 menuitem 的 `aria-label`,可见原因节点 `aria-hidden="true"` 避免重复播报;键盘可发现但不可激活。普通后缀与快捷键保持原有行为。
684
+
685
+ 新增公开类名:`menu__item-content`(锁定项标签与原因容器)、`menu__item-reason`(完整原因)。仅锁定项新增这两层 DOM,非锁定项结构不变;不新增 props 或 token,调用方无需迁移。
@@ -25,6 +25,7 @@ README owns the repository inventory and generated-file boundary. This file owns
25
25
  | Component preview tile | Control density sample | Custom preview composition using component token mappings | Surface, border, action, focus, radius tokens | Button and segment visual states | Flex wrap preserves compact layout | Decorative in intro, real controls documented on component pages |
26
26
  | Color rods preview | Color scale summary | Custom preview composition using color scale aliases | `--q1-color-scale-*` aliases | None | Rods distribute across available width | Semantic labels identify the represented scale |
27
27
  | Color page reference and semantic tokens | Token reference and theme value copy | `ColorSwatch`, `SemanticColorListItem`, and `SemanticColorDemo` inside `ColorsPage` | `--q1-color-*`, semantic color tokens (including `--q1-color-border-warning` and `--q1-color-bg-warning-subtle`), and semantic action tokens | Left click copies token, context menu copies resolved value. The focus shadow token shows as an applied focus ring, not a flat color swatch | Ten-step grid and semantic rows adapt to available width | Button labels, semantic rows, live copy feedback |
28
+ | Readable normal text over images | Opt-in media-text backing | `MediaScrimSpecimen` on `ColorsPage`; image/text composition belongs to the host, with no new Image, Video or Modal slot | `--q1-color-media-scrim` + opaque `--q1-color-text-on-media` | Existing component defaults remain unchanged | Image and text wrap within their host | Complete text backing; white-image alpha-composition gate requires 4.5:1 in both themes |
28
29
  | Optical alignment | Aligned-looking media, icons, labels, and column edges | `ContextSwitcher` two-line rows, `Navigation` icons and chevron, `Table` edge columns and actions column, `Badge` label wrapper, `Button` affix | Optical tokens: `--q1-optical-icon-shift-cjk-label`, `--q1-optical-media-first-line-offset`, `--q1-surface-inset-inline`, `--q1-table-edge-padding-inline`, `--q1-button-hang-inline`, `--q1-badge-optical-shift`, `--q1-button-affix-optical-y` | Shifts use standalone `translate`; rotations and layout stay intact | Integer-pixel values only; locked by the `check:browser` optical fixture | Wrapper and class changes add no accessible names or roles |
29
30
  | Page footer navigation | Sequential documentation reading | `PageNavigation` | Surface, border, text, spacing tokens | Hover, focus, feedback buttons | Three-column footer collapses with content | Links are named and feedback controls are buttons |
30
31
 
@@ -100,6 +100,7 @@ Adding a clause therefore means answering two questions before the wording: who
100
100
  - [both] SHOULD avoid widows and orphans in headings and short paragraphs; `text-wrap: balance` for headings and `text-wrap: pretty` for body copy, plus punctuation hanging where the script needs it.
101
101
  - [both] SHOULD separate a number from its unit with a non-breaking space, and keep glued terms (product names, shortcuts) from wrapping mid-term. (排版瑕疵而非缺陷;本仓中文文案里数字+单位的组合极少,写断言的假阳风险高于收益。)
102
102
  - [product] SHOULD resolve language from the browser language setting and request headers, never from IP address or GPS location.
103
+ - [both] MUST pair normal text over an image with fully opaque `--q1-color-text-on-media` and `--q1-color-media-scrim` covering the entire text background, or an independently verified opaque text backing. Do not assume `overlay-scrim` provides text contrast. Verify at least 4.5:1 after actual composition; translucent text, parent opacity, filters, blending and gradients require their own measurement.
103
104
  - [both] MUST caption spoken audio and provide a transcript for any media that carries information not available in surrounding text.
104
105
 
105
106
  ## Accessibility Tiers
@@ -103,6 +103,8 @@ Examples:
103
103
 
104
104
  `--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.
105
105
 
106
+ `--q1-color-media-scrim` is the media-text backdrop, separate from the unchanged `--q1-color-overlay-scrim` overlay role. Both themes use `rgba(2, 6, 23, 0.56)`. Pair it with fully opaque `--q1-color-text-on-media`, covering the complete text background; ordinary source-over composition over an opaque white image meets 4.5:1 for normal text. Parent opacity, translucent text, filters, blending and shallower gradient regions require separate contrast verification. The overlay token does not guarantee media text contrast. Adoption is additive and opt-in: migrate only media text hosts; rollback removes their new references before deleting this token and its guards, then regenerates the contract mirrors.
107
+
106
108
  `--q1-color-border-warning` and `--q1-color-bg-warning-subtle` name the warning border and subtle background by role. They are equivalent to the existing `--q1-color-status-warning-border` and `--q1-color-status-warning-surface`; the background uses amber-100 in both themes, matching the success/danger subtle-surface mapping. Existing status names remain valid. Use `--q1-color-status-warning-text` on the subtle background for AA normal text. The border is a quiet decorative outline, not a standalone control boundary or the sole warning cue; pair it with warning text or an icon.
107
109
 
108
110
  `--q1-color-bg-selected-neutral` is the opaque neutral current-item background, separate from the branded `bg-selected`, quiet `bg-subtle`, and transient `bg-hover`. It references existing `gray-300` in both light and dark mode. Default, secondary, and ghost Button selected states consume it while retaining border and `aria-pressed` cues and using a heavier font weight than unselected controls; primary selected retains its primary press color, and warning/danger selected retains `bg-subtle`. The neutral selected background has measured DeltaE00 >= 3 against resting canvas, panel, and subtle surfaces in both themes; no separation from transient hover is required. Consumers may adopt the new role without renaming existing tokens; revert the Button background references and remove this additive role to roll back.
@@ -473,6 +473,8 @@ export declare type CascaderProps = CascaderSelectionProps & CascaderQueryProps
473
473
  placeholder?: string;
474
474
  searchPlaceholder?: string;
475
475
  emptyText?: ReactNode;
476
+ emptyTreeText?: ReactNode;
477
+ displayPath?: boolean;
476
478
  disabled?: boolean;
477
479
  readOnly?: boolean;
478
480
  required?: boolean;
@@ -507,10 +509,12 @@ export declare type CascaderSearchResult = {
507
509
 
508
510
  declare type CascaderSelectionProps = {
509
511
  mode: 'single';
512
+ branchSelection?: 'immediate' | 'confirm';
510
513
  value: string | null;
511
514
  onChange: (value: string | null, path: CascaderPath | null) => void;
512
515
  } | {
513
516
  mode: 'multiple';
517
+ branchSelection?: never;
514
518
  value: string[];
515
519
  onChange: (values: string[], changedPath: CascaderPath | null) => void;
516
520
  };
@@ -1232,13 +1236,13 @@ export declare type FileTreeNode = {
1232
1236
  };
1233
1237
 
1234
1238
  /** 筛选选择器入口;弹层、筛选值与 expanded 状态归调用方。 */
1235
- export declare const FilterChip: ForwardRefExoticComponent< {
1236
- label: string;
1237
- /** 可选同高尺寸;默认 sm(32px)胶囊。 */
1238
- size?: ButtonSize;
1239
- /** undefined 表示未设置;0、空字符串和 null 仍是已设置。 */
1240
- value?: ReactNode;
1241
- onClear?: () => void;
1239
+ export declare const FilterChip: ForwardRefExoticComponent<{
1240
+ label: string;
1241
+ /** 可选同高尺寸;默认 sm(32px)胶囊。 */
1242
+ size?: ButtonSize;
1243
+ /** undefined 表示未设置;0、空字符串和 null 仍是已设置。 */
1244
+ value?: ReactNode;
1245
+ onClear?: () => void;
1242
1246
  } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "value"> & RefAttributes<HTMLButtonElement>>;
1243
1247
 
1244
1248
  export declare type FilterChipProps = {
@@ -1613,7 +1617,7 @@ declare type MenuItemBase = {
1613
1617
  type: 'item';
1614
1618
  label: string;
1615
1619
  icon?: ReactNode;
1616
- /** 后缀内容(如快捷键提示);locked 项未显式传入时显示锁定原因。 */
1620
+ /** 后缀内容(如快捷键提示);锁定原因独立显示在标签下方。 */
1617
1621
  suffix?: ReactNode;
1618
1622
  danger?: boolean;
1619
1623
  };