@q1travel/design-system 0.16.0 → 0.17.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.
@@ -3,14 +3,17 @@ import { ButtonHTMLAttributes } from 'react';
3
3
  import { ComponentPropsWithoutRef } from 'react';
4
4
  import { CSSProperties } from 'react';
5
5
  import { FocusEventHandler } from 'react';
6
+ import { ForwardRefExoticComponent } from 'react';
6
7
  import { HTMLAttributes } from 'react';
7
8
  import { InputHTMLAttributes } from 'react';
8
9
  import { JSX } from 'react';
9
10
  import { KeyboardEventHandler } from 'react';
10
11
  import { MouseEventHandler } from 'react';
12
+ import { PointerEventHandler } from 'react';
11
13
  import { ReactElement } from 'react';
12
14
  import { ReactNode } from 'react';
13
15
  import { Ref } from 'react';
16
+ import { RefAttributes } from 'react';
14
17
  import { RefObject } from 'react';
15
18
  import { SelectHTMLAttributes } from 'react';
16
19
  import { TableHTMLAttributes } from 'react';
@@ -123,10 +126,10 @@ export declare type BannerTone = 'neutral' | 'info' | 'success' | 'warning' | 'd
123
126
 
124
127
  export declare type BannerVariant = 'default' | 'success' | 'warning' | 'error';
125
128
 
126
- export declare function Book({ title, variant, color, bandColor, textColor, icon, illustration, textured, width, className, style, ...rest }: BookProps): JSX.Element;
129
+ export declare function Book({ title, variant, color, bandColor, textColor, icon, illustration, textured, width, className, style, onLostPointerCapture, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, ...rest }: BookProps): JSX.Element;
127
130
 
