@q1travel/design-system 0.30.3 → 0.30.5

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.
@@ -501,7 +501,7 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
501
501
 
502
502
 
503
503
  - 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.
504
- - Switch selects among mutually exclusive views or modes; its outer sm / md / lg heights are 32 / 40 / 48px on fine pointers, defaulting to md.
504
+ - Switch selects among mutually exclusive views or modes; its outer sm / md / lg heights are 32 / 40 / 48px on fine pointers, defaulting to md. Optional `variant="cards"` provides equal-width wrapping cards with a left-aligned label-12 label above caller-owned `meta` (number or ReactNode) in regular label-14 tabular figures, space-2 padding/gap and content-driven equal sm/md/lg height; cards alone use a two-pixel border-active selected border and inset line without a tint, a matching border-active label and the complete shared keyboard focus ring; disabled selected cards keep a neutral two-pixel border-strong outline with muted text, so the selection stays distinguishable. An auto-fit grid keeps any item count and its last row equally wide, with a readable 10rem minimum; the four-item example uses 全部 / 需要处理 / 更新 / 已归档 with numeric counts 128 / 12 / 8 / 32; the default `segmented` markup, dimensions and keyboard/radio semantics remain unchanged.
505
505
  - 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.
506
506
  - RangeSlider is two thumbs over one interval, paired with numeric inputs; Slider is a single value.
507
507
 
@@ -512,7 +512,7 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
512
512
  - HoverCard presents supplemental noninteractive content on fine-pointer hover or keyboard focus after openDelay (default 0ms); closeDelay defaults to 90ms and entering the card cancels closing. Escape dismisses without moving focus into the card; aria-describedby connects the named native trigger to a nonmodal tooltip. Coarse/touch hover is ignored, trigger activation is preserved, and reduced-motion uses the shared Popover styles and anchored overlay foundation.
513
513
  - 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.
514
514
  - 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.
515
- - DestructiveActionModal is the required shape for irreversible actions. Do not rebuild that confirmation from a plain Modal.
515
+ - DestructiveActionModal is the required shape for irreversible actions. Do not rebuild that confirmation from a plain Modal. It is also where high-risk, irreversible, or data-overwriting consequences are stated; do not move that warning into option second lines.
516
516
  - 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.
517
517
  - Tooltip carries a short label for a control. Anything a reader must read to decide belongs in the page or in a ContextCard.
518
518
 
@@ -523,9 +523,17 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
523
523
  - Gauge is one ratio as a ring. Progress is advancement along a task, and takes segment stops.
524
524
  - RelativeTimeCard reveals the absolute time behind a relative one. Prefer it to printing both.
525
525
 
526
+ CheckCircleFill accepts `tone?: 'default' | 'success'` (default `default`); success adds `.check-circle-fill--success`, using the same derived solid success fill as Badge and `--q1-color-action-on-primary` foreground; existing calls retain their DOM and appearance, and adjacent text conveys completion.
527
+
528
+
529
+ **Images and proportions.** AspectRatio requires a finite positive width/height ratio (invalid values render as 1 with one development warning) and only reserves layout space. Image requires alt (empty for decoration), defaults to contain and eager, accepts optional src, fit, loading, sm/md/lg square sizes (32/40/48), onError and root className; omitted size follows host width and natural image ratio. Loading keeps img mounted under a decorative Skeleton; missing and failed sources show a single named image fallback, and source changes isolate stale events. Decorative states are hidden from assistive technology; neither Image nor its host becomes inert. Inside AspectRatio, omit size: the Image root and img fill the ratio frame and object-fit controls complete centered containment or cropping. No new tokens or existing-consumer migration; remove new usages before reverting the additive exports.
530
+
526
531
  **Status and feedback.** Banner, ProjectBanner, Note, ErrorCard, RegionErrorState, ErrorMessage, EmptyState, Badge, Pill, CheckCircleFill, StatusDot, ToastProvider, useToast, Feedback, PageFeedback, Spinner, LoadingDots, Skeleton.
532
+ **Status and feedback.** Banner, ProjectBanner, Note, ErrorCard, RegionErrorState, ErrorMessage, EmptyState, Badge, Pill, CheckCircleFill, StatusDot, ToastProvider, useToast, Feedback, PageFeedback, Spinner, LoadingDots, Skeleton, StatusPage, SkeletonIllustration, EmptyListIllustration.
527
533
 
528
534
  - Banner announces at page scope. Note is an inline aside. ErrorMessage sits against one field. ErrorCard replaces a region that failed to load. Picking the widest one available overstates the problem.
