@minimalstuff/ui 3.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sonny
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Callable } from 'react-call';
2
2
  import { ComponentPropsWithRef } from 'react';
3
- import { HTMLAttributeAnchorTarget } from 'react';
3
+ import type { HTMLAttributeAnchorTarget } from 'react';
4
4
  import { JSX } from 'react';
5
5
  import { JSXElementConstructor } from 'react';
6
- import { MouseEvent as MouseEvent_2 } from 'react';
6
+ import type { MouseEvent as MouseEvent_2 } from 'react';
7
7
  import { ReactElement } from 'react';
8
8
  import { ReactNode } from 'react';
9
9
  import { ReactPortal } from 'react';
@@ -11,6 +11,34 @@ import { Ref } from 'react';
11
11
  import { StoreApi } from 'zustand';
12
12
  import { UseBoundStore } from 'zustand';
13
13
 
14
+ /**
15
+ * The picture of a person, or the initial of `name` when there is none.
16
+ * Labelled with the full `name` so screen readers announce the person rather
17
+ * than a stray letter; the `<img>` itself stays out of the accessibility
18
+ * tree to avoid announcing it twice.
19
+ *
20
+ * A `src` that fails to load falls back to the initial — remote avatars go
21
+ * missing (deleted accounts, rate limits), and a broken-image glyph in a
22
+ * circle looks like a bug. Pointing `src` at a different URL retries.
23
+ *
24
+ * A missing name is the caller's call to make: this renders whatever `name`
25
+ * starts with, and an empty circle for a blank string, rather than inventing
26
+ * a placeholder identity.
27
+ */
28
+ export declare function Avatar({ name, src, size, color, radius, unstyled, className, }: Readonly<AvatarProps>): JSX.Element;
29
+
30
+ export declare interface AvatarProps {
31
+ name: string;
32
+ src?: string;
33
+ size?: AvatarSize;
34
+ color?: ButtonColor;
35
+ radius?: Radius;
36
+ unstyled?: boolean;
37
+ className?: string;
38
+ }
39
+
40
+ export declare type AvatarSize = ControlSize;
41
+
14
42
  export declare const Badge: ({ children, color, variant, size, radius, className, ...props }: Readonly<BadgeProps>) => JSX.Element;
15
43
 
