@q1travel/design-system 0.23.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 +10 -3
- package/contracts/design.md +11 -4
- package/contracts/implementation-map.md +12 -3
- package/contracts/interface-guidelines.md +3 -3
- package/contracts/pagination-migration.md +2 -2
- package/dist-pkg/design-system.d.ts +98 -25
- package/dist-pkg/design-system.js +5115 -4945
- package/dist-pkg/style.css +78 -8
- package/package.json +2 -2
|
@@ -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,19 +436,22 @@ 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
|
|
|
443
443
|
- Button carries the action. ButtonLink navigates but reads as a button, for a page-level call to action. Link reads as text, inside a sentence. Substituting one for another makes the page read wrong.
|
|
444
444
|
- SplitButton is a primary action with an adjacent menu whose first entry mirrors it. Do not use it to hide unrelated actions behind a chevron.
|
|
445
|
-
- FilterChip opens a consumer-owned filter picker; undefined means unset, other values mean set. Its
|
|
445
|
+
- FilterChip opens a consumer-owned filter picker; undefined means unset, other values mean set. Its default sm 32px pill uses a dashed border-strong outline with CirclePlus when unset, and a solid outline with label, border-token divider, action-text value and ChevronDown when set. The optional leading CircleX clear action is a separate named native button before the picker, with its own Tab stop and shared focus ring.
|
|
446
|
+
- FilterOptionPanel is searchable single-select content inside Popover, usually anchored by FilterChip. It owns initial search focus, named combobox/listbox, active-descendant arrow navigation with disabled skipping, loading/error/retry/empty/no-match states, and label/keywords includes filtering. Callers own selection, closing, business ranking and async queries through controlled query/onQueryChange and an injected filter; Escape dismissal and trigger focus return stay with Popover. It does not provide multiselect or an application footer.
|
|
446
447
|
- IconButton requires an accessible name. An icon-only control without one is not deliverable.
|
|
447
448
|
|
|
448
449
|
**Text fields.** FormField, Label, Input, ClearableInput, SearchInput, InputOTP, Textarea, Select, Fieldset, ErrorMessage.
|
|
449
450
|
|
|
450
451
|
- InputOTP collects a fixed six-digit code in one joined group by default; `separator` explicitly enables 3+3 groups. VerificationCodeInput and VerificationCodeInputProps remain deprecated aliases for one minor version; migrate to InputOTP and InputOTPProps before their removal in the next minor version. The old `/components/verification-code-input` route redirects to `/components/input-otp`.
|
|
451
452
|
- FormField owns the label, help text, and error slot. Do not assemble those three around a bare Input.
|
|
453
|
+
- `labelHidden` defaults to false. For a single inline field already named by context, it visually hides the real associated label through `q1-sr-only` without reserving a label row or gap; description, visible error, and `aria-describedby` remain unchanged. A label is still required; bare mode rejects `labelHidden`. Input’s existing string `hideLabel` still names the password hide action.
|
|
454
|
+
- FormField positions its visually hidden label and empty live status within its own containing block so an overflowing inline row cannot enlarge the page scroll width.
|
|
452
455
|
- Select is for a short, fixed list. Anything searchable, or longer than roughly seven entries, is a Combobox.
|
|
453
456
|
|
|
454
457
|
**Option fields.** ControlOption, Checkbox, Radio, Choicebox, Combobox, MultiSelect, Switch, Toggle, ToggleGroup, Slider, RangeSlider.
|
|
@@ -463,7 +466,7 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
|
|
|
463
466
|
|
|
464
467
|
|
|
465
468
|
- Toggle represents one on/off setting and reports a requested change immediately. Square Checkbox stages a form change that a submit applies; circle Checkbox marks task completion through the consumer’s change handler. Choosing the wrong one misstates when the change takes effect.
|
|
466
|
-
- Switch selects among mutually exclusive views or modes.
|
|
469
|
+
- Switch selects among mutually exclusive views or modes; its outer sm / md / lg heights are 32 / 40 / 48px on fine pointers, defaulting to md.
|
|
467
470
|
- ToggleGroup uses pressed buttons for single or multiple choices; arrow keys move focus without selecting. Icon-only items require an accessible name. See `implementation-map.md` for selection ownership.
|
|
468
471
|
- RangeSlider is two thumbs over one interval, paired with numeric inputs; Slider is a single value.
|
|
469
472
|
|
|
@@ -619,3 +622,7 @@ Before delivery, confirm each of these. They are observable; none of them is a m
|
|
|
619
622
|
In this repository, `npm run check` is the full gate; a partial run is not a pass. In consuming repositories, run their design and token gates before reporting completion.
|
|
620
623
|
|
|
621
624
|
公开 Foundation 集成:`getOverlayCoordinator` 协调 package 与宿主 overlay 的栈序、inert 与滚动锁;契约见 [Overlay Foundation](./overlay-foundation.md#11-o3-公开-host-协调扩展2026-09-08)。
|
|
625
|
+
|
|
626
|
+
### 单行控件尺寸
|
|
627
|
+
|
|
628
|
+
显式 sm / md / lg 的单行控件与 Button 对齐为 32 / 40 / 48px;使用现有 `--q1-space-8`、`--q1-control-height-default` 与 `--q1-space-2`。SearchInput 与 Menu 文字触发器默认 md,FilterChip 默认 sm32,Switch 外框 sm / md / lg 同高 32 / 40 / 48px,默认 md。Calendar 的 size 只控制网格,触发器使用 fieldSize。空或缺省 label 不创建可见标签行,消费方须提供可访问名称。粗指针最小 44px 命中规则保持现有契约。
|
package/contracts/design.md
CHANGED
|
@@ -436,19 +436,22 @@ 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. 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
|
|
|
443
443
|
- Button carries the action. ButtonLink navigates but reads as a button, for a page-level call to action. Link reads as text, inside a sentence. Substituting one for another makes the page read wrong.
|
|
444
444
|
- SplitButton is a primary action with an adjacent menu whose first entry mirrors it. Do not use it to hide unrelated actions behind a chevron.
|
|
445
|
-
- FilterChip opens a consumer-owned filter picker; undefined means unset, other values mean set. Its
|
|
445
|
+
- FilterChip opens a consumer-owned filter picker; undefined means unset, other values mean set. Its default sm 32px pill uses a dashed border-strong outline with CirclePlus when unset, and a solid outline with label, border-token divider, action-text value and ChevronDown when set. The optional leading CircleX clear action is a separate named native button before the picker, with its own Tab stop and shared focus ring.
|
|
446
|
+
- FilterOptionPanel is searchable single-select content inside Popover, usually anchored by FilterChip. It owns initial search focus, named combobox/listbox, active-descendant arrow navigation with disabled skipping, loading/error/retry/empty/no-match states, and label/keywords includes filtering. Callers own selection, closing, business ranking and async queries through controlled query/onQueryChange and an injected filter; Escape dismissal and trigger focus return stay with Popover. It does not provide multiselect or an application footer.
|
|
446
447
|
- IconButton requires an accessible name. An icon-only control without one is not deliverable.
|
|
447
448
|
|
|
448
449
|
**Text fields.** FormField, Label, Input, ClearableInput, SearchInput, InputOTP, Textarea, Select, Fieldset, ErrorMessage.
|
|
449
450
|
|
|
450
451
|
- InputOTP collects a fixed six-digit code in one joined group by default; `separator` explicitly enables 3+3 groups. VerificationCodeInput and VerificationCodeInputProps remain deprecated aliases for one minor version; migrate to InputOTP and InputOTPProps before their removal in the next minor version. The old `/components/verification-code-input` route redirects to `/components/input-otp`.
|
|
451
452
|
- FormField owns the label, help text, and error slot. Do not assemble those three around a bare Input.
|
|
453
|
+
- `labelHidden` defaults to false. For a single inline field already named by context, it visually hides the real associated label through `q1-sr-only` without reserving a label row or gap; description, visible error, and `aria-describedby` remain unchanged. A label is still required; bare mode rejects `labelHidden`. Input’s existing string `hideLabel` still names the password hide action.
|
|
454
|
+
- FormField positions its visually hidden label and empty live status within its own containing block so an overflowing inline row cannot enlarge the page scroll width.
|
|
452
455
|
- Select is for a short, fixed list. Anything searchable, or longer than roughly seven entries, is a Combobox.
|
|
453
456
|
|
|
454
457
|
**Option fields.** ControlOption, Checkbox, Radio, Choicebox, Combobox, MultiSelect, Switch, Toggle, ToggleGroup, Slider, RangeSlider.
|
|
@@ -463,7 +466,7 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
|
|
|
463
466
|
|
|
464
467
|
|
|
465
468
|
- Toggle represents one on/off setting and reports a requested change immediately. Square Checkbox stages a form change that a submit applies; circle Checkbox marks task completion through the consumer’s change handler. Choosing the wrong one misstates when the change takes effect.
|
|
466
|
-
- Switch selects among mutually exclusive views or modes.
|
|
469
|
+
- Switch selects among mutually exclusive views or modes; its outer sm / md / lg heights are 32 / 40 / 48px on fine pointers, defaulting to md.
|
|
467
470
|
- ToggleGroup uses pressed buttons for single or multiple choices; arrow keys move focus without selecting. Icon-only items require an accessible name. See `implementation-map.md` for selection ownership.
|
|
468
471
|
- RangeSlider is two thumbs over one interval, paired with numeric inputs; Slider is a single value.
|
|
469
472
|
|
|
@@ -475,7 +478,7 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
|
|
|
475
478
|
- Popover is a named anchored dialog for interactive content; it supports controlled/default open, four-side collision positioning plus controlled anchorRef placement, menu/listbox role focus, width matching, Escape focus return and outside pointer-down dismissal. Keyboard opening moves focus into content; pointer opening retains trigger focus and Tab enters the panel. It is nonmodal by default; opt-in modal locks the background and traps focus. ensurePopoverRoot exposes the same shared Foundation host for consumer-owned sibling portals; dismissExcludeRefs and nested panels preserve parent dismissal boundaries.
|
|
476
479
|
- Modal blocks and demands an answer. Use it for confirmation, not for a long form; a long form belongs in a Drawer or its own route.
|
|
477
480
|
- DestructiveActionModal is the required shape for irreversible actions. Do not rebuild that confirmation from a plain Modal.
|
|
478
|
-
- Sheet slides in from an edge with a focus trap; opt-in `mobileFullscreen` fills narrow viewports with safe-area padding and no outer inset or radius, while default floating spacing remains unchanged; Drawer is the wider panel form. Menu is anchored and flips on collision; ContextMenu and DotsMenu share its keyboard engine.
|
|
481
|
+
- Sheet slides in from an edge with a focus trap; opt-in `mobileFullscreen` fills narrow viewports with safe-area padding and no outer inset or radius, while default floating spacing remains unchanged; Drawer is the wider panel form. Menu is anchored and flips on collision; ContextMenu and DotsMenu share its keyboard engine. DotsMenu accepts contextual `label` (default 更多操作) for trigger and menu, plus `{type:'separator'}` entries using the shared Menu separator; roving focus and typeahead skip separators and disabled items.
|
|
479
482
|
- Tooltip carries a short label for a control. Anything a reader must read to decide belongs in the page or in a ContextCard.
|
|
480
483
|
|
|
481
484
|
**Data and evidence.** Table, Pagination, DocsPagination, ShowMore, Chart, Gauge, Progress, JsonView, Entity, Description, RelativeTimeCard.
|
|
@@ -619,3 +622,7 @@ Before delivery, confirm each of these. They are observable; none of them is a m
|
|
|
619
622
|
In this repository, `npm run check` is the full gate; a partial run is not a pass. In consuming repositories, run their design and token gates before reporting completion.
|
|
620
623
|
|
|
621
624
|
公开 Foundation 集成:`getOverlayCoordinator` 协调 package 与宿主 overlay 的栈序、inert 与滚动锁;契约见 [Overlay Foundation](./overlay-foundation.md#11-o3-公开-host-协调扩展2026-09-08)。
|
|
625
|
+
|
|
626
|
+
### 单行控件尺寸
|
|
627
|
+
|
|
628
|
+
显式 sm / md / lg 的单行控件与 Button 对齐为 32 / 40 / 48px;使用现有 `--q1-space-8`、`--q1-control-height-default` 与 `--q1-space-2`。SearchInput 与 Menu 文字触发器默认 md,FilterChip 默认 sm32,Switch 外框 sm / md / lg 同高 32 / 40 / 48px,默认 md。Calendar 的 size 只控制网格,触发器使用 fieldSize。空或缺省 label 不创建可见标签行,消费方须提供可访问名称。粗指针最小 44px 命中规则保持现有契约。
|
|
@@ -15,7 +15,8 @@ README owns the repository inventory and generated-file boundary. This file owns
|
|
|
15
15
|
| Mobile full-viewport details | Opt-in Sheet mobileFullscreen | `Sheet` | Existing spacing/radius/surface tokens and safe-area env | Default floating inset and overlay lifecycle preserved | Narrow viewport opt-in removes inset/radius and fills viewport | Existing focus trap, Escape and return focus |
|
|
16
16
|
| Hoverable supplemental information | Read-only member or role preview | `HoverCard`, shared anchored overlay foundation | Panel background, popover shadow, radius, spacing and motion tokens | Fine-pointer hover or keyboard focus; configurable 0ms open / 90ms close; card entry cancels close; Escape dismissal; trigger click preserved | Shared collision positioning and portal; coarse/touch hover ignored | Named native trigger, aria-describedby tooltip, no focus transfer or trap, reduced motion |
|
|
17
17
|
| Anchored interactive content | Consumer-owned inline dialog | `Popover`, `ensurePopoverRoot`, `FilterChip`, shared overlay foundation | Panel background, popover shadow, radius, spacing and motion tokens | Controlled/default open or external anchorRef (FilterChip ref forwards to picker); menu/listbox role focus; nested/excluded targets, focusout and anchor visibility dismissal; retained exit animation | Four-side collision plus auto/fixed placement; preferred-height flip, viewport clamp, matchWidth and ancestor scroll; fixed shared portal | Named dialog, expanded/controls wiring, focus return; opt-in modal trap |
|
|
18
|
-
| Compact dashboard filters | Consumer-owned filter picker | `FilterChip` | `--q1-space-
|
|
18
|
+
| Compact dashboard filters | Consumer-owned filter picker | `FilterChip` | `--q1-space-8` (default sm32), border-strong, text-secondary, action-text, shared focus | Unset dashed CirclePlus; set solid leading CircleX clear, label, divider, value and ChevronDown | Ellipsis bounds long values; shared TouchTarget preserves coarse 44px targets | Sibling native buttons, clear before picker in Tab order, focus returns to picker |
|
|
19
|
+
| Searchable filter choices | Consumer-owned single-select content | `FilterOptionPanel`, `Popover`, `FilterChip` | Existing control, surface, text, radius, spacing and focus tokens | Label/keywords includes or injected filter; controlled query; loading/error/retry/empty/no-match; select callback | Viewport-bound width and scroll list; coarse option height | Named combobox/listbox, initial search focus, aria-activedescendant, disabled skipping; Popover Escape returns to anchor |
|
|
19
20
|
| 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 |
|
|
20
21
|
| 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 |
|
|
21
22
|
| 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 |
|
|
@@ -75,7 +76,7 @@ Command Menu cycles Tab between its search input and sole Esc keycap close butto
|
|
|
75
76
|
commands use text without leading arrows and space-8 + space-1 row height. Multi Select
|
|
76
77
|
options use background-only focus feedback; its bulk text action is compact and neutral,
|
|
77
78
|
with no divider. Coarse-pointer targets retain the existing 44px minimum; the compact
|
|
78
|
-
Command Menu close button uses the shared TouchTarget hit region.
|
|
79
|
+
Command Menu close button uses the shared TouchTarget hit region. DotsMenu accepts contextual `label` (default 更多操作) for trigger and menu, plus `{type:'separator'}` entries using the shared Menu separator; roving focus and typeahead skip separators and disabled items.
|
|
79
80
|
|
|
80
81
|
Context Switcher identifies the current context with a neutral check and regular-weight
|
|
81
82
|
labels, without selected fill or a stronger selected press layer. File Tree starts with
|
|
@@ -99,7 +100,7 @@ does not pull focus from the activated button. Consumers own URL synchronization
|
|
|
99
100
|
|
|
100
101
|
## Record activity (owner approved 2026-10-06)
|
|
101
102
|
|
|
102
|
-
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 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.
|
|
103
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.
|
|
104
105
|
|
|
105
106
|
## ToggleGroup selection ownership
|
|
@@ -126,3 +127,11 @@ The consumer mapping was checked against q1travel-web origin/main: `src/componen
|
|
|
126
127
|
| conversation switching / new conversation | conversationKey resets follow state, visible anchor and announcement |
|
|
127
128
|
| scroll-to-latest and streaming narration | named jumpLabel button, labelled region, separate polite announcement; caller can pass completed-turn text or empty announcement to silence |
|
|
128
129
|
Keyboard: native viewport Arrow/PageUp/PageDown/Home/End; Tab reaches the viewport and buttons; Enter/Space activates retry or jump. Jump moves focus to the viewport before its button disappears. No custom composite widget keyboard model is introduced.
|
|
130
|
+
|
|
131
|
+
## Hidden field labels
|
|
132
|
+
|
|
133
|
+
Owner approved 2026-10-08: additive `labelHidden?: boolean` (default false) keeps a real associated label through `q1-sr-only` while removing its visual row and gap. Input, Textarea, Select, InputOTP and Checkbox/Radio (including circular Checkbox) expose the shell option; bare mode rejects it. SearchInput and Combobox compositions use `FormField labelHidden`, preserving their existing APIs. Calendar/RangeField does not consume FieldShellProps and retains its existing date-trigger behavior. Errors and descriptions remain visible and connected through `aria-describedby`. Input's existing string `hideLabel` remains the password hide-action copy.
|
|
134
|
+
|
|
135
|
+
`FormField` establishes a relative containing block for hidden labels and empty status regions. Package consumer fixtures enforce label ownership, SSR contracts cover names/messages, and `scripts/lib/check-label-hidden-browser.mjs` checks native labels, visible errors, inline Button alignment and a deterministic 390px scrollable max-content row without page overflow.
|
|
136
|
+
## Control density scale
|
|
137
|
+
Owner approved 2026-10-08: explicitly sized single-line Button, ButtonLink, Input, SearchInput, Select, RangeField trigger, Menu text trigger and FilterChip share sm32 / md40 / lg48 on fine pointers. SearchInput defaults to md and retains native numeric size compatibility; FilterChip defaults to sm32. Menu text triggers default to md40 after the rendered fine-pointer audit confirmed the prior omitted-size trigger measured 38–39px; icon triggers retain their prior behavior. Calendar size remains grid-only; fieldSize controls its trigger. Switch outer sm / md / lg heights align to 32 / 40 / 48px, defaulting to md; coarse-pointer 44px rules remain unchanged. FormField and Select omit empty or absent visible labels; callers supply aria-label, aria-labelledby or a native external label. Select reuses the development-only bare-field accessible-name warning.
|
|
@@ -24,7 +24,7 @@ Adding a clause therefore means answering two questions before the wording: who
|
|
|
24
24
|
- [both] MUST use native links for navigation and native buttons for actions.
|
|
25
25
|
- [both] MUST keep visual and hit targets aligned; controls smaller than 24px need a larger interactive area.
|
|
26
26
|
- [both] MUST keep mobile control targets at least 44px where touch is expected.
|
|
27
|
-
- [both] MUST use `--q1-touch-target-min` (44px) for the shared centered invisible child-span hit region of Button (all sizes, including compact consumer overrides and icon-only), CopyButton, Menu/DotsMenu triggers, Description info/hint buttons, and the independent FilterChip picker/clear buttons only under `(pointer: coarse), (any-pointer: coarse)`. Preserve every existing coarse-pointer visual-size rule. Only axes still below the minimum receive extra hit area; existing 44px targets do not expand outside their visual frame. The region covers the complete border box: canonical Button/CopyButton/Menu/DotsMenu borders are 1px, while Description borders are none. Consumers overriding a control border width must also set its private `--touch-target-border-width` to the actual per-side width (including zero for `border: none`); asymmetric borders need their own hit-region sizing. FilterChip keeps its
|
|
27
|
+
- [both] MUST use `--q1-touch-target-min` (44px) for the shared centered invisible child-span hit region of Button (all sizes, including compact consumer overrides and icon-only), CopyButton, Menu/DotsMenu triggers, Description info/hint buttons, and the independent FilterChip picker/clear buttons only under `(pointer: coarse), (any-pointer: coarse)`. Preserve every existing coarse-pointer visual-size rule. Only axes still below the minimum receive extra hit area; existing 44px targets do not expand outside their visual frame. The region covers the complete border box: canonical Button/CopyButton/Menu/DotsMenu borders are 1px, while Description borders are none. Consumers overriding a control border width must also set its private `--touch-target-border-width` to the actual per-side width (including zero for `border: none`); asymmetric borders need their own hit-region sizing. FilterChip keeps its default sm32 visual height and existing gaps/margins; its picker and clear hit regions must not overlap. Menu item rows use a real `min-height: var(--q1-touch-target-min)` under the same coarse-pointer query so neighboring rows remain independent. Focus rings stay on the visual control; child hit-region events activate that native control without replacing its pseudo-elements or overflow rules.
|
|
28
28
|
- [both] MUST leave enough space for expanded targets: dense neighbors must not overlap each other's visual frames. Consumers must reserve the expansion on each side and avoid clipping ancestors; if this is impossible, regroup controls or use larger visual controls. The shared region cannot infer neighbor gaps or escape control/ancestor clipping; clipped compact controls must use a visual size of at least 44px.
|
|
29
29
|
- [both] SHOULD deliberately depart from Geist's measured 24–32px controls without coarse-pointer enlargement: Apple HIG's 44pt guidance and WCAG 2.5.5 motivate q1travel's 44×44 CSS-pixel mobile usability target; pt and CSS pixels are different units.
|
|
30
30
|
- [both] NEVER disable browser zoom.
|
|
@@ -209,7 +209,7 @@ Theming owns tokens and `color-scheme`; the interaction-contrast rule lives in D
|
|
|
209
209
|
- [both] SHOULD resolve data states in the order loading → error → empty → content.
|
|
210
210
|
- [both] SHOULD give every flow a way forward and a way back (「取消」「返回」), and confirm costly or hard-to-reverse actions before running them.
|
|
211
211
|
|
|
212
|
-
These copy clauses
|
|
212
|
+
These copy clauses keep reader address and empty states consistent with a formal business console: address the reader as 「您」, omit trailing punctuation from empty-state titles, and explain when content will appear in the description.
|
|
213
213
|
|
|
214
214
|
### Component Naming
|
|
215
215
|
|
|
@@ -218,7 +218,7 @@ These copy clauses follow the actual Stripe Chinese Dashboard for reader address
|
|
|
218
218
|
|
|
219
219
|
### Component Documentation Pages
|
|
220
220
|
|
|
221
|
-
Component pages follow one skeleton so a reader who has used one page can find the same thing on every other. The shape
|
|
221
|
+
Component pages follow one skeleton so a reader who has used one page can find the same thing on every other. The shape keeps every page predictable: one sentence says what the component is for, the fixed sections sit in a fixed order, and only the feature sections in the middle vary by component. Shared terms live in `.agents/skills/product-design/references/glossary.md`.
|
|
222
222
|
|
|
223
223
|
- [repo] MUST open each component page with one sentence that says what a reader uses the component for. It names no props, no implementation, and no 「输入…输出…」 pairing.
|
|
224
224
|
- [repo] MUST keep the fixed sections in this order: examples first, then feature sections, then 「API」, then 「使用原则」, then 「可访问性」 where the page has one, then 「另请参阅」 as the last section.
|
|
@@ -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;
|
|
@@ -426,7 +426,7 @@ declare type CheckboxOnlyProps = {
|
|
|
426
426
|
};
|
|
427
427
|
|
|
428
428
|
/** Checkbox 的完整 props。消费方包一层时用它标注,无需知道内部由哪几块组合而成。 */
|
|
429
|
-
export declare type CheckboxProps = ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & CheckboxOnlyProps & {
|
|
429
|
+
export declare type CheckboxProps = ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & FieldLabelVisibilityProps & CheckboxOnlyProps & {
|
|
430
430
|
/** 圆形仅用于任务与清单完成;表单多选保留默认方形。 */
|
|
431
431
|
shape?: 'square' | 'circle';
|
|
432
432
|
/** 仅圆形生效;业务方自行映射优先级。 */
|
|
@@ -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, 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,12 +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[];
|
|
651
|
+
onMentionQuery?: MentionQuery;
|
|
652
|
+
placeholder?: string;
|
|
653
|
+
hint?: ReactNode;
|
|
650
654
|
disabled?: boolean;
|
|
651
655
|
};
|
|
652
656
|
|
|
657
|
+
export declare type ComposerReference = {
|
|
658
|
+
char: string;
|
|
659
|
+
id: string;
|
|
660
|
+
label: string;
|
|
661
|
+
};
|
|
662
|
+
|
|
653
663
|
export declare type ComposerSubmission = {
|
|
654
664
|
text: string;
|
|
655
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;
|
|
656
677
|
};
|
|
657
678
|
|
|
658
679
|
export declare function ContextCard({ name, identity, rows, action, onAction, actionHref, placement, align, children, }: ContextCardProps): JSX.Element;
|
|
@@ -798,7 +819,7 @@ export declare type ContextSwitcherSearch = {
|
|
|
798
819
|
noResults: ContextSwitcherEmptyState;
|
|
799
820
|
};
|
|
800
821
|
|
|
801
|
-
export declare function ControlOption({ id, label, description, error, indeterminate, ref, type, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, onClick, ...rest }: ControlOptionProps): JSX.Element;
|
|
822
|
+
export declare function ControlOption({ id, label, labelHidden, description, error, indeterminate, ref, type, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, onClick, ...rest }: ControlOptionProps): JSX.Element;
|
|
802
823
|
|
|
803
824
|
declare type ControlOptionNativeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'type'>;
|
|
804
825
|
|
|
@@ -810,7 +831,7 @@ declare type ControlOptionOwnProps = {
|
|
|
810
831
|
};
|
|
811
832
|
|
|
812
833
|
/** ControlOption 的完整 props(Checkbox / Radio 的共同底座,须显式给 type)。 */
|
|
813
|
-
export declare type ControlOptionProps = ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & CheckboxOnlyProps & {
|
|
834
|
+
export declare type ControlOptionProps = ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & FieldLabelVisibilityProps & CheckboxOnlyProps & {
|
|
814
835
|
type: 'checkbox' | 'radio';
|
|
815
836
|
} & ControlOptionNativeInputProps;
|
|
816
837
|
|
|
@@ -868,14 +889,18 @@ export declare type DocsPaginationProps = {
|
|
|
868
889
|
next?: DocsPageLink;
|
|
869
890
|
};
|
|
870
891
|
|
|
871
|
-
export declare function DotsMenu({ entries, size, disabled, align, }: {
|
|
892
|
+
export declare function DotsMenu({ entries, size, disabled, align, label, }: {
|
|
872
893
|
entries: DotsMenuEntry[];
|
|
894
|
+
label?: string;
|
|
873
895
|
size?: 'sm' | 'md' | 'lg';
|
|
874
896
|
disabled?: boolean;
|
|
875
897
|
align?: 'start' | 'end';
|
|
876
898
|
}): JSX.Element;
|
|
877
899
|
|
|
878
900
|
export declare type DotsMenuEntry = {
|
|
901
|
+
type: 'separator';
|
|
902
|
+
} | {
|
|
903
|
+
type?: 'item';
|
|
879
904
|
label: string;
|
|
880
905
|
disabled?: boolean;
|
|
881
906
|
danger?: boolean;
|
|
@@ -967,9 +992,17 @@ declare type FieldBareProps = {
|
|
|
967
992
|
error?: never;
|
|
968
993
|
};
|
|
969
994
|
|
|
995
|
+
export declare type FieldLabelVisibilityProps = {
|
|
996
|
+
label: string;
|
|
997
|
+
labelHidden?: boolean;
|
|
998
|
+
} | {
|
|
999
|
+
label?: never;
|
|
1000
|
+
labelHidden?: never;
|
|
1001
|
+
};
|
|
1002
|
+
|
|
970
1003
|
export declare function Fieldset({ title, subtitle, tone, footerStatus, footerAction, disabled, children, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, }: {
|
|
971
1004
|
title?: string;
|
|
972
|
-
subtitle
|
|
1005
|
+
subtitle?: ReactNode;
|
|
973
1006
|
tone?: FieldsetTone;
|
|
974
1007
|
footerStatus?: ReactNode;
|
|
975
1008
|
footerAction?: ReactNode;
|
|
@@ -1006,6 +1039,8 @@ export declare type FileTreeNode = {
|
|
|
1006
1039
|
/** 筛选选择器入口;弹层、筛选值与 expanded 状态归调用方。 */
|
|
1007
1040
|
export declare const FilterChip: ForwardRefExoticComponent< {
|
|
1008
1041
|
label: string;
|
|
1042
|
+
/** 可选同高尺寸;默认 sm(32px)胶囊。 */
|
|
1043
|
+
size?: ButtonSize;
|
|
1009
1044
|
/** undefined 表示未设置;0、空字符串和 null 仍是已设置。 */
|
|
1010
1045
|
value?: ReactNode;
|
|
1011
1046
|
onClear?: () => void;
|
|
@@ -1013,19 +1048,49 @@ onClear?: () => void;
|
|
|
1013
1048
|
|
|
1014
1049
|
export declare type FilterChipProps = {
|
|
1015
1050
|
label: string;
|
|
1051
|
+
/** 可选同高尺寸;默认 sm(32px)胶囊。 */
|
|
1052
|
+
size?: ButtonSize;
|
|
1016
1053
|
/** undefined 表示未设置;0、空字符串和 null 仍是已设置。 */
|
|
1017
1054
|
value?: ReactNode;
|
|
1018
1055
|
onClear?: () => void;
|
|
1019
1056
|
} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'value'>;
|
|
1020
1057
|
|
|
1021
|
-
export declare
|
|
1022
|
-
|
|
1058
|
+
export declare type FilterOption = {
|
|
1059
|
+
value: string;
|
|
1023
1060
|
label: string;
|
|
1024
1061
|
description?: string;
|
|
1062
|
+
keywords?: string[];
|
|
1063
|
+
disabled?: boolean;
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
/** 可搜索单选内容;调用方通过 Popover 管理关闭和入口焦点。每次打开时面板自行把焦点放进搜索框,无需向 Popover 传 initialFocus。 */
|
|
1067
|
+
export declare function FilterOptionPanel({ options, value, onSelect, label, searchPlaceholder, loading, error, onRetry, emptyText, noMatchText, filter, query: controlledQuery, onQueryChange }: FilterOptionPanelProps): JSX.Element;
|
|
1068
|
+
|
|
1069
|
+
export declare type FilterOptionPanelProps = {
|
|
1070
|
+
options: FilterOption[];
|
|
1071
|
+
value?: string;
|
|
1072
|
+
onSelect: (value: string) => void;
|
|
1073
|
+
/** 搜索框与列表的可访问名称。 */
|
|
1074
|
+
label: string;
|
|
1075
|
+
searchPlaceholder?: string;
|
|
1076
|
+
loading?: boolean;
|
|
1077
|
+
error?: ReactNode;
|
|
1078
|
+
onRetry?: () => void;
|
|
1079
|
+
emptyText?: ReactNode;
|
|
1080
|
+
noMatchText?: (query: string) => ReactNode;
|
|
1081
|
+
filter?: (options: FilterOption[], query: string) => FilterOption[];
|
|
1082
|
+
query?: string;
|
|
1083
|
+
onQueryChange?: (query: string) => void;
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
export declare function FormField({ controlId, label, labelHidden, description, error, wide, children, }: {
|
|
1087
|
+
controlId: string;
|
|
1088
|
+
label?: string;
|
|
1089
|
+
description?: string;
|
|
1025
1090
|
error?: string;
|
|
1026
1091
|
wide?: boolean;
|
|
1027
1092
|
children: ReactNode;
|
|
1028
|
-
}): JSX.Element;
|
|
1093
|
+
} & FieldLabelVisibilityProps): JSX.Element;
|
|
1029
1094
|
|
|
1030
1095
|
export declare function Gauge({ value, size, showValue, tone, toneDirection, label, indeterminate, }: {
|
|
1031
1096
|
value?: number;
|
|
@@ -1094,7 +1159,7 @@ export declare type IconButtonProps = IconButtonAccessibleName & IconButtonBaseP
|
|
|
1094
1159
|
ref?: Ref<HTMLButtonElement>;
|
|
1095
1160
|
};
|
|
1096
1161
|
|
|
1097
|
-
export declare function Input({ id, label, description, error, invalid, errorId, ref, prefix, suffix, prefixStyling, suffixStyling, rounded, wide, size, className, revealable, revealed, onRevealedChange, revealLabel, hideLabel, disabled, ...rest }: {
|
|
1162
|
+
export declare function Input({ id, label, labelHidden, description, error, invalid, errorId, ref, prefix, suffix, prefixStyling, suffixStyling, rounded, wide, size, className, revealable, revealed, onRevealedChange, revealLabel, hideLabel, disabled, ...rest }: {
|
|
1098
1163
|
/** 可选:未传时内部 useId 兜底(对齐 Combobox);显式传入时行为同 0.3.0。 */
|
|
1099
1164
|
id?: string;
|
|
1100
1165
|
/** 置 aria-invalid 的业务校验态,不渲染文案;与壳模式 error 并轨(invalid || Boolean(error))。 */
|
|
@@ -1131,9 +1196,9 @@ export declare function Input({ id, label, description, error, invalid, errorId,
|
|
|
1131
1196
|
rounded?: boolean;
|
|
1132
1197
|
wide?: boolean;
|
|
1133
1198
|
size?: FieldSize;
|
|
1134
|
-
} & (FieldShellProps | FieldBareProps) & Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'size' | 'prefix'>): JSX.Element;
|
|
1199
|
+
} & (FieldShellProps | FieldBareProps) & FieldLabelVisibilityProps & Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'size' | 'prefix'>): JSX.Element;
|
|
1135
1200
|
|
|
1136
|
-
export declare function InputOTP({ id, name, value, onValueChange, disabled, readOnly, required, invalid, errorId, size, separator, ref, label, description, error, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': describedBy, }: InputOTPProps): JSX.Element;
|
|
1201
|
+
export declare function InputOTP({ id, name, value, onValueChange, disabled, readOnly, required, invalid, errorId, size, separator, ref, label, labelHidden, description, error, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': describedBy, }: InputOTPProps): JSX.Element;
|
|
1137
1202
|
|
|
1138
1203
|
export declare type InputOTPProps = {
|
|
1139
1204
|
id?: string;
|
|
@@ -1151,7 +1216,7 @@ export declare type InputOTPProps = {
|
|
|
1151
1216
|
separator?: boolean;
|
|
1152
1217
|
ref?: Ref<HTMLInputElement>;
|
|
1153
1218
|
'aria-describedby'?: string;
|
|
1154
|
-
} & ((FieldShellProps & {
|
|
1219
|
+
} & FieldLabelVisibilityProps & ((FieldShellProps & {
|
|
1155
1220
|
'aria-label'?: never;
|
|
1156
1221
|
'aria-labelledby'?: never;
|
|
1157
1222
|
}) | (FieldBareProps & ({
|
|
@@ -1264,8 +1329,14 @@ export declare type MentionProps = {
|
|
|
1264
1329
|
children: ReactNode;
|
|
1265
1330
|
};
|
|
1266
1331
|
|
|
1267
|
-
|
|
1332
|
+
declare type MentionQuery = (query: string, options: {
|
|
1333
|
+
signal: AbortSignal;
|
|
1334
|
+
}) => Promise<ComposerMention[]>;
|
|
1335
|
+
|
|
1336
|
+
export declare function Menu({ label, entries, withChevron, align, triggerContent, size }: {
|
|
1268
1337
|
label: string;
|
|
1338
|
+
/** 文字触发器尺寸,默认 md;图标触发器保留原尺寸。 */
|
|
1339
|
+
size?: ButtonSize;
|
|
1269
1340
|
entries: MenuEntry[];
|
|
1270
1341
|
withChevron?: boolean;
|
|
1271
1342
|
align?: 'start' | 'end';
|
|
@@ -1709,7 +1780,7 @@ export declare function Q1travelSymbol(props: SVGProps<SVGSVGElement>): JSX.Elem
|
|
|
1709
1780
|
export declare function Radio({ ...props }: RadioProps): JSX.Element;
|
|
1710
1781
|
|
|
1711
1782
|
/** Radio 的完整 props。 */
|
|
1712
|
-
export declare type RadioProps = ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & ControlOptionNativeInputProps;
|
|
1783
|
+
export declare type RadioProps = ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & FieldLabelVisibilityProps & ControlOptionNativeInputProps;
|
|
1713
1784
|
|
|
1714
1785
|
export declare function RangeField(props: CalendarSelectionProps & {
|
|
1715
1786
|
layout?: PopoverLayout;
|
|
@@ -1819,10 +1890,12 @@ export declare type SearchDialogTriggerProps = {
|
|
|
1819
1890
|
'aria-controls': string;
|
|
1820
1891
|
};
|
|
1821
1892
|
|
|
1822
|
-
export declare function SearchInput({ id, ariaLabel, value: controlledValue, defaultValue, onValueChange, loading, kbdHint, icon, ref, className, disabled, readOnly, autoComplete, spellCheck, onKeyDown: onInputKeyDown, ...inputProps }: SearchInputProps): JSX.Element;
|
|
1893
|
+
export declare function SearchInput({ id, size, ariaLabel, value: controlledValue, defaultValue, onValueChange, loading, kbdHint, icon, ref, className, disabled, readOnly, autoComplete, spellCheck, onKeyDown: onInputKeyDown, ...inputProps }: SearchInputProps): JSX.Element;
|
|
1823
1894
|
|
|
1824
1895
|
export declare type SearchInputProps = {
|
|
1825
1896
|
id: string;
|
|
1897
|
+
/** 与 Button 同高,默认 md;数字保留原生 input 的字符宽度语义。 */
|
|
1898
|
+
size?: ButtonSize | number;
|
|
1826
1899
|
/** 无可见 label 时的可访问名;与 FormField 或外部 label 组合时留空。 */
|
|
1827
1900
|
ariaLabel?: string;
|
|
1828
1901
|
value?: string;
|
|
@@ -1835,11 +1908,11 @@ export declare type SearchInputProps = {
|
|
|
1835
1908
|
icon?: ReactNode;
|
|
1836
1909
|
/** React 19 ref-as-prop,指向原生 search input。 */
|
|
1837
1910
|
ref?: Ref<HTMLInputElement>;
|
|
1838
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'aria-label' | 'defaultValue' | 'id' | 'onChange' | 'ref' | 'type' | 'value'>;
|
|
1911
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'aria-label' | 'defaultValue' | 'id' | 'onChange' | 'ref' | 'type' | 'value'>;
|
|
1839
1912
|
|
|
1840
|
-
export declare function Select({ id, label, description, error, ref, wide, size, prefix, suffix, className, children, value, defaultValue, multiple, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, ...rest }: {
|
|
1913
|
+
export declare function Select({ id, label, labelHidden, description, error, ref, wide, size, prefix, suffix, className, children, value, defaultValue, multiple, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, ...rest }: {
|
|
1841
1914
|
id: string;
|
|
1842
|
-
label
|
|
1915
|
+
label?: string;
|
|
1843
1916
|
description?: string;
|
|
1844
1917
|
error?: string;
|
|
1845
1918
|
/** 指向原生 select(React 19 ref-as-prop),供表单校验后聚焦等场景。 */
|
|
@@ -1847,7 +1920,7 @@ export declare function Select({ id, label, description, error, ref, wide, size,
|
|
|
1847
1920
|
wide?: boolean;
|
|
1848
1921
|
size?: FieldSize;
|
|
1849
1922
|
prefix?: ReactNode;
|
|
1850
|
-
/** 装饰性后缀图标(aria-hidden),渲染在下拉箭头左侧;跟 prefix
|
|
1923
|
+
/** 装饰性后缀图标(aria-hidden),渲染在下拉箭头左侧;跟 prefix 前缀一样不承载信息,可访问名称来自可见 label 或消费方提供的 ARIA / 外部 label。 */
|
|
1851
1924
|
suffix?: ReactNode;
|
|
1852
1925
|
children: ReactNode;
|
|
1853
1926
|
/** Select 只接受单一值;多值选择使用 MultiSelect。 */
|
|
@@ -1856,7 +1929,7 @@ export declare function Select({ id, label, description, error, ref, wide, size,
|
|
|
1856
1929
|
defaultValue?: string | number;
|
|
1857
1930
|
/** Select 是单选字段;多值选择使用 MultiSelect。 */
|
|
1858
1931
|
multiple?: never;
|
|
1859
|
-
} & Omit<SelectHTMLAttributes<HTMLSelectElement>, 'id' | 'children' | 'size' | 'prefix' | 'multiple' | 'value' | 'defaultValue'>): JSX.Element;
|
|
1932
|
+
} & FieldLabelVisibilityProps & Omit<SelectHTMLAttributes<HTMLSelectElement>, 'id' | 'children' | 'size' | 'prefix' | 'multiple' | 'value' | 'defaultValue'>): JSX.Element;
|
|
1860
1933
|
|
|
1861
1934
|
export declare function Separator({ orientation, decorative, className, }: {
|
|
1862
1935
|
orientation?: SeparatorOrientation;
|
|
@@ -2147,7 +2220,7 @@ export declare function Tabs({ tabs, ariaLabel, variant, value, defaultValue, on
|
|
|
2147
2220
|
onValueChange?: (id: string) => void;
|
|
2148
2221
|
}): JSX.Element | null;
|
|
2149
2222
|
|
|
2150
|
-
export declare function Textarea({ id, label, description, error, invalid, errorId, ref, wide, size, className, maxLength, onInput, ...rest }: TextareaProps): JSX.Element;
|
|
2223
|
+
export declare function Textarea({ id, label, labelHidden, description, error, invalid, errorId, ref, wide, size, className, maxLength, onInput, ...rest }: TextareaProps): JSX.Element;
|
|
2151
2224
|
|
|
2152
2225
|
/** Textarea 的完整 props。消费方包一层时用它标注,无需知道内部由哪几块组合而成。 */
|
|
2153
2226
|
export declare type TextareaProps = {
|
|
@@ -2161,7 +2234,7 @@ export declare type TextareaProps = {
|
|
|
2161
2234
|
ref?: Ref<HTMLTextAreaElement>;
|
|
2162
2235
|
wide?: boolean;
|
|
2163
2236
|
size?: FieldSize;
|
|
2164
|
-
} & (FieldShellProps | FieldBareProps) & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'id'>;
|
|
2237
|
+
} & (FieldShellProps | FieldBareProps) & FieldLabelVisibilityProps & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'id'>;
|
|
2165
2238
|
|
|
2166
2239
|
export declare function TextWithCopyButton({ text, copyValue, successMessage, size, }: {
|
|
2167
2240
|
text: string;
|