@q1travel/design-system 0.2.0 → 0.3.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.
Files changed (32) hide show
  1. package/.agents/skills/product-design/AGENTS.md +9 -0
  2. package/.agents/skills/product-design/SKILL.md +63 -0
  3. package/.agents/skills/product-design/exemplars/README.md +12 -0
  4. package/.agents/skills/product-design/references/copy.md +7 -0
  5. package/.agents/skills/product-design/references/coverage-gaps.md +9 -0
  6. package/.agents/skills/product-design/references/glossary.md +5 -0
  7. package/.agents/skills/product-design/references/interface-quality.md +7 -0
  8. package/.agents/skills/product-design/references/patterns.md +13 -0
  9. package/.agents/skills/product-design/references/product-judgment.md +7 -0
  10. package/.agents/skills/product-design/references/resilience.md +13 -0
  11. package/.agents/skills/product-design/references/review-geist.md +94 -0
  12. package/.agents/skills/product-design/references/rules.md +17 -0
  13. package/.agents/skills/product-design/references/surfaces-forms.md +14 -0
  14. package/.agents/skills/product-design/references/surfaces-overlays.md +12 -0
  15. package/.agents/skills/product-design/references/surfaces.md +14 -0
  16. package/bin/q1-design.mjs +464 -0
  17. package/contracts/design-engineering-principles.md +39 -0
  18. package/contracts/design.dark.md +333 -0
  19. package/contracts/design.md +333 -0
  20. package/contracts/icon-system.md +77 -0
  21. package/contracts/implementation-map.md +29 -0
  22. package/contracts/interface-guidelines.md +122 -0
  23. package/contracts/token-naming.md +82 -0
  24. package/{dist → dist-pkg}/design-system.d.ts +2 -2
  25. package/{dist → dist-pkg}/design-system.js +630 -628
  26. package/{dist → dist-pkg}/style.css +76 -78
  27. package/package.json +19 -9
  28. package/tooling/README.md +9 -0
  29. package/tooling/scripts/evals/fixtures.json +7 -0
  30. package/tooling/scripts/evals/rules-checklist.json +23 -0
  31. package/tooling/scripts/evals/transition-all/after/example.css +4 -0
  32. package/tooling/scripts/evals/transition-all/before/example.css +4 -0