128
131
  export declare type BookProps = {
129
- /** 封面标题;语义由标题承载,封面其余元素均为装饰。 */
132
+ /** 封面标题;完整文本保留在 DOM,视觉最多四行;封面其余元素均为装饰。 */
130
133
  title: string;
131
134
  /** stripe=顶部色带+下方标签区(默认);simple=纯封面、标题置顶。 */
132
135
  variant?: 'stripe' | 'simple';
@@ -136,9 +139,9 @@ export declare type BookProps = {
136
139
  bandColor?: string;
137
140
  /** 标题颜色;自定义封面色时务必保证对比可读。 */
138
141
  textColor?: string;
139
- /** 装饰图标:stripe 置于色带中央,simple 置于标题上方;组件自动 aria-hidden。 */
142
+ /** 装饰图标:stripe 置于色带中央,simple 置于标题上方;组件自动 aria-hidden + inert。 */
140
143
  icon?: ReactNode;
141
- /** 整幅插画:铺满封面、裁切;标题浮于其上;aria-hidden。 */
144
+ /** 整幅插画:铺满封面、裁切;标题浮于其上;aria-hidden + inert。 */
142
145
  illustration?: ReactNode;
143
146
  /** 细密交叉纹理(自有配方);只提供单一纹理样式,未做多纹理体系(记 non-goal)。仅用于主视觉,成排书架勿用。 */
144
147
  textured?: boolean;
@@ -199,15 +202,67 @@ export declare type BrowserVariant = 'light' | 'dark';
199
202
 
200
203
  export declare function Button(props: ButtonProps): JSX.Element;
201
204
 
202
- declare type ButtonBaseProps = {
203
- variant?: ButtonVariant;
204
- size?: ButtonSize;
205
- svgOnly?: boolean;
205
+ declare type ButtonAccessibleName = {
206
+ 'aria-label': string;
207
+ /**
208
+ * @deprecated Deprecated in the unreleased post-0.4.0 migration on 2026-07-20.
209
+ * Use aria-label. Migration is tracked by #59; removal conditions are in contracts/button-api-compatibility.md.
210
+ */
211
+ ariaLabel?: string;
212
+ } | {
213
+ 'aria-label'?: never;
206
214
  /**
207
215
  * @deprecated Deprecated in the unreleased post-0.4.0 migration on 2026-07-20.
208
- * Use svgOnly. Migration is tracked by #59; removal conditions are in contracts/button-api-compatibility.md.
216
+ * Use aria-label. Migration is tracked by #59; removal conditions are in contracts/button-api-compatibility.md.
209
217
  */
218
+ ariaLabel: string;
219
+ };
220
+
221
+ declare type ButtonBaseProps = ButtonSharedProps & ButtonIconLayout;
222
+
223
+ declare type ButtonIconLayout = ({
224
+ svgOnly: true;
225
+ /** @deprecated Use svgOnly. Removal conditions are in contracts/button-api-compatibility.md. */
210
226
  iconOnly?: boolean;
227
+ } & ButtonAccessibleName) | ({
228
+ svgOnly?: undefined;
229
+ /** @deprecated Use svgOnly. Removal conditions are in contracts/button-api-compatibility.md. */
230
+ iconOnly?: boolean;
231
+ } & ButtonAccessibleName) | ({
232
+ svgOnly: false;
233
+ /** @deprecated Use svgOnly. Removal conditions are in contracts/button-api-compatibility.md. */
234
+ iconOnly?: boolean;
235
+ } & OptionalButtonAccessibleName) | ({
236
+ svgOnly?: undefined;
237
+ /** @deprecated Use svgOnly. Removal conditions are in contracts/button-api-compatibility.md. */
238
+ iconOnly?: false | undefined;
239
+ } & OptionalButtonAccessibleName);
240
+
241
+ export declare function ButtonLink(props: ButtonLinkProps): JSX.Element;
242
+
243
+ declare type ButtonLinkBaseProps = DistributiveOmit<ButtonBaseProps, 'type'>;
244
+
245
+ export declare type ButtonLinkProps = ButtonLinkBaseProps & Omit<ComponentPropsWithoutRef<'a'>, keyof ButtonLinkBaseProps | 'href'> & {
246
+ /**
247
+ * @deprecated Deprecated in the unreleased post-0.4.0 migration on 2026-07-20.
248
+ * ButtonLink renders an anchor and ignores this compatibility field.
249
+ * Migration is tracked by #59; removal conditions are in contracts/button-api-compatibility.md.
250
+ */
251
+ type?: ButtonBaseProps['type'];
252
+ href: string;
253
+ [dataAttribute: `data-${string}`]: string | number | boolean | null | undefined;
254
+ ref?: Ref<HTMLAnchorElement>;
255
+ };
256
+
257
+ export declare type ButtonProps = ButtonBaseProps & Omit<ComponentPropsWithoutRef<'button'>, keyof ButtonBaseProps> & {
258
+ [dataAttribute: `data-${string}`]: string | number | boolean | null | undefined;
259
+ /** 供 focus 管理、测量、浮层定位等场景使用。 */
260
+ ref?: Ref<HTMLButtonElement>;
261
+ };
262
+
263
+ declare type ButtonSharedProps = {
264
+ variant?: ButtonVariant;
265
+ size?: ButtonSize;
211
266
  /** 圆形——仅用于 icon-only 按钮。与 rounded 互斥(同传时 circle 优先)。 */
212
267
  circle?: boolean;
213
268
  /** 药丸形(full radius)+ 柔和抬起阴影,营销页/落地页文字 CTA 用。与 circle 互斥。 */
@@ -237,41 +292,11 @@ declare type ButtonBaseProps = {
237
292
  prefix?: ReactNode;
238
293
  /** 文字后置图标槽,同上。 */
239
294
  suffix?: ReactNode;
240
- 'aria-label'?: string;
241
- /**
242
- * @deprecated Deprecated in the unreleased post-0.4.0 migration on 2026-07-20.
243
- * Use aria-label. Migration is tracked by #59; removal conditions are in contracts/button-api-compatibility.md.
244
- */
245
- ariaLabel?: string;
246
295
  ariaKeyshortcuts?: string;
247
296
  /** 供 Tooltip 等外部浮层关联描述文本、绑定展开/收起时机用;不是 Button 自身的常规用法。 */
248
297
  'aria-describedby'?: string;
249
298
  };
250
299
 
251
- export declare function ButtonLink(props: ButtonLinkProps): JSX.Element;
252
-
253
- export declare type ButtonLinkProps = Omit<ButtonBaseProps, 'type'> & {
254
- /**
255
- * @deprecated Deprecated in the unreleased post-0.4.0 migration on 2026-07-20.
256
- * ButtonLink renders an anchor and ignores this compatibility field.
257
- * Migration is tracked by #59; removal conditions are in contracts/button-api-compatibility.md.
258
- */
259
- type?: ButtonBaseProps['type'];
260
- href: string;
261
- onClick?: MouseEventHandler<HTMLAnchorElement>;
262
- onFocus?: FocusEventHandler<HTMLAnchorElement>;
263
- onBlur?: FocusEventHandler<HTMLAnchorElement>;
264
- onKeyDown?: KeyboardEventHandler<HTMLAnchorElement>;
265
- 'aria-keyshortcuts'?: string;
266
- ref?: Ref<HTMLAnchorElement>;
267
- };
268
-
269
- export declare type ButtonProps = ButtonBaseProps & Omit<ComponentPropsWithoutRef<'button'>, keyof ButtonBaseProps> & {
270
- [dataAttribute: `data-${string}`]: string | number | boolean | null | undefined;
271
- /** 供 focus 管理、测量、浮层定位等场景使用。 */
272
- ref?: Ref<HTMLButtonElement>;
273
- };
274
-
275
300
  export declare type ButtonSize = 'sm' | 'md' | 'lg';
276
301
 
277
302
  export declare type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'warning' | 'danger';
@@ -359,7 +384,7 @@ declare type CheckboxOnlyProps = {
359
384
  /** Checkbox 的完整 props。消费方包一层时用它标注,无需知道内部由哪几块组合而成。 */
360
385
  export declare type CheckboxProps = ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & CheckboxOnlyProps & ControlOptionNativeInputProps;
361
386
 
362
- export declare function Choicebox({ type, label, description, extra, className, ...rest }: ChoiceboxProps): JSX.Element;
387
+ export declare function Choicebox({ type, label, description, extra, className, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, ...rest }: ChoiceboxProps): JSX.Element;
363
388
 
364
389
  declare type ChoiceboxNativeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
365
390
 
@@ -375,27 +400,30 @@ declare type ChoiceboxOwnProps = {
375
400
  /** Choicebox 的完整 props。 */
376
401
  export declare type ChoiceboxProps = ChoiceboxOwnProps & ChoiceboxNativeInputProps;
377
402
 
378
- export declare function ClearableInput({ id, placeholder, defaultValue, disabled, kbdHint, onClear, ariaLabel, }: ClearableInputProps): JSX.Element;
403
+ export declare function ClearableInput({ id, placeholder, value: controlledValue, defaultValue, onValueChange, disabled, readOnly, kbdHint, onClear, ariaLabel, ref, className, onChange: onInputChange, onKeyDown: onInputKeyDown, ...inputProps }: ClearableInputProps): JSX.Element;
379
404
 
380
405
  export declare type ClearableInputProps = {
381
406
  id: string;
382
- placeholder?: string;
407
+ value?: string;
383
408
  defaultValue?: string;
384
- disabled?: boolean;
385
- /** 空态时右侧显示 Esc/⌘K 快捷键提示,开始输入后让位给清除按钮。 */
409
+ /** 键入、点击清除和按 Esc 清除共用的值变化通道。 */
410
+ onValueChange?: (value: string) => void;
411
+ /** 有可清除内容时显示组件已真实接线的 Esc 提示。 */
386
412
  kbdHint?: boolean;
387
413
  /** 清空(点击清除按钮或按 Esc)时回调,用于联动外部状态。 */
388
414
  onClear?: () => void;
389
415
  /** 无可见 label 时的可访问名。有可见 label(FormField 组合)时勿再传——aria-label 会覆盖
390
416
  * 可见标签成为可访问名,视觉与播报分叉(WCAG 2.5.3 Label in Name)。 */
391
417
  ariaLabel?: string;
392
- };
418
+ /** React 19 ref-as-prop,指向原生 text input。 */
419
+ ref?: Ref<HTMLInputElement>;
420
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, 'aria-label' | 'defaultValue' | 'id' | 'ref' | 'type' | 'value'>;
393
421
 
394
- export declare function ClearButton({ className, label, onClick, }: {
422
+ export declare function ClearButton({ className, label, onClick, ...buttonProps }: {
395
423
  className: string;
396
424
  label: string;
397
425
  onClick: () => void;
398
- }): JSX.Element;
426
+ } & Omit<ComponentPropsWithoutRef<'button'>, 'aria-label' | 'className' | 'onClick' | 'type'>): JSX.Element;
399
427
 
400
428
  export declare function Code({ lines, ariaLabel }: {
401
429
  lines: CodeToken[][];
@@ -442,11 +470,13 @@ export declare function CodeTokens({ tokens }: {
442
470
  tokens: CodeToken[];
443
471
  }): JSX.Element;
444
472
 
445
- export declare function Collapse({ title, defaultOpen, small, children, }: {
473
+ export declare function Collapse({ title, defaultOpen, small, headingLevel, children, }: {
446
474
  /** 固定文案传字符串;随展开/收起切换文案(如"显示代码"/"收起代码")传函数,入参为当前 open 状态。 */
447
475
  title: string | ((open: boolean) => string);
448
476
  defaultOpen?: boolean;
449
477
  small?: boolean;
478
+ /** 标题层级:默认 h3;按宿主页面的标题树传 1-6。 */
479
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
450
480
  children: ReactNode;
451
481
  }): JSX.Element;
452
482
 
@@ -528,6 +558,8 @@ export declare type CommandMenuItem = {
528
558
  keybind?: string;
529
559
  /** 通用后缀(元信息文本/状态图标),装饰性 aria-hidden;语义信息应进 label。 */
530
560
  suffix?: ReactNode;
561
+ /** 面板先关闭并归还焦点,再同步执行命令;导航、新弹层与异步状态由调用方负责。 */
562
+ onSelect?: () => void;
531
563
  };
532
564
 
533
565
  export declare type CommandMenuProps = {
@@ -543,22 +575,47 @@ export declare type CommandMenuSection = {
543
575
  items: CommandMenuItem[];
544
576
  };
545
577
 
546
- export declare function ContextCard({ name, identity, rows, action, placement, align, children, }: ContextCardProps): JSX.Element;
578
+ export declare function ContextCard({ name, identity, rows, action, onAction, actionHref, placement, align, children, }: ContextCardProps): JSX.Element;
579
+
580
+ declare type ContextCardAction = {
581
+ action?: string;
582
+ onAction?: never;
583
+ actionHref?: never;
584
+ } | {
585
+ action: string;
586
+ onAction: MouseEventHandler<HTMLButtonElement>;
587
+ actionHref?: never;
588
+ } | {
589
+ action: string;
590
+ actionHref: string;
591
+ onAction?: never;
592
+ };
547
593
 
548
594
  export declare type ContextCardAlign = 'start' | 'center' | 'end';
549
595
 
550
596
  export declare type ContextCardPlacement = 'top' | 'bottom' | 'left' | 'right';
551
597
 
552
- export declare type ContextCardProps = {
598
+ export declare type ContextCardProps = ContextCardAction & {
553
599
  name: string;
554
600
  identity: string;
555
601
  rows: [string, string][];
556
- action?: string;
557
602
  placement?: ContextCardPlacement;
558
603
  align?: ContextCardAlign;
604
+ /** 自定义组件应接受 ContextCardTriggerProps,并把注入的 class、ARIA 与事件转发到真实交互元素。 */
559
605
  children: ReactNode;
560
606
  };
561
607
 
608
+ export declare type ContextCardTriggerProps = {
609
+ className?: string;
610
+ 'aria-expanded'?: boolean;
611
+ 'aria-controls'?: string;
612
+ onFocus?: FocusEventHandler<HTMLElement>;
613
+ onBlur?: FocusEventHandler<HTMLElement>;
614
+ onPointerDown?: PointerEventHandler<HTMLElement>;
615
+ onClick?: MouseEventHandler<HTMLElement>;
616
+ onKeyDown?: KeyboardEventHandler<HTMLElement>;
617
+ };
618
+
562
619
  export declare function ContextMenu({ label, entries, children, }: {
563
620
  label: string;
564
621
  entries: ContextMenuEntry[];
@@ -572,6 +629,7 @@ export declare type ContextMenuEntry = {
572
629
  suffix?: ReactNode;
573
630
  disabled?: boolean;
574
631
  danger?: boolean;
632
+ onSelect?: () => void;
575
633
  } | {
576
634
  type: 'link';
577
635
  label: string;
@@ -660,7 +718,7 @@ export declare type ContextSwitcherSearch = {
660
718
  noResults: ContextSwitcherEmptyState;
661
719
  };
662
720
 
663
- export declare function ControlOption({ id, label, description, error, indeterminate, ref, type, ...rest }: ControlOptionProps): JSX.Element;
721
+ 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;
664
722
 
665
723
  declare type ControlOptionNativeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'type'>;
666
724
 
@@ -703,9 +761,11 @@ export declare function DestructiveActionModal({ open, onClose, title, descripti
703
761
  irreversibleDescription?: string;
704
762
  /** 提交进行中:双按钮禁用、主操作显示加载指示;open 由调用方控制,加载中模态保持打开。 */
705
763
  loading?: boolean;
706
- onConfirm: () => string | null;
764
+ onConfirm: () => string | null | Promise<string | null>;
707
765
  }): ReactNode;
708
766
 
767
+ declare type DistributiveOmit<Props, Keys extends PropertyKey> = Props extends unknown ? Omit<Props, Keys> : never;
768
+
709
769
  export declare type DocsPageLink = {
710
770
  title: string;
711
771
  href: string;
@@ -729,6 +789,8 @@ export declare type DotsMenuEntry = {
729
789
  label: string;
730
790
  disabled?: boolean;
731
791
  danger?: boolean;
792
+ /** 菜单先关闭并归还焦点,再同步执行动作;确认、撤销与异步状态由调用方负责。 */
793
+ onSelect?: () => void;
732
794
  };
733
795
 
734
796
  export declare function Drawer({ open, onClose, title, children, footer, height, }: {
@@ -764,14 +826,16 @@ export declare function ErrorCard({ title, message, action }: {
764
826
  action?: ReactNode;
765
827
  }): JSX.Element;
766
828
 
767
- export declare function ErrorMessage({ label, size, action, children, }: {
829
+ export declare function ErrorMessage({ label, size, action, children, className, 'aria-live': ariaLive, 'aria-atomic': ariaAtomic, ...nativeProps }: ErrorMessageProps): JSX.Element;
830
+
831
+ export declare type ErrorMessageProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> & {
768
832
  /** 可见的粗体标签前缀(如「邮箱错误:」),点明出错对象;缺省不显示(q1-sr-only 前缀恒在)。 */
769
833
  label?: string;
770
834
  size?: ErrorMessageSize;
771
- /** 恢复操作插槽:可安全重试用「重试」按钮,链接式出口放 <a>。 */
835
+ /** 恢复操作插槽;字段可重新验证时传 Button,链接式出口传原生链接或 Link。 */
772
836
  action?: ReactNode;
773
837
  children: ReactNode;
774
- }): JSX.Element;
838
+ };
775
839
 
776
840
  export declare type ErrorMessageSize = 'sm' | 'md' | 'lg';
777
841
 
@@ -783,14 +847,26 @@ export declare type ExternalOverlayRegistration = {
783
847
  getContainer: () => HTMLElement | null;
784
848
  };
785
849
 
786
- export declare function Feedback({ label, prompt, placeholder, inline, topics, }: {
850
+ export declare function Feedback({ label, prompt, placeholder, inline, topics, onSubmit, disabled, }: FeedbackProps): JSX.Element;
851
+
852
+ export declare interface FeedbackProps {
787
853
  label?: string;
788
854
  prompt?: string;
789
855
  /** textarea 占位:换成更具体的引导,帮助用户知道从哪里说起。 */
790
856
  placeholder?: string;
791
857
  inline?: boolean;
792
858
  topics?: string[];
793
- }): JSX.Element;
859
+ onSubmit?: (payload: FeedbackSubmitPayload) => void | Promise<void>;
860
+ disabled?: boolean;
861
+ }
862
+
863
+ export declare type FeedbackRating = 1 | 2 | 3 | 4;
864
+
865
+ export declare interface FeedbackSubmitPayload {
866
+ rating: FeedbackRating | null;
867
+ topic: string;
868
+ comment: string;
869
+ }
794
870
 
795
871
  declare type FieldBareProps = {
796
872
  label?: never;
@@ -798,7 +874,7 @@ declare type FieldBareProps = {
798
874
  error?: never;
799
875
  };
800
876
 
801
- export declare function Fieldset({ title, subtitle, tone, footerStatus, footerAction, disabled, children, }: {
877
+ export declare function Fieldset({ title, subtitle, tone, footerStatus, footerAction, disabled, children, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, }: {
802
878
  title?: string;
803
879
  subtitle: string;
804
880
  tone?: FieldsetTone;
@@ -806,6 +882,10 @@ export declare function Fieldset({ title, subtitle, tone, footerStatus, footerAc
806
882
  footerAction?: ReactNode;
807
883
  disabled?: boolean;
808
884
  children?: ReactNode;
885
+ /** 无可见 title 时,为字段组提供可访问名称。 */
886
+ 'aria-label'?: string;
887
+ /** 用外部可见文本命名字段组;与原生 fieldset 属性一致。 */
888
+ 'aria-labelledby'?: string;
809
889
  }): JSX.Element;
810
890
 
811
891
  export declare type FieldsetTone = 'danger' | 'warning';
@@ -856,7 +936,7 @@ export declare type GaugeToneDirection = 'quota' | 'health';
856
936
  /** One coordinator per document, shared with all package overlays. Null during SSR. */
857
937
  export declare function getOverlayCoordinator(doc?: Document | null): OverlayCoordinator | null;
858
938
 
859
- export declare function IconButton({ 'aria-label': canonicalAriaLabel, ariaLabel: legacyAriaLabel, ...rest }: IconButtonProps): JSX.Element;
939
+ export declare function IconButton({ 'aria-label': canonicalAriaLabel, ariaLabel: legacyAriaLabel, 'aria-pressed': ariaPressed, disabled, loading, onClick, onBlur, onKeyDown, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, onLostPointerCapture, ...rest }: IconButtonProps): JSX.Element;
860
940
 
861
941
  declare type IconButtonAccessibleName = {
862
942
  'aria-label': string;
@@ -891,7 +971,7 @@ export declare type IconButtonProps = IconButtonAccessibleName & IconButtonBaseP
891
971
  ref?: Ref<HTMLButtonElement>;
892
972
  };
893
973
 
894
- export declare function Input({ id, label, description, error, invalid, errorId, ref, prefix, suffix, prefixStyling, suffixStyling, rounded, wide, size, className, revealable, revealed, onRevealedChange, revealLabel, hideLabel, ...rest }: {
974
+ 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 }: {
895
975
  /** 可选:未传时内部 useId 兜底(对齐 Combobox);显式传入时行为同 0.3.0。 */
896
976
  id?: string;
897
977
  /** 置 aria-invalid 的业务校验态,不渲染文案;与壳模式 error 并轨(invalid || Boolean(error))。 */
@@ -933,13 +1013,13 @@ export declare function Input({ id, label, description, error, invalid, errorId,
933
1013
  export declare function JsonView({ value, singleLine, wrap, collapsedDepth, highlight, embedded, label, className, }: JsonViewProps): JSX.Element;
934
1014
 
935
1015
  export declare type JsonViewProps = {
936
- /** 要展示的值。函数与 symbol 不属于 JSON,会渲染为不可序列化标记。 */
1016
+ /** 要展示的值。函数、symbol 与 undefined 不属于 JSON,会渲染为不可序列化标记。 */
937
1017
  value: unknown;
938
- /** 单行紧凑呈现:折叠全部层级、不换行,用于表格单元格或日志行。 */
1018
+ /** 单行紧凑呈现:压平全部层级、不换行,用于表格单元格或日志行。 */
939
1019
  singleLine?: boolean;
940
- /** 长字符串在容器内换行,而不是横向滚动。 */
1020
+ /** 长字符串在容器内换行,而不是横向滚动;singleLine 为 true 时单行优先。 */
941
1021
  wrap?: boolean;
942
- /** 初始折叠深度:0 表示只展开根,1 表示展开一层;缺省全部展开。 */
1022
+ /** 初始折叠深度:0 表示全部折叠,1 表示只展开根;缺省全部展开。 */
943
1023
  collapsedDepth?: number;
944
1024
  /** 需要强调的键。`a.b` 形式按完整路径精确匹配;裸键名(如 `status`)在任意深度命中,
945
1025
  * 用于「把所有 status 字段都标出来」这类排查。两种写法可混用。 */
@@ -981,16 +1061,16 @@ export declare function Label({ htmlFor, required, children, }: {
981
1061
  export declare function Link({ href, tone, external, className, children, ref, ...rest }: LinkProps): JSX.Element;
982
1062
 
983
1063
  export declare type LinkProps = {
984
- /** 目标地址。省略时渲染为不可点的当前项文本(例:面包屑末节、已停用的外链)。 */
1064
+ /** 目标地址。省略时渲染为静态文本,不表示 disabled 链接。 */
985
1065
  href?: string;
986
1066
  tone?: LinkTone;
987
1067
  /**
988
1068
  * 站外链接:追加一枚外链图标,并补 rel="noopener noreferrer"。
989
1069
  *
990
- * 图标不是装饰——它是「点下去会离开当前上下文」的预告。省掉它,用户要到新标签页
991
- * 打开之后才知道自己被带走了。
1070
+ * 图标提示目的地位于站外;是否新开标签页仍由 target 决定。
992
1071
  */
993
1072
  external?: boolean;
1073
+ /** 仅在 href 存在、渲染为原生锚点时绑定。 */
994
1074
  ref?: Ref<HTMLAnchorElement>;
995
1075
  children?: ReactNode;
996
1076
  } & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>;
@@ -1004,13 +1084,18 @@ export declare function LoadingDots({ label, size }: {
1004
1084
 
1005
1085
  export declare type LoadingDotsSize = 'sm' | 'md' | 'lg' | number;
1006
1086
 
1007
- export declare function LoadMoreButton({ loading, noGap, noBorderRadius, onClick, children, }: {
1087
+ export declare function LoadMoreButton({ loading, loadingLabel, noGap, noBorderRadius, disabled, type, className, children, onClick, onKeyDown, ref, 'aria-disabled': ariaDisabled, ...nativeProps }: LoadMoreButtonProps): JSX.Element;
1088
+
1089
+ declare type LoadMoreButtonOwnProps = {
1008
1090
  loading?: boolean;
1091
+ loadingLabel?: string;
1009
1092
  noGap?: boolean;
1010
1093
  noBorderRadius?: boolean;
1011
- onClick?: () => void;
1012
1094
  children: ReactNode;
1013
- }): JSX.Element;
1095
+ ref?: Ref<HTMLButtonElement>;
1096
+ };
1097
+
1098
+ export declare type LoadMoreButtonProps = LoadMoreButtonOwnProps & Omit<ComponentPropsWithoutRef<'button'>, keyof LoadMoreButtonOwnProps>;
1014
1099
 
1015
1100
  export declare function Menu({ label, entries, withChevron, align, triggerContent }: {
1016
1101
  label: string;
@@ -1021,26 +1106,57 @@ export declare function Menu({ label, entries, withChevron, align, triggerConten
1021
1106
  triggerContent?: ReactNode;
1022
1107
  }): JSX.Element;
1023
1108
 
1024
- export declare type MenuEntry = {
1109
+ export declare type MenuEntry = (MenuItemBase & {
1110
+ disabled?: boolean;
1111
+ locked?: false;
1112
+ lockedReason?: never;
1113
+ /** 菜单先完成逻辑关闭,再同步执行该动作;异步状态与后续确认由调用方负责。 */
1114
+ onSelect: () => void;
1115
+ }) | (MenuItemBase & {
1116
+ disabled: true;
1117
+ locked?: false;
1118
+ lockedReason?: never;
1119
+ onSelect?: never;
1120
+ }) | (MenuItemBase & {
1121
+ disabled?: false;
1122
+ locked: true;
1123
+ /** 锁定原因会并入 menuitem 的可访问名称。 */
1124
+ lockedReason: string;
1125
+ onSelect?: never;
1126
+ }) | (MenuLinkBase & {
1127
+ disabled?: false;
1128
+ locked?: false;
1129
+ lockedReason?: never;
1130
+ }) | (MenuLinkBase & {
1131
+ disabled: true;
1132
+ locked?: false;
1133
+ lockedReason?: never;
1134
+ }) | (MenuLinkBase & {
1135
+ disabled?: false;
1136
+ locked: true;
1137
+ lockedReason: string;
1138
+ }) | {
1139
+ type: 'section';
1140
+ label: string;
1141
+ } | {
1142
+ type: 'separator';
1143
+ };
1144
+
1145
+ declare type MenuItemBase = {
1025
1146
  type: 'item';
1026
1147
  label: string;
1027
1148
  icon?: ReactNode;
1028
- /** 后缀内容(如快捷键提示);locked 项在未显式传入 suffix 时仍兜底显示锁图标。 */
1149
+ /** 后缀内容(如快捷键提示);locked 项未显式传入时显示锁定原因。 */
1029
1150
  suffix?: ReactNode;
1030
- disabled?: boolean;
1031
- locked?: boolean;
1032
1151
  danger?: boolean;
1033
- } | {
1152
+ };
1153
+
1154
+ declare type MenuLinkBase = {
1034
1155
  type: 'link';
1035
1156
  label: string;
1036
1157
  href: string;
1037
1158
  icon?: ReactNode;
1038
1159
  suffix?: ReactNode;
1039
- } | {
1040
- type: 'section';
1041
- label: string;
1042
- } | {
1043
- type: 'separator';
1044
1160
  };
1045
1161
 
1046
1162
  export declare function MiddleTruncate({ text, tailLength, mono }: {
@@ -1166,20 +1282,43 @@ declare type NavigationSectionWithLabel = NavigationSectionNativeProps & Omit<Na
1166
1282
  label: NavigationSectionLabel;
1167
1283
  };
1168
1284
 
1169
- export declare function Note({ tone, size, filled, disabled, label, action, children, }: {
1285
+ export declare function Note({ tone, size, filled, disabled, label, action, children, }: NoteProps): JSX.Element;
1286
+
1287
+ export declare type NoteAction = {
1288
+ type: 'button';
1289
+ label: string;
1290
+ onClick: MouseEventHandler<HTMLButtonElement>;
1291
+ href?: never;
1292
+ } | {
1293
+ type: 'link';
1294
+ label: string;
1295
+ href: string;
1296
+ onClick?: never;
1297
+ };
1298
+
1299
+ export declare type NoteProps = {
1170
1300
  tone?: NoteTone;
1171
1301
  size?: NoteSize;
1172
1302
  filled?: boolean;
1173
1303
  disabled?: boolean;
1174
1304
  label?: string;
1175
- action?: string;
1305
+ action?: NoteAction;
1176
1306
  children: ReactNode;
1177
- }): JSX.Element;
1307
+ };
1178
1308
 
1179
1309
  export declare type NoteSize = 'small' | 'default' | 'large';
1180
1310
 
1181
1311
  export declare type NoteTone = 'info' | 'success' | 'warning' | 'error' | 'secondary';
1182
1312
 
1313
+ declare type OptionalButtonAccessibleName = {
1314
+ 'aria-label'?: string;
1315
+ /**
1316
+ * @deprecated Deprecated in the unreleased post-0.4.0 migration on 2026-07-20.
1317
+ * Use aria-label. Migration is tracked by #59; removal conditions are in contracts/button-api-compatibility.md.
1318
+ */
1319
+ ariaLabel?: string;
1320
+ };
1321
+
1183
1322
  export declare type OverlayCoordinator = {
1184
1323
  register: (entry: ExternalOverlayRegistration) => () => void;
1185
1324
  isTopMost: (id: string) => boolean;
@@ -1224,11 +1363,11 @@ export declare function PeriodCombobox({ presets, activeLabel, onPick, }: {
1224
1363
  onPick: (preset: CalendarPreset) => void;
1225
1364
  }): JSX.Element;
1226
1365
 
1227
- export declare function Phone({ screenLabel }: {
1228
- screenLabel: string;
1366
+ export declare function Phone({ children }: {
1367
+ children: ReactNode;
1229
1368
  }): JSX.Element;
1230
1369
 
1231
- export declare function Pill({ href, size, icon, title, className, children, ...rest }: PillProps): JSX.Element;
1370
+ export declare function Pill({ href, size, icon, title, className, children, onBlur, onKeyDown, onLostPointerCapture, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, ...rest }: PillProps): JSX.Element;
1232
1371
 
1233
1372
  export declare type PillProps = {
1234
1373
  href: string;
@@ -1255,11 +1394,25 @@ export declare type ProgressStop = number | {
1255
1394
  label?: string;
1256
1395
  };
1257
1396
 
1258
- export declare function ProjectBanner({ variant, message, cta }: {
1397
+ export declare function ProjectBanner({ variant, message, action }: ProjectBannerProps): JSX.Element;
1398
+
1399
+ export declare type ProjectBannerAction = {
1400
+ type: 'button';
1401
+ label: string;
1402
+ onClick: MouseEventHandler<HTMLButtonElement>;
1403
+ href?: never;
1404
+ } | {
1405
+ type: 'link';
1406
+ label: string;
1407
+ href: string;
1408
+ onClick?: never;
1409
+ };
1410
+
1411
+ export declare type ProjectBannerProps = {
1259
1412
  variant?: BannerVariant;
1260
1413
  message: string;
1261
- cta: string;
1262
- }): JSX.Element;
1414
+ action: ProjectBannerAction;
1415
+ };
1263
1416
 
1264
1417
  export declare function Radio({ ...props }: RadioProps): JSX.Element;
1265
1418
 
@@ -1279,22 +1432,34 @@ export declare function RangeField({ layout, trigger, size, minValue, maxValue,
1279
1432
  onChange: (next: RangeValue) => void;
1280
1433
  }): JSX.Element;
1281
1434
 
1282
- export declare function RangeInputs({ value, withTime, onApply, pinnedTimezone, }: {
1435
+ export declare function RangeInputs({ value, onApply, pinnedTimezone, }: {
1283
1436
  value: RangeValue;
1437
+ /** 兼容保留;当前组件不提供时间值或时间编辑能力。 */
1284
1438
  withTime: boolean;
1285
1439
  onApply: () => void;
1286
1440
  /** 固定时区:传入时时区从可选 select 变只读文本、不可切换。 */
1287
1441
  pinnedTimezone?: string;
1288
1442
  }): JSX.Element;
1289
1443
 
1290
- export declare function RangeSlider({ min, max, step, defaultLow, defaultHigh, disabled }: {
1444
+ export declare const RangeSlider: ForwardRefExoticComponent<RangeSliderProps & RefAttributes<HTMLInputElement>>;
1445
+
1446
+ export declare type RangeSliderProps = {
1447
+ label?: string;
1448
+ unit?: string;
1291
1449
  min?: number;
1292
1450
  max?: number;
1293
1451
  step?: number;
1294
- defaultLow: number;
1295
- defaultHigh: number;
1452
+ defaultLow?: number;
1453
+ defaultHigh?: number;
1454
+ value?: RangeSliderValue;
1455
+ onValueChange?: (value: RangeSliderValue) => void;
1456
+ id?: string;
1457
+ name?: string;
1296
1458
  disabled?: boolean;
1297
- }): JSX.Element;
1459
+ 'aria-describedby'?: string;
1460
+ };
1461
+
1462
+ export declare type RangeSliderValue = readonly [low: number, high: number];
1298
1463
 
1299
1464
  export declare type RangeValue = {
1300
1465
  start: Date | null;
@@ -1360,29 +1525,44 @@ export declare type SearchDialogTriggerProps = {
1360
1525
  'aria-controls': string;
1361
1526
  };
1362
1527
 
1363
- export declare function SearchInput({ id, ariaLabel, placeholder, defaultValue, disabled, loading, kbdHint, icon, }: {
1528
+ 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;
1529
+
1530
+ export declare type SearchInputProps = {
1364
1531
  id: string;
1365
- ariaLabel: string;
1366
- placeholder: string;
1532
+ /** 无可见 label 时的可访问名;与 FormField 或外部 label 组合时留空。 */
1533
+ ariaLabel?: string;
1534
+ value?: string;
1367
1535
  defaultValue?: string;
1368
- disabled?: boolean;
1536
+ /** 键入、点击清除和按 Esc 清除共用的值变化通道。 */
1537
+ onValueChange?: (value: string) => void;
1369
1538
  loading?: boolean;
1370
- kbdHint?: boolean;
1539
+ /** true 显示跨平台 Meta/Ctrl+K;也可传消费方已真实接线的自定义 Kbd 节点。 */
1540
+ kbdHint?: ReactNode;
1371
1541
  icon?: ReactNode;
1372
- }): JSX.Element;
1542
+ /** React 19 ref-as-prop,指向原生 search input。 */
1543
+ ref?: Ref<HTMLInputElement>;
1544
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, 'aria-label' | 'defaultValue' | 'id' | 'onChange' | 'ref' | 'type' | 'value'>;
1373
1545
 
1374
- export declare function Select({ id, label, description, error, wide, size, prefix, suffix, className, children, ...rest }: {
1546
+ 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 }: {
1375
1547
  id: string;
1376
1548
  label: string;
1377
1549
  description?: string;
1378
1550
  error?: string;
1551
+ /** 指向原生 select(React 19 ref-as-prop),供表单校验后聚焦等场景。 */
1552
+ ref?: Ref<HTMLSelectElement>;
1379
1553
  wide?: boolean;
1380
1554
  size?: FieldSize;
1381
1555
  prefix?: ReactNode;
1382
1556
  /** 装饰性后缀图标(aria-hidden),渲染在下拉箭头左侧;跟 prefix 前缀一样不承载信息,可访问名称仍完全来自 label。 */
1383
1557
  suffix?: ReactNode;
1384
1558
  children: ReactNode;
1385
- } & Omit<SelectHTMLAttributes<HTMLSelectElement>, 'id' | 'children' | 'size' | 'prefix'>): JSX.Element;
1559
+ /** Select 只接受单一值;多值选择使用 MultiSelect。 */
1560
+ value?: string | number;
1561
+ /** Select 只接受单一默认值;多值选择使用 MultiSelect。 */
1562
+ defaultValue?: string | number;
1563
+ /** Select 是单选字段;多值选择使用 MultiSelect。 */
1564
+ multiple?: never;
1565
+ } & Omit<SelectHTMLAttributes<HTMLSelectElement>, 'id' | 'children' | 'size' | 'prefix' | 'multiple' | 'value' | 'defaultValue'>): JSX.Element;
1386
1566
 
1387
1567
  export declare function Separator({ orientation, decorative, className, }: {
1388
1568
  orientation?: SeparatorOrientation;
@@ -1411,7 +1591,7 @@ export declare function ShowMore({ items, initial, noBorder, initialExpanded, }:
1411
1591
  items: string[];
1412
1592
  initial?: number;
1413
1593
  noBorder?: boolean;
1414
- /** 仅用于演示常驻展开态的初始值;组件仍是非受控的,不支持中途从外部切换展开状态。 */
1594
+ /** 仅用于演示初始展开态;组件仍是非受控的,不支持中途从外部切换展开状态。 */
1415
1595
  initialExpanded?: boolean;
1416
1596
  }): JSX.Element;
1417
1597
 
@@ -1465,25 +1645,41 @@ export declare type SidebarSlotProps = HTMLAttributes<HTMLDivElement>;
1465
1645
 
1466
1646
  export declare type SidebarVariant = 'panel' | 'plain';
1467
1647
 
1468
- export declare function Skeleton({ shape, animated, show, className, children, }: {
1648
+ export declare function Skeleton({ shape, animated, show, as: Component, className, children, ...rest }: SkeletonProps): JSX.Element;
1649
+
1650
+ declare type SkeletonDataAttributes = {
1651
+ [key: `data-${string}`]: string | number | boolean | null | undefined;
1652
+ };
1653
+
1654
+ export declare type SkeletonProps = {
1469
1655
  shape?: SkeletonShape;
1470
1656
  animated?: boolean;
1471
1657
  /** 包裹模式:数据就绪后置 true,原地显示子内容。 */
1472
1658
  show?: boolean;
1659
+ /** 默认 span 适合短文案与控件;包裹块级内容时显式使用 div。 */
1660
+ as?: 'span' | 'div';
1473
1661
  className?: string;
1474
1662
  children?: ReactNode;
1475
- }): JSX.Element;
1663
+ } & Omit<HTMLAttributes<HTMLElement>, 'aria-hidden' | 'children' | 'className'> & SkeletonDataAttributes;
1476
1664
 
1477
1665
  export declare type SkeletonShape = 'rounded' | 'pill' | 'squared';
1478
1666
 
1479
- export declare function Slider({ label, unit, min, max, step, defaultValue }: {
1667
+ export declare const Slider: ForwardRefExoticComponent<SliderProps & RefAttributes<HTMLInputElement>>;
1668
+
1669
+ export declare type SliderProps = {
1480
1670
  label: string;
1481
1671
  unit: string;
1482
1672
  min?: number;
1483
1673
  max?: number;
1484
1674
  step?: number;
1485
- defaultValue: number;
1486
- }): JSX.Element;
1675
+ defaultValue?: number;
1676
+ value?: number;
1677
+ onValueChange?: (value: number) => void;
1678
+ id?: string;
1679
+ name?: string;
1680
+ disabled?: boolean;
1681
+ 'aria-describedby'?: string;
1682
+ };
1487
1683
 
1488
1684
  export declare function Snippet({ text, prompt, inverted, tone, copyText, onCopy, }: {
1489
1685
  text: string | string[];
@@ -1508,7 +1704,7 @@ export declare type SpinnerSize = 'sm' | 'md' | 'lg' | 'xl';
1508
1704
 
1509
1705
  export declare type SpinnerTone = 'default' | 'danger' | 'success' | 'info';
1510
1706
 
1511
- export declare function SplitButton({ label, entries, variant, size, align, menuButtonLabel, icon }: {
1707
+ export declare function SplitButton({ label, entries, variant, size, align, menuButtonLabel, icon, disabled, loading, loadingLabel, }: {
1512
1708
  label: string;
1513
1709
  entries: SplitButtonEntry[];
1514
1710
  variant?: 'default' | 'secondary';
@@ -1516,12 +1712,17 @@ export declare function SplitButton({ label, entries, variant, size, align, menu
1516
1712
  align?: 'start' | 'end';
1517
1713
  menuButtonLabel: string;
1518
1714
  icon?: ReactNode;
1715
+ disabled?: boolean;
1716
+ loading?: boolean;
1717
+ loadingLabel?: string;
1519
1718
  }): JSX.Element;
1520
1719
 
1521
1720
  export declare type SplitButtonEntry = {
1522
1721
  label: string;
1523
1722
  danger?: boolean;
1524
1723
  icon?: ReactNode;
1724
+ disabled?: boolean;
1725
+ onSelect?: () => void;
1525
1726
  };
1526
1727
 
1527
1728
  export declare function StatusDot({ tone, label, animated, showLabel, titlePrefix, }: {
@@ -1563,7 +1764,7 @@ export declare type TabItem = {
1563
1764
  content: ReactNode;
1564
1765
  icon?: ReactNode;
1565
1766
  disabled?: boolean;
1566
- /** 禁用原因(原生 title,桌面端悬浮显示);放在外层包装上,因为禁用按钮本身在部分浏览器不触发 hover。 */
1767
+ /** 禁用原因;在 tablist 下方常显,并通过 aria-describedby 与禁用标签关联。 */
1567
1768
  tooltip?: string;
1568
1769
  };
1569
1770
 
@@ -1784,6 +1985,7 @@ export declare type UnknownTailPaginationProps = PaginationCommonProps & {
1784
1985
 
1785
1986
  export declare function useCopy(): {
1786
1987
  copied: boolean;
1988
+ pending: boolean;
1787
1989
  copy: (value: string, successMessage?: string) => Promise<void>;
1788
1990
  reset: () => void;
1789
1991
  };
@@ -1826,21 +2028,37 @@ export declare type VerificationCodeInputProps = {
1826
2028
  'aria-label'?: never;
1827
2029
  })));
1828
2030
 
1829
- export declare function Video({ src, poster, tracks, label, controls, loop, }: VideoProps): JSX.Element;
2031
+ export declare function Video({ src, poster, tracks, label, purpose, controls, loop, muted, }: VideoProps): JSX.Element;
1830
2032
 
1831
- export declare type VideoProps = {
2033
+ declare type VideoBaseProps = {
1832
2034
  /** 视频源,必填。组件不持有任何资产路径——写死默认值会让消费方开箱即拿到不存在的地址。 */
1833
2035
  src: string;
1834
- /** 首帧海报,兼作弱网/加载失败的兜底画面;缺省时浏览器显示首帧或空白,属合理降级。 */
2036
+ /** 首帧海报;媒体数据尚未加载时保持稳定画面。 */
1835
2037
  poster?: string;
2038
+ };
2039
+
2040
+ export declare type VideoContentProps = VideoBaseProps & {
2041
+ purpose?: 'content';
1836
2042
  /** 字幕轨;承载信息的视频必须配(见界面准则「媒体可访问」)。 */
1837
2043
  tracks?: VideoTrack[];
1838
2044
  /** 内容视频的可访问名。 */
1839
- label?: string;
2045
+ label: string;
1840
2046
  controls?: boolean;
1841
2047
  loop?: boolean;
2048
+ muted?: boolean;
1842
2049
  };
1843
2050
 
2051
+ export declare type VideoDecorativeProps = VideoBaseProps & {
2052
+ purpose: 'decorative';
2053
+ label?: never;
2054
+ tracks?: never;
2055
+ controls?: false;
2056
+ loop?: true;
2057
+ muted?: true;
2058
+ };
2059
+
2060
+ export declare type VideoProps = VideoContentProps | VideoDecorativeProps;
2061
+
1844
2062
  /** 字幕/副标题轨;同一组里至多一条 default。 */
1845
2063
  export declare type VideoTrack = {
1846
2064
  /** WebVTT 文件地址。 */