535
+ - RegionErrorState replaces only the failed region in place (table body under a kept header, card body, page section) while the rest of the page stays usable: neutral surface, danger color on the icon only, polite `role=status` by default, built-in retry that keeps focus while `retrying`. ErrorCard is for a failure that blocks the current task (danger card, assertive `role=alert`). EmptyState is a successful load with no data: default `layout="center"` keeps the full empty view; `layout="inline"` is an icon and regular secondary title row inside a section whose heading and actions belong to the host, without description, actions, headingLevel, or illustration. Center accepts a decorative `illustration?: ReactNode` in place of icon; built-in `EmptyListIllustration` depicts a fully processed list or inbox, without an icon backplate. See `implementation-map.md` for the retry and announcement boundary.
536
+ - StatusPage defaults to a whole unavailable page with a caller-owned title, decorative SkeletonIllustration, plain-text description rendered as a paragraph, and actions. Its size="region" variant centers an icon or small illustration, title, description, and up to two actions inside a substantial content region, with a transparent background and content-driven height. ErrorCard covers a blocking compact failure; RegionErrorState is a compact retryable region message with its own status announcement; EmptyState means loading succeeded without content. StatusPage creates no live region; its host owns focus and announcements. StatusPage code is metadata only, never a message or spoken number.
529
537
  - RegionErrorState replaces only the failed region in place (table body under a kept header, card body, page section) while the rest of the page stays usable: neutral surface, danger color on the icon only, polite `role=status` by default, built-in retry that keeps focus while `retrying`. ErrorCard is for a failure that blocks the current task (danger card, assertive `role=alert`). EmptyState is a successful load with no data. See `implementation-map.md` for the retry and announcement boundary.
530
538
  - Toast is for non-blocking confirmation of something that already happened. It is not where an error the reader must act on belongs.
531
539
  - Badge and Pill label a state drawn from a known set. Ordinary metadata is text, not a badge. StatusDot is the smallest form, and needs a text label beside it.
@@ -604,6 +612,8 @@ Label, value, and detail spacing is identical across every peer in a set. One pa
604
612
 
605
613
  **Copy.** Sentence case headings that state the claim rather than name the section. Simplify the language, never the claim. Keep every qualifier attached to the number it qualifies.
606
614
 
615
+ Second-line text in options and list rows — option descriptions, row subtitles, and secondary labels — stays empty unless it adds information nothing else provides. Add it only when it carries information the label cannot: items at the same level share the same or easily confused labels and the primary text cannot explain itself, or choosing the item has a result the user cannot see from the label, such as ordering, scope, reach, or timing. Translations, restatements of the label, and decorative notes are not information. The pull request must give the reason. Treat second-line text as an exception patch for the primary message, not as standard layout. Severe consequences such as high-risk, irreversible, or data-overwriting actions are stated in the DestructiveActionModal confirmation, not in option or row second lines. When an external product is used as a reference, its second-line information is not carried over. Body descriptions of panels such as empty states, error states, and dialogs are the main message and are not second-line text; field helper text follows the existing note and tooltip rules.
616
+
607
617
  ## DO
608
618
 
609
619
  - Answer the reader's question in the first viewport, together with the one relationship the page turns on.
@@ -501,7 +501,7 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
501
501
 
502
502
 
503
503
  - 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.
504
- - Switch selects among mutually exclusive views or modes; its outer sm / md / lg heights are 32 / 40 / 48px on fine pointers, defaulting to md.
504
+ - Switch selects among mutually exclusive views or modes; its outer sm / md / lg heights are 32 / 40 / 48px on fine pointers, defaulting to md. Optional `variant="cards"` provides equal-width wrapping cards with a left-aligned label-12 label above caller-owned `meta` (number or ReactNode) in regular label-14 tabular figures, space-2 padding/gap and content-driven equal sm/md/lg height; cards alone use a two-pixel border-active selected border and inset line without a tint, a matching border-active label and the complete shared keyboard focus ring; disabled selected cards keep a neutral two-pixel border-strong outline with muted text, so the selection stays distinguishable. An auto-fit grid keeps any item count and its last row equally wide, with a readable 10rem minimum; the four-item example uses 全部 / 需要处理 / 更新 / 已归档 with numeric counts 128 / 12 / 8 / 32; the default `segmented` markup, dimensions and keyboard/radio semantics remain unchanged.
505
505
  - 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.
506
506
  - RangeSlider is two thumbs over one interval, paired with numeric inputs; Slider is a single value.
