@q1travel/design-system 0.1.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.
@@ -0,0 +1,1099 @@
1
+ import { AnchorHTMLAttributes } from 'react';
2
+ import { FocusEventHandler } from 'react';
3
+ import { HTMLAttributes } from 'react';
4
+ import { InputHTMLAttributes } from 'react';
5
+ import { JSX } from 'react';
6
+ import { KeyboardEventHandler } from 'react';
7
+ import { MouseEventHandler } from 'react';
8
+ import { ReactElement } from 'react';
9
+ import { ReactNode } from 'react';
10
+ import { RefObject } from 'react';
11
+ import { SelectHTMLAttributes } from 'react';
12
+ import { TextareaHTMLAttributes } from 'react';
13
+
14
+ export declare function addDays(date: Date, amount: number): Date;
15
+
16
+ export declare function Avatar({ title, src, letter, glyph, placeholder, icon, iconColor, size, className }: AvatarProps): JSX.Element;
17
+
18
+ export declare function AvatarGroup({ members, label, size, limit, overlap, reverse, className, }: {
19
+ members: AvatarMember[];
20
+ /** 可选整组名;传入则套 role=group 作整组增强,不传则跟 Geist 默认逐个头像标注(读屏念每个成员名)。 */
21
+ label?: string;
22
+ /** 成员统一直径;缺省 32。 */
23
+ size?: number;
24
+ /** 显示上限,超出收纳为 +N;非法值(负数/NaN)忽略。 */
25
+ limit?: number;
26
+ /** 重叠像素;'auto' = 尺寸的 30% 取整(Geist 实测 16→5 / 24→7 / 32→10 / 48→14);负数按 0 处理。 */
27
+ overlap?: number | 'auto';
28
+ /** 翻转堆叠顺序。 */
29
+ reverse?: boolean;
30
+ className?: string;
31
+ }): JSX.Element;
32
+
33
+ export declare type AvatarMember = Omit<AvatarProps, 'size' | 'className'>;
34
+
35
+ export declare type AvatarProps = {
36
+ /** 实体本名(陈一帆、产品团队):既是可访问名也是图片 alt。 */
37
+ title: string;
38
+ /** 头像图;加载失败自动回退到字母(failedSrc 按 src 记账,换新地址会重试)。 */
39
+ src?: string;
40
+ /** 无图回退字母(中文取姓、英文取首字母,最多两字符);缺省时组件自动从 title 派生。 */
41
+ letter?: string;
42
+ /** 图标作头像本体(团队/组织等无人像实体);本库自有扩展,与右下角标是两种用途。 */
43
+ glyph?: ReactNode;
44
+ /** 加载占位骨架;只用于加载态,不作长期缺省。 */
45
+ placeholder?: boolean;
46
+ /** 右下角标图标(对标 Geist With custom icon);纯装饰,语义信息由调用方文字承载。 */
47
+ icon?: ReactNode;
48
+ /** 角标底色(任意 CSS color,建议用语义 token);缺省中性灰盘。 */
49
+ iconColor?: string;
50
+ /** 直径像素;缺省 32(组内缺省继承组尺寸)。非法值(0/负数/NaN)按缺省处理。 */
51
+ size?: number;
52
+ className?: string;
53
+ };
54
+
55
+ declare type Axis = 'vertical' | 'horizontal' | 'free';
56
+
57
+ export declare function Badge({ tone, subtle, inverted, size, icon, count, title, className, children, ...rest }: BadgeProps): JSX.Element;
58
+
59
+ export declare type BadgeProps = {
60
+ /** 语义色调,颜色即语义:灰=中性、蓝=信息、绿=成功、琥珀=警告、红=危险。 */
61
+ tone?: BadgeTone;
62
+ /** 密集表面上的低对比形态。 */
63
+ subtle?: boolean;
64
+ /** 反转高对比形态;设置后忽略 tone/subtle。 */
65
+ inverted?: boolean;
66
+ /** 尺寸档 20/24/32(Geist 实测阶梯)。 */
67
+ size?: BadgeSize;
68
+ /** 前置图标;纯装饰(组件自动 aria-hidden),宽高随档位 12/14/16 由样式钉死。 */
69
+ icon?: ReactNode;
70
+ /** 计数徽标形态(自有扩展):单数字圆形,多位自动撑开。 */
71
+ count?: boolean;
72
+ /** 悬停提示;纯图标(无 children)时兼作读屏可访问名——单靠 title 属性多数读屏不播报,组件会补 role=img + aria-label。 */
73
+ title?: string;
74
+ } & HTMLAttributes<HTMLSpanElement>;
75
+
76
+ export declare type BadgeSize = 'sm' | 'md' | 'lg';
77
+
78
+ export declare type BadgeTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
79
+
80
+ export declare function Banner({ title, children, tone, icon, action, onDismiss, progress, className, ...rest }: BannerProps): JSX.Element;
81
+
82
+ export declare type BannerProps = {
83
+ /** 粗体导语,一眼点题。 */
84
+ title: string;
85
+ /** 描述文案;组件统一用「 — 」与导语衔接。 */
86
+ children?: ReactNode;
87
+ /** 未设 = 页顶公告形态;设值 = 页内卡条形态(neutral 为中性卡条)。 */
88
+ tone?: BannerTone;
89
+ /** 卡条形态的前缀图标;纯装饰(组件自动 aria-hidden)。公告形态与进度形态不渲染图标。 */
90
+ icon?: ReactNode;
91
+ /** 主操作:公告形态渲染恒深药丸(无 chevron,Geist 同款);卡条形态渲染描边药丸 + chevron。进度形态忽略 action——任务进行中不挂主跳转,完成后换普通卡条。 */
92
+ action?: {
93
+ label: string;
94
+ href: string;
95
+ };
96
+ /** 关闭回调;设置后渲染关闭按钮。公告形态无关闭(跟 Geist);进度形态渲染在进度头右侧。 */
97
+ onDismiss?: () => void;
98
+ /** 进度形态(自有扩展):value 为 0–100 的百分比(非法值归 0),label 供读屏。进度恒为卡条形态。 */
99
+ progress?: {
100
+ value: number;
101
+ label: string;
102
+ };
103
+ } & HTMLAttributes<HTMLDivElement>;
104
+
105
+ export declare type BannerTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
106
+
107
+ declare type BannerVariant = 'default' | 'success' | 'warning' | 'error';
108
+
109
+ export declare function Book({ title, variant, color, bandColor, textColor, icon, illustration, textured, width, className, style, ...rest }: BookProps): JSX.Element;
110
+
111
+ export declare type BookProps = {
112
+ /** 封面标题;语义由标题承载,封面其余元素均为装饰。 */
113
+ title: string;
114
+ /** stripe=顶部色带+下方标签区(Geist 默认);simple=纯封面、标题置顶。 */
115
+ variant?: 'stripe' | 'simple';
116
+ /** 封面底色;建议传设计 token(var(--q1-color-…)),勿用裸 hex(Geist Best Practices 同款要求)。 */
117
+ color?: string;
118
+ /** stripe 色带颜色;缺省琥珀(Geist 实测默认带色)。 */
119
+ bandColor?: string;
120
+ /** 标题颜色;自定义封面色时务必保证对比可读。 */
121
+ textColor?: string;
122
+ /** 装饰图标:stripe 置于色带中央,simple 置于标题上方;组件自动 aria-hidden。 */
123
+ icon?: ReactNode;
124
+ /** 整幅插画:铺满封面、裁切;标题浮于其上;aria-hidden。 */
125
+ illustration?: ReactNode;
126
+ /** 细密交叉纹理(自有配方;Geist 的多款纹理样式记 non-goal)。仅用于主视觉,成排书架勿用。 */
127
+ textured?: boolean;
128
+ /** 数字按 px;字符串原样透传(如 clamp(...) 做响应式宽度)。内部排版随宽度等比缩放。
129
+ * width 是唯一尺寸入口:用 style.width 改宽会与内部缩放脱节。 */
130
+ width?: number | string;
131
+ } & Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
132
+
133
+ export declare function Breadcrumb({ items, label, type, }: {
134
+ items: BreadcrumbCrumb[];
135
+ label: string;
136
+ type?: 'text' | 'menu';
137
+ }): JSX.Element;
138
+
139
+ declare type BreadcrumbCrumb = {
140
+ label: string;
141
+ href?: string;
142
+ icon?: ReactNode;
143
+ isCurrent?: boolean;
144
+ isDisabled?: boolean;
145
+ };
146
+
147
+ export declare function Browser({ address, variant, tabs, children, className, ...rest }: BrowserProps): JSX.Element;
148
+
149
+ export declare function BrowserAddress({ address, className }: {
150
+ address: string;
151
+ className?: string;
152
+ }): JSX.Element;
153
+
154
+ export declare function BrowserControls({ className }?: {
155
+ className?: string;
156
+ }): JSX.Element;
157
+
158
+ export declare function BrowserDots({ className }?: {
159
+ className?: string;
160
+ }): JSX.Element;
161
+
162
+ export declare function BrowserPlaceholder(): JSX.Element;
163
+
164
+ export declare type BrowserProps = {
165
+ address: string;
166
+ variant?: BrowserVariant;
167
+ tabs?: BrowserTab[];
168
+ children: ReactNode;
169
+ } & HTMLAttributes<HTMLDivElement>;
170
+
171
+ export declare type BrowserTab = {
172
+ label: string;
173
+ isActive?: boolean;
174
+ };
175
+
176
+ export declare function BrowserTabs({ tabs, className }: {
177
+ tabs: BrowserTab[];
178
+ className?: string;
179
+ }): JSX.Element;
180
+
181
+ export declare type BrowserVariant = 'light' | 'dark';
182
+
183
+ export declare function Button(props: ButtonProps): JSX.Element;
184
+
185
+ declare type ButtonProps = {
186
+ variant?: ButtonVariant;
187
+ size?: ButtonSize;
188
+ iconOnly?: boolean;
189
+ /** 圆形——仅用于 icon-only 按钮。与 rounded 互斥(同传时 circle 优先)。 */
190
+ circle?: boolean;
191
+ /** 药丸形(full radius)+ 柔和抬起阴影(对标 Geist Rounded,营销页/落地页文字 CTA 用)。与 circle 互斥。 */
192
+ rounded?: boolean;
193
+ loading?: boolean;
194
+ disabled?: boolean;
195
+ href?: string;
196
+ type?: 'button' | 'submit' | 'reset';
197
+ shortcut?: string;
198
+ className?: string;
199
+ children?: ReactNode;
200
+ onClick?: MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
201
+ ariaLabel?: string;
202
+ ariaKeyshortcuts?: string;
203
+ /** 供 Tooltip 等外部浮层关联描述文本、绑定展开/收起时机用;不是 Button 自身的常规用法。 */
204
+ 'aria-describedby'?: string;
205
+ onFocus?: FocusEventHandler<HTMLButtonElement | HTMLAnchorElement>;
206
+ onBlur?: FocusEventHandler<HTMLButtonElement | HTMLAnchorElement>;
207
+ onKeyDown?: KeyboardEventHandler<HTMLButtonElement | HTMLAnchorElement>;
208
+ };
209
+
210
+ export declare type ButtonSize = 'sm' | 'md' | 'lg';
211
+
212
+ export declare type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'warning' | 'danger';
213
+
214
+ export declare function CalendarGrid({ value, onChange, size, minValue, maxValue, today, }: {
215
+ value: RangeValue;
216
+ onChange: (next: RangeValue) => void;
217
+ size?: CalendarSize;
218
+ minValue?: Date;
219
+ maxValue?: Date;
220
+ today?: Date;
221
+ }): JSX.Element;
222
+
223
+ export declare type CalendarPreset = {
224
+ label: string;
225
+ getRange: () => RangeValue;
226
+ };
227
+
228
+ export declare type CalendarSize = 'large' | 'small';
229
+
230
+ export declare function Card(props: CardProps): JSX.Element;
231
+
232
+ declare type CardAsContainer = CardOwnProps & {
233
+ href?: undefined;
234
+ } & Omit<HTMLAttributes<HTMLDivElement>, keyof CardOwnProps>;
235
+
236
+ declare type CardAsLink = CardOwnProps & {
237
+ /** 传入则整张卡片是可导航链接,渲染为 <a>(进 Tab 序、有焦点环)。 */
238
+ href: string;
239
+ } & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof CardOwnProps | 'href'>;
240
+
241
+ export declare type CardDirection = 'column' | 'row';
242
+
243
+ declare type CardOwnProps = {
244
+ /** 可点击卡片的悬停附能:轻微抬起 + 边框增强 + 柔和投影,暗示可交互。仅在整卡可点时用。 */
245
+ hover?: boolean;
246
+ /** 次要表面:更弱的底色,与主卡片区分层级。 */
247
+ secondary?: boolean;
248
+ /** 分段:用分隔线把卡片切成几段(对齐 Geist borderBetween)。 */
249
+ divided?: boolean;
250
+ /** 分段方向:column 竖排(默认)/ row 横排。与 divided 正交——单传 row 只横向铺开,配 divided 才加分隔线。 */
251
+ direction?: CardDirection;
252
+ /** 常驻柔和投影(对齐 Geist shadow):让卡片浮于背景,用于落地/营销卡片。 */
253
+ shadow?: boolean;
254
+ /** 是否带边框,默认 true。传 false 得无框卡片(靠底色/投影表达边界,对齐 Geist border 可选)。 */
255
+ bordered?: boolean;
256
+ className?: string;
257
+ children: ReactNode;
258
+ };
259
+
260
+ export declare type CardProps = CardAsLink | CardAsContainer;
261
+
262
+ export declare function Checkbox(props: ControlOptionOwnProps & CheckboxOnlyProps & NativeInputProps): JSX.Element;
263
+
264
+ declare type CheckboxOnlyProps = {
265
+ /** 半选:视觉态而非第三个值,由父级逻辑驱动(如"部分子项已选")。AT 读作 mixed。 */
266
+ indeterminate?: boolean;
267
+ };
268
+
269
+ export declare function Choicebox({ type, label, description, extra, className, ...rest }: ChoiceboxOwnProps & NativeInputProps_2): JSX.Element;
270
+
271
+ declare type ChoiceboxOwnProps = {
272
+ type: 'radio' | 'checkbox';
273
+ /** 磁贴标题(与 ControlOption 家族同名 label,不占用 HTML 原生 title)。 */
274
+ label: string;
275
+ description?: string;
276
+ /** 选中时展示的额外内容(如试用说明、配额明细);未选中时隐藏。 */
277
+ extra?: ReactNode;
278
+ };
279
+
280
+ export declare function ClearableInput({ id, placeholder, defaultValue, disabled, kbdHint, onClear, ariaLabel, }: ClearableInputProps): JSX.Element;
281
+
282
+ declare type ClearableInputProps = {
283
+ id: string;
284
+ placeholder?: string;
285
+ defaultValue?: string;
286
+ disabled?: boolean;
287
+ /** 空态时右侧显示 Esc/⌘K 快捷键提示,开始输入后让位给清除按钮。 */
288
+ kbdHint?: boolean;
289
+ /** 清空(点击清除按钮或按 Esc)时回调,用于联动外部状态。 */
290
+ onClear?: () => void;
291
+ /** 无可见 label 时的可访问名。有可见 label(FormField 组合)时勿再传——aria-label 会覆盖
292
+ * 可见标签成为可访问名,视觉与播报分叉(WCAG 2.5.3 Label in Name)。 */
293
+ ariaLabel?: string;
294
+ };
295
+
296
+ export declare function ClearButton({ className, label, onClick, }: {
297
+ className: string;
298
+ label: string;
299
+ onClick: () => void;
300
+ }): JSX.Element;
301
+
302
+ export declare function Code({ lines, ariaLabel }: {
303
+ lines: CodeToken[][];
304
+ ariaLabel?: string;
305
+ }): JSX.Element;
306
+
307
+ export declare function CodeBlock(props: CodeBlockProps): JSX.Element;
308
+
309
+ declare type CodeBlockBaseProps = {
310
+ lineNumbers?: boolean;
311
+ };
312
+
313
+ export declare type CodeBlockLine = {
314
+ tokens: CodeToken[];
315
+ state?: 'highlight' | 'added' | 'removed';
316
+ };
317
+
318
+ declare type CodeBlockProps = CodeBlockBaseProps & ({
319
+ filename?: string;
320
+ lines: CodeBlockLine[];
321
+ tabs?: undefined;
322
+ } | {
323
+ tabs: CodeBlockTab[];
324
+ filename?: undefined;
325
+ lines?: undefined;
326
+ });
327
+
328
+ export declare type CodeBlockTab = {
329
+ label: string;
330
+ filename?: string;
331
+ lines: CodeBlockLine[];
332
+ };
333
+
334
+ export declare function CodeInline({ children }: {
335
+ children: ReactNode;
336
+ }): JSX.Element;
337
+
338
+ export declare type CodeToken = {
339
+ text: string;
340
+ type?: 'keyword' | 'string' | 'fn' | 'comment';
341
+ };
342
+
343
+ export declare function CodeTokens({ tokens }: {
344
+ tokens: CodeToken[];
345
+ }): JSX.Element;
346
+
347
+ export declare function Collapse({ title, defaultOpen, small, children, }: {
348
+ title: string;
349
+ defaultOpen?: boolean;
350
+ small?: boolean;
351
+ children: ReactNode;
352
+ }): JSX.Element;
353
+
354
+ export declare function CollapseGroup({ multiple, children }: {
355
+ multiple?: boolean;
356
+ children: ReactNode;
357
+ }): JSX.Element;
358
+
359
+ export declare function CollapsibleBreadcrumb({ items, label }: {
360
+ items: BreadcrumbCrumb[];
361
+ label: string;
362
+ }): JSX.Element;
363
+
364
+ export declare function Combobox({ options, placeholder, emptyLabel, size, disabled, error, clearable, inputId, }: ComboboxProps): JSX.Element;
365
+
366
+ export declare type ComboboxOption = {
367
+ value: string;
368
+ /** 选项文本前的图标/装饰(如区域旗帜、状态点)。 */
369
+ prefix?: ReactNode;
370
+ /** 选项文本后的图标/装饰(如快捷键、外链标记)。 */
371
+ suffix?: ReactNode;
372
+ };
373
+
374
+ declare type ComboboxProps = {
375
+ options: ComboboxOption[];
376
+ placeholder: string;
377
+ /** 空状态模板的名词(「没有匹配『查询』的{emptyLabel}」)。 */
378
+ emptyLabel?: string;
379
+ size?: ComboboxSize;
380
+ disabled?: boolean;
381
+ error?: string;
382
+ clearable?: boolean;
383
+ /** 供外部 <label htmlFor> 关联;组件自身无 label 属性。 */
384
+ inputId?: string;
385
+ };
386
+
387
+ export declare type ComboboxSize = 'sm' | 'md' | 'lg';
388
+
389
+ export declare function CommandMenu({ sections, triggerLabel, hotkey }: CommandMenuProps): JSX.Element;
390
+
391
+ export declare type CommandMenuItem = {
392
+ label: string;
393
+ /** 快捷键槽(Kbd 呈现并作为标签一部分播报)。 */
394
+ keybind?: string;
395
+ /** 通用后缀(元信息文本/状态图标),装饰性 aria-hidden;语义信息应进 label。 */
396
+ suffix?: ReactNode;
397
+ };
398
+
399
+ declare type CommandMenuProps = {
400
+ sections: CommandMenuSection[];
401
+ triggerLabel?: string;
402
+ /** 绑定全局 ⌘K(macOS)/ Ctrl+K 打开。 */
403
+ hotkey?: boolean;
404
+ };
405
+
406
+ export declare type CommandMenuSection = {
407
+ /** 段标题;缺省时该段以无标题分隔线与上文分隔(对标 Geist CommandMenuDivider)。 */
408
+ heading?: string;
409
+ items: CommandMenuItem[];
410
+ };
411
+
412
+ export declare function ContextCard({ name, identity, rows, action, placement, align, children, }: ContextCardProps): JSX.Element;
413
+
414
+ export declare type ContextCardAlign = 'start' | 'center' | 'end';
415
+
416
+ export declare type ContextCardPlacement = 'top' | 'bottom' | 'left' | 'right';
417
+
418
+ declare type ContextCardProps = {
419
+ name: string;
420
+ identity: string;
421
+ rows: [string, string][];
422
+ action?: string;
423
+ placement?: ContextCardPlacement;
424
+ align?: ContextCardAlign;
425
+ children: ReactNode;
426
+ };
427
+
428
+ export declare function ContextMenu({ label, entries, children, }: {
429
+ label: string;
430
+ entries: ContextMenuEntry[];
431
+ children: ReactNode;
432
+ }): JSX.Element;
433
+
434
+ export declare type ContextMenuEntry = {
435
+ type: 'item';
436
+ label: string;
437
+ icon?: ReactNode;
438
+ suffix?: ReactNode;
439
+ disabled?: boolean;
440
+ danger?: boolean;
441
+ } | {
442
+ type: 'link';
443
+ label: string;
444
+ href: string;
445
+ icon?: ReactNode;
446
+ suffix?: ReactNode;
447
+ } | {
448
+ type: 'separator';
449
+ };
450
+
451
+ export declare function ControlOption({ id, label, description, error, indeterminate, type, ...rest }: ControlOptionOwnProps & CheckboxOnlyProps & {
452
+ type: 'checkbox' | 'radio';
453
+ } & NativeInputProps): JSX.Element;
454
+
455
+ declare type ControlOptionOwnProps = {
456
+ id: string;
457
+ label: string;
458
+ description?: string;
459
+ error?: string;
460
+ };
461
+
462
+ export declare function CopyButton({ value, label, successMessage, size, className, }: {
463
+ value: string;
464
+ label: string;
465
+ successMessage?: string;
466
+ size?: number;
467
+ className?: string;
468
+ }): JSX.Element;
469
+
470
+ export declare function Description({ title, tooltip, align, ellipsis, children, }: {
471
+ title: string;
472
+ tooltip?: string;
473
+ align?: 'right';
474
+ ellipsis?: boolean;
475
+ children: ReactNode;
476
+ }): JSX.Element;
477
+
478
+ export declare function DestructiveActionModal({ open, onClose, title, description, confirmLabel, verificationLabel, verificationPhrase, irreversibleDescription, loading, onConfirm, }: {
479
+ open: boolean;
480
+ onClose: () => void;
481
+ title: string;
482
+ description: ReactNode;
483
+ confirmLabel: string;
484
+ verificationLabel: string;
485
+ verificationPhrase: string;
486
+ irreversibleDescription?: string;
487
+ /** 提交进行中:双按钮禁用、主操作显示加载指示;open 由调用方控制,加载中模态保持打开。 */
488
+ loading?: boolean;
489
+ onConfirm: () => string | null;
490
+ }): JSX.Element | null;
491
+
492
+ export declare function DotsMenu({ entries, size, disabled, align, }: {
493
+ entries: DotsMenuEntry[];
494
+ size?: 'sm' | 'md' | 'lg';
495
+ disabled?: boolean;
496
+ align?: 'start' | 'end';
497
+ }): JSX.Element;
498
+
499
+ export declare type DotsMenuEntry = {
500
+ label: string;
501
+ disabled?: boolean;
502
+ danger?: boolean;
503
+ };
504
+
505
+ export declare function Drawer({ open, onClose, title, children, footer, height, }: {
506
+ open: boolean;
507
+ onClose: () => void;
508
+ title: string;
509
+ children: ReactNode;
510
+ footer: ReactNode;
511
+ /** 面板最大高度(px),覆盖默认 60vh;仅当默认高度会裁切主操作时使用。 */
512
+ height?: number;
513
+ }): JSX.Element | null;
514
+
515
+ export declare function EmptyState({ icon, title, description, actions, live, }: {
516
+ icon: ReactNode;
517
+ title: string;
518
+ description: string;
519
+ /** CTA 区:传家族 <Button> 与次要链接;最多一个主 CTA。 */
520
+ actions?: ReactNode;
521
+ live?: boolean;
522
+ }): JSX.Element;
523
+
524
+ export declare function Entity({ leading, title, subtitle, trailing, }: {
525
+ leading?: ReactNode;
526
+ title: string;
527
+ subtitle?: string;
528
+ trailing?: ReactNode;
529
+ }): JSX.Element;
530
+
531
+ export declare function ErrorCard({ title, message, action }: {
532
+ title: string;
533
+ message?: string;
534
+ action?: ReactNode;
535
+ }): JSX.Element;
536
+
537
+ export declare function ErrorMessage({ label, size, action, children, }: {
538
+ /** 可见的粗体标签前缀(如「邮箱错误:」),点明出错对象;缺省不显示(sr-only 前缀恒在)。 */
539
+ label?: string;
540
+ size?: ErrorMessageSize;
541
+ /** 恢复操作插槽:可安全重试用「重试」按钮,链接式出口放 <a>。 */
542
+ action?: ReactNode;
543
+ children: ReactNode;
544
+ }): JSX.Element;
545
+
546
+ export declare type ErrorMessageSize = 'sm' | 'md' | 'lg';
547
+
548
+ export declare function Feedback({ label, prompt, placeholder, inline, topics, }: {
549
+ label?: string;
550
+ prompt?: string;
551
+ /** textarea 占位(对标 Geist Custom Placeholder):换成更具体的引导,帮助用户知道从哪里说起。 */
552
+ placeholder?: string;
553
+ inline?: boolean;
554
+ topics?: string[];
555
+ }): JSX.Element;
556
+
557
+ export declare function Fieldset({ title, subtitle, tone, footerStatus, footerAction, disabled, children, }: {
558
+ title?: string;
559
+ subtitle: string;
560
+ tone?: FieldsetTone;
561
+ footerStatus?: ReactNode;
562
+ footerAction?: ReactNode;
563
+ disabled?: boolean;
564
+ children?: ReactNode;
565
+ }): JSX.Element;
566
+
567
+ export declare type FieldsetTone = 'danger' | 'warning';
568
+
569
+ export declare type FieldSize = 'xs' | 'sm' | 'md' | 'lg';
570
+
571
+ export declare function FileTree({ nodes, label, defaultExpanded, }: {
572
+ nodes: FileTreeNode[];
573
+ label?: string;
574
+ defaultExpanded?: string[];
575
+ }): JSX.Element;
576
+
577
+ export declare type FileTreeNode = {
578
+ name: string;
579
+ type: 'folder' | 'file';
580
+ children?: FileTreeNode[];
581
+ };
582
+
583
+ export declare function FormField({ controlId, label, description, error, wide, children, }: {
584
+ controlId: string;
585
+ label: string;
586
+ description?: string;
587
+ error?: string;
588
+ wide?: boolean;
589
+ children: ReactNode;
590
+ }): JSX.Element;
591
+
592
+ export declare function Gauge({ value, size, showValue, tone, toneDirection, label, indeterminate, }: {
593
+ value?: number;
594
+ size?: GaugeSize;
595
+ showValue?: boolean;
596
+ tone?: ThresholdTone;
597
+ toneDirection?: GaugeToneDirection;
598
+ label: string;
599
+ indeterminate?: boolean;
600
+ }): JSX.Element;
601
+
602
+ declare type GaugeSize = 'xs' | 'sm' | 'md' | 'lg';
603
+
604
+ declare type GaugeToneDirection = 'quota' | 'health';
605
+
606
+ export declare function Input({ id, label, description, error, prefix, suffix, prefixStyling, suffixStyling, rounded, wide, size, className, ...rest }: {
607
+ id: string;
608
+ label: string;
609
+ description?: string;
610
+ error?: string;
611
+ prefix?: ReactNode;
612
+ suffix?: ReactNode;
613
+ /** 置 false 去掉前缀的灰块底色与分隔线,变成纯文本/裸图标(对标 Geist prefixStyling)。 */
614
+ prefixStyling?: boolean;
615
+ /** 置 false 去掉后缀的灰块底色与分隔线(对标 Geist suffixStyling)。 */
616
+ suffixStyling?: boolean;
617
+ /** 药丸形全圆角外框(对标 Geist rounded,实测 9999px 级 pill 半径)。 */
618
+ rounded?: boolean;
619
+ wide?: boolean;
620
+ size?: FieldSize;
621
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'size' | 'prefix'>): JSX.Element;
622
+
623
+ export declare function Kbd({ meta, shift, alt, ctrl, small, children, }: {
624
+ meta?: boolean;
625
+ shift?: boolean;
626
+ alt?: boolean;
627
+ ctrl?: boolean;
628
+ small?: boolean;
629
+ children?: ReactNode;
630
+ }): JSX.Element;
631
+
632
+ export declare function Label({ htmlFor, required, children, }: {
633
+ htmlFor?: string;
634
+ required?: boolean;
635
+ children: string;
636
+ }): JSX.Element;
637
+
638
+ export declare function LoadingDots({ label, size }: {
639
+ label?: string;
640
+ size?: LoadingDotsSize;
641
+ }): JSX.Element;
642
+
643
+ declare type LoadingDotsSize = 'sm' | 'md' | 'lg' | number;
644
+
645
+ export declare function LoadMoreButton({ loading, noGap, noBorderRadius, onClick, children, }: {
646
+ loading?: boolean;
647
+ noGap?: boolean;
648
+ noBorderRadius?: boolean;
649
+ onClick?: () => void;
650
+ children: ReactNode;
651
+ }): JSX.Element;
652
+
653
+ export declare function Menu({ label, entries, withChevron, align, triggerContent }: {
654
+ label: string;
655
+ entries: MenuEntry[];
656
+ withChevron?: boolean;
657
+ align?: 'start' | 'end';
658
+ /** 自定义触发器内容(如纯图标);label 始终作为可访问名称的兜底,图标-only 时经 aria-label 暴露。 */
659
+ triggerContent?: ReactNode;
660
+ }): JSX.Element;
661
+
662
+ export declare type MenuEntry = {
663
+ type: 'item';
664
+ label: string;
665
+ icon?: ReactNode;
666
+ /** 后缀内容(如快捷键提示);locked 项在未显式传入 suffix 时仍兜底显示锁图标。 */
667
+ suffix?: ReactNode;
668
+ disabled?: boolean;
669
+ locked?: boolean;
670
+ danger?: boolean;
671
+ } | {
672
+ type: 'link';
673
+ label: string;
674
+ href: string;
675
+ icon?: ReactNode;
676
+ suffix?: ReactNode;
677
+ } | {
678
+ type: 'section';
679
+ label: string;
680
+ } | {
681
+ type: 'separator';
682
+ };
683
+
684
+ export declare function MiddleTruncate({ text, tailLength, mono }: {
685
+ text: string;
686
+ tailLength?: number;
687
+ mono?: boolean;
688
+ }): JSX.Element;
689
+
690
+ export declare function Modal({ open, onClose, title, children, footer, initialFocusRef, dismissable, sticky }: {
691
+ open: boolean;
692
+ onClose: () => void;
693
+ title: string;
694
+ children: ReactNode;
695
+ footer: ReactNode;
696
+ initialFocusRef?: RefObject<HTMLElement | null>;
697
+ dismissable?: boolean;
698
+ /** 头尾固定、只有正文区域滚动;用于正文可能超出视口高度的场景(长列表、长条款)。 */
699
+ sticky?: boolean;
700
+ }): JSX.Element | null;
701
+
702
+ export declare function ModalInset({ children }: {
703
+ children: ReactNode;
704
+ }): JSX.Element;
705
+
706
+ export declare function MultiSelect({ options, defaultSelected, placeholder, onChange }: {
707
+ options: string[];
708
+ defaultSelected?: string[];
709
+ placeholder: string;
710
+ onChange?: (next: string[]) => void;
711
+ }): JSX.Element;
712
+
713
+ declare type NativeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'type'>;
714
+
715
+ declare type NativeInputProps_2 = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
716
+
717
+ export declare function Note({ type, size, filled, disabled, label, action, children, }: {
718
+ type?: NoteType;
719
+ size?: NoteSize;
720
+ filled?: boolean;
721
+ disabled?: boolean;
722
+ label?: string;
723
+ action?: string;
724
+ children: ReactNode;
725
+ }): JSX.Element;
726
+
727
+ declare type NoteSize = 'small' | 'default' | 'large';
728
+
729
+ declare type NoteType = 'info' | 'success' | 'warning' | 'error' | 'secondary';
730
+
731
+ declare type PageLink = {
732
+ title: string;
733
+ };
734
+
735
+ export declare function Pagination({ previous, next }: {
736
+ previous?: PageLink;
737
+ next?: PageLink;
738
+ }): JSX.Element;
739
+
740
+ export declare function PeriodCombobox({ presets, activeLabel, onPick, }: {
741
+ presets: CalendarPreset[];
742
+ activeLabel?: string;
743
+ onPick: (preset: CalendarPreset) => void;
744
+ }): JSX.Element;
745
+
746
+ export declare function Phone({ screenLabel }: {
747
+ screenLabel: string;
748
+ }): JSX.Element;
749
+
750
+ export declare function Pill({ href, size, icon, title, className, children, ...rest }: PillProps): JSX.Element;
751
+
752
+ declare type PillProps = {
753
+ href: string;
754
+ size?: BadgeSize;
755
+ /** 前置图标;纯装饰(组件自动 aria-hidden)。 */
756
+ icon?: ReactNode;
757
+ /** 悬停提示;纯图标(无 children)时兼作读屏可访问名。 */
758
+ title?: string;
759
+ } & AnchorHTMLAttributes<HTMLAnchorElement>;
760
+
761
+ export declare type PopoverLayout = 'vertical' | 'horizontal';
762
+
763
+ export declare function Progress({ value, max, tone, slim, stops, label, }: {
764
+ value: number;
765
+ max?: number;
766
+ tone?: 'neutral' | ThresholdTone;
767
+ slim?: boolean;
768
+ stops?: ProgressStop[];
769
+ label: string;
770
+ }): JSX.Element;
771
+
772
+ declare type ProgressStop = number | {
773
+ at: number;
774
+ label?: string;
775
+ };
776
+
777
+ export declare function ProjectBanner({ variant, message, cta }: {
778
+ variant?: BannerVariant;
779
+ message: string;
780
+ cta: string;
781
+ }): JSX.Element;
782
+
783
+ export declare function Radio(props: ControlOptionOwnProps & NativeInputProps): JSX.Element;
784
+
785
+ export declare function RangeField({ layout, trigger, size, minValue, maxValue, pinnedTimezone, today, value, onChange, }: {
786
+ layout?: PopoverLayout;
787
+ trigger?: TriggerKind;
788
+ size?: CalendarSize;
789
+ minValue?: Date;
790
+ maxValue?: Date;
791
+ pinnedTimezone?: string;
792
+ /** 透传给内部 CalendarGrid(默认真实当前日期);文档 demo 传固定值保持演示可控。 */
793
+ today?: Date;
794
+ value: RangeValue;
795
+ onChange: (next: RangeValue) => void;
796
+ }): JSX.Element;
797
+
798
+ export declare function RangeInputs({ value, withTime, onApply, pinnedTimezone, }: {
799
+ value: RangeValue;
800
+ withTime: boolean;
801
+ onApply: () => void;
802
+ /** 固定时区(对标 Geist pinnedTimezone):传入时时区从可选 select 变只读文本、不可切换。 */
803
+ pinnedTimezone?: string;
804
+ }): JSX.Element;
805
+
806
+ export declare function RangeSlider({ min, max, step, defaultLow, defaultHigh, disabled }: {
807
+ min?: number;
808
+ max?: number;
809
+ step?: number;
810
+ defaultLow: number;
811
+ defaultHigh: number;
812
+ disabled?: boolean;
813
+ }): JSX.Element;
814
+
815
+ export declare type RangeValue = {
816
+ start: Date | null;
817
+ end: Date | null;
818
+ };
819
+
820
+ export declare function RelativeTimeCard({ relative, relativeLong, iso, local, utc, }: {
821
+ relative: string;
822
+ relativeLong: string;
823
+ iso: string;
824
+ local: string;
825
+ utc: string;
826
+ }): JSX.Element;
827
+
828
+ export declare function Scroller({ axis, label, children, }: {
829
+ axis: Axis;
830
+ label: string;
831
+ children: ReactNode;
832
+ }): JSX.Element;
833
+
834
+ export declare function ScrollerWithButtons({ axis, contentName, label, children, }: {
835
+ axis?: 'horizontal' | 'vertical';
836
+ contentName: string;
837
+ label: string;
838
+ children: ReactNode;
839
+ }): JSX.Element;
840
+
841
+ export declare function SearchInput({ id, ariaLabel, placeholder, defaultValue, disabled, loading, kbdHint, icon, }: {
842
+ id: string;
843
+ ariaLabel: string;
844
+ placeholder: string;
845
+ defaultValue?: string;
846
+ disabled?: boolean;
847
+ loading?: boolean;
848
+ kbdHint?: boolean;
849
+ icon?: ReactNode;
850
+ }): JSX.Element;
851
+
852
+ export declare function Select({ id, label, description, error, wide, size, prefix, suffix, className, children, ...rest }: {
853
+ id: string;
854
+ label: string;
855
+ description?: string;
856
+ error?: string;
857
+ wide?: boolean;
858
+ size?: FieldSize;
859
+ prefix?: ReactNode;
860
+ /** 装饰性后缀图标(aria-hidden),渲染在下拉箭头左侧;跟 prefix 前缀一样不承载信息,可访问名称仍完全来自 label。 */
861
+ suffix?: ReactNode;
862
+ children: ReactNode;
863
+ } & Omit<SelectHTMLAttributes<HTMLSelectElement>, 'id' | 'children' | 'size' | 'prefix'>): JSX.Element;
864
+
865
+ export declare function Separator({ orientation, decorative, className, }: {
866
+ orientation?: SeparatorOrientation;
867
+ decorative?: boolean;
868
+ className?: string;
869
+ }): JSX.Element;
870
+
871
+ export declare type SeparatorOrientation = 'horizontal' | 'vertical';
872
+
873
+ export declare function Sheet({ open, onClose, title, side, children, footer }: {
874
+ open: boolean;
875
+ onClose: () => void;
876
+ title: string;
877
+ side?: SheetSide;
878
+ children: ReactNode;
879
+ footer?: ReactNode;
880
+ }): JSX.Element | null;
881
+
882
+ export declare type SheetSide = 'top' | 'right' | 'bottom' | 'left';
883
+
884
+ export declare function ShowMore({ items, initial, noBorder, initialExpanded, }: {
885
+ items: string[];
886
+ initial?: number;
887
+ noBorder?: boolean;
888
+ /** 仅用于演示常驻展开态的初始值;组件仍是非受控的,不支持中途从外部切换展开状态。 */
889
+ initialExpanded?: boolean;
890
+ }): JSX.Element;
891
+
892
+ export declare function Skeleton({ shape, animated, show, className, children, }: {
893
+ shape?: SkeletonShape;
894
+ animated?: boolean;
895
+ /** 包裹模式:数据就绪后置 true,原地显示子内容。 */
896
+ show?: boolean;
897
+ className?: string;
898
+ children?: ReactNode;
899
+ }): JSX.Element;
900
+
901
+ export declare type SkeletonShape = 'rounded' | 'pill' | 'squared';
902
+
903
+ export declare function Slider({ label, unit, min, max, step, defaultValue }: {
904
+ label: string;
905
+ unit: string;
906
+ min?: number;
907
+ max?: number;
908
+ step?: number;
909
+ defaultValue: number;
910
+ }): JSX.Element;
911
+
912
+ export declare function Snippet({ text, prompt, inverted, tone, copyText, onCopy, }: {
913
+ text: string | string[];
914
+ prompt?: boolean;
915
+ inverted?: boolean;
916
+ tone?: SnippetTone;
917
+ /** 显示与复制内容分离(对标 Geist):传了就复制它,不传复制显示内容。 */
918
+ copyText?: string;
919
+ /** 复制触发后调用,供外部消费复制事件(如埋点);不代表剪贴板写入一定成功。 */
920
+ onCopy?: () => void;
921
+ }): JSX.Element;
922
+
923
+ declare type SnippetTone = 'info' | 'danger' | 'warning';
924
+
925
+ export declare function Spinner({ size, tone, label, }: {
926
+ size?: SpinnerSize;
927
+ tone?: SpinnerTone;
928
+ label?: string;
929
+ }): JSX.Element;
930
+
931
+ export declare type SpinnerSize = 'sm' | 'md' | 'lg' | 'xl';
932
+
933
+ export declare type SpinnerTone = 'default' | 'danger' | 'success' | 'info';
934
+
935
+ export declare function SplitButton({ label, entries, variant, size, align, menuButtonLabel, icon }: {
936
+ label: string;
937
+ entries: SplitButtonEntry[];
938
+ variant?: 'default' | 'secondary';
939
+ size?: 'sm' | 'md' | 'lg';
940
+ align?: 'start' | 'end';
941
+ menuButtonLabel: string;
942
+ icon?: ReactNode;
943
+ }): JSX.Element;
944
+
945
+ export declare type SplitButtonEntry = {
946
+ label: string;
947
+ danger?: boolean;
948
+ icon?: ReactNode;
949
+ };
950
+
951
+ export declare function StatusDot({ tone, label, animated, showLabel, titlePrefix, }: {
952
+ tone: StatusDotTone;
953
+ label: string;
954
+ animated?: boolean;
955
+ showLabel?: boolean;
956
+ titlePrefix?: string;
957
+ }): JSX.Element;
958
+
959
+ export declare type StatusDotTone = 'neutral' | 'warning' | 'success' | 'danger';
960
+
961
+ export declare function Switch({ options, ariaLabel, name, defaultValue, onChange, size, fullWidth, iconOnly, }: {
962
+ options: SwitchOption[];
963
+ ariaLabel: string;
964
+ name?: string;
965
+ defaultValue?: string;
966
+ onChange?: (value: string) => void;
967
+ size?: 'sm' | 'md' | 'lg';
968
+ fullWidth?: boolean;
969
+ /** 纯图标模式:文字标签仍在,只是视觉隐藏(sr-only),可访问名称不丢失。 */
970
+ iconOnly?: boolean;
971
+ }): JSX.Element | null;
972
+
973
+ export declare type SwitchOption = {
974
+ value: string;
975
+ label: string;
976
+ icon?: ReactNode;
977
+ disabled?: boolean;
978
+ /** 补充说明(原生 title,桌面端悬浮显示);用于图标模式下文字看不出来的额外上下文。 */
979
+ tooltip?: string;
980
+ };
981
+
982
+ export declare type TabItem = {
983
+ id: string;
984
+ label: string;
985
+ content: ReactNode;
986
+ icon?: ReactNode;
987
+ disabled?: boolean;
988
+ /** 禁用原因(原生 title,桌面端悬浮显示);放在外层包装上,因为禁用按钮本身在部分浏览器不触发 hover。 */
989
+ tooltip?: string;
990
+ };
991
+
992
+ export declare function Tabs({ tabs, ariaLabel, variant, }: {
993
+ tabs: TabItem[];
994
+ ariaLabel: string;
995
+ variant?: 'default' | 'secondary';
996
+ }): JSX.Element | null;
997
+
998
+ export declare function Textarea({ id, label, description, error, wide, size, className, ...rest }: {
999
+ id: string;
1000
+ label: string;
1001
+ description?: string;
1002
+ error?: string;
1003
+ wide?: boolean;
1004
+ size?: FieldSize;
1005
+ } & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'id'>): JSX.Element;
1006
+
1007
+ export declare function TextWithCopyButton({ text, copyValue, successMessage, size, }: {
1008
+ text: string;
1009
+ copyValue?: string;
1010
+ successMessage?: string;
1011
+ size?: 'default' | 'small';
1012
+ }): JSX.Element;
1013
+
1014
+ export declare function ThemeSwitcher({ small, disabled }: {
1015
+ small?: boolean;
1016
+ disabled?: boolean;
1017
+ }): JSX.Element;
1018
+
1019
+ declare type ThresholdTone = 'primary' | 'success' | 'warning' | 'danger';
1020
+
1021
+ declare type ToastContextValue = {
1022
+ push: (toast: ToastOptions) => void;
1023
+ dismiss: (id: number) => void;
1024
+ };
1025
+
1026
+ export declare type ToastOptions = {
1027
+ tone?: ToastTone;
1028
+ /** 支持纯文本或富文本(如加粗/行内链接);aria-live 区域会播报文本内容,行内链接仍可被 Tab 到并激活。 */
1029
+ title: ReactNode;
1030
+ description?: ReactNode;
1031
+ actionLabel?: string;
1032
+ preserve?: boolean;
1033
+ duration?: number;
1034
+ };
1035
+
1036
+ export declare function ToastProvider({ children }: {
1037
+ children: ReactNode;
1038
+ }): JSX.Element;
1039
+
1040
+ export declare type ToastTone = 'default' | 'success' | 'warning' | 'error';
1041
+
1042
+ export declare function Toggle({ defaultOn, disabled, size, onColor, label, description, labelSide, ariaLabel, }: {
1043
+ defaultOn?: boolean;
1044
+ disabled?: boolean;
1045
+ size?: ToggleSize;
1046
+ onColor?: string;
1047
+ label?: string;
1048
+ description?: string;
1049
+ labelSide?: 'left' | 'right';
1050
+ ariaLabel?: string;
1051
+ }): JSX.Element;
1052
+
1053
+ export declare type ToggleSize = 'sm' | 'md' | 'lg';
1054
+
1055
+ export declare function Tooltip({ content, placement, delay, triggerLabel, children, align, tip, center, }: {
1056
+ content: ReactNode;
1057
+ placement?: TooltipPlacement;
1058
+ delay?: number;
1059
+ /** 内部默认触发器的文案;传 children 时不使用。 */
1060
+ triggerLabel?: string;
1061
+ /** 自定义触发器:包裹任意单个元素/组件(Button、原生 a/span 等)代替内部默认按钮。 */
1062
+ children?: ReactElement<TooltipTriggerProps>;
1063
+ /** 提示体相对触发器的对齐方式:垂直方位(top/bottom)沿水平轴对齐,水平方位(left/right)沿垂直轴对齐。 */
1064
+ align?: TooltipAlign;
1065
+ /** 是否显示指向触发器的箭头指示器。 */
1066
+ tip?: boolean;
1067
+ /** 提示文本是否居中对齐(默认左对齐)。 */
1068
+ center?: boolean;
1069
+ }): JSX.Element;
1070
+
1071
+ declare type TooltipAlign = 'start' | 'center' | 'end';
1072
+
1073
+ export declare type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
1074
+
1075
+ declare type TooltipTriggerProps = {
1076
+ 'aria-describedby'?: string;
1077
+ onFocus?: (event: never) => void;
1078
+ onBlur?: (event: never) => void;
1079
+ onKeyDown?: (event: {
1080
+ key: string;
1081
+ }) => void;
1082
+ };
1083
+
1084
+ export declare type TriggerKind = 'default' | 'compact';
1085
+
1086
+ export declare function useCopy(): {
1087
+ copied: boolean;
1088
+ copy: (value: string, successMessage?: string) => Promise<void>;
1089
+ reset: () => void;
1090
+ };
1091
+
1092
+ export declare function useToast(): ToastContextValue;
1093
+
1094
+ export declare function Video({ controls, loop }: {
1095
+ controls?: boolean;
1096
+ loop?: boolean;
1097
+ }): JSX.Element;
1098
+
1099
+ export { }