16
44
  export declare interface BadgeProps extends ComponentPropsWithRef<'span'> {
@@ -25,7 +53,6 @@ export declare type BadgeSize = ControlSize;
25
53
 
26
54
  export declare type BadgeVariant = 'solid' | 'outline' | 'subtle';
27
55
 
28
- /** Chrome shared by every text-entry control (Input, Textarea, Select, Combobox). */
29
56
  export declare const BASE_INPUT_STYLES = "w-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed";
30
57
 
31
58
  export declare function Button(buttonProps: Readonly<ButtonProps>): JSX.Element;
@@ -36,6 +63,7 @@ declare type ButtonColor =
36
63
  | 'danger'
37
64
  | 'success'
38
65
  | 'warning';
66
+ export { ButtonColor as AvatarColor }
39
67
  export { ButtonColor as BadgeColor }
40
68
  export { ButtonColor }
41
69
 
@@ -60,7 +88,40 @@ declare type ButtonStyle = {
60
88
 
61
89
  export declare type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'subtle';
62
90
 
63
- export declare function CharacterCount({ current, min, max, showMin, showMax, unstyled, className, }: Readonly<CharacterCountProps>): JSX.Element;
91
+ /**
92
+ * A section container: surface, border, radius, padding. Pass `title` (plus
93
+ * optionally `description` and `actions`, which sit opposite the title) to
94
+ * get the standard header, or omit all three and lay the section out inside
95
+ * `children` yourself.
96
+ *
97
+ * A titled card is also a labelled `region`, so screen reader users can jump
98
+ * between sections by name — worth it on a settings page stacking seven of
99
+ * them. Untitled cards stay plain `div`s rather than adding nameless
100
+ * landmarks. Set `headingLevel` when the card sits under an existing heading:
101
+ * the default `h2` is right at the top level of a page and wrong nested.
102
+ *
103
+ * `unstyled` strips the surface, border, radius and padding; the header
104
+ * markup stays, since that is structure rather than skin.
105
+ */
106
+ export declare function Card({ children, title, description, actions, headingLevel, padding, radius, unstyled, className, }: Readonly<CardProps>): JSX.Element;
107
+
108
+ export declare type CardHeadingLevel = 2 | 3 | 4;
109
+
110
+ export declare type CardPadding = 'none' | 'sm' | 'md' | 'lg';
111
+
112
+ export declare interface CardProps {
113
+ children: ReactNode;
114
+ title?: ReactNode;
115
+ description?: ReactNode;
116
+ actions?: ReactNode;
117
+ headingLevel?: CardHeadingLevel;
118
+ padding?: CardPadding;
119
+ radius?: Radius;
120
+ unstyled?: boolean;
121
+ className?: string;
122
+ }
123
+
124
+ export declare function CharacterCount({ current, min, max, showMin, showMax, unstyled, id, className, }: Readonly<CharacterCountProps>): JSX.Element;
64
125
 
65
126
  export declare interface CharacterCountProps {
66
127
  current: number;
@@ -69,10 +130,33 @@ export declare interface CharacterCountProps {
69
130
  showMin?: boolean;
70
131
  showMax?: boolean;
71
132
  unstyled?: boolean;
133
+ id?: string;
72
134
  className?: string;
73
135
  }
74
136
 
75
- export declare function Checkbox({ label, description, error, radius, unstyled, className, wrapperClassName, checked, defaultChecked, onChange, id, ...props }: Readonly<CheckboxProps>): JSX.Element;
137
+ export declare function Checkbox({ label, description, error, radius, unstyled, fullWidth, variant, className, wrapperClassName, checked, defaultChecked, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<CheckboxProps>): JSX.Element;
138
+
139
+ export declare type CheckboxOption = ChoiceOption;
140
+
141
+ export declare function CheckboxOptions({ options, orientation, values, defaultValues, onChange, name: nameProp, label, error, required, requiredLabel, disabled, radius, unstyled, className, wrapperClassName, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<CheckboxOptionsProps>): JSX.Element;
142
+
143
+ export declare interface CheckboxOptionsProps extends Omit<ComponentPropsWithRef<'fieldset'>, 'onChange'> {
144
+ options: string[] | CheckboxOption[];
145
+ orientation?: 'vertical' | 'horizontal';
146
+ values?: readonly string[];
147
+ defaultValues?: readonly string[];
148
+ onChange?: (values: readonly string[]) => void;
149
+ name?: string;
150
+ label?: string | React.ReactNode;
151
+ error?: string;
152
+ required?: boolean;
153
+ requiredLabel?: string;
154
+ radius?: Radius;
155
+ unstyled?: boolean;
156
+ className?: string;
157
+ wrapperClassName?: string;
158
+ id?: string;
159
+ }
76
160
 
77
161
  export declare interface CheckboxProps extends Omit<ComponentPropsWithRef<'input'>, 'type' | 'className'> {
78
162
  label?: string | React.ReactNode;
@@ -80,17 +164,28 @@ export declare interface CheckboxProps extends Omit<ComponentPropsWithRef<'input
80
164
  error?: string;
81
165
  radius?: Radius;
82
166
  unstyled?: boolean;
167
+ fullWidth?: boolean;
168
+ variant?: 'inline' | 'card';
83
169
  className?: string;
84
170
  wrapperClassName?: string;
85
171
  }
86
172
 
87
- export declare function ClientOnly({ children, fallback }: Readonly<ClientOnlyProps>): string | number | bigint | boolean | Iterable< ReactNode> | Promise<string | number | bigint | boolean | ReactPortal | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable< ReactNode> | null | undefined> | JSX.Element | null;
173
+ /** One choice in a `RadioOptions` or `CheckboxOptions` list. */
174
+ export declare interface ChoiceOption {
175
+ value: string;
176
+ label: string;
177
+ description?: string;
178
+ icon?: string;
179
+ disabled?: boolean;
180
+ }
181
+
182
+ export declare function ClientOnly({ children, fallback }: Readonly<ClientOnlyProps>): string | number | bigint | boolean | JSX.Element | Iterable< ReactNode> | Promise<string | number | bigint | boolean | ReactPortal | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable< ReactNode> | null | undefined> | null;
88
183
 
89
184
  export declare interface ClientOnlyProps extends React.PropsWithChildren {
90
185
  fallback?: React.ReactNode;
91
186
  }
92
187
 
93
- export declare function Combobox({ options, label, error, placeholder, noResultsText, clearLabel, radius, unstyled, disabled, required, className, wrapperClassName, value, defaultValue, onChange, id, }: Readonly<ComboboxProps>): JSX.Element;
188
+ export declare function Combobox({ options, label, 'aria-label': ariaLabel, error, placeholder, noResultsText, clearLabel, radius, unstyled, disabled, required, className, wrapperClassName, value, defaultValue, onChange, id, }: Readonly<ComboboxProps>): JSX.Element;
94
189
 
95
190
  export declare interface ComboboxOption {
96
191
  value: string;
@@ -100,6 +195,7 @@ export declare interface ComboboxOption {
100
195
  export declare interface ComboboxProps {
101
196
  options: ComboboxOption[];
102
197
  label?: string | ReactNode;
198
+ 'aria-label'?: string;
103
199
  error?: string;
104
200
  placeholder?: string;
105
201
  noResultsText?: string;
@@ -135,15 +231,21 @@ export declare interface ConfirmModalProps {
135
231
  export declare type ConfirmModalResponse = boolean;
136
232
 
137
233
  /**
138
- * Wraps `children` (the right-click target area) and opens `items`, a list
139
- * of `MenuItem` elements as direct children (see `MenuItem`'s own doc
140
- * comment), at the cursor position. Right-click again elsewhere on the
141
- * wrapped area to reposition it.
234
+ * Wraps `children` (the right-click target area) and opens `items` — made
235
+ * of `MenuItem`s, optionally wrapped in `MenuGroup`s and split by
236
+ * `MenuSeparator`s — at the cursor position. Right-click again elsewhere on
237
+ * the wrapped area to reposition it.
238
+ *
239
+ * Keyboard-only users reach it via Shift+F10 or the Menu key instead of a
240
+ * right-click, but only once the wrapped area (or something inside it) can
241
+ * hold focus — give `children` a focusable element, or a `tabIndex={0}` plus
242
+ * a `role` and `aria-label` on the wrapper itself, or Shift+F10 has nothing
243
+ * to fire on. See `context_menu.stories.tsx`'s `Default` story.
142
244
  *
143
245
  * For a menu anchored to a specific button (e.g. a kebab icon) instead of a
144
246
  * right-click, use `Menu`.
145
247
  */
146
- export declare function ContextMenu({ children, items, radius, className, ref, }: Readonly<ContextMenuProps>): JSX.Element;
248
+ export declare function ContextMenu({ children, items, radius, className, ref, 'aria-label': ariaLabel, }: Readonly<ContextMenuProps>): JSX.Element;
147
249
 
148
250
  export declare interface ContextMenuProps {
149
251
  /** The area that opens the menu on right-click. */
@@ -153,6 +255,8 @@ export declare interface ContextMenuProps {
153
255
  radius?: Radius;
154
256
  className?: string;
155
257
  ref?: Ref<HTMLDivElement>;
258
+ /** Names the menu for assistive tech, since there is no trigger element to label it from. */
259
+ 'aria-label'?: string;
156
260
  }
157
261
 
158
262
  /** The size scale every inline control shares (Button, IconButton, Badge, Kbd). */
@@ -205,7 +309,7 @@ declare type IconButtonStyle = {
205
309
  radius?: Radius;
206
310
  };
207
311
 
208
- export declare function Input({ label, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, ...props }: Readonly<InputProps>): JSX.Element;
312
+ export declare function Input({ label, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<InputProps>): JSX.Element;
209
313
 
210
314
  export declare interface InputProps extends ComponentPropsWithRef<'input'> {
211
315
  label?: string | ReactNode;
@@ -233,23 +337,63 @@ export declare type KbdSize = ControlSize;
233
337
 
234
338
  /**
235
339
  * A dropdown anchored to `trigger` (e.g. a kebab `IconButton`): click to
236
- * open, click again/click outside/Escape to close. `children` must be
237
- * `MenuItem` elements as direct children (see `MenuItem`'s own doc comment)
238
- * for keyboard nav and close-on-select to work.
340
+ * open, click again/click outside/Escape to close, or ArrowDown/ArrowUp on
341
+ * the closed trigger to open focused on the first/last item respectively.
342
+ * `children` is made of `MenuItem`s, optionally wrapped in `MenuGroup`s and
343
+ * split by `MenuSeparator`s.
239
344
  *
240
345
  * For "right-click anywhere on this area" instead of a specific trigger
241
346
  * button, use `ContextMenu`.
347
+ *
348
+ * Safe to nest inside a `Modal`: Escape on the open menu calls
349
+ * `event.preventDefault()` before closing it (see `MenuSurface`), so the
350
+ * modal's own Escape handler — which ignores an already-`defaultPrevented`
351
+ * event — leaves the dialog open and only the menu closes.
352
+ *
353
+ * Opening a `Modal` from a `MenuItem`'s `onClick` is also safe: the menu
354
+ * returns focus to `trigger` synchronously during the click, then the modal
355
+ * mounts a render later and takes focus from there. That ordering is what
356
+ * makes the modal record `trigger` as its restore target, so focus lands
357
+ * back on the trigger when the modal closes. The menu panel outlives the
358
+ * click by one exit animation, but the modal sits above it and owns Escape
359
+ * (a document listener), so the fading panel is inert. See
360
+ * `menu_with_modal.test.tsx`.
242
361
  */
243
362
  export declare function Menu({ trigger, children, side, align, radius, className, ref, }: Readonly<MenuProps>): JSX.Element;
244
363
 
245
364
  export declare type MenuAlign = 'start' | 'center' | 'end';
246
365
 
247
366
  /**
248
- * A row inside a `Menu` or `ContextMenu`. Must be a direct child of one of
249
- * those (or of a `<>` fragment passed as their `children`/`items`): arrow
250
- * key navigation and close-on-select both rely on `role="menuitem"` being a
251
- * direct descendant. Wrapping items in another element (e.g. a `<div>` for
252
- * a labeled section) will render fine but breaks both.
367
+ * A named group of `MenuItem`s inside a `Menu` or `ContextMenu`. Where
368
+ * `MenuSeparator` cuts, this one names — and unlike a bare title sitting
369
+ * next to the items, `role="group"` plus `aria-labelledby` actually tells
370
+ * assistive tech which items the name covers.
371
+ *
372
+ * Wrapping items is safe: the enclosing menu collects `[role="menuitem"]`
373
+ * across all its descendants, so keyboard navigation still walks into the
374
+ * group, and close-on-select travels through React context rather than the
375
+ * DOM tree.
376
+ *
377
+ * `className` styles the label — the only part of the group that carries any
378
+ * skin. `wrapperClassName` styles the `role="group"` element around both the
379
+ * label and the items.
380
+ */
381
+ export declare function MenuGroup({ label, children, unstyled, className, wrapperClassName, }: Readonly<MenuGroupProps>): JSX.Element;
382
+
383
+ export declare interface MenuGroupProps {
384
+ label: ReactNode;
385
+ children: ReactNode;
386
+ unstyled?: boolean;
387
+ className?: string;
388
+ wrapperClassName?: string;
389
+ }
390
+
391
+ /**
392
+ * A row inside a `Menu` or `ContextMenu`, at any depth: the menu collects
393
+ * `[role="menuitem"]`/`[role="menuitemradio"]` across all its descendants
394
+ * for keyboard navigation, and close-on-select travels through React
395
+ * context rather than the DOM tree. `MenuGroup` relies on that to wrap the
396
+ * items it names.
253
397
  *
254
398
  * Renders either a `<button>` (pass `onClick`) or a native `<a>` (pass
255
399
  * `href`, plus optional `target`/`rel`); the two are mutually exclusive.
@@ -263,27 +407,45 @@ export declare type MenuAlign = 'start' | 'center' | 'end';
263
407
  export declare function MenuItem(menuItemProps: Readonly<MenuItemProps>): JSX.Element;
264
408
 
265
409
  declare type MenuItemBaseProps = {
266
- icon?: string;
267
- danger?: boolean;
268
- disabled?: boolean;
269
- children: ReactNode;
270
- className?: string;
410
+ icon?: string;
411
+ /**
412
+ * Content pinned to the end of the row, dimmed by default — a `Kbd`, the
413
+ * current value of a setting. Keep it inert: the whole row is already the
414
+ * control, so anything focusable or separately clickable in here breaks
415
+ * both the menu's keyboard navigation and its `menuitem` semantics.
416
+ *
417
+ * It sits inside the row, so it is part of what the row announces:
418
+ * "Theme, Dark" for a value, "Shortcuts, Command K" for a shortcut. That
419
+ * is usually what you want; pass already-hidden content if it is not.
420
+ */
421
+ trailing?: ReactNode;
422
+ danger?: boolean;
423
+ disabled?: boolean;
424
+ children: ReactNode;
425
+ className?: string;
271
426
  };
272
427
 
273
428
  export declare type MenuItemButtonProps = MenuItemBaseProps & {
274
- onClick: (event: MouseEvent_2<HTMLButtonElement>) => void;
275
- href?: never;
276
- target?: never;
277
- rel?: never;
278
- ref?: Ref<HTMLButtonElement>;
429
+ onClick: (event: MouseEvent_2<HTMLButtonElement>) => void;
430
+ /**
431
+ * Turns the item into one option of a choice: it reports as
432
+ * `menuitemradio`, carries `aria-checked`, and shows a check mark when
433
+ * true. Leave it out for plain actions — an unset `selected` is not the
434
+ * same as `false`, which reads as "an option, currently not the one".
435
+ */
436
+ selected?: boolean;
437
+ href?: never;
438
+ target?: never;
439
+ rel?: never;
440
+ ref?: Ref<HTMLButtonElement>;
279
441
  };
280
442
 
281
443
  export declare type MenuItemLinkProps = MenuItemBaseProps & {
282
- href: string;
283
- target?: HTMLAttributeAnchorTarget;
284
- rel?: string;
285
- onClick?: never;
286
- ref?: Ref<HTMLAnchorElement>;
444
+ href: string;
445
+ target?: HTMLAttributeAnchorTarget;
446
+ rel?: string;
447
+ onClick?: never;
448
+ ref?: Ref<HTMLAnchorElement>;
287
449
  };
288
450
 
289
451
  export declare type MenuItemProps = MenuItemButtonProps | MenuItemLinkProps;
@@ -299,6 +461,18 @@ export declare interface MenuProps {
299
461
  ref?: Ref<HTMLSpanElement>;
300
462
  }
301
463
 
464
+ /**
465
+ * A divider between groups of `MenuItem`s inside a `Menu` or `ContextMenu`.
466
+ * Carries `role="separator"` (never `menuitem`), so the surrounding menu's
467
+ * arrow key navigation skips it: only focusable items take part.
468
+ */
469
+ export declare const MenuSeparator: ({ unstyled, className, }: Readonly<MenuSeparatorProps>) => JSX.Element;
470
+
471
+ export declare interface MenuSeparatorProps {
472
+ unstyled?: boolean;
473
+ className?: string;
474
+ }
475
+
302
476
  export declare type MenuSide = 'top' | 'bottom' | 'left' | 'right';
303
477
 
304
478
  export declare const Modal: Callable<ModalProps, void, {}>;
@@ -323,6 +497,8 @@ export declare interface ModalProps {
323
497
  className?: string;
324
498
  dismissible?: boolean;
325
499
  closeLabel?: string;
500
+ /** Names the dialog when there is no `title`; ignored when `title` is set since the title labels it. */
501
+ 'aria-label'?: string;
326
502
  }
327
503
 
328
504
  export declare function ModalProvider(): JSX.Element;
@@ -331,15 +507,56 @@ declare type ModalRenderProp = ReactNode | ((close: () => void) => ReactNode);
331
507
 
332
508
  export declare type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
333
509
 
334
- export declare interface RadioOption {
510
+ /**
511
+ * Multi-select combobox: a trigger button showing the selected options as
512
+ * pills opens a searchable dropdown of checkbox-style options. Selecting an
513
+ * option never closes the dropdown, unlike the single-select `Combobox`.
514
+ */
515
+ export declare function MultiCombobox({ options, label, 'aria-label': ariaLabel, error, placeholder, searchPlaceholder, noResultsText, clearLabel, clearText, maxSelectedValues, isOptionDisabled, maxDisplayedValues, formatOverflowCount, formatSelectedCount, formatMaxSelectedHint, radius, unstyled, disabled, required, className, wrapperClassName, values, defaultValues, onChange, onDropdownClose, id, }: Readonly<MultiComboboxProps>): ReactElement;
516
+
517
+ export declare interface MultiComboboxOption {
335
518
  value: string;
336
519
  label: string;
337
- description?: string;
338
- icon?: string;
520
+ }
521
+
522
+ export declare interface MultiComboboxProps {
523
+ options: readonly MultiComboboxOption[];
524
+ label?: string | ReactNode;
525
+ 'aria-label'?: string;
526
+ error?: string;
527
+ placeholder?: string;
528
+ searchPlaceholder?: string;
529
+ noResultsText?: string;
530
+ clearLabel?: string;
531
+ clearText?: string;
532
+ maxSelectedValues?: number;
533
+ isOptionDisabled?: (optionValue: string, selectedValues: readonly string[]) => boolean;
534
+ maxDisplayedValues?: number;
535
+ formatOverflowCount?: (hiddenCount: number) => string;
536
+ formatSelectedCount?: (selectedCount: number) => string;
537
+ formatMaxSelectedHint?: (maxSelectedValues: number) => string;
538
+ radius?: Radius;
539
+ unstyled?: boolean;
339
540
  disabled?: boolean;
541
+ required?: boolean;
542
+ className?: string;
543
+ wrapperClassName?: string;
544
+ values?: readonly string[];
545
+ defaultValues?: readonly string[];
546
+ onChange?: (values: readonly string[]) => void;
547
+ /**
548
+ * Fires with the final selection whenever the user is done editing:
549
+ * when the dropdown closes (Escape, outside click, focus leaving the
550
+ * wrapper), and when the selection is cleared from the trigger's X
551
+ * button while the dropdown is closed.
552
+ */
553
+ onDropdownClose?: (values: readonly string[]) => void;
554
+ id?: string;
340
555
  }
341
556
 
342
- export declare function RadioOptions({ options, orientation, value, defaultValue, onChange, name: nameProp, label, error, required, disabled, radius, unstyled, className, wrapperClassName, id, ...props }: Readonly<RadioOptionsProps>): JSX.Element;
557
+ export declare type RadioOption = ChoiceOption;
558
+
559
+ export declare function RadioOptions({ options, orientation, value, defaultValue, onChange, name: nameProp, label, error, required, disabled, radius, unstyled, className, wrapperClassName, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<RadioOptionsProps>): JSX.Element;
343
560
 
344
561
  export declare interface RadioOptionsProps extends Omit<ComponentPropsWithRef<'fieldset'>, 'onChange'> {
345
562
  options: string[] | RadioOption[];
@@ -360,7 +577,7 @@ export declare interface RadioOptionsProps extends Omit<ComponentPropsWithRef<'f
360
577
 
361
578
  declare type Radius = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
362
579
 
363
- export declare function Select({ options, label, error, placeholder, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, ...props }: Readonly<SelectProps>): JSX.Element;
580
+ export declare function Select({ options, label, error, placeholder, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<SelectProps>): JSX.Element;
364
581
 
365
582
  export declare interface SelectOption {
366
583
  value: string;
@@ -418,13 +635,14 @@ export declare function splitIntoHighlightSegments(
418
635
  return segments;
419
636
  }
420
637
 
421
- export declare function Switch({ label, description, error, unstyled, className, wrapperClassName, checked, defaultChecked, onChange, id, ...props }: Readonly<SwitchProps>): JSX.Element;
638
+ export declare function Switch({ label, description, error, unstyled, fullWidth, className, wrapperClassName, checked, defaultChecked, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<SwitchProps>): JSX.Element;
422
639
 
423
640
  export declare interface SwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'type' | 'className'> {
424
641
  label?: string | ReactNode;
425
642
  description?: string | ReactNode;
426
643
  error?: string;
427
644
  unstyled?: boolean;
645
+ fullWidth?: boolean;
428
646
  className?: string;
429
647
  wrapperClassName?: string;
430
648
  }
@@ -436,21 +654,31 @@ export declare interface TabItem {
436
654
  icon?: string;
437
655
  }
438
656
 
439
- export declare function Tabs({ items, value, defaultIndex, radius, unstyled, className, tabListClassName, panelClassName, onChange, }: Readonly<TabsProps>): JSX.Element;
657
+ export declare function Tabs({ items, value, defaultIndex, variant, size, radius, fullWidth, unstyled, animated, className, tabListClassName, panelClassName, onChange, }: Readonly<TabsProps>): JSX.Element;
440
658
 
441
659
  export declare interface TabsProps {
442
660
  items: TabItem[];
443
661
  value?: number;
444
662
  defaultIndex?: number;
663
+ variant?: TabsVariant;
664
+ size?: ControlSize;
665
+ /**
666
+ * Only visibly rounds the `segmented` variant's track and tabs. The `line`
667
+ * variant has no filled surface to round, so radius is a no-op there.
668
+ */
445
669
  radius?: Radius;
670
+ fullWidth?: boolean;
446
671
  unstyled?: boolean;
672
+ animated?: boolean;
447
673
  className?: string;
448
674
  tabListClassName?: string;
449
675
  panelClassName?: string;
450
676
  onChange?: (index: number) => void;
451
677
  }
452
678
 
453
- export declare function Textarea({ label, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, ...props }: Readonly<TextareaProps>): JSX.Element;
679
+ export declare type TabsVariant = 'line' | 'segmented';
680
+
681
+ export declare function Textarea({ label, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<TextareaProps>): JSX.Element;
454
682
 
455
683
  export declare interface TextareaProps extends ComponentPropsWithRef<'textarea'> {
456
684
  label?: string | ReactNode;
@@ -466,11 +694,9 @@ export declare interface TextareaProps extends ComponentPropsWithRef<'textarea'>
466
694
 
467
695
  export declare type Theme = 'light' | 'dark' | 'system';
468
696
 
469
- declare type Theme_2 = 'light' | 'dark' | 'system';
470
-
471
697
  declare interface ThemeStore {
472
- theme: Theme_2;
473
- setTheme: (theme: Theme_2) => void;
698
+ theme: Theme;
699
+ setTheme: (theme: Theme) => void;
474
700
  }
475
701
 
476
702
  export declare function ThemeToggle({ isTransitionEnabled, transitionDuration, transitionEasing, size, radius, variant, getAriaLabel, }: Readonly<ThemeToggleProps>): JSX.Element;
@@ -482,9 +708,15 @@ export declare interface ThemeToggleProps {
482
708
  size?: 'sm' | 'md' | 'lg';
483
709
  radius?: Radius;
484
710
  variant?: ButtonVariant;
485
- getAriaLabel?: (theme: Theme_2) => string;
711
+ getAriaLabel?: (theme: Theme) => string;
486
712
  }
487
713
 
714
+ /**
715
+ * The trigger (`children`) must be focusable, otherwise the tooltip is
716
+ * unreachable by keyboard. Shows on hover and focus; Escape dismisses it.
717
+ * `temporaryContent` is announced to screen readers through a polite status
718
+ * region.
719
+ */
488
720
  export declare function Tooltip({ content, children, position, showOnClick, temporaryContent, temporaryDuration, disabled, radius, onTemporaryShow, className, ref, }: Readonly<TooltipProps>): JSX.Element;
489
721
 
490
722
  export declare type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';