507
507
 
@@ -512,7 +512,7 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
512
512
  - HoverCard presents supplemental noninteractive content on fine-pointer hover or keyboard focus after openDelay (default 0ms); closeDelay defaults to 90ms and entering the card cancels closing. Escape dismisses without moving focus into the card; aria-describedby connects the named native trigger to a nonmodal tooltip. Coarse/touch hover is ignored, trigger activation is preserved, and reduced-motion uses the shared Popover styles and anchored overlay foundation.
513
513
  - 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.
514
514
  - 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.
515
- - DestructiveActionModal is the required shape for irreversible actions. Do not rebuild that confirmation from a plain Modal.
515
+ - DestructiveActionModal is the required shape for irreversible actions. Do not rebuild that confirmation from a plain Modal. It is also where high-risk, irreversible, or data-overwriting consequences are stated; do not move that warning into option second lines.
516
516
  - 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.
517
517
  - Tooltip carries a short label for a control. Anything a reader must read to decide belongs in the page or in a ContextCard.
518
518
 
@@ -523,9 +523,17 @@ Static WCAG stroke contrast against canvas/panel (2026-10-07): light neutral 5.3
523
523
  - Gauge is one ratio as a ring. Progress is advancement along a task, and takes segment stops.
524
524
  - RelativeTimeCard reveals the absolute time behind a relative one. Prefer it to printing both.
525
525
 
526
+ CheckCircleFill accepts `tone?: 'default' | 'success'` (default `default`); success adds `.check-circle-fill--success`, using the same derived solid success fill as Badge and `--q1-color-action-on-primary` foreground; existing calls retain their DOM and appearance, and adjacent text conveys completion.
527
+
528
+
529
+ **Images and proportions.** AspectRatio requires a finite positive width/height ratio (invalid values render as 1 with one development warning) and only reserves layout space. Image requires alt (empty for decoration), defaults to contain and eager, accepts optional src, fit, loading, sm/md/lg square sizes (32/40/48), onError and root className; omitted size follows host width and natural image ratio. Loading keeps img mounted under a decorative Skeleton; missing and failed sources show a single named image fallback, and source changes isolate stale events. Decorative states are hidden from assistive technology; neither Image nor its host becomes inert. Inside AspectRatio, omit size: the Image root and img fill the ratio frame and object-fit controls complete centered containment or cropping. No new tokens or existing-consumer migration; remove new usages before reverting the additive exports.
530
+
526
531
  **Status and feedback.** Banner, ProjectBanner, Note, ErrorCard, RegionErrorState, ErrorMessage, EmptyState, Badge, Pill, CheckCircleFill, StatusDot, ToastProvider, useToast, Feedback, PageFeedback, Spinner, LoadingDots, Skeleton.
532
+ **Status and feedback.** Banner, ProjectBanner, Note, ErrorCard, RegionErrorState, ErrorMessage, EmptyState, Badge, Pill, CheckCircleFill, StatusDot, ToastProvider, useToast, Feedback, PageFeedback, Spinner, LoadingDots, Skeleton, StatusPage, SkeletonIllustration, EmptyListIllustration.
527
533
 
528
534
  - Banner announces at page scope. Note is an inline aside. ErrorMessage sits against one field. ErrorCard replaces a region that failed to load. Picking the widest one available overstates the problem.
535
+ - RegionErrorState replaces only the failed region in place (table body under a kept header, card body, page section) while the rest of the page stays usable: neutral surface, danger color on the icon only, polite `role=status` by default, built-in retry that keeps focus while `retrying`. ErrorCard is for a failure that blocks the current task (danger card, assertive `role=alert`). EmptyState is a successful load with no data: default `layout="center"` keeps the full empty view; `layout="inline"` is an icon and regular secondary title row inside a section whose heading and actions belong to the host, without description, actions, headingLevel, or illustration. Center accepts a decorative `illustration?: ReactNode` in place of icon; built-in `EmptyListIllustration` depicts a fully processed list or inbox, without an icon backplate. See `implementation-map.md` for the retry and announcement boundary.
536
+ - StatusPage defaults to a whole unavailable page with a caller-owned title, decorative SkeletonIllustration, plain-text description rendered as a paragraph, and actions. Its size="region" variant centers an icon or small illustration, title, description, and up to two actions inside a substantial content region, with a transparent background and content-driven height. ErrorCard covers a blocking compact failure; RegionErrorState is a compact retryable region message with its own status announcement; EmptyState means loading succeeded without content. StatusPage creates no live region; its host owns focus and announcements. StatusPage code is metadata only, never a message or spoken number.
529
537
  - RegionErrorState replaces only the failed region in place (table body under a kept header, card body, page section) while the rest of the page stays usable: neutral surface, danger color on the icon only, polite `role=status` by default, built-in retry that keeps focus while `retrying`. ErrorCard is for a failure that blocks the current task (danger card, assertive `role=alert`). EmptyState is a successful load with no data. See `implementation-map.md` for the retry and announcement boundary.
