@weichenlin/swell-ui 0.0.0-stage → 0.2.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,659 @@
1
+ import { ClassValue } from "clsx";
2
+ import { VariantProps } from "class-variance-authority";
3
+ import { ComponentProps, MouseEvent, ReactElement, ReactNode } from "react";
4
+ //#region src/components/badge/badge.d.ts
5
+ type BadgeTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
6
+ type BadgeVariant = 'subtle' | 'outline' | 'solid';
7
+ type BadgeSize = 'sm' | 'md';
8
+ type BadgeProps = Omit<ComponentProps<'span'>, 'onClick'> & {
9
+ tone?: BadgeTone;
10
+ variant?: BadgeVariant;
11
+ size?: BadgeSize;
12
+ /** Leading, decorative glyph (hidden from assistive tech). Ignored while `busy`. */
13
+ icon?: ReactNode;
14
+ /** In-progress state: swaps the icon for a spinning ring (a static ring under reduced motion). */
15
+ busy?: boolean;
16
+ /** Visually-hidden prefix for screen readers, e.g. "Health" reads as "Health: Unknown". */
17
+ context?: string;
18
+ };
19
+ export declare function Badge({ tone, variant, size, icon, busy, context, className, children, ...props }: BadgeProps): import("react").JSX.Element;
20
+ //#endregion
21
+ //#region src/components/tooltip.d.ts
22
+ type Side = 'top' | 'bottom' | 'left' | 'right';
23
+ type TriggerProps = {
24
+ 'aria-describedby'?: string;
25
+ };
26
+ type TooltipProps = {
27
+ /** Nothing renders (and no aria-describedby is added) when empty. */
28
+ content?: ReactNode;
29
+ /** Preferred side; flips to the opposite one when it doesn't fit the viewport. */
30
+ side?: Side;
31
+ /**
32
+ * Link the tooltip to the trigger via aria-describedby. Turn off when the
33
+ * tooltip only repeats the trigger's accessible name (e.g. icon button labels).
34
+ */
35
+ describe?: boolean;
36
+ /** Classes for the wrapper that anchors the tooltip. */
37
+ className?: string;
38
+ children: ReactElement<TriggerProps>;
39
+ };
40
+ /**
41
+ * Hover/focus tooltip around any element. The bubble is portaled to `<body>` with
42
+ * fixed positioning, so scroll containers (tables, drawers) never clip it.
43
+ * Events are read on the wrapper, so aria-disabled triggers work; React still
44
+ * treats the portaled bubble as inside the wrapper, so the pointer can rest on it.
45
+ */
46
+ export declare function Tooltip({ content, side, describe, className, children }: TooltipProps): import("react").JSX.Element;
47
+ //#endregion
48
+ //#region src/components/button/button.d.ts
49
+ declare const buttonVariants: (props?: ({
50
+ intent?: "surface" | "primary" | "secondary" | "dark" | "ghost" | null | undefined;
51
+ size?: "sm" | "md" | "lg" | null | undefined;
52
+ tone?: "danger" | "default" | null | undefined;
53
+ fullWidth?: boolean | null | undefined;
54
+ square?: boolean | null | undefined;
55
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
56
+ type BaseProps = Omit<ComponentProps<'button'>, 'children'> & Omit<VariantProps<typeof buttonVariants>, 'square'> & {
57
+ /** Shows a spinner, keeps width and focus, blocks activation. */
58
+ loading?: boolean;
59
+ /** Announced through a polite live region while loading. */
60
+ loadingText?: string;
61
+ /** Tooltip explaining why the button is disabled; shown on hover and keyboard focus. */
62
+ disabledReason?: string;
63
+ /** Material-style press ripple; on by default. */
64
+ ripple?: boolean;
65
+ };
66
+ type TextButtonProps = BaseProps & {
67
+ icon?: never;
68
+ iconLeft?: ReactNode;
69
+ iconRight?: ReactNode;
70
+ children?: ReactNode;
71
+ tooltip?: never;
72
+ tooltipSide?: never;
73
+ };
74
+ type IconOnlyButtonProps = Omit<BaseProps, 'aria-label' | 'fullWidth'> & {
75
+ /** Renders a square icon-only button. */
76
+ icon: NonNullable<ReactNode>;
77
+ /** Required: an icon has no text to name the button. */
78
+ 'aria-label': string;
79
+ /** Show the label as a tooltip on hover/focus. */
80
+ tooltip?: boolean;
81
+ tooltipSide?: TooltipProps['side'];
82
+ fullWidth?: never;
83
+ children?: never;
84
+ iconLeft?: never;
85
+ iconRight?: never;
86
+ };
87
+ type ButtonProps = TextButtonProps | IconOnlyButtonProps;
88
+ export declare function Button(props: ButtonProps): import("react").JSX.Element;
89
+ //#endregion
90
+ //#region src/components/card/card.d.ts
91
+ type CardElement = 'div' | 'section' | 'article';
92
+ type CardProps = ComponentProps<'div'> & {
93
+ /** `section`/`article` are named by their CardHeader title. */
94
+ as?: CardElement;
95
+ };
96
+ /**
97
+ * Bordered surface for a group of related content. No padding of its own: CardHeader and
98
+ * CardContent add it, so full-bleed rows (lists, tables) can sit edge to edge.
99
+ */
100
+ export declare function Card({ as: Comp, className, ...props }: CardProps): import("react").JSX.Element;
101
+ type CardHeaderProps = Omit<ComponentProps<'div'>, 'title' | 'children'> & {
102
+ title: ReactNode;
103
+ description?: ReactNode;
104
+ /** Trailing control, e.g. a "View all" link. */
105
+ action?: ReactNode;
106
+ headingLevel?: 2 | 3;
107
+ };
108
+ export declare function CardHeader({ title, description, action, headingLevel, className, ...props }: CardHeaderProps): import("react").JSX.Element;
109
+ export declare function CardContent({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
110
+ //#endregion
111
+ //#region src/components/checkbox/choice-row.d.ts
112
+ /**
113
+ * Either a visible label, or only an aria-label when the context already names the control
114
+ * (a table row, a toolbar). Same idea as the input family's FieldLabelProps.
115
+ */
116
+ type ChoiceLabelProps = {
117
+ label: ReactNode;
118
+ 'aria-label'?: string;
119
+ } | {
120
+ label?: never;
121
+ 'aria-label': string;
122
+ };
123
+ //#endregion
124
+ //#region src/components/checkbox/checkbox.d.ts
125
+ type NativeCheckboxProps = Omit<ComponentProps<'input'>, 'type' | 'size' | 'children' | 'aria-label'>;
126
+ type CheckboxProps = NativeCheckboxProps & ChoiceLabelProps & {
127
+ /** One muted line under the label, linked with aria-describedby. */
128
+ description?: ReactNode;
129
+ /** Truthy sets aria-invalid; text is shown under the label and linked with aria-describedby. */
130
+ error?: ReactNode;
131
+ /**
132
+ * Partly selected (a "select all" over some rows): drawn as a dash, announced as mixed.
133
+ * A visual state only; the form still submits `checked`. The browser clears it on click, so
134
+ * derive it from the children's state and it stays right after every change.
135
+ */
136
+ indeterminate?: boolean;
137
+ /** Classes for the `<input>`; `className` goes to the row. */
138
+ inputClassName?: string;
139
+ };
140
+ export declare function Checkbox({ label, description, error, indeterminate, className, inputClassName, ref, checked, 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, ...props }: CheckboxProps): import("react").JSX.Element;
141
+ //#endregion
142
+ //#region src/components/checkbox/checkbox-group.d.ts
143
+ type CheckboxGroupProps = Omit<ComponentProps<'fieldset'>, 'children'> & {
144
+ /** Names the group (fieldset legend); title case noun, no trailing colon. */
145
+ legend: ReactNode;
146
+ /** Muted line under the legend, linked to the group with aria-describedby. */
147
+ description?: ReactNode;
148
+ /**
149
+ * Group-level message (e.g. "Pick at least one"), linked with aria-describedby. Not aria-invalid:
150
+ * ARIA 1.2 doesn't support it on the group role. Native `required` can't express "one of", so
151
+ * validate in your submit handler and pass the message here.
152
+ */
153
+ error?: ReactNode;
154
+ orientation?: 'vertical' | 'horizontal';
155
+ /** Checkbox (or Switch) rows; each keeps its own name/checked. `disabled` reaches them natively. */
156
+ children: ReactNode;
157
+ };
158
+ /** A `<fieldset>` + `<legend>` around related checkboxes; holds no value of its own. */
159
+ export declare function CheckboxGroup({ legend, description, error, orientation, className, 'aria-describedby': describedByProp, children, ...props }: CheckboxGroupProps): import("react").JSX.Element;
160
+ //#endregion
161
+ //#region src/components/modal/modal-shell.d.ts
162
+ /**
163
+ * Why the modal asks to close. `programmatic` is never sent by the modal itself; it is there for
164
+ * callers that route their own closes (e.g. after a successful submit) through the same handler.
165
+ */
166
+ type ModalCloseReason = 'escape' | 'backdrop' | 'close-button' | 'programmatic';
167
+ //#endregion
168
+ //#region src/components/dialog/dialog.d.ts
169
+ type DialogSize = 'sm' | 'md' | 'lg';
170
+ /**
171
+ * Why the dialog asks to close. `programmatic` is never sent by the dialog itself; it is there for
172
+ * callers that route their own closes (e.g. after a successful submit) through the same handler.
173
+ */
174
+ type DialogCloseReason = ModalCloseReason;
175
+ type DialogProps = Omit<ComponentProps<'dialog'>, 'open'> & {
176
+ open: boolean;
177
+ onOpenChange: (open: boolean, reason: DialogCloseReason) => void;
178
+ /** Max width: sm 384px (confirmations), md 480px (default), lg 640px (wide forms). */
179
+ size?: DialogSize;
180
+ /**
181
+ * Destructive confirmation: role="alertdialog", no close button by default, and a backdrop
182
+ * click doesn't close (it bounces instead). Put `autoFocus` on the least destructive button.
183
+ */
184
+ alert?: boolean;
185
+ /** False blocks Esc, the backdrop and the close button (e.g. while a request is pending). */
186
+ dismissible?: boolean;
187
+ };
188
+ /**
189
+ * Modal dialog on the native `<dialog>` + showModal() (behavior in ModalShell). Controlled: `open`
190
+ * drives it and every close request goes through `onOpenChange`.
191
+ */
192
+ export declare function Dialog({ size, className, children, ...props }: DialogProps): import("react").JSX.Element;
193
+ type DialogHeaderProps = Omit<ComponentProps<'div'>, 'title'> & {
194
+ title: ReactNode;
195
+ description?: ReactNode;
196
+ /** Top-right close button. Defaults to on, except for `alert` dialogs (answer with the footer). */
197
+ closeButton?: boolean;
198
+ };
199
+ export declare function DialogHeader({ title, description, closeButton, className, ...props }: DialogHeaderProps): import("react").JSX.Element;
200
+ /** Scrolls when the content is taller than the space left between header and footer. */
201
+ export declare function DialogBody({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
202
+ /** Actions, right-aligned: Cancel first, the primary action last (rightmost). */
203
+ export declare function DialogFooter({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
204
+ //#endregion
205
+ //#region src/components/drawer/drawer.d.ts
206
+ type DrawerSide = 'left' | 'right';
207
+ type DrawerSize = 'sm' | 'md' | 'lg';
208
+ /** Same reasons as Dialog's; `programmatic` is for callers routing their own closes. */
209
+ type DrawerCloseReason = ModalCloseReason;
210
+ type DrawerProps = Omit<ComponentProps<'dialog'>, 'open'> & {
211
+ open: boolean;
212
+ onOpenChange: (open: boolean, reason: DrawerCloseReason) => void;
213
+ /** Edge it slides out of. Defaults to right (details, filters); navigation passes left. */
214
+ side?: DrawerSide;
215
+ /** Width: sm 280px (navigation), md 384px (default, filters), lg 480px (details, forms). */
216
+ size?: DrawerSize;
217
+ };
218
+ /**
219
+ * Modal side panel on the native `<dialog>` (behavior shared with Dialog through ModalShell).
220
+ * Controlled through `open` / `onOpenChange(open, reason)`; Esc, the backdrop, DrawerHeader's close
221
+ * button and DrawerClose all ask through `onOpenChange`. Needs a name: `aria-label` /
222
+ * `aria-labelledby`, or a DrawerHeader title.
223
+ */
224
+ export declare function Drawer({ side, size, className, children, ref, ...props }: DrawerProps): import("react").JSX.Element;
225
+ type DrawerHeaderProps = Omit<ComponentProps<'div'>, 'title'> & {
226
+ /** Also names the drawer. */
227
+ title: ReactNode;
228
+ description?: ReactNode;
229
+ };
230
+ /** Title, optional description and the close button, pinned above the body. */
231
+ export declare function DrawerHeader({ title, description, className, ...props }: DrawerHeaderProps): import("react").JSX.Element;
232
+ /** Fills the space between header and footer and scrolls on its own; they stay put. */
233
+ export declare function DrawerBody({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
234
+ /** Actions, right-aligned: Cancel first, the primary action last (rightmost). */
235
+ export declare function DrawerFooter({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
236
+ type DrawerCloseProps = Omit<ComponentProps<'button'>, 'children' | 'type' | 'aria-label' | 'onClick'> & {
237
+ /** Required: the button shows only an icon. */
238
+ 'aria-label': string;
239
+ size?: 'sm' | 'md' | 'lg';
240
+ /** Defaults to X. */
241
+ icon?: ReactNode;
242
+ };
243
+ /** A ghost icon button that closes the drawer, for custom headers. */
244
+ export declare function DrawerClose({ size, icon, ...props }: DrawerCloseProps): import("react").JSX.Element;
245
+ //#endregion
246
+ //#region src/components/input/field.d.ts
247
+ type FieldSize = 'sm' | 'md' | 'lg';
248
+ type NativeInputProps = Omit<ComponentProps<'input'>, 'size' | 'children'>;
249
+ /** Props every input in the family shares. */
250
+ type FieldProps = NativeInputProps & {
251
+ /** Visible label, rendered as a real `<label>` above the field. */
252
+ label: string;
253
+ /** Outlined floating label: rests inside the field and moves onto the top border. */
254
+ floating?: boolean;
255
+ helperText?: ReactNode;
256
+ /** Truthy puts the field in the error state; the text replaces helperText. */
257
+ error?: ReactNode;
258
+ size?: FieldSize;
259
+ /** Decorative leading icon (aria-hidden) or plain text prefix such as `https://`. */
260
+ start?: ReactNode;
261
+ /** Decorative trailing icon (aria-hidden) or plain text suffix. */
262
+ end?: ReactNode;
263
+ /** Monospace with spellcheck/autocorrect off, for tags, SHAs and hostnames. */
264
+ mono?: boolean;
265
+ /** Shows a spinner and announces validatingText; the field stays editable. */
266
+ validating?: boolean;
267
+ validatingText?: string;
268
+ /** Classes for the `<input>`; `className` goes to the outer wrapper. */
269
+ inputClassName?: string;
270
+ };
271
+ /**
272
+ * Either a visible label, or only an aria-label when the context already names the field
273
+ * (a table cell, a toolbar filter). Floating needs a visible label.
274
+ */
275
+ type FieldLabelProps = {
276
+ label: string;
277
+ floating?: boolean;
278
+ } | {
279
+ label?: never;
280
+ floating?: never;
281
+ 'aria-label': string;
282
+ };
283
+ //#endregion
284
+ //#region src/components/input/copy-input.d.ts
285
+ type CopyInputProps = Omit<FieldProps, 'type' | 'value' | 'defaultValue' | 'readOnly' | 'onChange'> & {
286
+ value: string;
287
+ };
288
+ export declare function CopyInput({ value, mono, size, onFocus, onClick, ...props }: CopyInputProps): import("react").JSX.Element;
289
+ //#endregion
290
+ //#region src/components/input/input.d.ts
291
+ /**
292
+ * Password and search have dedicated components (PasswordInput, SearchInput).
293
+ * No `number`: its spinners and wheel stepping misfire; use `inputMode="numeric"` instead.
294
+ */
295
+ type InputType = 'text' | 'email' | 'url' | 'tel';
296
+ type InputProps = Omit<FieldProps, 'type' | 'label' | 'floating'> & FieldLabelProps & {
297
+ type?: InputType;
298
+ };
299
+ export declare function Input({ type, ...props }: InputProps): import("react").JSX.Element;
300
+ //#endregion
301
+ //#region src/components/input/password-input.d.ts
302
+ type PasswordInputProps = Omit<FieldProps, 'type'> & {
303
+ type?: never;
304
+ };
305
+ export declare function PasswordInput({ autoComplete, size, ...props }: PasswordInputProps): import("react").JSX.Element;
306
+ //#endregion
307
+ //#region src/components/input/search-input.d.ts
308
+ type SearchInputProps = Omit<FieldProps, 'type' | 'label' | 'floating' | 'start'> & {
309
+ /** Required: a search field has no visible label. */
310
+ 'aria-label': string;
311
+ /** Called after the clear button or Esc empties the field. */
312
+ onClear?: () => void;
313
+ label?: never;
314
+ floating?: never;
315
+ start?: never;
316
+ type?: never;
317
+ };
318
+ export declare function SearchInput({ onClear, onChange, onKeyDown, inputClassName, size, ...props }: SearchInputProps): import("react").JSX.Element;
319
+ //#endregion
320
+ //#region src/components/meter/meter.d.ts
321
+ type MeterTone = BadgeTone;
322
+ type MeterSegment = {
323
+ label: string;
324
+ value: number;
325
+ tone: MeterTone;
326
+ };
327
+ type MeterProps = Omit<ComponentProps<'div'>, 'children'> & {
328
+ label: ReactNode;
329
+ /** Short trailing text on the label row, e.g. "9 of 13 report health". */
330
+ summary?: ReactNode;
331
+ /** Drawn in order; zero values are left out of both the bar and the legend. */
332
+ segments: MeterSegment[];
333
+ };
334
+ /**
335
+ * Stacked proportion bar with a legend. The bar is decorative; the legend list carries the
336
+ * numbers for assistive tech, so nothing is conveyed by color alone.
337
+ */
338
+ export declare function Meter({ label, summary, segments, className, ...props }: MeterProps): import("react").JSX.Element;
339
+ //#endregion
340
+ //#region src/components/select/select.d.ts
341
+ /** `value` must be non-empty: `''` is reserved for "nothing chosen". */
342
+ type SelectOption = {
343
+ value: string;
344
+ /** Also the option's text, which typeahead and screen readers use. */
345
+ label: string;
346
+ /** Decorative (aria-hidden); shown in the picker and on the trigger while selected. */
347
+ icon?: ReactNode;
348
+ disabled?: boolean;
349
+ };
350
+ type SelectGroup = {
351
+ label: string;
352
+ options: SelectOption[];
353
+ };
354
+ type NativeSelectProps = Omit<ComponentProps<'select'>, 'size' | 'children' | 'multiple' | 'value' | 'defaultValue'>;
355
+ type SelectProps = NativeSelectProps & FieldLabelProps & {
356
+ options: (SelectOption | SelectGroup)[];
357
+ /** `''` means nothing chosen. */
358
+ value?: string;
359
+ defaultValue?: string;
360
+ /** Shown while nothing is chosen. Label-above only: a floating label takes its place (MUI). */
361
+ placeholder?: string;
362
+ helperText?: ReactNode;
363
+ /** Truthy puts the field in the error state; the text replaces helperText. */
364
+ error?: ReactNode;
365
+ size?: FieldSize;
366
+ /** Fixed decorative leading icon; the selected option's own icon wins when it has one. */
367
+ start?: ReactNode;
368
+ mono?: boolean;
369
+ /** Classes for the `<select>`; `className` goes to the outer wrapper. */
370
+ selectClassName?: string;
371
+ /** A native select can't be read-only; use disabled or a read-only Input. */
372
+ readOnly?: never;
373
+ /** Single choice only. */
374
+ multiple?: never;
375
+ /** The trailing slot belongs to the chevron. */
376
+ end?: never;
377
+ };
378
+ /**
379
+ * Single-choice select: a real `<select>` (native keyboard, typeahead, forms, validation and
380
+ * autofill), customized through `appearance: base-select` where supported. Same frame as Input.
381
+ */
382
+ export declare function Select({ options, placeholder, helperText, error, size, start, mono, className, selectClassName, label, floating, id, required, disabled, value, defaultValue, onChange, ref, 'aria-describedby': describedByProp, 'aria-invalid': ariaInvalid, ...props }: SelectProps): import("react").JSX.Element;
383
+ //#endregion
384
+ //#region src/components/sidebar/sidebar.d.ts
385
+ /**
386
+ * Drawer open state shared by Sidebar and SidebarTrigger, which usually sit in different parts of
387
+ * the app shell. One per sidebar; no shortcuts, no persistence.
388
+ */
389
+ export declare function SidebarProvider({ children }: {
390
+ children: ReactNode;
391
+ }): import("react").JSX.Element;
392
+ type SidebarLabel = {
393
+ 'aria-label': string;
394
+ 'aria-labelledby'?: never;
395
+ } | {
396
+ 'aria-labelledby': string;
397
+ 'aria-label'?: never;
398
+ };
399
+ type SidebarProps = Omit<ComponentProps<'nav'>, 'aria-label' | 'aria-labelledby'> & SidebarLabel;
400
+ /**
401
+ * App navigation. From 960px up it is docked at the start of the layout: 240px, full height, only
402
+ * the body scrolls. Below 960px it is hidden and SidebarTrigger opens the same content in a drawer.
403
+ * Needs a SidebarProvider around both.
404
+ */
405
+ export declare function Sidebar({ className, children, ...props }: SidebarProps): import("react").JSX.Element;
406
+ type SidebarTriggerProps = Omit<ComponentProps<'button'>, 'children' | 'type' | 'aria-label' | 'aria-expanded' | 'aria-controls'> & {
407
+ 'aria-label'?: string;
408
+ size?: 'sm' | 'md' | 'lg';
409
+ };
410
+ /** Menu button that opens the drawer; only shown below 960px. Focus returns here on close. */
411
+ export declare function SidebarTrigger({ 'aria-label': ariaLabel, className, onClick, ...props }: SidebarTriggerProps): import("react").JSX.Element;
412
+ /** Brand row, pinned above the body. In the drawer it also holds the close button. */
413
+ export declare function SidebarHeader({ className, children, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
414
+ /** The groups, between header and footer; the only part that scrolls. */
415
+ export declare function SidebarBody({ className, ref, onPointerMove, onPointerLeave, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
416
+ /** Pinned below the body. */
417
+ export declare function SidebarFooter({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
418
+ type SidebarGroupProps = ComponentProps<'div'> & {
419
+ /** Short sentence-case label above the items; also names the list for screen readers. */
420
+ label?: ReactNode;
421
+ };
422
+ export declare function SidebarGroup({ label, className, children, ...props }: SidebarGroupProps): import("react").JSX.Element;
423
+ type SidebarItemProps = ComponentProps<'a'> & {
424
+ /**
425
+ * Render the only child (usually a router Link) as the item, merging these props into it. The
426
+ * link sets href and aria-current="page"; the item is styled from them.
427
+ */
428
+ asChild?: boolean;
429
+ };
430
+ /**
431
+ * A sidebar link. Plain `<a>` by default; with `asChild`, your router's Link. Mark the current one
432
+ * aria-current="page". Inside the drawer, a click the link handles in place (preventDefault, as
433
+ * router links do) closes the drawer; a modified click opens a new tab and leaves it open.
434
+ */
435
+ export declare function SidebarItem({ asChild, className, children, ...props }: SidebarItemProps): import("react").JSX.Element;
436
+ /** Decorative 16px leading icon for a SidebarItem (hidden from assistive tech); takes the text color. */
437
+ export declare function SidebarIcon({ className, ...props }: ComponentProps<'span'>): import("react").JSX.Element;
438
+ /** Count at the end of a SidebarItem, as a small neutral Badge; part of the name ("Projects 8"). */
439
+ export declare function SidebarBadge({ className, ...props }: BadgeProps): import("react").JSX.Element;
440
+ //#endregion
441
+ //#region src/components/switch/switch.d.ts
442
+ type SwitchSize = 'sm' | 'md';
443
+ type NativeSwitchProps = Omit<ComponentProps<'input'>, 'type' | 'size' | 'children' | 'role' | 'aria-checked' | 'aria-label'>;
444
+ type SwitchProps = NativeSwitchProps & ChoiceLabelProps & {
445
+ /** One muted line under the label (what is true while it's on), linked with aria-describedby. */
446
+ description?: ReactNode;
447
+ /** Truthy sets aria-invalid; text is shown under the label and linked with aria-describedby. */
448
+ error?: ReactNode;
449
+ /** sm 28x14 for dense rows and tables, md 36x20 for settings. */
450
+ size?: SwitchSize;
451
+ /**
452
+ * A spinner in the thumb while the change is being saved: aria-busy, and clicks/Space are
453
+ * swallowed without disabling, so focus stays put.
454
+ */
455
+ loading?: boolean;
456
+ /** `start`: label first and the switch pushed to the far end, as in a settings row. */
457
+ labelPosition?: 'end' | 'start';
458
+ /** Classes for the `<input>` (the track); `className` goes to the row. */
459
+ inputClassName?: string;
460
+ };
461
+ export declare function Switch({ label, description, error, size, loading, labelPosition, className, inputClassName, disabled, onChange, 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, ...props }: SwitchProps): import("react").JSX.Element;
462
+ //#endregion
463
+ //#region src/components/tabs/shared.d.ts
464
+ type TabsVariant = 'line' | 'segmented';
465
+ type TabsSize = 'sm' | 'md';
466
+ type TabContentProps = {
467
+ /** Decorative leading icon (hidden from assistive tech). */
468
+ icon?: ReactNode;
469
+ /** Trailing slot, usually a Badge; part of the accessible name (e.g. "Resources 12"). */
470
+ badge?: ReactNode;
471
+ children?: ReactNode;
472
+ };
473
+ //#endregion
474
+ //#region src/components/tabs/tab-nav.d.ts
475
+ type TabNavLabel = {
476
+ 'aria-label': string;
477
+ 'aria-labelledby'?: never;
478
+ } | {
479
+ 'aria-labelledby': string;
480
+ 'aria-label'?: never;
481
+ };
482
+ type TabNavProps = Omit<ComponentProps<'nav'>, 'aria-label' | 'aria-labelledby'> & TabNavLabel & {
483
+ variant?: TabsVariant;
484
+ size?: TabsSize;
485
+ /** Classes for the inner `<ul>` (the scrolling bar); `className` goes to the `<nav>`. */
486
+ listClassName?: string;
487
+ };
488
+ /**
489
+ * Tabs that change the URL: a `<nav>` of links, the current one marked (by the router, usually)
490
+ * with aria-current="page". Same look as Tabs, but link semantics: Tab moves between links, Enter
491
+ * follows one, and each can be opened in a new tab. For in-page panels, use Tabs.
492
+ */
493
+ export declare function TabNav({ variant, size, className, listClassName, children, ...props }: TabNavProps): import("react").JSX.Element;
494
+ type TabNavLinkProps = ComponentProps<'a'> & TabContentProps & {
495
+ /**
496
+ * Render the only child (usually a router Link) as the tab, merging these props into it. The
497
+ * link sets href, aria-current="page" and aria-disabled; the tab is styled from them.
498
+ */
499
+ asChild?: boolean;
500
+ };
501
+ /**
502
+ * A link styled as a tab. Plain `<a>` by default; with `asChild`, your router's Link (for an index
503
+ * route, make it current only on an exact match, or it stays current on every child route).
504
+ */
505
+ export declare function TabNavLink({ asChild, icon, badge, className, onFocus, children, ...props }: TabNavLinkProps): import("react").JSX.Element;
506
+ //#endregion
507
+ //#region src/components/tabs/tabs.d.ts
508
+ type TabsActivationMode = 'automatic' | 'manual';
509
+ type TabsLabel = {
510
+ 'aria-label': string;
511
+ 'aria-labelledby'?: never;
512
+ } | {
513
+ 'aria-labelledby': string;
514
+ 'aria-label'?: never;
515
+ };
516
+ type TabsState = {
517
+ value: string;
518
+ defaultValue?: never;
519
+ onValueChange?: (value: string) => void;
520
+ } | {
521
+ value?: never;
522
+ defaultValue: string;
523
+ onValueChange?: (value: string) => void;
524
+ };
525
+ type TabsProps = Omit<ComponentProps<'div'>, 'defaultValue' | 'onChange' | 'aria-label' | 'aria-labelledby'> & TabsLabel & TabsState & {
526
+ /**
527
+ * `automatic` (default): arrow keys select as they move, for panels that show instantly.
528
+ * `manual`: arrows only move focus, Enter/Space selects; use it when a panel loads data.
529
+ */
530
+ activationMode?: TabsActivationMode;
531
+ variant?: TabsVariant;
532
+ size?: TabsSize;
533
+ };
534
+ /**
535
+ * In-page tabs (WAI-ARIA APG tabs pattern): a tablist that switches panels without changing the
536
+ * URL. For tabs that navigate between routes, use TabNav.
537
+ */
538
+ export declare function Tabs({ value, defaultValue, onValueChange, activationMode, variant, size, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, children, ...props }: TabsProps): import("react").JSX.Element;
539
+ type TabListProps = Omit<ComponentProps<'div'>, 'role'>;
540
+ export declare function TabList({ className, ref, onKeyDown, onPointerMove, onPointerLeave, children, ...props }: TabListProps): import("react").JSX.Element;
541
+ type TabProps = Omit<ComponentProps<'button'>, 'value' | 'role' | 'type' | 'children'> & TabContentProps & {
542
+ value: string;
543
+ };
544
+ export declare function Tab({ value, icon, badge, disabled, className, ref, onClick, onFocus, children, ...props }: TabProps): import("react").JSX.Element;
545
+ type TabPanelProps = Omit<ComponentProps<'div'>, 'role' | 'hidden'> & {
546
+ value: string;
547
+ /** Keep the panel (and its state) mounted while hidden; by default only the selected panel renders. */
548
+ keepMounted?: boolean;
549
+ };
550
+ export declare function TabPanel({ value, keepMounted, className, ...props }: TabPanelProps): import("react").JSX.Element | null;
551
+ //#endregion
552
+ //#region src/components/theme-switcher/use-theme.d.ts
553
+ type Theme = 'system' | 'light' | 'dark';
554
+ type UseThemeOptions = {
555
+ /** localStorage key the choice is saved under. */
556
+ storageKey?: string;
557
+ };
558
+ /** Persisted color theme; `system` clears data-theme so prefers-color-scheme decides. */
559
+ export declare function useTheme({ storageKey }?: UseThemeOptions): {
560
+ theme: Theme;
561
+ setTheme: import("react").Dispatch<import("react").SetStateAction<Theme>>;
562
+ };
563
+ //#endregion
564
+ //#region src/components/theme-switcher/theme-switcher.d.ts
565
+ type ThemeSwitcherProps = Omit<ComponentProps<'button'>, 'onChange' | 'value' | 'defaultValue' | 'children'> & {
566
+ value: Theme;
567
+ onChange: (value: Theme) => void;
568
+ };
569
+ /** Toggle the visible theme in one click, including when the initial choice follows the system. */
570
+ export declare function ThemeSwitcher({ value, onChange, onClick, className, 'aria-label': ariaLabel, ...props }: ThemeSwitcherProps): import("react").JSX.Element;
571
+ //#endregion
572
+ //#region src/components/toast/store.d.ts
573
+ type ToastType = 'neutral' | 'success' | 'info' | 'warning' | 'danger' | 'loading';
574
+ /** A button rendered with the toast's Button styling. Clicking it dismisses the toast unless `onClick` calls `event.preventDefault()`. */
575
+ type ToastActionButton = {
576
+ label: string;
577
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
578
+ };
579
+ type ToastOptions = {
580
+ /** Reusing the id of a toast still on screen updates that toast in place instead of adding one. */
581
+ id?: string;
582
+ title: ReactNode;
583
+ description?: ReactNode;
584
+ /** Default `neutral`. */
585
+ type?: ToastType;
586
+ /**
587
+ * `{ label, onClick }` renders a small secondary Button. Any other node (e.g. a router `<Link>`
588
+ * styled as a button) is rendered as-is and never dismisses the toast by itself.
589
+ */
590
+ action?: ToastActionButton | ReactNode;
591
+ /**
592
+ * Milliseconds on screen; `Infinity` keeps it until dismissed. Default: 5000, 10000 with an
593
+ * action, never for `danger` and `loading`.
594
+ */
595
+ duration?: number;
596
+ /** False hides the close button and turns off swipe and Esc. Default true. */
597
+ dismissible?: boolean;
598
+ /** The `<Toaster id>` that shows it. Left out, it goes to the Toaster without an id. */
599
+ toasterId?: string;
600
+ };
601
+ type ToastPatch = Partial<Omit<ToastOptions, 'id' | 'toasterId'>>;
602
+ declare function update(id: string, patch: ToastPatch): void;
603
+ type ShortcutOptions = Omit<ToastOptions, 'title' | 'type'>;
604
+ type PromiseStep = ReactNode | Omit<ToastOptions, 'id' | 'type'>;
605
+ type ToastPromiseOptions<T> = {
606
+ id?: string;
607
+ toasterId?: string;
608
+ loading: PromiseStep;
609
+ success: PromiseStep | ((data: T) => PromiseStep);
610
+ error: PromiseStep | ((error: unknown) => PromiseStep);
611
+ };
612
+ /**
613
+ * Imperative toasts, callable from anywhere (event handlers, mutations, loaders) once a
614
+ * `<Toaster />` is mounted. Every call returns the toast's id. `toasterId` routes a toast to a
615
+ * `<Toaster id>` instead.
616
+ */
617
+ export declare const toast: ((options: ToastOptions) => string) & {
618
+ success: (title: ReactNode, options?: ShortcutOptions) => string;
619
+ info: (title: ReactNode, options?: ShortcutOptions) => string;
620
+ warning: (title: ReactNode, options?: ShortcutOptions) => string;
621
+ /** Renders as the `danger` type. Stays until dismissed. */
622
+ error: (title: ReactNode, options?: ShortcutOptions) => string;
623
+ /** Spinner; stays until updated or dismissed. */
624
+ loading: (title: ReactNode, options?: ShortcutOptions) => string;
625
+ /** Merges into a toast still on screen and restarts its timer. No-op for unknown ids. */
626
+ update: typeof update;
627
+ /** Plays the exit of one toast, or of all of them without an id. */
628
+ dismiss: (id?: string) => void;
629
+ /**
630
+ * Loading toast that turns into success or danger in place when the promise settles. Steps
631
+ * are a title or full options; success/error may be functions of the result / the error.
632
+ */
633
+ promise<T>(promise: Promise<T> | (() => Promise<T>), steps: ToastPromiseOptions<T>): string;
634
+ };
635
+ //#endregion
636
+ //#region src/components/toast/toaster.d.ts
637
+ type ToastPosition = 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center';
638
+ type ToasterProps = {
639
+ /**
640
+ * Shows only toasts created with this `toasterId`. Without one it shows toasts that have none:
641
+ * that's the app's single main Toaster. Ids let a separate area (or each Storybook docs story)
642
+ * keep its own stack and position.
643
+ */
644
+ id?: string;
645
+ /** Corner (or edge center) the stack grows from. Default `bottom-right`. */
646
+ position?: ToastPosition;
647
+ /** Cards shown in the collapsed stack; older ones wait hidden. Default 3, at most 2 on phones. */
648
+ visibleToasts?: number;
649
+ };
650
+ /**
651
+ * The single place toasts render: mount one near the app root (inside the router, so a `<Link>`
652
+ * action has its context). Toasts themselves come from `toast()` and friends.
653
+ */
654
+ export declare function Toaster(props: ToasterProps): import("react").ReactPortal | null;
655
+ //#endregion
656
+ //#region src/lib/cn.d.ts
657
+ export declare function cn(...inputs: ClassValue[]): string;
658
+ //#endregion
659
+ export type { BadgeProps, BadgeTone, ButtonProps, CardHeaderProps, CardProps, CheckboxGroupProps, CheckboxProps, CopyInputProps, DialogCloseReason, DialogHeaderProps, DialogProps, DialogSize, DrawerCloseProps, DrawerCloseReason, DrawerHeaderProps, DrawerProps, DrawerSide, DrawerSize, InputProps, MeterProps, MeterSegment, MeterTone, PasswordInputProps, SearchInputProps, SelectGroup, SelectOption, SelectProps, SidebarGroupProps, SidebarItemProps, SidebarProps, SidebarTriggerProps, SwitchProps, SwitchSize, TabListProps, TabNavLinkProps, TabNavProps, TabPanelProps, TabProps, TabsActivationMode, TabsProps, TabsSize, TabsVariant, Theme, ThemeSwitcherProps, ToastActionButton, ToastOptions, ToastPatch, ToastPosition, ToastPromiseOptions, ToastType, ToasterProps, TooltipProps, UseThemeOptions };