@q1travel/design-system 0.24.0 → 0.25.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.
@@ -35,7 +35,7 @@ Package-owned semantics are applied after native props. `type`, `className`, `di
35
35
  | State | Button | ButtonLink | Label and status |
36
36
  | --- | --- | --- | --- |
37
37
  | `loading` | Keeps the existing `aria-disabled="true"` and `tabIndex=0` focusable contract; does not add `aria-busy` or native `disabled` unless `disabled` was also passed. | Removes `href`, keeps `aria-disabled="true"` and `tabIndex=0` so the loading state remains discoverable. | Keeps the original visible children and announces `loadingLabel` through the existing internal `role="status"` spinner. |
38
- | `busy` | Uses native `disabled`, sets `aria-busy="true"`, and blocks clicks. | Removes `href`, sets `aria-disabled="true"`, `aria-busy="true"`, `tabIndex=-1`, and blocks clicks. | Shows one spinner. A non-empty `busyLabel` replaces the visible label without replacing the stable accessible name; a separate polite `role="status"` announces `busyLabel`, then `loadingLabel`, then `处理中…`. |
38
+ | `busy` | Uses native `disabled`, sets `aria-busy="true"`, and blocks clicks. | Removes `href`, sets `aria-disabled="true"`, `aria-busy="true"`, `tabIndex=-1`, and blocks clicks. | Shows one spinner. A non-empty `busyLabel` replaces the visible label without replacing the stable accessible name; a separate polite `role="status"` announces `busyLabel`, then `loadingLabel`, then `正在处理…`. |
39
39
  | `busy + loading` | Busy wins; one spinner and the busy interaction contract apply. | Busy wins; the link is not navigable or focusable. | `busyLabel` wins for visible/status text; `loadingLabel` is only a fallback when busyLabel is empty. |
40
40
 
41
41
  `busyLabel` is an optional string. An empty string behaves as absent and never disables repeat-submission prevention. The original children remain the accessible-name source (and an explicit `aria-label` remains unchanged); the visible busy label is a separate decorative overlay, while the live status node is outside the button/anchor name calculation. The label slot reserves geometry for both values. Under `prefers-reduced-motion: reduce`, the spinner remains present but static; no rotation, pulse, scale, or spring animation is required to understand the state.
@@ -436,7 +436,7 @@ These components ship in the package. Compose from this list before writing new
436
436
 
437
437
  **Chat messages.** Bubble (incoming/outgoing, optional avatar/name/time, controlled pending/error and retry/actions slots) and MessageScroller (stable keyed items, near-bottom following, streaming growth, prepend anchor preservation, conversationKey reset, named native jump button and separate polite new-message announcements) are public components. They reuse existing tokens and Button; Message and Scroller APIs remain unchanged. Tier B uses native keyboard scrolling and buttons; callers own constrained height, message data, streaming, Markdown, tool cards, history cursors, permissions and network recovery.
438
438
 
439
- **Record activity.** Timeline, TimelineItem, TimelineCollapsedGroup, Marker, Message, Mention, Composer, Attachment. Timeline uses chronological ol/li with tone dots or Avatar; TimelineCollapsedGroup uses a native disclosure for consecutive system events; Marker keeps system events quiet and dates centered. Message supports pending/failed and caller actions; Mention renders caller-owned inline member references using action-text and the selected surface. Composer is a textarea combobox with listbox mentions, Enter sends and Shift+Enter inserts a newline; IME composition never sends or picks. Attachment reuses Progress and named removal. Network, permissions and notifications remain caller-owned.
439
+ **Record activity.** Timeline, TimelineItem, TimelineCollapsedGroup, Marker, Message, Mention, Composer, Attachment. Timeline uses chronological ol/li with tone dots or Avatar; TimelineCollapsedGroup uses a native disclosure for consecutive system events; Marker keeps system events quiet and dates centered. Message supports pending/failed and caller actions; Mention renders caller-owned inline member references using action-text and the selected surface. Composer is a textarea combobox with listbox mentions, Enter sends and Shift+Enter inserts a newline; IME composition never sends or picks. Attachment reuses Progress and named removal. Network, permissions and notifications remain caller-owned. Composer accepts optional `triggers` ({char,label,options?,onQuery?,emptyText?,errorText?,toToken?}); single-symbol triggers share debounce, abort/stale rejection, statuses, retry, combobox/listbox keyboard and synchronous caret insertion. Explicit @ overrides legacy mentions/onMentionQuery; otherwise they remain an implicit @ trigger. Slash is reserved for unchanged commands and rejected as a trigger with a development warning. Enabled triggers alone appear in the default hint. Han text may directly precede any trigger; word/email interiors do not trigger. Selection inserts toToken(item), defaulting to char + label, and surviving selections produce {char,id,label} references alongside existing text/mentionIds; references is optional in the type for legacy constructed submissions and always present on component submissions. Editing a token invalidates its reference.
440
440
 
441
441
  **Actions.** Button, ButtonLink, IconButton, SplitButton, LoadMoreButton, ClearButton, CopyButton, FilterChip, Link, Toolbar.
442
442
 
@@ -436,7 +436,7 @@ These components ship in the package. Compose from this list before writing new
436
436
 
437
437
  **Chat messages.** Bubble (incoming/outgoing, optional avatar/name/time, controlled pending/error and retry/actions slots) and MessageScroller (stable keyed items, near-bottom following, streaming growth, prepend anchor preservation, conversationKey reset, named native jump button and separate polite new-message announcements) are public components. They reuse existing tokens and Button; Message and Scroller APIs remain unchanged. Tier B uses native keyboard scrolling and buttons; callers own constrained height, message data, streaming, Markdown, tool cards, history cursors, permissions and network recovery.
438
438
 
439
- **Record activity.** Timeline, TimelineItem, TimelineCollapsedGroup, Marker, Message, Mention, Composer, Attachment. Timeline uses chronological ol/li with tone dots or Avatar; TimelineCollapsedGroup uses a native disclosure for consecutive system events; Marker keeps system events quiet and dates centered. Message supports pending/failed and caller actions; Mention renders caller-owned inline member references using action-text and the selected surface. Composer is a textarea combobox with listbox mentions, Enter sends and Shift+Enter inserts a newline; IME composition never sends or picks. Composer also accepts `onMentionQuery(query, {signal})` with 200ms debounce, abort/stale-result rejection, loading/empty/error states and keyboard retry; async lookup takes precedence over static members. Optional `placeholder` and `hint` preserve the input label; member instructions appear only with mention support. Han text may directly precede @, while Unicode word/email interiors do not trigger. Selection inserts text and sets the caret synchronously. Attachment reuses Progress and named removal. Network, permissions and notifications remain caller-owned.
439
+ **Record activity.** Timeline, TimelineItem, TimelineCollapsedGroup, Marker, Message, Mention, Composer, Attachment. Timeline uses chronological ol/li with tone dots or Avatar; TimelineCollapsedGroup uses a native disclosure for consecutive system events; Marker keeps system events quiet and dates centered. Message supports pending/failed and caller actions; Mention renders caller-owned inline member references using action-text and the selected surface. Composer is a textarea combobox with listbox mentions, Enter sends and Shift+Enter inserts a newline; IME composition never sends or picks. Composer also accepts `onMentionQuery(query, {signal})` with 200ms debounce, abort/stale-result rejection, loading/empty/error states and keyboard retry; async lookup takes precedence over static members. Optional `placeholder` and `hint` preserve the input label; member instructions appear only with mention support. Han text may directly precede @, while Unicode word/email interiors do not trigger. Selection inserts text and sets the caret synchronously. Attachment reuses Progress and named removal. Network, permissions and notifications remain caller-owned. Composer accepts optional `triggers` ({char,label,options?,onQuery?,emptyText?,errorText?,toToken?}); single-symbol triggers share debounce, abort/stale rejection, statuses, retry, combobox/listbox keyboard and synchronous caret insertion. Explicit @ overrides legacy mentions/onMentionQuery; otherwise they remain an implicit @ trigger. Slash is reserved for unchanged commands and rejected as a trigger with a development warning. Enabled triggers alone appear in the default hint. Han text may directly precede any trigger; word/email interiors do not trigger. Selection inserts toToken(item), defaulting to char + label, and surviving selections produce {char,id,label} references alongside existing text/mentionIds; references is optional in the type for legacy constructed submissions and always present on component submissions. Editing a token invalidates its reference.
440
440
 
441
441
  **Actions.** Button, ButtonLink, IconButton, SplitButton, LoadMoreButton, ClearButton, CopyButton, FilterChip, Link, Toolbar.
442
442
 
@@ -100,7 +100,7 @@ does not pull focus from the activated button. Consumers own URL synchronization
100
100
 
101
101
  ## Record activity (owner approved 2026-10-06)
102
102
 
103
- Timeline / TimelineItem (ol/li, 8px token dot or Avatar), Marker (quiet actor/time, date separator), Message (default/pending/failed, caller actions) / Mention (inline action-text on selected surface), Composer (Tier A textarea combobox/listbox, IME guard, Enter send / Shift+Enter newline), Attachment (Progress, retry/remove) are public package components. TimelineCollapsedGroup uses a native disclosure button with aria-expanded and Enter/Space; callers group runs of consecutive system events (docs example uses three or more). Marker unread uses centered action text; caller places and scrolls to the boundary. Message acknowledgements and its caller-owned actions slot display receipt state. Composer also accepts `onMentionQuery(query, {signal})` with 200ms debounce, abort/stale-result rejection, loading/empty/error states and keyboard retry; async lookup takes precedence over static members. Optional `placeholder` and `hint` preserve the input label; member instructions appear only with mention support. Han text may directly precede @, while Unicode word/email interiors do not trigger. Selection inserts text and sets the caret synchronously. Composer commands share the mention combobox/listbox keyboard model and IME guard; known slash commands invoke onCommand instead of onSubmit. Attachment paste/drop passes File[] to onAttach; legacy clicks remain argument-free. Callers own the file picker and object URLs and revoke previews on removal or unmount. Existing tokens only; data, permissions, network and notifications remain caller-owned.
103
+ Timeline / TimelineItem (ol/li, 8px token dot or Avatar), Marker (quiet actor/time, date separator), Message (default/pending/failed, caller actions) / Mention (inline action-text on selected surface), Composer (Tier A textarea combobox/listbox, IME guard, Enter send / Shift+Enter newline), Attachment (Progress, retry/remove) are public package components. TimelineCollapsedGroup uses a native disclosure button with aria-expanded and Enter/Space; callers group runs of consecutive system events (docs example uses three or more). Marker unread uses centered action text; caller places and scrolls to the boundary. Message acknowledgements and its caller-owned actions slot display receipt state. Composer also accepts `onMentionQuery(query, {signal})` with 200ms debounce, abort/stale-result rejection, loading/empty/error states and keyboard retry; async lookup takes precedence over static members. Optional `placeholder` and `hint` preserve the input label; member instructions appear only with mention support. Han text may directly precede @, while Unicode word/email interiors do not trigger. Selection inserts text and sets the caret synchronously. Composer commands share the mention combobox/listbox keyboard model and IME guard; known slash commands invoke onCommand instead of onSubmit. Attachment paste/drop passes File[] to onAttach; legacy clicks remain argument-free. Callers own the file picker and object URLs and revoke previews on removal or unmount. Existing tokens only; data, permissions, network and notifications remain caller-owned. Composer accepts optional `triggers` ({char,label,options?,onQuery?,emptyText?,errorText?,toToken?}); single-symbol triggers share debounce, abort/stale rejection, statuses, retry, combobox/listbox keyboard and synchronous caret insertion. Explicit @ overrides legacy mentions/onMentionQuery; otherwise they remain an implicit @ trigger. Slash is reserved for unchanged commands and rejected as a trigger with a development warning. Enabled triggers alone appear in the default hint. Han text may directly precede any trigger; word/email interiors do not trigger. Selection inserts toToken(item), defaulting to char + label, and surviving selections produce {char,id,label} references alongside existing text/mentionIds; references is optional in the type for legacy constructed submissions and always present on component submissions. Editing a token invalidates its reference.
104
104
  Timeline / TimelineItem (ol/li, 8px token dot or Avatar), Marker (quiet actor/time, date separator), Message (default/pending/failed, caller actions) / Mention (inline action-text on selected surface), Composer (Tier A textarea combobox/listbox, IME guard, Enter send / Shift+Enter newline), Attachment (Progress, retry/remove) are public package components. `/patterns/record-activity` composes order facts, Switch, chronological activity and a pinned Composer. Existing tokens only; data, permissions, network and notifications remain caller-owned.
105
105
 
106
106
  ## ToggleGroup selection ownership
@@ -61,7 +61,7 @@ This contract applies to the current known-total and unknown-tail models. A futu
61
61
 
62
62
  ### Loading, focus, and completion
63
63
 
64
- - While `loading` is true, the pagination `nav` exposes `aria-busy="true"` and the existing Spinner exposes the polite status text `加载中…`.
64
+ - While `loading` is true, the pagination `nav` exposes `aria-busy="true"` and the existing Spinner exposes the polite status text `正在加载…`.
65
65
  - Structural boundary controls and empty-state controls remain natively disabled.
66
66
  - Actionable pagination controls remain focusable while loading and expose `aria-disabled="true"`. Their click and keyboard handlers are inert until loading ends. This preserves the user's current focus rather than moving focus to a newly rendered control.
67
67
  - The current-page marker and `aria-current="page"` remain stable while loading.
@@ -70,7 +70,7 @@ This contract applies to the current known-total and unknown-tail models. A futu
70
70
  ### Responsive and unavailable states
71
71
 
72
72
  - `compact` and the existing tokenized responsive layout own dense and narrow presentation; the shared semantics do not change at smaller widths.
73
- - `total={0}` exposes the existing `暂无数据` summary and does not fabricate page numbers.
73
+ - `total={0}` exposes the existing `没有数据` summary and does not fabricate page numbers.
74
74
  - Error or unavailable presentation is consumer-owned composition around `Pagination` (for example, an adjacent alert and a disabled/empty pagination state); #111 does not add an `error` or `unavailable` prop.
75
75
 
76
76
  ### Required evidence
@@ -40,7 +40,7 @@ export declare function AuthCard({ title, description, action, className }: Auth
40
40
  /** Focused presentational card for account entry and connection flows. */
41
41
  export declare interface AuthCardProps {
42
42
  title: ReactNode;
43
- description: ReactNode;
43
+ description?: ReactNode;
44
44
  action?: ReactNode;
45
45
  className?: string;
46
46
  }
@@ -307,7 +307,7 @@ declare type ButtonSharedProps = {
307
307
  selected?: boolean;
308
308
  /** 载入态:禁点 + 保留可聚焦 + spinner 的 role=status 播报;不改变控件尺寸。 */
309
309
  loading?: boolean;
310
- /** loading 时 role=status 播报的文案,默认"加载中…";仅供屏幕阅读器,不影响可见文案。 */
310
+ /** loading 时 role=status 播报的文案,默认"正在加载…";仅供屏幕阅读器,不影响可见文案。 */
311
311
  loadingLabel?: string;
312
312
  /** 已提交忙态:原生禁用 + aria-busy,阻止重复提交。 */
313
313
  busy?: boolean;
@@ -628,7 +628,7 @@ export declare type CommandMenuSection = {
628
628
  items: CommandMenuItem[];
629
629
  };
630
630
 
631
- export declare function Composer({ onSubmit, onAttach, attachments, mentions, onMentionQuery, placeholder, hint, commands, onCommand, disabled, }: ComposerProps): JSX.Element;
631
+ export declare function Composer({ onSubmit, onAttach, attachments, mentions, onMentionQuery, placeholder, triggers, hint, commands, onCommand, disabled, }: ComposerProps): JSX.Element;
632
632
 
633
633
  export declare type ComposerCommand = ComposerMention & {
634
634
  keywords?: string[];
@@ -647,15 +647,33 @@ export declare type ComposerProps = {
647
647
  onCommand?: (id: string, argumentText: string) => void;
648
648
  attachments?: ReactNode;
649
649
  mentions?: ComposerMention[];
650
+ triggers?: ComposerTrigger[];
650
651
  onMentionQuery?: MentionQuery;
651
652
  placeholder?: string;
652
653
  hint?: ReactNode;
653
654
  disabled?: boolean;
654
655
  };
655
656
 
657
+ export declare type ComposerReference = {
658
+ char: string;
659
+ id: string;
660
+ label: string;
661
+ };
662
+
656
663
  export declare type ComposerSubmission = {
657
664
  text: string;
658
665
  mentionIds: string[];
666
+ references?: ComposerReference[];
667
+ };
668
+
669
+ export declare type ComposerTrigger = {
670
+ char: string;
671
+ label: string;
672
+ options?: ComposerMention[];
673
+ onQuery?: MentionQuery;
674
+ emptyText?: string;
675
+ errorText?: string;
676
+ toToken?: (item: ComposerMention) => string;
659
677
  };
660
678
 
661
679
  export declare function ContextCard({ name, identity, rows, action, onAction, actionHref, placement, align, children, }: ContextCardProps): JSX.Element;
@@ -984,7 +1002,7 @@ export declare type FieldLabelVisibilityProps = {
984
1002
 
985
1003
  export declare function Fieldset({ title, subtitle, tone, footerStatus, footerAction, disabled, children, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, }: {
986
1004
  title?: string;
987
- subtitle: string;
1005
+ subtitle?: ReactNode;
988
1006
  tone?: FieldsetTone;
989
1007
  footerStatus?: ReactNode;
990
1008
  footerAction?: ReactNode;