530
538
  - Toast is for non-blocking confirmation of something that already happened. It is not where an error the reader must act on belongs.
531
539
  - Badge and Pill label a state drawn from a known set. Ordinary metadata is text, not a badge. StatusDot is the smallest form, and needs a text label beside it.
@@ -604,6 +612,8 @@ Label, value, and detail spacing is identical across every peer in a set. One pa
604
612
 
605
613
  **Copy.** Sentence case headings that state the claim rather than name the section. Simplify the language, never the claim. Keep every qualifier attached to the number it qualifies.
606
614
 
615
+ Second-line text in options and list rows — option descriptions, row subtitles, and secondary labels — stays empty unless it adds information nothing else provides. Add it only when it carries information the label cannot: items at the same level share the same or easily confused labels and the primary text cannot explain itself, or choosing the item has a result the user cannot see from the label, such as ordering, scope, reach, or timing. Translations, restatements of the label, and decorative notes are not information. The pull request must give the reason. Treat second-line text as an exception patch for the primary message, not as standard layout. Severe consequences such as high-risk, irreversible, or data-overwriting actions are stated in the DestructiveActionModal confirmation, not in option or row second lines. When an external product is used as a reference, its second-line information is not carried over. Body descriptions of panels such as empty states, error states, and dialogs are the main message and are not second-line text; field helper text follows the existing note and tooltip rules.
616
+
607
617
  ## DO
608
618
 
609
619
  - Answer the reader's question in the first viewport, together with the one relationship the page turns on.
@@ -18,6 +18,7 @@ import { MouseEvent as MouseEvent_2 } from 'react';
18
18
  import { MouseEventHandler } from 'react';
19
19
  import { PointerEventHandler } from 'react';
20
20
  import { ReactElement } from 'react';
21
+ import { ReactEventHandler } from 'react';
21
22
  import { ReactNode } from 'react';
22
23
  import { Ref } from 'react';
23
24
  import { RefAttributes } from 'react';
@@ -29,6 +30,14 @@ import { TextareaHTMLAttributes } from 'react';
29
30
 
30
31
  export declare function addDays(date: Date, amount: number): Date;
31
32
 
33
+ export declare function AspectRatio({ ratio, children, className }: AspectRatioProps): JSX.Element;
34
+
35
+ export declare type AspectRatioProps = {
36
+ ratio: number;
37
+ children: ReactNode;
38
+ className?: string;
39
+ };
40
+
32
41
  export declare function Attachment({ name, size, type, progress, error, onRetry, onRemove, }: AttachmentProps): JSX.Element;
33
42
 
34
43
  export declare type AttachmentProps = {
@@ -465,10 +474,11 @@ export declare type CheckboxProps = ControlOptionOwnProps & (FieldShellProps | F
465
474
  } & Omit<ControlOptionNativeInputProps, 'size'>;
466
475
 
467
476
  /** 装饰性圆底勾;当前或选中语义由宿主表达。 */
468
- export declare function CheckCircleFill({ className, ...props }: CheckCircleFillProps): JSX.Element;
477
+ export declare function CheckCircleFill({ className, tone, ...props }: CheckCircleFillProps): JSX.Element;
469
478
 
470
479
  export declare type CheckCircleFillProps = {
471
480
  className?: string;
481
+ tone?: 'default' | 'success';
472
482
  children?: never;
473
483
  [attribute: `data-${string}`]: string | number | boolean | undefined;
474
484
  };
@@ -998,15 +1008,27 @@ export declare function Drawer({ open, onClose, title, children, footer, height,
998
1008
  height?: number;
999
1009
  }): ReactNode;
1000
1010
 
1001
- export declare function EmptyState({ icon, title, description, actions, headingLevel, }: {
1011
+ /** 列表或收件箱内容已全部处理的装饰插画;状态含义由相邻文字表达。 */
1012
+ export declare function EmptyListIllustration(): JSX.Element;
1013
+
1014
+ export declare function EmptyState({ icon, illustration, title, description, actions, headingLevel, layout, }: {
1002
1015
  icon?: ReactNode;
1003
1016
  title: string;
1017
+ } & ({
1018
+ layout?: 'center';
1019
+ illustration?: ReactNode;
1004
1020
  description?: string;
1005
1021
  /** CTA 区:传家族 <Button> 与次要链接;最多一个主 CTA。 */
1006
1022
  actions?: ReactNode;
1007
1023
  /** 标题层级:缺省渲染 p(不进标题树);作为页面区块时传 2-6 渲染对应 h 标签。 */
1008
1024
  headingLevel?: 2 | 3 | 4 | 5 | 6;
1009
- }): JSX.Element;
1025
+ } | {
1026
+ layout: 'inline';
1027
+ illustration?: never;
1028
+ description?: never;
1029
+ actions?: never;
1030
+ headingLevel?: never;
1031
+ })): JSX.Element;
1010
1032
 
1011
1033
  /** Public host for consumer-owned sibling portals. Package overlays share this Foundation root. */
1012
1034
  export declare function ensurePopoverRoot(): HTMLElement | null;
@@ -1247,6 +1269,19 @@ export declare type IconButtonProps = IconButtonAccessibleName & IconButtonBaseP
1247
1269
  ref?: Ref<HTMLButtonElement>;
1248
1270
  };
