@q1travel/design-system 0.24.0 → 0.25.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/button-api-compatibility.md +1 -1
- package/contracts/design.dark.md +1 -1
- package/contracts/design.md +1 -1
- package/contracts/implementation-map.md +1 -1
- package/contracts/pagination-migration.md +2 -2
- package/dist-pkg/design-system.d.ts +22 -4
- package/dist-pkg/design-system.js +4172 -4152
- package/package.json +1 -1
|
@@ -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.
|
package/contracts/design.dark.md
CHANGED
|
@@ -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
|
|
package/contracts/design.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
1005
|
+
subtitle?: ReactNode;
|
|
988
1006
|
tone?: FieldsetTone;
|
|
989
1007
|
footerStatus?: ReactNode;
|
|
990
1008
|
footerAction?: ReactNode;
|