@@ -0,0 +1,77 @@
1
+ # 图标系统 · Icons
2
+
3
+ > **状态**:本规范定义图标系统的**目标态**。当前文档站的界面图标仍由 `lucide-react` 渲染(其几何与下方规范一致),并存在若干 `18px` 等迁移前尺寸;迁移到自建工厂 + 注册表是独立排期任务,尚未完成。品牌符号已是自有原生 SVG。
4
+
5
+ q1travel 的界面图标**目标是**一套自建的线性图标系统:几何参照 Lucide,实现为受控的原生 SVG,不依赖第三方图标库。品牌符号(q1travel 标识)不属于此系统,作为品牌资产单独维护。
6
+
7
+ 本规范是图标系统的**单一真相源**;自建工厂落地时,其代码注释应指回本规范,而非另立编号体系。
8
+
9
+ ---
10
+
11
+ ## 设计规范
12
+
13
+ 所有界面图标共享同一组参数,由图标工厂统一强制,不依赖单个图标自觉遵守。
14
+
15
+ | 属性 | 值 |
16
+ | --- | --- |
17
+ | 画布 `viewBox` | `0 0 24 24` |
18
+ | 描边宽度 `stroke-width` | `1.8` |
19
+ | 填充 `fill` | `none` |
20
+ | 描边颜色 `stroke` | `currentColor` |
21
+ | 线帽 `stroke-linecap` | `round` |
22
+ | 连接 `stroke-linejoin` | `round` |
23
+ | `aria-hidden` | `true`(装饰默认)|
24
+ | `focusable` | `false` |
25
+
26
+ - **线性风格**:统一描边、无填充,与 Lucide 图标库一致的线性视觉语言。
27
+ - **`currentColor`**:图标颜色继承当前文本颜色,随主题与组件状态自动适配;**不在图标内写死颜色**。
28
+
29
+ ---
30
+
31
+ ## 尺寸
32
+
33
+ 按所在场景的密度选择,不在区间内随意取值。**默认 16px**(不传 size 时)。现有 `18px` 等实例为迁移前遗留,随自建迁移一并收敛(见顶部状态)。
34
+
35
+ | 尺寸 | 值 | 场景 |
36
+ | --- | --- | --- |
37
+ | 小 | `16px`(默认)| 按钮内、紧凑控件、导航 |
38
+ | 中 | `20px` | 独立图标、列表项 |
39
+ | 大 | `24px` | 强调、空状态 |
40
+
41
+ ---
42
+
43
+ ## 来源
44
+
45
+ | 类别 | 方案 |
46
+ | --- | --- |
47
+ | 界面图标 | 几何参照 Lucide,自建原生 SVG;**不引入** `lucide-react` 或任何第三方图标库(目标态,迁移中)|
48
+ | 品牌符号 | q1travel 标识,自有原生 SVG,作为品牌资产单独维护 |
49
+
50
+ 参照 Lucide 几何,是为沿用其成熟、克制的线性视觉;自建实现,是为完全可控、无第三方依赖、可统一治理。
51
+
52
+ ---
53
+
54
+ ## 治理
55
+
56
+ 图标是受控资源,统一遵循以下约束:
57
+
58
+ - **工厂**:所有图标经统一工厂创建,几何参数、颜色、尺寸与可访问性默认值由工厂强制,而非逐个图标维护。
59
+ - **注册表**:所有图标登记在唯一清单中,记录名称、用途与同义词;语义重复的图标只保留一个(例如「编辑」不并存 edit / pencil / modify)。
60
+ - **单一入口**:界面一律使用图标组件,不在业务代码中内联 `<svg>`。
61
+ - **受控例外(special)**:带额外状态或逻辑、确实无法走工厂的历史图标,登记在注册表的 `special` 字段、单独维护,不作为新增图标的范例。
62
+ - **新增流程**:先登记注册表、补入图标库展示,再投入使用。
63
+
64
+ ---
65
+
66
+ ## 可访问性
67
+
68
+ - 图标默认 `aria-hidden="true"` 且 `focusable="false"`,视为装饰;语义由相邻文本或调用方的 `aria-label` 承担。
69
+ - 纯图标控件(如图标按钮)必须由调用方提供可访问名称。
70
+
71
+ ---
72
+
73
+ ## 使用
74
+
75
+ - **颜色**:不为图标单独设色,依赖 `currentColor` 跟随文本。
76
+ - **间距**:图标与文本之间保留一致间距,并与文本基线对齐。
77
+ - **一致性**:同一控件组内不混用不同描边或尺寸。
@@ -0,0 +1,29 @@
1
+ # q1travel Design System Implementation Map
2
+
3
+ This map records how external reference intent is translated into q1travel production code. It is not a screenshot checklist and it is not a source for copied markup or copied styles.
4
+
5
+ ## Directory Shape
6
+
7
+ README owns the repository inventory and generated-file boundary. This file owns the reference-to-implementation mapping.
8
+
9
+ | Reference intent | q1travel semantic | Canonical surface | Token source | State | Responsive | Accessibility |
10
+ | --- | --- | --- | --- | --- | --- | --- |
11
+ | Bounded documentation frame | Public design-system shell | `AppShell`, `Sidebar`, `Topbar` | `--q1-color-bg-canvas`, `--q1-color-border`, spacing tokens | Route changes reset document scroll | Frame width and sidebar collapse through layout CSS | Landmarks, keyboard search, focus-visible ring |
12
+ | Compact search and command menu | Fast documentation navigation | `CommandMenu`, `Topbar` search trigger | Surface, border, text, focus tokens | Open, active option, escape close | Dialog width clamps on small screens | `role="dialog"`, `aria-modal`, keyboard navigation |
13
+ | Foundation page rhythm | Scannable reference pages | `PageHeader`, `SpecSection`, `SpecTable` | Heading, copy, border, spacing tokens | None beyond links and focus | Tables scroll horizontally when needed | Semantic headings and tables |
14
+ | Introduction tile grid | Entry points into public groups | `IntroTileGrid`, `IntroTile` | Surface, border, text, spacing tokens | Hover, focus | Two columns on desktop, one column on small screens | Tile is a single link with hidden decorative visual |
15
+ | Brand lockup preview | q1travel identity specimen | `Q1travelSymbol` with custom lockup composition | Text, border, spacing tokens plus documented lockup variables | None | Asset stage clamps to tile width | Decorative visual is hidden from assistive tech |
16
+ | Icon matrix preview | Icon component density sample | `showcaseIconEntries` rendered with Lucide icons | `currentColor`, text-secondary token | None | Grid clamps inside tile | Icons are decorative in the tile, named on the Icon component page |
17
+ | 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 |
18
+ | 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 |
19
+ | Color page reference and semantic tokens | Token reference and theme value copy | `ColorSwatch`, `SemanticColorListItem`, and `SemanticColorDemo` inside `ColorsPage` | `--q1-color-*`, semantic color tokens, 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 |
20
+ | 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 |
21
+
22
+ ## Implementation Rules
23
+
24
+ - Reference behavior must map to a q1travel semantic before it reaches `src`.
25
+ - New public tokens use `--q1-*`; existing product `--ds-*` names are legacy migration inputs, not new contract names.
26
+ - Canonical components own repeated structure. Page-local custom structures are allowed only for visual specimens with a narrow purpose.
27
+ - Token references are the design source for production code. Current theme resolved values are clipboard output only.
28
+ - The same public navigation groups remain in the product surface: `基础`, `品牌`, and `组件`.
29
+ - If a capability is missing from a shared component, add the capability to that component before adding another page-local pattern.
@@ -0,0 +1,122 @@
1
+ # q1travel Interface Guidelines
2
+
3
+ These guidelines adapt mature web interface rules into q1travel contracts. They apply to documentation pages, component samples, and future product surfaces that consume this design system. The public localized version is the `/guidelines` page (`src/pages/GuidelinesPage.tsx`); keep both in sync.
4
+
5
+ ## Interactions
6
+
7
+ - MUST support keyboard operation for every interactive path.
8
+ - MUST show a visible `:focus-visible` state for every focusable element.
9
+ - MUST manage focus for overlays: move focus on open, return it on close, and trap it where the APG pattern requires.
10
+ - MUST use native links for navigation and native buttons for actions.
11
+ - MUST keep visual and hit targets aligned; controls smaller than 24px need a larger interactive area.
12
+ - MUST keep mobile control targets at least 44px where touch is expected.
13
+ - NEVER disable browser zoom.
14
+ - MUST avoid dead zones: if a region looks clickable, the clickable element must cover it.
15
+ - MUST show a loading indicator on in-flight buttons while keeping the original label.
16
+ - SHOULD delay spinners and skeletons by ~150–300ms and keep them visible for ~300–500ms so fast responses do not flicker.
17
+ - SHOULD update the UI optimistically when success is likely, and roll back with an error (or offer Undo) on failure.
18
+ - MUST require confirmation or offer a safe-window Undo for destructive actions.
19
+ - MUST announce async updates (toasts, inline validation) via polite `aria-live`.
20
+ - SHOULD set `overscroll-behavior: contain` inside modals and drawers to prevent scroll chaining.
21
+ - SHOULD delay only the first tooltip in a group; subsequent peers open without delay.
22
+ - SHOULD persist meaningful UI state in the URL when state must survive refresh, sharing, or Back/Forward navigation.
23
+
24
+ ## Forms
25
+
26
+ - MUST associate every input, textarea, select, checkbox, radio, and switch with a label or accessible name.
27
+ - MUST focus the associated control when its label is clicked; label and control share one generous hit target.
28
+ - MUST allow paste and password-manager behavior unless the field has a documented security reason.
29
+ - MUST validate after input instead of blocking normal typing.
30
+ - MUST show validation near the field and move focus to the first blocking error on submit.
31
+ - MUST keep submit enabled until the request starts; disable and show loading only while the request is in flight.
32
+ - SHOULD submit on Enter when a single text input is focused; in a textarea, ⌘/⌃+Enter submits and Enter inserts a newline.
33
+ - MUST keep mobile input text at 16px or larger.
34
+ - SHOULD use correct `type` and `inputmode` values for better keyboards and validation.
35
+ - SHOULD set `autocomplete` and meaningful `name` values so browser autofill works.
36
+ - MUST trim trailing whitespace introduced by IME or text replacement before validating.
37
+ - SHOULD use placeholders only as examples or patterns, and end placeholder copy with `…`.
38
+
39
+ ## Layout
40
+
41
+ - MUST align every element intentionally to a grid, edge, baseline, or optical center.
42
+ - MUST prefer CSS grid, flex, and intrinsic sizing over JavaScript measurement.
43
+ - SHOULD balance contrast in icon-and-text lockups by adjusting weight, size, spacing, or color.
44
+ - MUST avoid unwanted internal scrollbars.
45
+ - MUST verify small, laptop, desktop, and wide layouts.
46
+ - SHOULD respect device safe areas (notches, gesture zones) with safe-area variables.
47
+ - SHOULD use semantic layout tokens for repeated frame, rail, topbar, page-header, and specimen proportions.
48
+ - SHOULD allow small optical adjustments when they are named and localized.
49
+
50
+ ## Content And Accessibility
51
+
52
+ - MUST keep headings hierarchical and provide stable section anchors where deep links exist.
53
+ - MUST keep `<title>` reflecting the current context.
54
+ - MUST provide accessible names for icon-only controls.
55
+ - MUST hide decorative visuals from assistive technology.
56
+ - MUST use redundant status cues; color alone is not enough.
57
+ - MUST mirror final content geometry in skeletons to avoid layout shift when loading completes.
58
+ - MUST design empty, sparse, dense, and error states.
59
+ - MUST offer a next step or recovery path on every screen; no dead ends.
60
+ - MUST keep layouts resilient to short, average, and very long content, especially user-generated content.
61
+ - SHOULD format dates, times, numbers, and currencies for the user's locale.
62
+ - MUST keep technical identifiers, token names, and brand names protected from browser translation with `translate="no"` where appropriate.
63
+ - SHOULD prefer inline help over tooltips.
64
+ - SHOULD use tabular numbers for comparison rows and token tables.
65
+
66
+ ## Accessibility Tiers
67
+
68
+ Every component is classified into one accessibility tier; the tier sets its bar. The tier is decided by how much keyboard and focus behavior the component must own beyond native semantics. The keyboard model source is always the matching WAI-ARIA APG pattern, not invention — established design systems follow APG too, so "matching a reference" and "following APG" do not conflict.
69
+
70
+ - **Tier A — composite widgets** (calendar, combobox, menu, modal, drawer, tabs, slider, listbox, tree, …): MUST implement the full keyboard model of the matching APG pattern (roving tabindex; arrow / `Home` / `End` / `PageUp` / `PageDown` as the pattern defines; `Enter` / `Space` activation; `Esc` dismissal that returns focus to the trigger), MUST manage focus on open and close, MUST expose the required ARIA (`role`, `aria-selected` / `aria-expanded` / `aria-controls`, `aria-live` where state changes), MUST document the key map as a「按键 | 行为」keyboard table (`.a11y-keys`) in the page's 可访问性 section, and MUST be locked by a runtime keyboard assertion in `scripts/check-browser.mjs`.
71
+ - **Tier B — native-semantic controls** (button, input, textarea, checkbox, radio, switch, select, links): MUST rely on native elements for keyboard and role, MUST carry an associated label or accessible name, and MUST show a visible `:focus-visible` state through the shared focus token. No custom key handling is expected.
72
+ - **Tier C — display / decorative** (avatar, badge, banner, book, browser, icon, card, skeleton, …): MUST hide purely decorative visuals from assistive technology (`aria-hidden`, non-focusable) and MUST give every icon-only control an accessible name. No keyboard model is required.
73
+
74
+ Calendar (`src/pages/CalendarPage.tsx`) and Tabs (`src/pages/TabsPage.tsx`) are the Tier A reference implementations to copy.
75
+
76
+ ## Animation
77
+
78
+ - MUST honor `prefers-reduced-motion`.
79
+ - MUST animate only `opacity` and `transform` unless a documented reason requires otherwise.
80
+ - SHOULD prefer CSS, then the Web Animations API, then JavaScript libraries; avoid main-thread-driven animation.
81
+ - SHOULD choose easing based on what changes (size, distance, trigger).
82
+ - SHOULD keep animations interruptible by user input.
83
+ - SHOULD animate in response to input instead of autoplaying.
84
+ - SHOULD anchor `transform-origin` where the motion physically starts.
85
+ - NEVER use `transition: all`.
86
+ - SHOULD animate only to clarify cause and effect or to reinforce a deliberate state change.
87
+
88
+ ## Theming
89
+
90
+ - MUST support light and dark themes through tokens, not page-local color constants.
91
+ - MUST set the appropriate `color-scheme` so native controls and scrollbars match the current theme.
92
+ - MUST keep browser theme color aligned with the first paint background.
93
+ - SHOULD give `:hover` / `:active` / `:focus` states more contrast than the rest state.
94
+ - MUST explicitly set native select foreground and background when styling select controls.
95
+
96
+ ## Performance
97
+
98
+ - MUST prevent layout shift by reserving space for media, fonts, and stable specimens.
99
+ - MUST avoid repeated layout reads and writes during interaction.
100
+ - SHOULD complete POST/PATCH/DELETE requests within 500ms.
101
+ - SHOULD keep controlled input updates cheap and use uncontrolled inputs where appropriate.
102
+ - SHOULD subset CJK fonts and preload critical above-the-fold fonts to avoid flashes and layout shift.
103
+ - SHOULD move long tasks to Web Workers instead of blocking the main thread.
104
+ - SHOULD virtualize long lists before they become a documentation or product performance problem.
105
+
106
+ ## Copy
107
+
108
+ - MUST be public, neutral, and specific.
109
+ - MUST use consistent nouns across pages, navigation, tables, and examples.
110
+ - SHOULD prefer short action-oriented labels.
111
+ - MUST use active voice.
112
+ - MUST use unambiguous action labels (「保存 API Key」, not 「继续」).
113
+ - MUST make error messages guide the exit: say how to fix it, not only what failed.
114
+ - SHOULD default to positive, problem-solving language, including errors.
115
+ - SHOULD use numerals for counts and keep number/unit formatting consistent.
116
+ - MUST keep currency decimal places consistent within a context (0 or 2, never mixed).
117
+
118
+ ## Agent Integration
119
+
120
+ - This file is the machine-readable mirror of the public 界面准则 page (`/guidelines`); keep them in sync.
121
+ - `AGENTS.md` at the repository root constrains agent generation and modification behavior.
122
+ - `npm run check` (build + shell contract + browser contract) is the merge gate for any interface change.
@@ -0,0 +1,82 @@
1
+ # q1travel Token Naming Contract
2
+
3
+ Status: accepted
4
+
5
+ This contract defines the token naming standard for q1travel Design System v1. It records the naming decision only; it does not migrate existing `q1travel-web` runtime tokens.
6
+
7
+ ## Decision
8
+
9
+ New public design-system tokens use the `--q1-*` prefix.
10
+
11
+ Existing `--ds-*` tokens in product repositories are legacy implementation tokens. They may remain during migration, but they are not the source name for new q1travel Design System contracts, documentation, or component examples.
12
+
13
+ External reference systems can guide the token layer model and page behavior. Their exact token names, class names, and computed styles are not implementation source.
14
+
15
+ ## Layers
16
+
17
+ ### Reference Tokens
18
+
19
+ Reference tokens hold source values and scale steps. They are useful for color ramps, spacing scales, radius scales, and typography primitives.
20
+
21
+ Examples:
22
+
23
+ - `--q1-color-gray-100`
24
+ - `--q1-color-primary-700`
25
+ - `--q1-color-background-100`
26
+ - `--q1-space-4`
27
+ - `--q1-radius-2`
28
+ - `--q1-font-size-copy-14`
29
+
30
+ Reference color scales use numeric steps from `100` to `1000`.
31
+
32
+ ### Semantic Tokens
33
+
34
+ Semantic tokens describe product meaning. Product surfaces should consume these before reaching for reference tokens.
35
+
36
+ Examples:
37
+
38
+ - `--q1-color-bg-canvas`
39
+ - `--q1-color-bg-panel`
40
+ - `--q1-color-text-primary`
41
+ - `--q1-color-border`
42
+ - `--q1-color-action-primary`
43
+ - `--q1-color-status-danger`
44
+ - `--q1-shadow-focus`
45
+
46
+ ### Component Tokens
47
+
48
+ Component tokens are allowed only when a shared component needs a stable public customization surface. Do not create component tokens for one page or one specimen.
49
+
50
+ Pattern:
51
+
52
+ - `--q1-<component>-<slot>`
53
+ - `--q1-<component>-<slot>-<state>`
54
+
55
+ Examples:
56
+
57
+ - `--q1-button-bg`
58
+ - `--q1-button-bg-hover`
59
+ - `--q1-input-border-focus`
60
+
61
+ ## Usage Rules
62
+
63
+ - Product code should use semantic tokens first.
64
+ - Documentation color ramps may show and copy reference tokens.
65
+ - Documentation semantic color rows may show and copy semantic tokens.
66
+ - Left-clicking a color token swatch copies the token reference; context menu copies the current theme resolved value for inspection.
67
+ - Raw hex values are contract source values and inspection output, not the preferred product-consumption API.
68
+ - Shadow tokens should be displayed as token references, not as color swatches.
69
+ - Theme-specific values may differ, but token names must stay stable across light and dark themes.
70
+
71
+ ## Migration Rules
72
+
73
+ - Do not create new public `--ds-*` tokens.
74
+ - Do not rename all product `--ds-*` tokens in a broad sweep.
75
+ - During migration, add explicit aliases only when they reduce risk and point toward the accepted `--q1-*` naming.
76
+ - Treat `--ds-*` tokens in `q1travel-web` as legacy product implementation until a dedicated migration plan lands.
77
+
78
+ ## Non-Goals
79
+
80
+ - This contract does not publish an npm token package.
81
+ - This contract does not migrate `q1travel-web`.
82
+ - This contract does not require deleting every local or private product CSS variable.
@@ -539,7 +539,7 @@ export declare function ErrorCard({ title, message, action }: {
539
539
  }): JSX.Element;
540
540
 
541
541
  export declare function ErrorMessage({ label, size, action, children, }: {
542
- /** 可见的粗体标签前缀(如「邮箱错误:」),点明出错对象;缺省不显示(sr-only 前缀恒在)。 */
542
+ /** 可见的粗体标签前缀(如「邮箱错误:」),点明出错对象;缺省不显示(q1-sr-only 前缀恒在)。 */
543
543
  label?: string;
544
544
  size?: ErrorMessageSize;
545
545
  /** 恢复操作插槽:可安全重试用「重试」按钮,链接式出口放 <a>。 */
@@ -970,7 +970,7 @@ export declare function Switch({ options, ariaLabel, name, defaultValue, onChang
970
970
  onChange?: (value: string) => void;
971
971
  size?: 'sm' | 'md' | 'lg';
972
972
  fullWidth?: boolean;
973
- /** 纯图标模式:文字标签仍在,只是视觉隐藏(sr-only),可访问名称不丢失。 */
973
+ /** 纯图标模式:文字标签仍在,只是视觉隐藏(q1-sr-only),可访问名称不丢失。 */
974
974
  iconOnly?: boolean;
975
975
  }): JSX.Element | null;
976
976