1249
1271
 
1272
+ declare function Image_2({ src, alt, loading, fit, size, onError, className }: ImageProps): JSX.Element;
1273
+ export { Image_2 as Image }
1274
+
1275
+ export declare type ImageProps = {
1276
+ src?: string;
1277
+ alt: string;
1278
+ loading?: 'eager' | 'lazy';
1279
+ fit?: 'contain' | 'cover';
1280
+ size?: 'sm' | 'md' | 'lg';
1281
+ onError?: ReactEventHandler<HTMLImageElement>;
1282
+ className?: string;
1283
+ };
1284
+
1250
1285
  export declare function InfoTip({ label, content }: InfoTipProps): JSX.Element;
1251
1286
 
1252
1287
  export declare type InfoTipProps = {
@@ -2312,6 +2347,8 @@ declare type SkeletonDataAttributes = {
2312
2347
  [key: `data-${string}`]: string | number | boolean | null | undefined;
2313
2348
  };
2314
2349
 
2350
+ export declare function SkeletonIllustration(): JSX.Element;
2351
+
2315
2352
  export declare type SkeletonProps = {
2316
2353
  shape?: SkeletonShape;
2317
2354
  animated?: boolean;
@@ -2395,7 +2432,23 @@ export declare function StatusDot({ tone, label, showLabel, titlePrefix, }: {
2395
2432
 
2396
2433
  export declare type StatusDotTone = 'neutral' | 'warning' | 'success' | 'danger';
2397
2434
 
2398
- export declare function Switch({ options, ariaLabel, name, defaultValue, value, onChange, size, fullWidth, iconOnly, }: {
2435
+ export declare function StatusPage({ code, size, title, description, primaryAction, secondaryAction, illustration, icon, headingLevel }: StatusPageProps): JSX.Element;
2436
+
2437
+ export declare type StatusPageCode = '402' | '403' | '404' | '500' | 'offline' | 'timeout' | 'session-expired';
2438
+
2439
+ export declare type StatusPageProps = {
2440
+ code?: StatusPageCode;
2441
+ size?: 'page' | 'region';
2442
+ title: string;
2443
+ description?: string;
2444
+ primaryAction?: ReactNode;
2445
+ secondaryAction?: ReactNode;
2446
+ illustration?: ReactNode;
2447
+ icon?: ReactNode;
2448
+ headingLevel?: 1 | 2;
2449
+ };
2450
+
2451
+ export declare function Switch({ options, ariaLabel, name, defaultValue, value, onChange, size, variant, fullWidth, iconOnly, }: {
2399
2452
  options: SwitchOption[];
2400
2453
  ariaLabel: string;
2401
2454
  name?: string;
@@ -2403,6 +2456,7 @@ export declare function Switch({ options, ariaLabel, name, defaultValue, value,
2403
2456
  value?: string;
2404
2457
  onChange?: (value: string) => void;
2405
2458
  size?: 'sm' | 'md' | 'lg';
2459
+ variant?: 'segmented' | 'cards';
2406
2460
  fullWidth?: boolean;
2407
2461
  /** 纯图标模式:文字标签仍在,只是视觉隐藏(q1-sr-only),可访问名称不丢失。 */
2408
2462
  iconOnly?: boolean;