@lessly/ui 0.27.0 → 1.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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ClassValue } from 'clsx';
2
- import * as class_variance_authority_types from 'class-variance-authority/types';
3
2
  import * as React$1 from 'react';
4
3
  import { ComponentProps } from 'react';
4
+ import * as class_variance_authority_types from 'class-variance-authority/types';
5
5
  import * as class_variance_authority from 'class-variance-authority';
6
6
  import { VariantProps } from 'class-variance-authority';
7
7
  import * as DialogPrimitive from '@radix-ui/react-dialog';
@@ -31,6 +31,7 @@ import * as TabsPrimitive from '@radix-ui/react-tabs';
31
31
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
32
32
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
33
33
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
34
+ import { Command as Command$1 } from 'cmdk';
34
35
  import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
35
36
  import { Toaster as Toaster$1 } from 'sonner';
36
37
  export { toast } from 'sonner';
@@ -41,18 +42,110 @@ import { FieldValues, FieldPath, ControllerProps } from 'react-hook-form';
41
42
 
42
43
  declare function cn(...inputs: ClassValue[]): string;
43
44
 
45
+ type AutoHeightProps = React$1.HTMLAttributes<HTMLDivElement>;
46
+ /**
47
+ * Eases its own height as the content inside it changes size — a dialog body that swaps between two
48
+ * layouts, a panel that reveals a section — so the container grows or shrinks smoothly instead of
49
+ * jumping. The content's height is measured with a ResizeObserver and written straight onto the
50
+ * wrapper; routing it through React state instead lands a re-render between the measure and the
51
+ * paint, which swallows the transition. The transition itself is the `.motion-auto-height` class
52
+ * (shipped in styles.css): it is motion-token driven, so it inherits the viewer's reduce-motion
53
+ * preference (the duration resolves to 0ms then).
54
+ *
55
+ * Wrap the changing content directly; anything that resizes it — a conditional branch, added rows,
56
+ * a data update — animates. Extra props and `className` land on the outer element.
57
+ *
58
+ * This is for size changes of content that stays mounted (a dialog body swapping layouts). For a
59
+ * show/hide reveal where the content mounts/unmounts (`{open ? <block/> : null}`), use `Collapsible`
60
+ * instead: AutoHeight flashes the block for a frame on show and can't animate the unmount on hide.
61
+ *
62
+ * Three things to know as a consumer: it owns `height` imperatively, so a `style={{ height }}` or
63
+ * `maxHeight` you pass is overwritten; it clips overflow *while animating* and gives your own
64
+ * `overflow` back at rest, so anything inside that must escape the box mid-ease — a tooltip, a
65
+ * non-portaled dropdown — should portal to the body; and the content sits in a block formatting
66
+ * context, so a vertical margin on a direct child is measured inside the box instead of collapsing
67
+ * out of it.
68
+ */
69
+ declare const AutoHeight: React$1.ForwardRefExoticComponent<AutoHeightProps & React$1.RefAttributes<HTMLDivElement>>;
70
+
44
71
  declare const buttonVariants: (props?: ({
45
- variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
46
- size?: "default" | "sm" | "lg" | "icon" | null | undefined;
72
+ variant?: "link" | "default" | "destructive" | "destructive-ghost" | "destructive-solid" | "outline" | "secondary" | "ghost" | null | undefined;
73
+ size?: "default" | "sm" | "xs" | "lg" | "icon" | null | undefined;
47
74
  } & class_variance_authority_types.ClassProp) | undefined) => string;
48
- interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
75
+ type ButtonBase = Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & VariantProps<typeof buttonVariants>;
76
+ /**
77
+ * The labelled form. With the `icon` prop the component renders and sizes the glyph and marks it
78
+ * `aria-hidden`, because the label beside it already carries the meaning.
79
+ *
80
+ * `asChild` hands the element to the consumer, which leaves nowhere to put an `icon` — passing both
81
+ * warns in dev and renders the child untouched.
82
+ */
83
+ type ButtonLabelledProps = ButtonBase & {
84
+ children: React$1.ReactNode;
85
+ icon?: React$1.ReactNode;
86
+ iconPosition?: 'leading' | 'trailing';
49
87
  asChild?: boolean;
50
- }
88
+ };
89
+ /**
90
+ * Icon-only: an icon and no children, and the type is what enforces the accessible name.
91
+ *
92
+ * It owes a **tooltip** as well, and that half is not enforced here on purpose: `Tooltip.Root`
93
+ * throws without a `TooltipProvider` above it, and one provider is mounted per canvas — never one
94
+ * per icon — so a Button that mounted its own would crash any consumer rendering outside an
95
+ * `AppShell`. Wrap the call site instead.
96
+ *
97
+ * Known consequence: the base class sets `disabled:pointer-events-none`, so a **disabled** icon-only
98
+ * button fires no hover and its tooltip never opens — on exactly the button whose disabled reason
99
+ * most needs explaining. Put the trigger on a wrapping element when the hint has to survive the
100
+ * disabled state (`Button --disabled-with-tooltip` shows both).
101
+ */
102
+ type ButtonIconOnlyProps = ButtonBase & {
103
+ children?: never;
104
+ icon: React$1.ReactNode;
105
+ iconPosition?: never;
106
+ asChild?: never;
107
+ } & ({
108
+ 'aria-label': string;
109
+ } | {
110
+ 'aria-labelledby': string;
111
+ });
112
+ /**
113
+ * No label and no icon. Nonsense to render, but it is what `<Button />` typed as before the union
114
+ * landed, and this arm is what keeps that true.
115
+ */
116
+ type ButtonEmptyProps = ButtonBase & {
117
+ children?: never;
118
+ icon?: never;
119
+ iconPosition?: never;
120
+ asChild?: boolean;
121
+ };
122
+ type ButtonProps = ButtonLabelledProps | ButtonIconOnlyProps | ButtonEmptyProps;
51
123
  declare const Button: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<HTMLButtonElement>>;
52
124
 
53
- declare const Card: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
125
+ interface CardProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title'> {
126
+ /**
127
+ * A title bar: a heading left, one action right, over a hairline. With neither a title nor an
128
+ * action no bar is drawn at all, so a list starts at the top of the card.
129
+ */
130
+ title?: React$1.ReactNode;
131
+ action?: React$1.ReactNode;
132
+ /**
133
+ * `list` clips to the card's radius and hairlines between children.
134
+ * `nested` is the quiet inner box: a smaller radius, sunk a step, no shadow.
135
+ */
136
+ variant?: 'default' | 'list' | 'nested';
137
+ }
138
+ declare const Card: React$1.ForwardRefExoticComponent<CardProps & React$1.RefAttributes<HTMLDivElement>>;
54
139
  declare const CardHeader: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
55
- declare const CardTitle: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLHeadingElement> & React$1.RefAttributes<HTMLParagraphElement>>;
140
+ interface CardTitleProps extends React$1.HTMLAttributes<HTMLElement> {
141
+ /**
142
+ * The tag the title emits, so the card can take the outline level the page around it leaves
143
+ * free. A title that isn't a section heading — inside a dialog, or a card whose heading is
144
+ * already stated — takes `p`, `div` or `span` instead of a level nobody wanted.
145
+ */
146
+ as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'div' | 'span';
147
+ }
148
+ declare const CardTitle: React$1.ForwardRefExoticComponent<CardTitleProps & React$1.RefAttributes<HTMLElement>>;
56
149
  declare const CardDescription: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLParagraphElement> & React$1.RefAttributes<HTMLParagraphElement>>;
57
150
  declare const CardContent: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
58
151
  declare const CardFooter: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
@@ -62,7 +155,20 @@ declare const DialogTrigger: React$1.ForwardRefExoticComponent<DialogPrimitive.D
62
155
  declare const DialogPortal: React$1.FC<DialogPrimitive.DialogPortalProps>;
63
156
  declare const DialogClose: React$1.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React$1.RefAttributes<HTMLButtonElement>>;
64
157
  declare const DialogOverlay: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
65
- declare const DialogContent: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
158
+ interface DialogContentProps extends React$1.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
159
+ /**
160
+ * Whether the corner ✕ is drawn. On by default — a dialog someone opened is one they can shut,
161
+ * and the mark is where every dialog in the console keeps it.
162
+ *
163
+ * Turn it off for a surface that is not the console's to close: a step mocking an OS sheet, whose
164
+ * real counterpart has no web close affordance. **Escape and the overlay still dismiss the
165
+ * dialog** — Radix owns both and neither is touched here — so this removes an affordance, never
166
+ * the only way out. A step whose only exit should be its own footer is a different thing again,
167
+ * and it is built by holding `open` yourself, not by hiding this.
168
+ */
169
+ showClose?: boolean;
170
+ }
171
+ declare const DialogContent: React$1.ForwardRefExoticComponent<DialogContentProps & React$1.RefAttributes<HTMLDivElement>>;
66
172
  declare const DialogHeader: {
67
173
  ({ className, ...props }: React$1.HTMLAttributes<HTMLDivElement>): React$1.JSX.Element;
68
174
  displayName: string;
@@ -75,11 +181,51 @@ declare const DialogTitle: React$1.ForwardRefExoticComponent<Omit<DialogPrimitiv
75
181
  declare const DialogDescription: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React$1.RefAttributes<HTMLParagraphElement>, "ref"> & React$1.RefAttributes<HTMLParagraphElement>>;
76
182
 
77
183
  declare const DropdownMenu: React$1.FC<DropdownMenuPrimitive.DropdownMenuProps>;
78
- declare const DropdownMenuTrigger: React$1.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & React$1.RefAttributes<HTMLButtonElement>>;
79
184
  declare const DropdownMenuGroup: React$1.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & React$1.RefAttributes<HTMLDivElement>>;
80
185
  declare const DropdownMenuPortal: React$1.FC<DropdownMenuPrimitive.DropdownMenuPortalProps>;
81
186
  declare const DropdownMenuSub: React$1.FC<DropdownMenuPrimitive.DropdownMenuSubProps>;
82
187
  declare const DropdownMenuRadioGroup: React$1.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuRadioGroupProps & React$1.RefAttributes<HTMLDivElement>>;
188
+ type DropdownMenuTriggerBaseProps = React$1.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>;
189
+ /**
190
+ * `quiet` appends the chevron as a second child, so it cannot be combined with `asChild`: a Radix
191
+ * `Slot` takes exactly one and throws on two. `asChild?: never` is what makes that a compile error
192
+ * rather than a runtime one. `bare` hands `children` straight through untouched, so a `false` from
193
+ * the unrendered chevron never reaches `Slot` and counts as that second child.
194
+ */
195
+ type DropdownMenuTriggerProps = (DropdownMenuTriggerBaseProps & {
196
+ variant?: 'bare';
197
+ chevron?: never;
198
+ }) | (Omit<DropdownMenuTriggerBaseProps, 'asChild'> & {
199
+ variant: 'quiet';
200
+ asChild?: never;
201
+ /**
202
+ * Whether the trigger wears its chevron. That mark means "there is something to pick here"
203
+ * (Guidelines/Controls/Stated, not picked), so a menu that only explains — a role a group
204
+ * carries, a reader who may not act — sets it `false` and stays pressable without promising a
205
+ * choice. Defaults to `true`.
206
+ */
207
+ chevron?: boolean;
208
+ });
209
+ /**
210
+ * `bare` is the Radix trigger with nothing added — whatever it wraps is the whole control, which is
211
+ * what `asChild` around a `Button` wants and what every trigger shipped before this prop existed
212
+ * got. It stays the default, and it stays byte-identical: `className` is left inside the spread
213
+ * rather than destructured and re-passed, so a trigger given none renders with no `class` attribute
214
+ * at all. Handing Radix an explicit `className={undefined}` is not the same thing — its `Slot`
215
+ * copies the key because the key is present, and writes `class=""`.
216
+ *
217
+ * `quiet` is the trigger that answers a row rather than a form: no border, sized to the words it
218
+ * happens to be showing, with the hover fill saying it can be pressed and the chevron saying a menu
219
+ * is behind it. A row's answer is already labelled by the row, so a bordered box beside it marks
220
+ * nothing, and a column of them down a list reads as a form put inside a list.
221
+ *
222
+ * **One `quiet`, one box.** It is spelled to match `Select variant="quiet"` step for step, because
223
+ * the two answer rows on the same screens and a word that meant three sizes was a word that meant
224
+ * nothing. The 36px floor is not decoration: a 20px control fails WCAG 2.5.8's 24px target size.
225
+ * A caption-scale handle inside a sub-line takes `min-h-6 text-xs` on top — smaller type in a
226
+ * smaller row, still on the floor.
227
+ */
228
+ declare const DropdownMenuTrigger: React$1.ForwardRefExoticComponent<DropdownMenuTriggerProps & React$1.RefAttributes<HTMLButtonElement>>;
83
229
  declare const DropdownMenuSubTrigger: React$1.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubTriggerProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & {
84
230
  inset?: boolean;
85
231
  } & React$1.RefAttributes<HTMLDivElement>>;
@@ -100,7 +246,14 @@ declare const DropdownMenuShortcut: {
100
246
  displayName: string;
101
247
  };
102
248
 
103
- type InputProps = React$1.InputHTMLAttributes<HTMLInputElement>;
249
+ interface InputProps extends React$1.InputHTMLAttributes<HTMLInputElement> {
250
+ /**
251
+ * The unit the value is in — a currency, a period, a rate. It sits inside the field's border, on
252
+ * the side the number ends, because a unit set outside the box reads as the next word of the row
253
+ * rather than as part of the answer. It is text, never a control: nothing here is pressable.
254
+ */
255
+ suffix?: React$1.ReactNode;
256
+ }
104
257
  declare const Input: React$1.ForwardRefExoticComponent<InputProps & React$1.RefAttributes<HTMLInputElement>>;
105
258
 
106
259
  type InputGroupProps = React$1.HTMLAttributes<HTMLDivElement>;
@@ -122,6 +275,30 @@ declare const InputGroupInput: React$1.ForwardRefExoticComponent<InputGroupInput
122
275
 
123
276
  declare const Label: React$1.ForwardRefExoticComponent<Omit<LabelPrimitive.LabelProps & React$1.RefAttributes<HTMLLabelElement>, "ref"> & VariantProps<(props?: class_variance_authority_types.ClassProp | undefined) => string> & React$1.RefAttributes<HTMLLabelElement>>;
124
277
 
278
+ interface OptionCardProps extends Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, 'title' | 'type'> {
279
+ /** The leading mark — an `EntityTile`, a `GlyphAvatar`, an icon. The call site supplies the node. */
280
+ mark?: React$1.ReactNode;
281
+ /** What the option is. */
282
+ title: React$1.ReactNode;
283
+ /** What choosing it means, in a phrase. Truncates rather than growing the card to a third line. */
284
+ description?: React$1.ReactNode;
285
+ /**
286
+ * Whether this option is the one that is on.
287
+ *
288
+ * **Leave it off entirely for a one-shot pick** — a grid that advances a stage and never rests on
289
+ * a choice. `aria-pressed` is then absent rather than `false`, because a control that is never
290
+ * pressed must not announce itself as a pressable-state one.
291
+ */
292
+ selected?: boolean;
293
+ }
294
+ /**
295
+ * One option in a set you choose from: a mark, a name, and a phrase saying what choosing it means.
296
+ *
297
+ * The card owns its frame, its padding and its focus treatment, so a call site supplies only the
298
+ * grid the cards sit in.
299
+ */
300
+ declare const OptionCard: React$1.ForwardRefExoticComponent<OptionCardProps & React$1.RefAttributes<HTMLButtonElement>>;
301
+
125
302
  interface PageHeaderProps {
126
303
  /** The page title. Rendered as an `<h2>`. */
127
304
  title: React$1.ReactNode;
@@ -141,9 +318,13 @@ interface PageHeaderProps {
141
318
  }
142
319
  /**
143
320
  * The standard page header for Organization and Product screens. Encodes the medallion↔subtitle
144
- * pair rule (Guidelines/Page headers): a decorative section medallion earns its place only beside a
145
- * subtitle, so keep both or drop both — you cannot render a lone medallion. An entity glyph (`media`)
146
- * is identity and always stays.
321
+ * pair rule (Guidelines/Page headers): a section medallion earns its place only beside a subtitle,
322
+ * so keep both or drop both — you cannot render a lone medallion. Cut a filler subtitle and the
323
+ * medallion goes with it, leaving a bare `<h2>`. An entity glyph (`media`) is identity, not
324
+ * decoration, and always stays.
325
+ *
326
+ * A header carrying a leading glyph indents its title past the content edge; a bare title sits on
327
+ * it. That difference is deliberate — it is what tells you a page has a mark.
147
328
  */
148
329
  declare function PageHeader({ title, subtitle, icon: Icon, media, badge, actions, id }: PageHeaderProps): React$1.JSX.Element;
149
330
 
@@ -156,6 +337,9 @@ declare function SectionIntro({ what, when }: SectionIntroProps): React$1.JSX.El
156
337
  interface SelectOption {
157
338
  value: string;
158
339
  label: string;
340
+ /** The line under the label, saying what choosing it does. Off the trigger — it belongs to the
341
+ * choice, not to the answer. */
342
+ description?: string;
159
343
  }
160
344
  interface SelectProps {
161
345
  value?: string;
@@ -169,8 +353,51 @@ interface SelectProps {
169
353
  'aria-label'?: string;
170
354
  'aria-labelledby'?: string;
171
355
  optionTestId?: (value: string) => string;
356
+ /**
357
+ * `quiet` is the select that answers a row rather than a form: no field border, no fixed height,
358
+ * sized to the word it is showing. A row's answer is already labelled by the row, so the box a
359
+ * field draws to say "type here" marks nothing — and a column of them down a list reads as a form
360
+ * put inside a list. Use it inside a row or a line of prose; keep `field` anywhere a label sits
361
+ * above the control.
362
+ */
363
+ variant?: 'field' | 'quiet';
364
+ }
365
+ declare function Select({ value, onValueChange, options, placeholder, disabled, className, 'data-testid': testId, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, optionTestId, variant, }: SelectProps): React$1.JSX.Element;
366
+
367
+ interface SettingRowProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title'> {
368
+ /** Leading glyph. Absent, the label starts at the row's left edge. */
369
+ icon?: LucideIcon;
370
+ label: React$1.ReactNode;
371
+ /** The second line under the label. */
372
+ description?: React$1.ReactNode;
373
+ /**
374
+ * Which side of the row carries the answer. `primary` is the settings row — the label names the
375
+ * thing and the control is whatever you set it to. `secondary` is the row that states a fact — a
376
+ * plan, a spend cap — where the value is what you came to read and the label only says what it is.
377
+ * Secondary also holds the label at the body weight under a description, because a quiet label
378
+ * does not become a heading by growing a second line, and it tops the value against that label
379
+ * rather than centring it: the right side is a string the reader baselines against the left, not
380
+ * an object beside a block.
381
+ */
382
+ labelTone?: 'primary' | 'secondary';
383
+ /** Names the control this row carries; renders <label>, otherwise <span>. */
384
+ htmlFor?: string;
385
+ /** The right-hand side — a Switch, a Select, a Button, or the value the row states. */
386
+ children: React$1.ReactNode;
172
387
  }
173
- declare function Select({ value, onValueChange, options, placeholder, disabled, className, 'data-testid': testId, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, optionTestId, }: SelectProps): React$1.JSX.Element;
388
+ /**
389
+ * One `label … value` line inside a card — where the value is a control you set, or a fact you read.
390
+ *
391
+ * `description` decides the row's shape, and that is a rule rather than an accident: a bare
392
+ * `label … control` line is a field caption, so it takes the body weight and centres on its
393
+ * control, while a label carrying a second line is the heading of a small block, so the two lines
394
+ * align to the top of the glyph beside them.
395
+ *
396
+ * `labelTone` decides which side the reader's eye lands on, and it is the one thing `description`
397
+ * does not settle: a row stating a plan or a spend cap wants a quiet label whether or not a second
398
+ * line explains who may change it.
399
+ */
400
+ declare const SettingRow: React$1.ForwardRefExoticComponent<SettingRowProps & React$1.RefAttributes<HTMLDivElement>>;
174
401
 
175
402
  interface SwitchProps {
176
403
  checked: boolean;
@@ -189,29 +416,95 @@ declare const RadioGroup: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimi
189
416
  declare const RadioGroupItem: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupItemProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
190
417
 
191
418
  type TextareaProps = React$1.TextareaHTMLAttributes<HTMLTextAreaElement>;
419
+ /** The same field edge an `Input` takes, for the same reason (`Guidelines/Look/Borders`, #417). */
192
420
  declare const Textarea: React$1.ForwardRefExoticComponent<TextareaProps & React$1.RefAttributes<HTMLTextAreaElement>>;
193
421
 
194
422
  declare const Slider: React$1.ForwardRefExoticComponent<Omit<SliderPrimitive.SliderProps & React$1.RefAttributes<HTMLSpanElement>, "ref"> & React$1.RefAttributes<HTMLSpanElement>>;
195
423
 
424
+ /**
425
+ * Two signals on two channels that never touch (#446), and two treatments for two shapes.
426
+ *
427
+ * **Fill means the pointer is here.** Selection reads as an edge, and `ToggleGroup` picks which
428
+ * edge from its `type` — the question being "can nothing be selected?".
429
+ *
430
+ * - `frame` (a standalone `Toggle`, and every `type="multiple"` group): each item carries its own
431
+ * 1px hairline and selection steps it up to `border-strong` — 5.17:1 against the page in light and
432
+ * 5.47:1 in dark, and 3.63:1 / 4.31:1 above the resting hairline it replaces. Fill used to say both
433
+ * things at 1.07:1, which is why a filter row could not say which of its filters were applied.
434
+ * - `track` (every `type="single"` group): the group draws the track and the selected slot takes the
435
+ * selection pair (#452) — `bg-bg-selected` filled inside a `ring-border-selected` edge. The fill is
436
+ * 1.08:1 against the page in dark and 1.04:1 in light, so it is the **edge** that carries the
437
+ * reading: 3.81:1 above the slot's own fill in dark and 3.75:1 in light, against 1.07:1 / 1.53:1
438
+ * for the `border-subtle` ring over `bg-bg-overlay` it replaces. A fill that faint is only placed
439
+ * at all against the track's own frame, which is why the track belongs to the component and not to
440
+ * the call site.
441
+ *
442
+ * The mark is a **ring**, not a border: a ring is a box-shadow, so it costs no layout and an
443
+ * icon-only toggle stays square at the height its `size` declares. It is also the whole mark —
444
+ * `track` carries no `shadow-sm`. The shadow was the raised reading a 1.18:1 fill could not give
445
+ * alone; under a 3.81:1 edge it is a second, weaker statement of one state, its blur compositing to
446
+ * 1.11:1 against the page in dark and 1.14:1 in light, and `shadow-sm` is the one dark step
447
+ * `@lessly/tokens@0.7.0` leaves without a rim, so in dark it can only darken.
448
+ *
449
+ * Focus is an **outline held 2px off the box** — a flush ring painted over the selection mark, and
450
+ * focused-selected and focused-unselected measured 1.55:1 apart, which is #446 on the keyboard.
451
+ *
452
+ * **An icon-only box drops its horizontal padding** (`ICON_ONLY_BOX` below), the same trade
453
+ * `Button`'s icon-only box makes with `p-0`. Padding is the whole of the intrinsic width when the
454
+ * only content is a 16px glyph, so `min-w-*` binds only while it stays under it: `sm` and `default`
455
+ * cleared that by coincidence (10+16+10 = 36, 12+16+12 = 40) and `lg` did not — `px-5` around a
456
+ * glyph is 56 against `h-12`, and an icon-only `lg` shipped 56&times;48. A **text** toggle is
457
+ * untouched at every size.
458
+ */
196
459
  declare const toggleVariants: (props?: ({
460
+ treatment?: "track" | "frame" | null | undefined;
197
461
  variant?: "default" | "outline" | null | undefined;
198
462
  size?: "default" | "sm" | "lg" | null | undefined;
199
463
  } & class_variance_authority_types.ClassProp) | undefined) => string;
200
464
  declare const Toggle: React$1.ForwardRefExoticComponent<Omit<TogglePrimitive.ToggleProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
465
+ treatment?: "track" | "frame" | null | undefined;
201
466
  variant?: "default" | "outline" | null | undefined;
202
467
  size?: "default" | "sm" | "lg" | null | undefined;
203
468
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLButtonElement>>;
204
469
 
470
+ /**
471
+ * `type` answers "can nothing be selected?", and that is what decides how selection reads (#446).
472
+ *
473
+ * `multiple` is a set of independent chips — a filter row, where nothing need be on — so each chip
474
+ * carries its own edge and selection steps that edge up. `single` is one object with a moving part,
475
+ * so it takes the segmented-control treatment (#346): the group draws the **track** — a hairline
476
+ * frame with no fill — and the selected slot is the only filled thing in the row.
477
+ *
478
+ * The track is the component's, not the call site's: the slot fill measures 1.04:1 against the page
479
+ * in light and 1.08:1 in dark, so without the track's edge a selected slot reads as nothing at all —
480
+ * the defect #446 reports. A component cannot own half of a two-part signal.
481
+ */
205
482
  declare const ToggleGroup: React$1.ForwardRefExoticComponent<((Omit<ToggleGroupPrimitive.ToggleGroupSingleProps & React$1.RefAttributes<HTMLDivElement>, "ref"> | Omit<ToggleGroupPrimitive.ToggleGroupMultipleProps & React$1.RefAttributes<HTMLDivElement>, "ref">) & VariantProps<(props?: ({
483
+ treatment?: "track" | "frame" | null | undefined;
206
484
  variant?: "default" | "outline" | null | undefined;
207
485
  size?: "default" | "sm" | "lg" | null | undefined;
208
- } & class_variance_authority_types.ClassProp) | undefined) => string>) & React$1.RefAttributes<HTMLDivElement>>;
486
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & {
487
+ /**
488
+ * The selection mark is one element that slides between slots on the motion tokens, rather
489
+ * than appearing on each. The group makes its slots equal-width to carry it; the width of the
490
+ * **track** is still the caller's, and defaults to the width of whatever holds it.
491
+ */
492
+ sliding?: boolean;
493
+ }) & React$1.RefAttributes<HTMLDivElement>>;
209
494
  declare const ToggleGroupItem: React$1.ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
495
+ treatment?: "track" | "frame" | null | undefined;
210
496
  variant?: "default" | "outline" | null | undefined;
211
497
  size?: "default" | "sm" | "lg" | null | undefined;
212
- } & class_variance_authority_types.ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLButtonElement>>;
498
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & {
499
+ /**
500
+ * Holds its column without being selectable — a rung that does not apply to this row, so a
501
+ * ladder of levels still lines up down a long list. Renders non-focusable and aria-hidden at
502
+ * the same width, with its label kept for the width and hidden from view.
503
+ */
504
+ inert?: boolean;
505
+ } & React$1.RefAttributes<HTMLButtonElement>>;
213
506
 
214
- declare const InputOTP: React$1.ForwardRefExoticComponent<(Omit<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
507
+ declare const InputOTP: React$1.ForwardRefExoticComponent<(Omit<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
215
508
  value?: string;
216
509
  onChange?: (newValue: string) => unknown;
217
510
  maxLength: number;
@@ -224,7 +517,7 @@ declare const InputOTP: React$1.ForwardRefExoticComponent<(Omit<Omit<React$1.Inp
224
517
  } & {
225
518
  render: (props: input_otp.RenderProps) => React$1.ReactNode;
226
519
  children?: never;
227
- } & React$1.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
520
+ } & React$1.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
228
521
  value?: string;
229
522
  onChange?: (newValue: string) => unknown;
230
523
  maxLength: number;
@@ -250,9 +543,26 @@ declare const PopoverAnchor: React$1.ForwardRefExoticComponent<PopoverPrimitive.
250
543
  declare const PopoverContent: React$1.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
251
544
 
252
545
  declare const TooltipProvider: React$1.FC<TooltipPrimitive.TooltipProviderProps>;
253
- declare const Tooltip: React$1.FC<TooltipPrimitive.TooltipProps>;
254
- declare const TooltipTrigger: React$1.ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & React$1.RefAttributes<HTMLButtonElement>>;
255
- declare const TooltipContent: React$1.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
546
+ declare const Tooltip: {
547
+ ({ children, ...props }: React$1.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>): React$1.JSX.Element;
548
+ displayName: string;
549
+ };
550
+ declare const TooltipTrigger: React$1.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipTriggerProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
551
+ type TooltipPrimitiveContentProps = React$1.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>;
552
+ interface TooltipContentProps extends TooltipPrimitiveContentProps {
553
+ /**
554
+ * Which side of the trigger the tooltip sits on. Physical: `left` and `right`
555
+ * are screen edges and stay where they are in a right-to-left layout.
556
+ */
557
+ side?: TooltipPrimitiveContentProps['side'];
558
+ /**
559
+ * Which end of the trigger the tooltip lines up with. Logical: `start` is the
560
+ * end the text starts at — the left in a left-to-right layout, the right in a
561
+ * right-to-left one.
562
+ */
563
+ align?: TooltipPrimitiveContentProps['align'];
564
+ }
565
+ declare const TooltipContent: React$1.ForwardRefExoticComponent<TooltipContentProps & React$1.RefAttributes<HTMLDivElement>>;
256
566
 
257
567
  declare const HoverCard: React$1.FC<HoverCardPrimitive.HoverCardProps>;
258
568
  declare const HoverCardTrigger: React$1.ForwardRefExoticComponent<HoverCardPrimitive.HoverCardTriggerProps & React$1.RefAttributes<HTMLAnchorElement>>;
@@ -264,7 +574,7 @@ declare const SheetClose: React$1.ForwardRefExoticComponent<DialogPrimitive.Dial
264
574
  declare const SheetPortal: React$1.FC<DialogPrimitive.DialogPortalProps>;
265
575
  declare const SheetOverlay: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
266
576
  declare const SheetContent: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
267
- side?: "top" | "right" | "bottom" | "left" | null | undefined;
577
+ side?: "bottom" | "left" | "right" | "top" | null | undefined;
268
578
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLDivElement>>;
269
579
  declare const SheetHeader: {
270
580
  ({ className, ...props }: React$1.HTMLAttributes<HTMLDivElement>): React$1.JSX.Element;
@@ -369,28 +679,129 @@ declare const MenubarShortcut: {
369
679
  displayName: string;
370
680
  };
371
681
 
682
+ /**
683
+ * `status` (#359) is the console's state pill: borderless, filled with `bg-bg-sunken`.
684
+ * `outline` gives a status the same hairline frame a button has — and since a ghost button carries
685
+ * no border at rest, the status pill ended up the most button-shaped object in a row. A fill with no
686
+ * frame reads as a label rather than a control. It is deliberately *not* `secondary`: that's the
687
+ * attribute chip (scope, auth method), so a status painted with it reads as an attribute. Under the
688
+ * cursor no neutral fill carries the pill's shape at all: `EntityRow` washes to `bg-bg-elevated`,
689
+ * and `bg-bg-sunken` measures 1.12:1 against it in light, `bg-bg-secondary` 1.01:1, where a non-text
690
+ * mark needs 3:1. `bg-bg-sunken` is the convention, not the measurement — there is no better fill in
691
+ * the ramp to go looking for.
692
+ *
693
+ * `danger-subtle`, `warning-subtle` and `neutral-subtle` are the three rungs of a severity ladder —
694
+ * critical, important, and the rung that is only worth knowing. They are the one place colour marks
695
+ * a state rather than an action, and *subtle* is the whole permission: the solid `destructive` and
696
+ * `warning` fills belong to a thing you must act on, and three of those read as three shouting
697
+ * pills. See Guidelines/Colour marks actions.
698
+ *
699
+ * The bottom rung is its own variant rather than the `status` pill because the three have to be read
700
+ * as one ladder: `bg-bg-sunken` is the strongest plate of the three in light, so a ladder resting on
701
+ * it puts its heaviest mark under its two lightest and reads upside down.
702
+ */
372
703
  declare const badgeVariants: (props?: ({
373
- variant?: "default" | "destructive" | "outline" | "secondary" | "success" | "warning" | null | undefined;
704
+ variant?: "status" | "default" | "destructive" | "outline" | "secondary" | "danger-subtle" | "warning-subtle" | "neutral-subtle" | "success" | "warning" | null | undefined;
374
705
  } & class_variance_authority_types.ClassProp) | undefined) => string;
375
706
  interface BadgeProps extends React$1.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
376
707
  }
377
708
  declare const Badge: React$1.ForwardRefExoticComponent<BadgeProps & React$1.RefAttributes<HTMLDivElement>>;
378
709
 
379
- declare const Table: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableElement> & React$1.RefAttributes<HTMLTableElement>>;
710
+ interface TableProps extends React$1.HTMLAttributes<HTMLTableElement> {
711
+ /**
712
+ * Name the table. Three tables on one page announce identically without a name,
713
+ * and a screen-reader user picking one out of the list has nothing to pick by.
714
+ * A `TableCaption` names it visibly and is the first choice; use this when the
715
+ * name is already on the page as a heading — then prefer `aria-labelledby`.
716
+ */
717
+ 'aria-label'?: string;
718
+ /** Names the table from a heading already on the page. See `aria-label`. */
719
+ 'aria-labelledby'?: string;
720
+ }
721
+ /**
722
+ * A data table. Give every one of them a name — a `TableCaption`, or
723
+ * `aria-label` / `aria-labelledby` when the name is already on the page.
724
+ */
725
+ declare const Table: React$1.ForwardRefExoticComponent<TableProps & React$1.RefAttributes<HTMLTableElement>>;
380
726
  declare const TableHeader: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableSectionElement> & React$1.RefAttributes<HTMLTableSectionElement>>;
381
727
  declare const TableBody: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableSectionElement> & React$1.RefAttributes<HTMLTableSectionElement>>;
382
728
  declare const TableFooter: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableSectionElement> & React$1.RefAttributes<HTMLTableSectionElement>>;
383
729
  declare const TableRow: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableRowElement> & React$1.RefAttributes<HTMLTableRowElement>>;
384
730
  declare const TableHead: React$1.ForwardRefExoticComponent<React$1.ThHTMLAttributes<HTMLTableCellElement> & React$1.RefAttributes<HTMLTableCellElement>>;
385
731
  declare const TableCell: React$1.ForwardRefExoticComponent<React$1.TdHTMLAttributes<HTMLTableCellElement> & React$1.RefAttributes<HTMLTableCellElement>>;
732
+ /** The table's visible name. Ends up as the table's accessible name. */
386
733
  declare const TableCaption: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableCaptionElement> & React$1.RefAttributes<HTMLTableCaptionElement>>;
387
734
 
388
735
  declare const Skeleton: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
389
736
 
737
+ /**
738
+ * @deprecated Use `PersonAvatar` for a person, `GlyphAvatar` for an agent or a group, or
739
+ * `EntityTile` for an object. Those three share one size scale, a tint family that holds contrast in
740
+ * both themes, and a fallback that survives a 404. `Avatar` will be removed in 1.0.
741
+ */
390
742
  declare const Avatar: React$1.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React$1.RefAttributes<HTMLSpanElement>, "ref"> & React$1.RefAttributes<HTMLSpanElement>>;
391
743
  declare const AvatarImage: React$1.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React$1.RefAttributes<HTMLImageElement>, "ref"> & React$1.RefAttributes<HTMLImageElement>>;
392
744
  declare const AvatarFallback: React$1.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React$1.RefAttributes<HTMLSpanElement>, "ref"> & React$1.RefAttributes<HTMLSpanElement>>;
393
745
 
746
+ /**
747
+ * The box every identity mark is drawn in. Internal on purpose: it is the only place that knows
748
+ * about `shape`, and keeping it unexported is what makes a round product unspellable. Import one of
749
+ * `PersonAvatar`, `GlyphAvatar` or `EntityTile` instead.
750
+ */
751
+ type MarkSize = 'xs' | 'sm' | 'md' | 'lg';
752
+
753
+ /**
754
+ * A person's mark: their photo, or their initials on a colour picked from their id so the same
755
+ * person is the same colour on every screen.
756
+ *
757
+ * Round, because a circle is a principal (`Guidelines/Avatars`). Pass `id` rather than relying on the
758
+ * name if the colour should survive a rename.
759
+ */
760
+ interface PersonAvatarProps {
761
+ name: string;
762
+ /** Seeds the tint. Falls back to the name, which is stable until the person is renamed. */
763
+ id?: string;
764
+ src?: string;
765
+ size?: MarkSize;
766
+ /** Opt into the accessibility tree. Omit beside a row title that already names the person. */
767
+ label?: string;
768
+ }
769
+ declare function PersonAvatar({ name, id, src, size, label }: PersonAvatarProps): React$1.JSX.Element;
770
+
771
+ /**
772
+ * The mark for a principal with no photo and no initials — an agent or a group.
773
+ *
774
+ * Round, like every principal. Never tinted: a tint follows a name, and `agent` is a kind rather than
775
+ * an identity, so colouring it would say nothing. Its job is to settle which glyph an agent gets, so
776
+ * two screens cannot pick different ones.
777
+ */
778
+ interface GlyphAvatarProps {
779
+ kind: 'agent' | 'group';
780
+ size?: MarkSize;
781
+ label?: string;
782
+ }
783
+ declare function GlyphAvatar({ kind, size, label }: GlyphAvatarProps): React$1.JSX.Element;
784
+
785
+ /**
786
+ * The mark for an object — a product, a connector, an API key, a device, a passkey.
787
+ *
788
+ * A rounded square, because a square is an object and a circle is a principal
789
+ * (`Guidelines/Avatars`). You can tell what a row is about before reading a word of it.
790
+ *
791
+ * **A tint follows a name, not a type.** A named thing you re-recognise across screens gets a colour;
792
+ * a thing identified only by what it is stays neutral. So a product tints and an API key does not.
793
+ */
794
+ interface EntityTileProps {
795
+ /** The object's own name. Its presence is what earns a tint, and its first letter is the fallback. */
796
+ name?: string;
797
+ /** A type glyph. Wins over the initial, and never tints. */
798
+ glyph?: React$1.ReactNode;
799
+ src?: string;
800
+ size?: MarkSize;
801
+ label?: string;
802
+ }
803
+ declare function EntityTile({ name, glyph, src, size, label }: EntityTileProps): React$1.JSX.Element;
804
+
394
805
  declare const Separator: React$1.ForwardRefExoticComponent<Omit<SeparatorPrimitive.SeparatorProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
395
806
 
396
807
  declare const Progress: React$1.ForwardRefExoticComponent<Omit<ProgressPrimitive.ProgressProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
@@ -417,9 +828,16 @@ declare const ScrollBar: React$1.ForwardRefExoticComponent<Omit<ScrollAreaPrimit
417
828
  declare const alertVariants: (props?: ({
418
829
  variant?: "default" | "destructive" | "success" | "warning" | null | undefined;
419
830
  } & class_variance_authority_types.ClassProp) | undefined) => string;
420
- declare const Alert: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
421
- variant?: "default" | "destructive" | "success" | "warning" | null | undefined;
422
- } & class_variance_authority_types.ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLDivElement>>;
831
+ interface AlertProps extends React$1.HTMLAttributes<HTMLDivElement>, VariantProps<typeof alertVariants> {
832
+ /**
833
+ * The value the alert is about — a secret, an id, an endpoint. It gets its own line below the
834
+ * words, in monospace, and truncates instead of running off the edge of the card.
835
+ */
836
+ value?: React$1.ReactNode;
837
+ /** What to do with that value — copy it, dismiss it. Sits at the end of the value's line, at full width. */
838
+ action?: React$1.ReactNode;
839
+ }
840
+ declare const Alert: React$1.ForwardRefExoticComponent<AlertProps & React$1.RefAttributes<HTMLDivElement>>;
423
841
  declare const AlertTitle: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLHeadingElement> & React$1.RefAttributes<HTMLParagraphElement>>;
424
842
  declare const AlertDescription: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLParagraphElement> & React$1.RefAttributes<HTMLParagraphElement>>;
425
843
 
@@ -489,7 +907,7 @@ declare const CommandInput: React$1.ForwardRefExoticComponent<Omit<Omit<Pick<Pic
489
907
  ref?: React$1.Ref<HTMLInputElement>;
490
908
  } & {
491
909
  asChild?: boolean;
492
- }, "asChild" | "key" | keyof React$1.InputHTMLAttributes<HTMLInputElement>>, "type" | "value" | "onChange"> & {
910
+ }, "asChild" | "key" | keyof React$1.InputHTMLAttributes<HTMLInputElement>>, "onChange" | "type" | "value"> & {
493
911
  value?: string;
494
912
  onValueChange?: (search: string) => void;
495
913
  } & React$1.RefAttributes<HTMLInputElement>, "ref"> & React$1.RefAttributes<HTMLInputElement>>;
@@ -515,7 +933,7 @@ declare const CommandGroup: React$1.ForwardRefExoticComponent<Omit<{
515
933
  ref?: React$1.Ref<HTMLDivElement>;
516
934
  } & {
517
935
  asChild?: boolean;
518
- }, "asChild" | "key" | keyof React$1.HTMLAttributes<HTMLDivElement>>, "value" | "heading"> & {
936
+ }, "asChild" | "key" | keyof React$1.HTMLAttributes<HTMLDivElement>>, "heading" | "value"> & {
519
937
  heading?: React$1.ReactNode;
520
938
  value?: string;
521
939
  forceMount?: boolean;
@@ -527,19 +945,13 @@ declare const CommandSeparator: React$1.ForwardRefExoticComponent<Omit<Pick<Pick
527
945
  }, "asChild" | "key" | keyof React$1.HTMLAttributes<HTMLDivElement>> & {
528
946
  alwaysRender?: boolean;
529
947
  } & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
530
- declare const CommandItem: React$1.ForwardRefExoticComponent<Omit<{
531
- children?: React$1.ReactNode;
532
- } & Omit<Pick<Pick<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React$1.HTMLAttributes<HTMLDivElement>> & {
533
- ref?: React$1.Ref<HTMLDivElement>;
534
- } & {
535
- asChild?: boolean;
536
- }, "asChild" | "key" | keyof React$1.HTMLAttributes<HTMLDivElement>>, "disabled" | "value" | "onSelect"> & {
537
- disabled?: boolean;
538
- onSelect?: (value: string) => void;
539
- value?: string;
540
- keywords?: string[];
541
- forceMount?: boolean;
542
- } & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
948
+ interface CommandItemProps extends React$1.ComponentPropsWithoutRef<typeof Command$1.Item> {
949
+ /** Leading mark — an avatar or tile. Does not shrink; the item switches to top alignment. */
950
+ mark?: React$1.ReactNode;
951
+ /** The second line under the label. */
952
+ sub?: React$1.ReactNode;
953
+ }
954
+ declare const CommandItem: React$1.ForwardRefExoticComponent<CommandItemProps & React$1.RefAttributes<HTMLDivElement>>;
543
955
  declare const CommandShortcut: {
544
956
  ({ className, ...props }: React$1.HTMLAttributes<HTMLSpanElement>): React$1.JSX.Element;
545
957
  displayName: string;
@@ -586,6 +998,40 @@ declare namespace DatePicker {
586
998
  var displayName: string;
587
999
  }
588
1000
 
1001
+ interface AddPickerItem {
1002
+ id: string;
1003
+ name: string;
1004
+ /** Second line under the name. */
1005
+ sub?: string;
1006
+ /** Leading mark — an avatar or a tile. */
1007
+ mark?: React$1.ReactNode;
1008
+ }
1009
+ interface AddPickerProps {
1010
+ /** Trigger label after the `+`. "Product" → "+ Product". */
1011
+ label: string;
1012
+ /** Plural noun for the search field: "Search 100 products". */
1013
+ noun: string;
1014
+ items: AddPickerItem[];
1015
+ /** Ids already taken. Filtered out of the list, still counted in the placeholder. */
1016
+ exclude?: string[];
1017
+ onPick: (id: string) => void;
1018
+ className?: string;
1019
+ }
1020
+ /**
1021
+ * The quiet `+ Label` that picks something that already exists, and behind it a search you type into
1022
+ * rather than a list you scroll (Guidelines/Controls/Add & search). The trigger is four lines; what
1023
+ * this owns is the forty under it — the open state, the query, the reset on both ways out of it, and
1024
+ * the filter.
1025
+ *
1026
+ * The count in the placeholder is the whole set, not what is left: it says how big the thing you are
1027
+ * searching is, which is why `exclude` leaves the list and not the number.
1028
+ *
1029
+ * `shouldFilter={false}` and our own `includes`: cmdk scores what it filters and reorders the list as
1030
+ * you type, and a reader looking for a name they can already see is helped by it shortening and not
1031
+ * by it rearranging.
1032
+ */
1033
+ declare const AddPicker: React$1.ForwardRefExoticComponent<AddPickerProps & React$1.RefAttributes<HTMLButtonElement>>;
1034
+
589
1035
  type CarouselApi = UseEmblaCarouselType[1];
590
1036
  type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
591
1037
  type CarouselOptions = UseCarouselParameters[0];
@@ -634,32 +1080,89 @@ declare const FormControl: React$1.ForwardRefExoticComponent<Omit<React$1.HTMLAt
634
1080
  declare const FormDescription: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLParagraphElement> & React$1.RefAttributes<HTMLParagraphElement>>;
635
1081
  declare const FormMessage: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLParagraphElement> & React$1.RefAttributes<HTMLParagraphElement>>;
636
1082
 
1083
+ /**
1084
+ * A dot is a small mark on a surface, so it paints from the theme-aware `--icon-*` status
1085
+ * tokens rather than the `--bg-*` fills, which exist to sit solid behind text and are not all
1086
+ * overridden per theme. Every variant clears 3:1 against `--bg-surface` in both themes —
1087
+ * `status-dot.test.tsx` pins that, reading the token straight off these class names.
1088
+ */
637
1089
  declare const statusDotVariants: (props?: ({
638
- status?: "success" | "warning" | "brand" | "danger" | "neutral" | null | undefined;
1090
+ status?: "success" | "warning" | "neutral" | "brand" | "danger" | null | undefined;
639
1091
  size?: "sm" | "lg" | "md" | null | undefined;
640
1092
  } & class_variance_authority_types.ClassProp) | undefined) => string;
641
1093
  interface StatusDotProps extends React$1.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof statusDotVariants> {
642
1094
  pulse?: boolean;
1095
+ /**
1096
+ * What the dot means, for the case where the dot is the only signal. Say the state in the
1097
+ * product's own words — "Blocked", "Awaiting review" — never the variant name, which is a
1098
+ * palette token the design system may rename without telling anyone downstream.
1099
+ *
1100
+ * Leave it off whenever a text label sits beside the dot. That is nearly every real usage,
1101
+ * and the dot then stays out of the accessibility tree so the label reads alone.
1102
+ */
1103
+ label?: string;
643
1104
  }
1105
+ /**
1106
+ * @deprecated A coloured circle that marks state. The console reads state as `Badge
1107
+ * variant="status"` — a borderless fill on `bg-bg-sunken`, no colour — because colour marks
1108
+ * actions there, never state, and decorative circles are banned outright. #334 took the last
1109
+ * three published components off this. It stays exported for the reference app's demo pages,
1110
+ * where a coloured dot on a campaign status is data, not console chrome. Reach for
1111
+ * `Badge variant="status"` in anything console-shaped.
1112
+ *
1113
+ * The dot is decorative unless you pass `label`, so a text label beside it reads on its own.
1114
+ */
644
1115
  declare const StatusDot: React$1.ForwardRefExoticComponent<StatusDotProps & React$1.RefAttributes<HTMLSpanElement>>;
645
1116
 
646
1117
  interface DocsLinkProps extends React$1.AnchorHTMLAttributes<HTMLAnchorElement> {
647
1118
  href?: string;
648
1119
  label?: string;
1120
+ /**
1121
+ * Show the leading `BookOpen` glyph. Defaults to `true` — the docs affordance. Set it `false`
1122
+ * where the target isn't documentation (a legal document, a status page): the book would either
1123
+ * mislabel the link or repeat a book already on screen, while the trailing `ExternalLink` mark,
1124
+ * the new-tab target and the `rel` are exactly what such a link still wants.
1125
+ */
1126
+ showLeadingIcon?: boolean;
649
1127
  }
650
1128
  declare const DocsLink: React$1.ForwardRefExoticComponent<DocsLinkProps & React$1.RefAttributes<HTMLAnchorElement>>;
651
1129
 
652
1130
  interface EmptyStateProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title'> {
653
1131
  icon?: LucideIcon;
654
1132
  title: React$1.ReactNode;
1133
+ /**
1134
+ * The tag the title emits. It defaults to `p` because an empty state usually sits inside a card
1135
+ * that already holds the heading; a page whose only text is an empty state names a level here so
1136
+ * the page has an outline at all.
1137
+ */
1138
+ titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p';
655
1139
  description?: React$1.ReactNode;
656
1140
  action?: React$1.ReactNode;
657
1141
  }
1142
+ /**
1143
+ * The empty state for any list, table or panel that can be empty (#356).
1144
+ *
1145
+ * It draws no frame and no fill of its own, because an empty state lives inside a Card and a second
1146
+ * border 16px in from the first is the same edge drawn twice. The glyph is bare for that same
1147
+ * reason, and only that one: it is already inside a frame. A plate is not decoration everywhere —
1148
+ * `PageHeader` gives the identical section glyph a medallion, because there the mark appears once
1149
+ * and stands alone on the page (Guidelines/Section glyphs). Standing on its own, wrap it in a Card.
1150
+ *
1151
+ * `title` states what is missing; `description` says what to do about it, and only earns its line
1152
+ * when it carries a fact the title doesn't; `action` is that step inline, so the way forward is
1153
+ * where the eye already is.
1154
+ */
658
1155
  declare const EmptyState: React$1.ForwardRefExoticComponent<EmptyStateProps & React$1.RefAttributes<HTMLDivElement>>;
659
1156
 
660
- interface CopyButtonProps extends Omit<ButtonProps, 'value'> {
1157
+ interface CopyButtonProps extends Omit<ButtonProps, 'value' | 'children' | 'icon' | 'iconPosition' | 'asChild'> {
661
1158
  value: string;
662
1159
  label?: string;
1160
+ /**
1161
+ * The value is a secret. Show it in front of the button as a fixed run of dots and its last four
1162
+ * characters — enough to tell two secrets apart, never enough to read one — and name the button by
1163
+ * that tail, so a screen reader says "Copy ending 7f3a" instead of reading out the dots.
1164
+ */
1165
+ masked?: boolean;
663
1166
  }
664
1167
  declare const CopyButton: React$1.ForwardRefExoticComponent<CopyButtonProps & React$1.RefAttributes<HTMLButtonElement>>;
665
1168
 
@@ -679,10 +1182,140 @@ interface StatCardProps extends React$1.HTMLAttributes<HTMLDivElement> {
679
1182
  }
680
1183
  declare const StatCard: React$1.ForwardRefExoticComponent<StatCardProps & React$1.RefAttributes<HTMLDivElement>>;
681
1184
 
1185
+ /** The factors this challenge can present. Order in `methods` is preference, not availability. */
1186
+ type StepUpMethod = 'passkey' | 'code';
1187
+ /**
1188
+ * The events that carry the digits of a one-time code. They are refused at compile time and stopped
1189
+ * at the field, so the code does not bubble out to a parent by the ordinary React route.
1190
+ */
1191
+ type CodeBearingHandler = 'onChange' | 'onChangeCapture' | 'onInput' | 'onInputCapture' | 'onBeforeInput' | 'onBeforeInputCapture' | 'onKeyDown' | 'onKeyDownCapture' | 'onKeyUp' | 'onKeyUpCapture' | 'onKeyPress' | 'onKeyPressCapture' | 'onPaste' | 'onPasteCapture' | 'onCopy' | 'onCopyCapture' | 'onCut' | 'onCutCapture' | 'onDrop' | 'onDropCapture';
1192
+ interface StepUpChallengeProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, CodeBearingHandler> {
1193
+ /**
1194
+ * What this person can actually use, strongest first. `['code']` is the user with no passkey
1195
+ * enrolled — the passkey route then isn't offered at all, rather than offered and failing.
1196
+ */
1197
+ methods?: readonly StepUpMethod[];
1198
+ /**
1199
+ * Which factor to open on, when it shouldn't be the first in `methods` — resuming a flow that had
1200
+ * already fallen back to the code, say. Ignored if it isn't one of `methods`.
1201
+ */
1202
+ defaultMethod?: StepUpMethod;
1203
+ /** Fires when the user changes factor. The switch itself is handled here. */
1204
+ onMethodChange?: (method: StepUpMethod) => void;
1205
+ /** Digits in the one-time code. 6 is TOTP's norm; some issuers use 8. */
1206
+ codeLength?: number;
1207
+ /**
1208
+ * A verification is out. Both actions freeze. It is the honest signal and worth wiring, but it is
1209
+ * not what makes one press one attempt — the component latches that itself, because a handler
1210
+ * that awaits a nonce before setting this leaves a window where it is still `false`.
1211
+ */
1212
+ verifying?: boolean;
1213
+ /**
1214
+ * What the user is told about a failed attempt, in the product's own words. Repeat the same
1215
+ * string as often as you like: nothing here keys off its identity, so one constant "That code is
1216
+ * not right" for every wrong code — which is what a server that doesn't leak *why* it failed
1217
+ * sends — behaves exactly like a message that changes every time.
1218
+ */
1219
+ error?: string;
1220
+ /** The confirm's label. The caller names the action its window is about, e.g. `Archive product`. */
1221
+ confirmLabel?: string;
1222
+ /**
1223
+ * The confirm rests filled red. For the window whose confirm **is** the destructive act — a dialog
1224
+ * asking for a code before it turns two-factor authentication off — where a dialog's confirm is
1225
+ * the one place red rests (Guidelines/Destructive actions). Leave it off when the challenge only
1226
+ * guards a step on the way somewhere: a red button there paints the verification as the damage.
1227
+ *
1228
+ * It changes the button and nothing else. **It does not turn the challenge into a confirmation**
1229
+ * — the question is still who you are, never whether you meant it, so no "are you sure?" appears
1230
+ * beside it and the window above still owes the stakes in its own words.
1231
+ */
1232
+ destructive?: boolean;
1233
+ /** The way back's label. `Cancel` when it closes the window, `Back` when it steps back. */
1234
+ backLabel?: string;
1235
+ /** Omit it and there is no way back — an inline challenge on a page has nowhere to go. */
1236
+ onBack?: () => void;
1237
+ /** The user asked to use their passkey. Perform the WebAuthn call here. */
1238
+ onVerifyPasskey?: () => void;
1239
+ /** The user submitted a complete code. Verify it here. It is handed over exactly once. */
1240
+ onVerifyCode?: (code: string) => void;
1241
+ }
1242
+ /**
1243
+ * Prove it's you before something serious happens: a passkey by preference, a one-time code as the
1244
+ * way out when the passkey can't answer.
1245
+ *
1246
+ * **A step-up is orthogonal to a confirm.** It asks *who you are*, never *whether you meant it*, so
1247
+ * it neither replaces an Undo nor is replaced by one — every Danger-zone action proves it's you, and
1248
+ * Archive passes its step-up and then fires with an Undo (Guidelines/Undo over confirmation). This
1249
+ * component must not grow a "are you sure?" question: that belongs to the window around it.
1250
+ *
1251
+ * **Where the boundary sits.** This renders the challenge and reports which factor the user reached
1252
+ * for; the product performs the verification. `onVerifyPasskey` is where a real consumer calls
1253
+ * `navigator.credentials.get()`; `onVerifyCode` is where it posts the code. Neither is awaited here.
1254
+ * The outcome comes back as props — `verifying` while the call is out, `error` when it failed — so
1255
+ * the component never stringifies an exception and the product owns every word a user is told about
1256
+ * a failure. The caller also owns the window: the `Dialog`, its title, and what happens on success.
1257
+ *
1258
+ * **Nothing keys off the identity of a message.** A product sends one constant string for every
1259
+ * wrong code, precisely so the wording doesn't leak which factor failed or why, and `Object.is`
1260
+ * cannot tell two of those apart. So the code is dropped the moment it is handed over rather than
1261
+ * when a new `error` arrives, and an error is hidden by *which factor it belongs to* rather than by
1262
+ * a latch some prop change has to clear. A caller owes nothing here: it need not vary the message,
1263
+ * and it need not pass an attempt token.
1264
+ *
1265
+ * **The code never leaves except on submit.** There is deliberately no `value`, no `defaultValue`
1266
+ * and no `onChange`, and the handlers that would see the digits — change, input, key, clipboard —
1267
+ * are omitted from the props type *and* stopped at the field, so a parent can neither seed a
1268
+ * one-time code nor watch one being typed by the ordinary React route. It reaches the caller once,
1269
+ * in `onVerifyCode`, and the boxes empty in the same breath: a code the server refused can never be
1270
+ * sent twice, and a challenge that passed leaves nothing behind in a mounted instance. The field
1271
+ * carries no `name`, so a surrounding form never serializes it, and every control here is
1272
+ * `type="button"`, so none of them submits that form either.
1273
+ *
1274
+ * **Two things it does not defend against, and the consumer owes both.** A parent that reaches the
1275
+ * DOM node through a `ref`, or listens on `document` in the capture phase, still sees the
1276
+ * keystrokes — the fence above is against the accidental route, not a hostile parent. And the
1277
+ * digits render as **text nodes** inside the slots, not as an input value: session-replay tools
1278
+ * mask `<input>` values by default and do not mask arbitrary text, so a product that records
1279
+ * sessions must exclude this subtree explicitly (PostHog `ph-no-capture`, FullStory
1280
+ * `data-fs-exclude`, Datadog `data-dd-privacy="mask"`). The code pane carries
1281
+ * `data-sensitive="one-time-code"` so one rule can find it.
1282
+ *
1283
+ * **A failed passkey does not fall back on the user's behalf.** The challenge holds the passkey
1284
+ * pane and leaves the code one press away. Downgrading someone to the weaker factor because the
1285
+ * strong one didn't answer is a decision about their security posture, and it belongs to them —
1286
+ * a cancelled prompt and a missing authenticator look identical from here. For the same reason the
1287
+ * WebAuthn ceremony never auto-starts and a complete code never auto-submits: every attempt is a
1288
+ * press the user made.
1289
+ */
1290
+ declare const StepUpChallenge: React$1.ForwardRefExoticComponent<StepUpChallengeProps & React$1.RefAttributes<HTMLDivElement>>;
1291
+
682
1292
  interface InlineErrorProps extends React$1.HTMLAttributes<HTMLDivElement> {
683
1293
  children: React$1.ReactNode;
684
1294
  }
685
1295
  declare const InlineError: React$1.ForwardRefExoticComponent<InlineErrorProps & React$1.RefAttributes<HTMLDivElement>>;
1296
+ /**
1297
+ * What the user did to prove it was them, handed to `onConfirm` so the product can verify it. Only a
1298
+ * dialog carrying `stepUp` sends one; every other confirm calls `onConfirm` with nothing.
1299
+ */
1300
+ type StepUpProof = {
1301
+ method: 'passkey';
1302
+ } | {
1303
+ method: 'code';
1304
+ code: string;
1305
+ };
1306
+ /**
1307
+ * The identity challenge a `ConfirmDialog` puts in place of its footer, and the words above it.
1308
+ *
1309
+ * The four factor settings are the caller's. Everything else the challenge takes is the dialog's,
1310
+ * because the dialog is the thing that knows the answer: the confirm's label, the way back, and
1311
+ * whether a verification is out or has failed all come from the confirm it replaced.
1312
+ */
1313
+ interface ConfirmDialogStepUp extends Pick<StepUpChallengeProps, 'methods' | 'defaultMethod' | 'codeLength' | 'onMethodChange'> {
1314
+ /** The panel's own title, when proving it's you is a different question from the one asked first. */
1315
+ title?: React$1.ReactNode;
1316
+ /** The panel's own description. Say what is about to happen, not how the challenge works. */
1317
+ description?: React$1.ReactNode;
1318
+ }
686
1319
  interface ConfirmDialogProps {
687
1320
  open?: boolean;
688
1321
  onOpenChange?: (open: boolean) => void;
@@ -692,14 +1325,35 @@ interface ConfirmDialogProps {
692
1325
  confirmLabel?: string;
693
1326
  cancelLabel?: string;
694
1327
  destructive?: boolean;
695
- onConfirm: () => void | Promise<void>;
1328
+ /**
1329
+ * The words the user has to type before the confirm will fire — a product's name, `DELETE`. For an
1330
+ * action whose cost is that it cannot be taken back by the person taking it.
1331
+ */
1332
+ confirmPhrase?: string;
1333
+ /**
1334
+ * Prove it's you before this fires. The challenge takes the footer's place, so there is no live
1335
+ * confirm sitting over an unanswered one. Orthogonal to `confirmPhrase`: that asks whether you
1336
+ * meant it, this asks who you are, and an action can want both.
1337
+ */
1338
+ stepUp?: ConfirmDialogStepUp;
1339
+ onConfirm: (proof?: StepUpProof) => void | Promise<void>;
1340
+ /**
1341
+ * Turns whatever `onConfirm` threw into the line the dialog shows. Without it the dialog shows
1342
+ * `CONFIRM_FAILED` and nothing else — a thrown value is written for whoever reads the logs, and
1343
+ * `e.message` on the screen has already put a host, a port and an internal id in front of a user
1344
+ * (#473). The product owns that translation because only it knows which failures it can name.
1345
+ */
1346
+ onError?: (error: unknown) => string;
696
1347
  }
697
- declare function ConfirmDialog({ open, onOpenChange, trigger, title, description, confirmLabel, cancelLabel, destructive, onConfirm, }: ConfirmDialogProps): React$1.JSX.Element;
1348
+ declare function ConfirmDialog({ open, onOpenChange, trigger, title, description, confirmLabel, cancelLabel, destructive, confirmPhrase, stepUp, onConfirm, onError, }: ConfirmDialogProps): React$1.JSX.Element;
698
1349
 
699
1350
  interface UserMenuUser {
700
1351
  name: string;
701
- /** Second line of the row. The shipped rail shows the org name here. */
1352
+ /** Seeds the avatar tint, so the colour survives a rename. Optional; falls back to the name. */
1353
+ id?: string;
1354
+ /** Overrides the second line where a rail needs something other than the email there. */
702
1355
  subtitle?: string;
1356
+ /** Second line of the row: the address this person signs in with. */
703
1357
  email?: string;
704
1358
  avatarUrl?: string;
705
1359
  }
@@ -755,42 +1409,950 @@ interface ExtensionIconProps extends LucideProps {
755
1409
  */
756
1410
  declare const ExtensionIcon: React$1.ForwardRefExoticComponent<Omit<ExtensionIconProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
757
1411
 
758
- /** True when the viewport is narrower than the `md` breakpoint (768px). SSR-safe. */
759
- declare function useIsMobile(): boolean;
760
-
761
- interface UseSidebarOptions {
762
- /** Controlled collapsed value. When provided, the hook does not own state. */
763
- collapsed?: boolean;
764
- /** Initial collapsed value in uncontrolled mode. Default false (expanded). */
765
- defaultCollapsed?: boolean;
766
- /** Called whenever the collapsed value should change (both modes). */
767
- onCollapsedChange?: (collapsed: boolean) => void;
768
- }
769
- interface UseSidebarResult {
770
- collapsed: boolean;
771
- setCollapsed: (collapsed: boolean) => void;
772
- toggle: () => void;
773
- }
774
1412
  /**
775
- * Controllable sidebar collapse state. Controlled when `collapsed` is passed,
776
- * otherwise internal state seeded by `defaultCollapsed`. Pureno persistence
777
- * or context; the host app owns persistence.
1413
+ * A glyph that stands on its own a warning triangle in a summary line, a lock beside a group
1414
+ * name, an info mark in a rowand explains itself.
1415
+ *
1416
+ * **Reach for this one when nothing else on screen says what the glyph means.** Its sibling
1417
+ * {@link DecorativeIcon} is for the opposite case, a glyph inside a control that already has a
1418
+ * name; the two render identically and differ only in the accessibility tree, which is why they
1419
+ * ship together and why the names have to carry the condition — picking the wrong one is not
1420
+ * visible in a screenshot.
1421
+ *
1422
+ * Four things it owns, and each of them is a bug you get composing `Tooltip` by hand:
1423
+ *
1424
+ * - **A role.** `aria-label` on a bare `<span>` is not reliably exposed. `role="img"` is what makes
1425
+ * the name count, and it is honest: the glyph *is* an image carrying meaning.
1426
+ * - **A tab stop, with a ring on it.** A tooltip only reachable by pointer is an explanation
1427
+ * keyboard and screen reader users never get. The trigger is focusable, focus opens the tooltip,
1428
+ * and `focus-visible` draws the ring — a tab stop nobody can see is not a tab stop.
1429
+ * - **One announcement.** Radix does two things with the sentence: it points the trigger's
1430
+ * `aria-describedby` at the open bubble, and it renders a `VisuallyHidden role="tooltip"` copy of
1431
+ * the text *inside* that bubble. With the sentence already serving as the accessible name, both
1432
+ * are duplicates — and suppressing only the relation leaves the copy orphaned, referenced by
1433
+ * nothing and still read. So the relation is suppressed **and** the bubble is `aria-hidden`: it
1434
+ * is a picture of the name, drawn for the people who can see it. WAI-ARIA APG: a tooltip that
1435
+ * supplies the name labels; it does not also describe.
1436
+ * - **Pointer events of its own.** A `disabled` control sets `pointer-events: none` over its whole
1437
+ * subtree (the kit `Button` does), which is exactly when a glyph explaining *why* it is disabled
1438
+ * matters most — and exactly when it would otherwise fall out of the hit stack. The trigger
1439
+ * re-enables its own. The trade-off is real and worth stating: one small part of a disabled
1440
+ * control now answers the pointer.
1441
+ *
1442
+ * **`label` is one string on purpose.** Splitting the name from the tooltip text would let them
1443
+ * drift, and drifting is the failure this component exists to stop. A blank one is a bug, not a
1444
+ * variant: a focusable `role="img"` with no name is a WCAG 4.1.2 failure and the bubble would open
1445
+ * empty. A blank `label` therefore renders the glyph as decorative — `aria-hidden`, no role, no tab
1446
+ * stop, no tooltip — and warns in development. Keep the sentence short, too: the bubble sets no
1447
+ * maximum width, so a paragraph runs off the edge of the viewport.
1448
+ *
1449
+ * **The component's own attributes win, not the call site's.** `role`, `aria-label`, `aria-hidden`,
1450
+ * `aria-describedby` and `tabIndex` are applied *after* your props are spread, so passing your own
1451
+ * cannot quietly undo any of the above. The `Omit` below stops `role` and `tabIndex` at compile
1452
+ * time; it cannot
1453
+ * stop `aria-*`, because TypeScript exempts hyphenated JSX attributes from excess-property
1454
+ * checking — which is why the ordering, and not the type, is the guarantee.
1455
+ *
1456
+ * **Requires a `TooltipProvider` above it.** One per app, near the root — never one per icon, which
1457
+ * puts every glyph in its own delay group so moving between two of them re-waits the full delay.
1458
+ * With none mounted, Radix throws ``\`Tooltip\` must be used within \`TooltipProvider\``` — and
1459
+ * because `@lessly/ui` re-exports those names verbatim, that message names two things you can
1460
+ * import from this package. See `Guidelines/Icons & tooltips`.
1461
+ */
1462
+ interface IconHintProps extends Omit<React$1.ComponentPropsWithoutRef<'span'>, 'role' | 'tabIndex' | 'children'> {
1463
+ /** The glyph. Size and colour it at the call site — this component owns behaviour, not looks. */
1464
+ children: React$1.ReactNode;
1465
+ /** The sentence. It is both the tooltip text and the glyph's accessible name. */
1466
+ label: string;
1467
+ /** Which edge the tooltip lands on. */
1468
+ side?: 'top' | 'right' | 'bottom' | 'left';
1469
+ /** How the tooltip lines up along that edge — for a glyph pinned to the edge of a narrow column. */
1470
+ align?: 'start' | 'center' | 'end';
1471
+ }
1472
+ declare const IconHint: React$1.ForwardRefExoticComponent<IconHintProps & React$1.RefAttributes<HTMLSpanElement>>;
1473
+
1474
+ /**
1475
+ * A glyph *inside* something that already has a name — a flag in a `Report` button, an info mark
1476
+ * after a role's label — with a hover hint for sighted users and nothing else.
1477
+ *
1478
+ * **Reach for this one when the text or control around the glyph already says what it means.** Its
1479
+ * sibling {@link IconHint} is for a glyph that stands alone. The two render identically; only the
1480
+ * accessibility tree tells them apart, which is why the name has to carry the condition for
1481
+ * choosing it — *decorative* is the term for a glyph that carries no meaning of its own, and that
1482
+ * is the whole test. (It was called `IconTip` and the name said nothing: both are icons, both are
1483
+ * tips.)
1484
+ *
1485
+ * Naming this glyph and giving it a tab stop — the obvious thing, and what you get by copying
1486
+ * `IconHint` — is wrong twice over:
1487
+ *
1488
+ * - **The name announces nothing.** The host's own `aria-label` halts descendant traversal, so a
1489
+ * name here is never read. Where the host is named by its text instead, the name *does* get
1490
+ * through and corrupts it: the control stops announcing "Report" and starts announcing "Report,
1491
+ * we'll sign this device out".
1492
+ * - **The tab stop is a stray one.** A focusable child inside a button makes the control take two
1493
+ * tabs, and the first lands somewhere that does nothing. A focusable `aria-hidden` element is an
1494
+ * ARIA violation in its own right.
1495
+ *
1496
+ * So the trigger is `aria-hidden` and takes no focus, and the bubble is `aria-hidden` too — Radix
1497
+ * renders a `VisuallyHidden role="tooltip"` copy of the text inside it, and leaving that in the
1498
+ * tree would put a loose sentence next to a glyph that is meant to be silent. `label` is hover
1499
+ * text, never a name. If a keyboard or screen reader user needs the sentence, that is the signal
1500
+ * that the glyph is not decorative and the wrong component is in use.
1501
+ *
1502
+ * **It keeps its own pointer events.** A `disabled` control sets `pointer-events: none` over its
1503
+ * whole subtree (the kit `Button` does), and that is the one moment the glyph's sentence matters
1504
+ * most — it is usually what says *why* the control is disabled. The trigger re-enables its own so a
1505
+ * disabled control can still explain itself. The trade-off is real and worth stating: one small
1506
+ * part of a disabled control now answers the pointer.
1507
+ *
1508
+ * A blank `label` leaves nothing to show, so it renders the bare glyph with no tooltip at all
1509
+ * rather than an empty bubble, and warns in development. Keep the sentence short: the bubble sets
1510
+ * no maximum width, so a paragraph runs off the edge of the viewport.
1511
+ *
1512
+ * **The component's own attributes win, not the call site's.** `aria-hidden` is applied *after*
1513
+ * your props are spread, and no `role`, `aria-label` or `tabIndex` is passed through, so a call
1514
+ * site cannot turn this back into an `IconHint`. The `Omit` below stops `role` and `tabIndex` at
1515
+ * compile time; it cannot stop `aria-*`, because TypeScript exempts hyphenated JSX attributes from
1516
+ * excess-property checking — which is why the ordering, and not the type, is the guarantee.
1517
+ *
1518
+ * **Requires a `TooltipProvider` above it** — one per app, near the root. See
1519
+ * `Guidelines/Icons & tooltips`.
1520
+ */
1521
+ interface DecorativeIconProps extends Omit<React$1.ComponentPropsWithoutRef<'span'>, 'role' | 'tabIndex' | 'children'> {
1522
+ /** The glyph. Hidden from assistive technology whatever it is. */
1523
+ children: React$1.ReactNode;
1524
+ /** The hover text. Not an accessible name — the host control owns that. */
1525
+ label: string;
1526
+ /** Which edge the tooltip lands on. */
1527
+ side?: 'top' | 'right' | 'bottom' | 'left';
1528
+ /** How the tooltip lines up along that edge. */
1529
+ align?: 'start' | 'center' | 'end';
1530
+ }
1531
+ declare const DecorativeIcon: React$1.ForwardRefExoticComponent<DecorativeIconProps & React$1.RefAttributes<HTMLSpanElement>>;
1532
+
1533
+ type ImageCropShape = 'square' | 'circle';
1534
+ type ImageCropType = 'image/png' | 'image/jpeg' | 'image/webp';
1535
+ interface ImageCropperProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'onError' | 'onLoad'> {
1536
+ /** The image to crop: a data URL, an object URL, or a URL the browser can fetch. */
1537
+ src: string;
1538
+ /**
1539
+ * The mask. `square` is the default because a logo is the commoner case and a rectangle is what an
1540
+ * image already is; `circle` is the avatar case and is baked into the export, not just previewed.
1541
+ */
1542
+ shape?: ImageCropShape;
1543
+ /** Edge of the exported square, in pixels. 256 covers every avatar slot the console draws. */
1544
+ outputSize?: number;
1545
+ /**
1546
+ * `image/jpeg` is the one format with no alpha channel, so it alone gets a ground painted under
1547
+ * the crop. PNG and WebP both carry alpha — including the canvas encoder that writes them — so a
1548
+ * circle exported as either comes back genuinely transparent in the corners.
1549
+ */
1550
+ outputType?: ImageCropType;
1551
+ /** 0–1, for the lossy formats. Ignored by `image/png`. */
1552
+ outputQuality?: number;
1553
+ /**
1554
+ * What is painted over the whole canvas before the crop, and before any mask. Defaults to white
1555
+ * for `image/jpeg` and to nothing for the two formats that can be transparent. Pass a colour to
1556
+ * flatten a PNG or WebP onto a ground, or `null` to let a JPEG's empty pixels fall to black.
1557
+ */
1558
+ background?: string | null;
1559
+ /** The smallest crop, in stage pixels, so the four corner grips never blanket the move region. */
1560
+ minCropSize?: number;
1561
+ /**
1562
+ * Set it when the image is served from another origin. Without it the image loads perfectly and
1563
+ * taints the canvas, so the failure arrives on Save as `exportErrorMessage`, not on load.
1564
+ */
1565
+ crossOrigin?: 'anonymous' | 'use-credentials';
1566
+ /** The cropped region, as a data URL of `outputType`. */
1567
+ onCrop: (dataUrl: string) => void;
1568
+ /** Omit it and no Cancel renders — for a cropper embedded in a page that owns its own way out. */
1569
+ onCancel?: () => void;
1570
+ saveLabel?: string;
1571
+ cancelLabel?: string;
1572
+ /** The line under the stage. Pass `null` to drop it. */
1573
+ hint?: React$1.ReactNode;
1574
+ /** Shown in place of the image when the source cannot be read. */
1575
+ errorMessage?: React$1.ReactNode;
1576
+ /**
1577
+ * Shown under a stage that still holds the photo, when the *export* was refused. A cross-origin
1578
+ * image with no `crossOrigin` loads perfectly and taints the canvas, so the failure arrives on
1579
+ * Save and the load copy would be describing something that never happened.
1580
+ */
1581
+ exportErrorMessage?: React$1.ReactNode;
1582
+ }
1583
+ declare const ImageCropper: React$1.ForwardRefExoticComponent<ImageCropperProps & React$1.RefAttributes<HTMLDivElement>>;
1584
+
1585
+ /**
1586
+ * `ImageCropper` in a window, which is where a crop step almost always happens: a file is picked,
1587
+ * and the crop is the one thing between picking it and saving it.
1588
+ *
1589
+ * It is small on purpose, and it exists for one reason — **it takes the caller's word for the thing
1590
+ * being cropped and puts it in the title**, so a logo is never called an avatar. `label` is the
1591
+ * whole feature; `title` is there for a sentence the "Crop <thing>" pattern does not fit.
1592
+ *
1593
+ * Controlled only. There is no uncontrolled form because a crop window has nothing to show until
1594
+ * the caller has a file in hand, so the caller already owns the open state.
1595
+ */
1596
+ interface ImageCropDialogProps extends Omit<ImageCropperProps, 'src' | 'onCancel' | 'className' | 'title'> {
1597
+ open: boolean;
1598
+ onOpenChange: (open: boolean) => void;
1599
+ /**
1600
+ * The picked image, or `null` before anything has been picked — the window then renders its frame
1601
+ * and no cropper, rather than a cropper pointed at nothing.
1602
+ */
1603
+ src: string | null;
1604
+ /** The thing being cropped, in the caller's own words: `Logo`, `Avatar`, `Cover image`. */
1605
+ label?: string;
1606
+ /** Overrides the whole title. Use it when `Crop <label>` is not the sentence you want. */
1607
+ title?: React$1.ReactNode;
1608
+ /** A crop window usually has nothing to add beyond its title; say something only when it does. */
1609
+ description?: React$1.ReactNode;
1610
+ }
1611
+ declare function ImageCropDialog({ open, onOpenChange, src, label, title, description, onCrop, ...cropperProps }: ImageCropDialogProps): React$1.JSX.Element;
1612
+ declare namespace ImageCropDialog {
1613
+ var displayName: string;
1614
+ }
1615
+
1616
+ /**
1617
+ * Pick an image, see it, crop it, keep it — an account photo, a product logo, an organization logo.
1618
+ * Without this a product gets the browser's bare file input, which is why every one of them would
1619
+ * otherwise install a package on day one.
1620
+ *
1621
+ * The value is a data URL, so it renders straight into an `<img>` and uploads with one line
1622
+ * (`await (await fetch(value)).blob()`). `onChange(null)` is the removal.
1623
+ *
1624
+ * **The word for the thing is the caller's.** `label` names it in the file input, the preview and
1625
+ * the crop window's title, so an organization logo is never called an avatar.
1626
+ */
1627
+ type ImageUploadSize = 'sm' | 'md' | 'lg';
1628
+ interface ImageUploadProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onError'> {
1629
+ /** The image, as a data URL or any src the browser can render. `null` is "nothing set yet". */
1630
+ value: string | null;
1631
+ /** The cropped image, or `null` when it is removed. */
1632
+ onChange: (value: string | null) => void;
1633
+ /**
1634
+ * What is being uploaded, in the caller's own words: `Logo`, `Avatar`, `Organization logo`. It
1635
+ * names the file input, the preview and the crop window.
1636
+ */
1637
+ label?: string;
1638
+ /**
1639
+ * A circle is a principal, a rounded square is an object (Guidelines/Avatars) — and the same
1640
+ * shape masks the crop, so what you see in the tile is what was saved.
1641
+ */
1642
+ shape?: ImageCropShape;
1643
+ /** The preview tile: 32, 48 or 64px. */
1644
+ size?: ImageUploadSize;
1645
+ /**
1646
+ * What the tile shows before anything is picked. Supply one and you own its frame — the tile
1647
+ * draws no ring of its own, so a `PersonAvatar` here doesn't end up double-ringed.
1648
+ */
1649
+ fallback?: React$1.ReactNode;
1650
+ /** A line under the buttons. There is no default: only the caller knows the real constraint. */
1651
+ hint?: React$1.ReactNode;
1652
+ /** The file input's filter. Anything that isn't an image is refused regardless. */
1653
+ accept?: string;
1654
+ /** In bytes. A picker with no ceiling is a bug waiting on the first 40MB photo. */
1655
+ maxFileSize?: number;
1656
+ /** Skip the crop step and take the file as it was picked. */
1657
+ crop?: boolean;
1658
+ disabled?: boolean;
1659
+ /** Edge of the stored square, in pixels. */
1660
+ outputSize?: number;
1661
+ outputType?: ImageCropType;
1662
+ outputQuality?: number;
1663
+ /** Called with the same sentence the control shows, for a caller that reports errors its own way. */
1664
+ onError?: (message: string) => void;
1665
+ uploadLabel?: string;
1666
+ changeLabel?: string;
1667
+ removeLabel?: string;
1668
+ }
1669
+ declare const ImageUpload: React$1.ForwardRefExoticComponent<ImageUploadProps & React$1.RefAttributes<HTMLDivElement>>;
1670
+
1671
+ /**
1672
+ * What opening this row does. The row's trailing column is a promise, and this states it.
1673
+ *
1674
+ * This is the set of **values**, for a caller's own data model — not a prop bag. `opens` lives in a
1675
+ * discriminated union with `expanded` (see `EntityRowOpensProps`), so a variable typed as this one
1676
+ * widens across both arms and satisfies neither: `<EntityRow opens={row.opens} />` does not compile.
1677
+ * A config-driven list narrows to `EntityRowOpensProps` and spreads that instead.
1678
+ */
1679
+ type EntityRowOpens = 'page' | 'modal' | 'disclosure' | 'none';
1680
+ interface EntityRowOwnProps {
1681
+ /**
1682
+ * Leading mark — who or what the row is about. Round for a principal (a person, an agent, a
1683
+ * group), a rounded square for an object (a product, a connector, a key). `PersonAvatar`,
1684
+ * `GlyphAvatar` and `EntityTile` are the three that ship; each is already `shrink-0`, which a
1685
+ * hand-rolled mark has to be too or a long title will squash it.
1686
+ */
1687
+ mark?: React$1.ReactNode;
1688
+ /**
1689
+ * The name of the thing this row is — a string in almost every list, and any node where the name
1690
+ * is built out of parts: an activity log's sentence with the agent's name a link inside it.
1691
+ *
1692
+ * A **focusable** node here is legal only on `opens="none"`, which renders a `<div>` and is not a
1693
+ * target — which is exactly how the activity log gets a link into the sentence. On the other three
1694
+ * the row is itself the control, so a control in the title nests one button inside another: broken
1695
+ * tab order, invalid HTML, and a hydration mismatch on the server.
1696
+ *
1697
+ * **The DOM `title` attribute is not in this component's type.** A row's name is content, not a
1698
+ * tooltip, and nothing here sets the attribute: a tooltip that only appears on hover, after a
1699
+ * delay, and never for a keyboard, is not where a row's name goes.
1700
+ */
1701
+ title: React$1.ReactNode;
1702
+ /**
1703
+ * A small chip beside the title — `You`, `Guest`, `Synced from Okta`. It sits in a slot that does
1704
+ * not shrink, so a long title truncates and the chip stays whole rather than the other way round.
1705
+ */
1706
+ badge?: React$1.ReactNode;
1707
+ /** The second line under the title: an email, a device, a count. Drops a type step (#364). */
1708
+ sub?: React$1.ReactNode;
1709
+ /**
1710
+ * The trailing value before the reserved column — a role name, a status `Badge`, an expiry. It is
1711
+ * the answer to the row, not a caption, so it holds `text-sm` (#364). Text and non-focusable
1712
+ * marks only on a row that opens something: the row is one target, so nothing focusable may sit
1713
+ * inside it. `opens="none"` is the exception — that row is not a target, so a control belongs here.
1714
+ */
1715
+ meta?: React$1.ReactNode;
1716
+ /**
1717
+ * A line under the whole row at full width — the row's question answered without opening it.
1718
+ * Unlike `sub` it does not share a line with `meta`, so a long summary is not truncated by the
1719
+ * trailing value. Inert content only: the row is one target.
1720
+ */
1721
+ summary?: React$1.ReactNode;
1722
+ }
1723
+ /**
1724
+ * What the trailing column promises, and — for the one value that has a state — which state the row
1725
+ * is in. Press Esc: if nothing is lost it is a modal, if something is it is a page, and "lost"
1726
+ * includes your place (#361).
1727
+ *
1728
+ * `expanded` is required by `disclosure` and rejected by the other two, so a row cannot claim a
1729
+ * state it does not have and a disclosure cannot forget to say which one it is in.
1730
+ */
1731
+ type EntityRowOpensProps = {
1732
+ /**
1733
+ * `page` (the default) is what opening an entity does, and it wears the `ChevronRight`. That
1734
+ * mark means an entity opening as a **page** and nothing else in this console carries one, so
1735
+ * it is stated here rather than passed in as an icon (#363, #411).
1736
+ *
1737
+ * `modal` opens a detail in place over the list and wears nothing: a modal moves you nowhere,
1738
+ * so a mark would promise travel that never happens.
1739
+ *
1740
+ * `disclosure` grows the detail underneath the row, and wears the caret the kit already gives
1741
+ * every disclosure — `Accordion`, `ConnectorCard` — a `ChevronDown` turning 180° (#401). It
1742
+ * takes `expanded`.
1743
+ *
1744
+ * The 16px column stays reserved whichever it is, so a list mixing them keeps one right edge
1745
+ * for its `meta`.
1746
+ */
1747
+ opens?: 'page' | 'modal';
1748
+ expanded?: never;
1749
+ } | {
1750
+ opens: 'disclosure';
1751
+ /**
1752
+ * Whether the block below the row is open. It drives the caret's rotation **and**
1753
+ * `aria-expanded`, so the mark and the accessibility tree cannot drift apart.
1754
+ */
1755
+ expanded: boolean;
1756
+ } | {
1757
+ /**
1758
+ * `none` opens nothing: the row is a line in a list you read, and whatever can be done to it
1759
+ * sits in `meta` as its own control — a role picker on a grant, a ✕. It is the same row
1760
+ * geometry and the same slots, with the three things that follow from "a row is something you
1761
+ * click" taken back off: no element to press, so no `<button>`, no `onClick` and no `asChild`;
1762
+ * no reserved trailing column, because there is no mark it could ever hold and a static list
1763
+ * has no chevron to line up with; and no hover plate, which on a row with nothing to press
1764
+ * promises a click that never happens. The title drops to the regular weight the rest of the
1765
+ * row already reads at.
1766
+ */
1767
+ opens: 'none';
1768
+ expanded?: never;
1769
+ onClick?: never;
1770
+ asChild?: never;
1771
+ };
1772
+ /**
1773
+ * Render the single child element instead of a button — a router `<Link>`, an `<a>`. The row builds
1774
+ * its content from props, so the child's own children are replaced; `children` is therefore only
1775
+ * accepted when `asChild` is true, and rejected at the type level otherwise rather than silently
1776
+ * dropped at render time.
1777
+ *
1778
+ * `title` is omitted from the button props alongside `children` for the same reason: the row owns
1779
+ * both slots. See `EntityRowOwnProps['title']`.
1780
+ */
1781
+ type EntityRowProps = EntityRowOwnProps & EntityRowOpensProps & Omit<React$1.ComponentPropsWithoutRef<'button'>, 'children' | 'title'> & ({
1782
+ asChild: true;
1783
+ children: React$1.ReactElement;
1784
+ } | {
1785
+ asChild?: false;
1786
+ children?: never;
1787
+ });
1788
+ /**
1789
+ * The console's one list item. Members, groups, products, roles and keys all render through it, so
1790
+ * the lists read the same from screen to screen.
1791
+ *
1792
+ * The whole row is the click target and it carries **no** inline action and no overflow menu —
1793
+ * entity actions live in the detail, where there is room to confirm and explain. A row that is not
1794
+ * navigable at all (a pending invite with Approve / Deny) is a different pattern and does not use
1795
+ * this. See `Guidelines/List items`.
1796
+ *
1797
+ * `opens="none"` is the one form that is not a target: a static line in a list, rendered as a `<div>`
1798
+ * with its controls in `meta`. Everything below is about the other three.
1799
+ *
1800
+ * **Hover and focus are one plate, and it is paint.** The fill and the focus ring share one
1801
+ * `::after`, inset from the row's box (see `rowClass` for the numbers). The row's own box, padding
1802
+ * and hit area are untouched, so do not shrink a row to match what it paints.
1803
+ *
1804
+ * Five consequences for a caller:
1805
+ *
1806
+ * 1. The row is `position: relative` and `isolation: isolate`.
1807
+ * 2. Being a stacking context, the row can no longer be painted over by a non-portaled popover
1808
+ * inside `mark`, `badge` or `meta` — such a popover is now trapped above this row and below the
1809
+ * next. Portal it, as the kit's own overlays do.
1810
+ * 3. `::before` is deliberately left free, for a caller stretching the row's hit area over a box
1811
+ * bigger than the button (#409).
1812
+ * 4. A caller whose row is bigger than this button needs **both** `static` **and** `isolation-auto`
1813
+ * on the button. `relative` alone is not a stacking context, so the `-z-10` plate escapes and
1814
+ * paints behind the host `Card` — hover fill and focus ring both vanish; `static` alone without
1815
+ * `isolation-auto` gives the mirror bug, a giant unclipped plate.
1816
+ * 5. The fill moved merge groups. A caller who used to override it with `className="hover:bg-…"`
1817
+ * now replaces nothing, because the fill is `hover:after:bg-…`. Turn this one off with
1818
+ * `hover:after:bg-transparent` and paint your own.
1819
+ */
1820
+ declare const EntityRow: React$1.ForwardRefExoticComponent<((EntityRowOwnProps & {
1821
+ /**
1822
+ * `page` (the default) is what opening an entity does, and it wears the `ChevronRight`. That
1823
+ * mark means an entity opening as a **page** and nothing else in this console carries one, so
1824
+ * it is stated here rather than passed in as an icon (#363, #411).
1825
+ *
1826
+ * `modal` opens a detail in place over the list and wears nothing: a modal moves you nowhere,
1827
+ * so a mark would promise travel that never happens.
1828
+ *
1829
+ * `disclosure` grows the detail underneath the row, and wears the caret the kit already gives
1830
+ * every disclosure — `Accordion`, `ConnectorCard` — a `ChevronDown` turning 180° (#401). It
1831
+ * takes `expanded`.
1832
+ *
1833
+ * The 16px column stays reserved whichever it is, so a list mixing them keeps one right edge
1834
+ * for its `meta`.
1835
+ */
1836
+ opens?: "page" | "modal";
1837
+ expanded?: never;
1838
+ } & Omit<Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "title" | "children"> & {
1839
+ asChild: true;
1840
+ children: React$1.ReactElement;
1841
+ }) | (EntityRowOwnProps & {
1842
+ /**
1843
+ * `page` (the default) is what opening an entity does, and it wears the `ChevronRight`. That
1844
+ * mark means an entity opening as a **page** and nothing else in this console carries one, so
1845
+ * it is stated here rather than passed in as an icon (#363, #411).
1846
+ *
1847
+ * `modal` opens a detail in place over the list and wears nothing: a modal moves you nowhere,
1848
+ * so a mark would promise travel that never happens.
1849
+ *
1850
+ * `disclosure` grows the detail underneath the row, and wears the caret the kit already gives
1851
+ * every disclosure — `Accordion`, `ConnectorCard` — a `ChevronDown` turning 180° (#401). It
1852
+ * takes `expanded`.
1853
+ *
1854
+ * The 16px column stays reserved whichever it is, so a list mixing them keeps one right edge
1855
+ * for its `meta`.
1856
+ */
1857
+ opens?: "page" | "modal";
1858
+ expanded?: never;
1859
+ } & Omit<Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "title" | "children"> & {
1860
+ asChild?: false;
1861
+ children?: never;
1862
+ }) | (EntityRowOwnProps & {
1863
+ opens: "disclosure";
1864
+ /**
1865
+ * Whether the block below the row is open. It drives the caret's rotation **and**
1866
+ * `aria-expanded`, so the mark and the accessibility tree cannot drift apart.
1867
+ */
1868
+ expanded: boolean;
1869
+ } & Omit<Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "title" | "children"> & {
1870
+ asChild: true;
1871
+ children: React$1.ReactElement;
1872
+ }) | (EntityRowOwnProps & {
1873
+ opens: "disclosure";
1874
+ /**
1875
+ * Whether the block below the row is open. It drives the caret's rotation **and**
1876
+ * `aria-expanded`, so the mark and the accessibility tree cannot drift apart.
1877
+ */
1878
+ expanded: boolean;
1879
+ } & Omit<Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "title" | "children"> & {
1880
+ asChild?: false;
1881
+ children?: never;
1882
+ }) | (EntityRowOwnProps & {
1883
+ /**
1884
+ * `none` opens nothing: the row is a line in a list you read, and whatever can be done to it
1885
+ * sits in `meta` as its own control — a role picker on a grant, a ✕. It is the same row
1886
+ * geometry and the same slots, with the three things that follow from "a row is something you
1887
+ * click" taken back off: no element to press, so no `<button>`, no `onClick` and no `asChild`;
1888
+ * no reserved trailing column, because there is no mark it could ever hold and a static list
1889
+ * has no chevron to line up with; and no hover plate, which on a row with nothing to press
1890
+ * promises a click that never happens. The title drops to the regular weight the rest of the
1891
+ * row already reads at.
1892
+ */
1893
+ opens: "none";
1894
+ expanded?: never;
1895
+ onClick?: never;
1896
+ asChild?: never;
1897
+ } & Omit<Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "title" | "children"> & {
1898
+ asChild?: false;
1899
+ children?: never;
1900
+ })) & React$1.RefAttributes<HTMLButtonElement>>;
1901
+
1902
+ interface BackLinkProps extends Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
1903
+ /**
1904
+ * The name of the page this returns to — `Members`, `Roles`, `Agents & API`. It names the parent
1905
+ * so the control reads without the trail above it; never the bare word "Back".
1906
+ */
1907
+ parent: string;
1908
+ /**
1909
+ * Hand the element to a router's own link (`<Link>`, `<a href>`): the component keeps the arrow,
1910
+ * the label and the geometry, the consumer keeps the URL. Pass exactly one element as `children`.
1911
+ */
1912
+ asChild?: boolean;
1913
+ /** The router link to slot. Only read when `asChild` is set. */
1914
+ children?: React$1.ReactNode;
1915
+ }
1916
+ /**
1917
+ * The way back from a sub-page (#362) — a member, a group, a product, a credential, a role, a
1918
+ * provider's configuration. **One** control, above the page title, on the content column's left
1919
+ * edge, naming the parent rather than saying "Back".
1920
+ *
1921
+ * It is not a second trail: the top bar keeps the whole breadcrumb, and the back/forward history
1922
+ * arrows are gone (#337), which is what leaves this the one control that walks. A **wizard gets
1923
+ * none** — its steps are the navigation. See `Guidelines/Second level navigation`.
1924
+ *
1925
+ * **Two ways to spell the destination, and one of them is required.**
1926
+ *
1927
+ * ```tsx
1928
+ * <BackLink parent="Members" onClick={() => attemptLeave(onBack)} /> // no router
1929
+ * <BackLink parent="Members" asChild><Link to="/org/members" /></BackLink> // a router
1930
+ * ```
1931
+ *
1932
+ * A product with a router should reach for `asChild`: the parent has a URL, so the way back is a
1933
+ * real link — Cmd-click opens the list in a new tab, the status bar previews it, and the router
1934
+ * navigates on the client. `onClick` is the form for a screen with no URL for its parent, which is
1935
+ * every prototype and any panel routed by component state.
1936
+ *
1937
+ * Where a guard stands between the reader and the parent — unsaved changes on the role editor — the
1938
+ * handler must be the *same* one the second-to-last crumb carries (`attemptLeave(onBack)`, not
1939
+ * `onBack`). Under `asChild`, that guard is the link's own `onClick` calling `preventDefault`.
1940
+ *
1941
+ * **No destination means no control.** Some detail views are reachable in a mode with no way back
1942
+ * wired, and the crumb above goes inert in exactly that case; a button that looks like an exit and
1943
+ * does nothing is worse than no button, so this renders `null` rather than a dead or disabled one.
1944
+ */
1945
+ declare const BackLink: React$1.ForwardRefExoticComponent<BackLinkProps & React$1.RefAttributes<HTMLButtonElement>>;
1946
+
1947
+ interface CardNoteProps extends React$1.HTMLAttributes<HTMLParagraphElement> {
1948
+ /** One sentence. Who may change what's above, or why nobody can right now. */
1949
+ children: React$1.ReactNode;
1950
+ }
1951
+ /**
1952
+ * The one-line constraint a card states at its foot: who may change what the card holds, or which
1953
+ * state has taken its controls away (#372).
1954
+ *
1955
+ * **It speaks for the card, not for one control on it.** A sentence about a single row belongs on
1956
+ * that row, as a second line under its label, where the reader meets it with the value it governs.
1957
+ * This is for the line that covers everything the card offers — a Danger zone's actions, a list's
1958
+ * add, a profile's name and logo together.
1959
+ *
1960
+ * **The line looks the same either way, and that is the component.** A card whose field has just
1961
+ * been frozen must not grow a box it didn't have when the field was live — so this takes no tone,
1962
+ * no severity and no variant, and there is deliberately no way to make the frozen sentence louder
1963
+ * than the permission one. Reaching for `Alert` here is the regression it exists to prevent:
1964
+ * `Alert` is a filled, four-sided, `role="alert"` box, and it shouts over the field it is about.
1965
+ *
1966
+ * A lock and one sentence. The glyph is fixed, because every line this component carries is about
1967
+ * permission — if a card's foot wants to say something else, it is not a `CardNote`.
1968
+ *
1969
+ * It draws one edge, the seam at the card's foot, and takes the card's own 16px inset, so it sits
1970
+ * flush at the bottom of a `Card` with no wrapper:
1971
+ *
1972
+ * ```tsx
1973
+ * <Card title="Danger zone">
1974
+ * {rows}
1975
+ * <CardNote>These actions come back when the block is lifted.</CardNote>
1976
+ * </Card>
1977
+ * ```
1978
+ *
1979
+ * The sentence itself follows `Guidelines/State with a reason`: it names the way back, or names
1980
+ * that there isn't one — an archived product's name points at Restore, a blocked one names nothing,
1981
+ * because the organization has nothing to name.
1982
+ */
1983
+ declare const CardNote: React$1.ForwardRefExoticComponent<CardNoteProps & React$1.RefAttributes<HTMLParagraphElement>>;
1984
+
1985
+ /** The three scales a remove ✕ rides at: 28px in a card header, 36px in a list row, 40px beside a
1986
+ * default-size text button. Literal strings, resolved by `Button` — this component never sizes a
1987
+ * box with a `className`. `lg` and the legacy `icon` size are deliberately not offered: nothing in
1988
+ * the console removes a row at 44px, and `icon` predates the icon-only form. */
1989
+ type RemoveButtonSize = 'xs' | 'sm' | 'default';
1990
+ interface RemoveButtonProps extends Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
1991
+ /**
1992
+ * The whole sentence: `"Remove Ana Ruiz"`, not `"Ana Ruiz"`. It is **both** the tooltip text and
1993
+ * the button's accessible name, deliberately one string — splitting them would let the hint a
1994
+ * sighted user reads and the name a screen reader hears drift apart, and drifting is one of the
1995
+ * two failures this component exists to stop.
1996
+ */
1997
+ label: string;
1998
+ /** Required. A ✕ with no handler is a button that lies about being one. */
1999
+ onClick: React$1.MouseEventHandler<HTMLButtonElement>;
2000
+ /** The square box. `sm` (36px) is the list-row scale and the default. */
2001
+ size?: RemoveButtonSize;
2002
+ /** Which edge the tooltip lands on. Radix pushes it off a viewport edge on its own. */
2003
+ side?: 'top' | 'right' | 'bottom' | 'left';
2004
+ }
2005
+ /**
2006
+ * A ✕ that removes a row, **shipped already wearing its tooltip**.
2007
+ *
2008
+ * The kit `Button` has had the right style for this all along — `variant="destructive-ghost"` rests
2009
+ * neutral and reddens only under the pointer (Guidelines/Destructive actions), borderless because a
2010
+ * column of framed ✕ buttons is a wall (Guidelines/Button pairs). What `Button` cannot ship is the
2011
+ * tooltip: it never mounts one, so every call site has to remember to compose `Tooltip` +
2012
+ * `TooltipTrigger asChild` + `TooltipContent` around it, and that is exactly the step people skip.
2013
+ * A ✕ with an `aria-label` and no tooltip is a control that explains itself to a screen reader and
2014
+ * to nobody else. So the pairing is the component.
2015
+ *
2016
+ * **What "paired" can mean, and what it can't.** It cannot mean owning a `TooltipProvider`. One
2017
+ * provider is mounted per canvas — never one per control, which puts every ✕ in its own delay group
2018
+ * so moving between two of them re-waits the full delay — and a component that mounted its own
2019
+ * would be a second provider inside every app that already has one. So this owns the *pairing* and
2020
+ * requires the *provider*, and with none mounted Radix throws
2021
+ * ``` `Tooltip` must be used within `TooltipProvider` ```. That message is a usable instruction
2022
+ * rather than a puzzle here, because `@lessly/ui` re-exports Radix's names verbatim: both symbols
2023
+ * it names are importable from this package. Mount `TooltipProvider` once near your root — `AppShell`
2024
+ * already does.
2025
+ *
2026
+ * **Disabled.** `Button`'s base class sets `disabled:pointer-events-none`, which would kill the
2027
+ * hover on exactly the button whose reason most needs explaining ("you can't remove the last
2028
+ * owner"). When `disabled` is set, the tooltip trigger moves to a wrapping `<span>` so the hint
2029
+ * survives; the wrapper is `inline-flex`, so it disappears into a flex row. It costs one layout
2030
+ * node, and only in the state that needs it. There is no keyboard path to it — a disabled button
2031
+ * is not a tab stop, by design — so if the reason has to reach a keyboard user, say it in the text
2032
+ * nearby (Guidelines/Button forms).
2033
+ *
2034
+ * **One announcement.** The sentence is the button's *name*, so it must not also be its
2035
+ * *description*. Radix does two things with the text: it points the trigger's `aria-describedby` at
2036
+ * the open bubble, and it renders a `VisuallyHidden role="tooltip"` copy inside it. Chrome's
2037
+ * accessibility tree showed the result as `button name="Remove Ana Ruiz" desc="Remove Ana Ruiz"`
2038
+ * plus an orphan tooltip node — the same words twice. Suppressing only the relation would leave the
2039
+ * copy referenced by nothing and still read, so the relation is suppressed **and** the bubble is
2040
+ * `aria-hidden`: it is a picture of the name, drawn for the people who can see it. WAI-ARIA APG: a
2041
+ * tooltip that supplies the name labels; it does not also describe.
2042
+ *
2043
+ * **The component's own attributes win.** `aria-label`, `aria-describedby`, `type` and the variant
2044
+ * are applied *after* your props are spread, so a caller's `aria-label` cannot quietly replace the
2045
+ * label the tooltip is showing. An `Omit` would not have done this: TypeScript exempts hyphenated
2046
+ * JSX attributes from excess-property checking, so every `aria-*` entry in an `Omit` is inert and
2047
+ * the ordering is the only real guard.
2048
+ *
2049
+ * Its sibling is {@link RemovableChip}, whose ✕ deliberately does *not* redden — see there.
2050
+ */
2051
+ declare const RemoveButton: React$1.ForwardRefExoticComponent<RemoveButtonProps & React$1.RefAttributes<HTMLButtonElement>>;
2052
+
2053
+ /**
2054
+ * A role a grant can name, as this control takes one. Roles are data rather than a fixed ladder,
2055
+ * because a console that lets an admin define a role has no enum to type against.
2056
+ */
2057
+ interface GrantRole {
2058
+ id: string;
2059
+ name: string;
2060
+ /** The line under the name in the menu: what choosing it does. */
2061
+ hint?: string;
2062
+ /**
2063
+ * Where this role sits on the power ladder. Drawn as monochrome weight and nothing else — colour
2064
+ * marks an action, never a state (Guidelines/Look/Colour marks actions). Defaults to `normal`.
2065
+ */
2066
+ weight?: 'faint' | 'normal' | 'strong';
2067
+ /** The band this role is listed under. Roles with no band are listed first, unbanded. */
2068
+ group?: string;
2069
+ }
2070
+ /**
2071
+ * How a role name is drawn, wherever one is drawn: the trigger, the rungs in the menu, and the
2072
+ * stated role on a `GrantRow` that offers no picker. One recipe, because a reader compares role
2073
+ * names down a card and a shape that dropped the ladder would rank them by which control happened
2074
+ * to draw them. Literal strings, so the scanner sees every step.
2075
+ */
2076
+ declare const WEIGHT_TONE: Record<NonNullable<GrantRole['weight']>, string>;
2077
+ /** A value naming no role is a broken grant needing attention, so it reads noticeably rather than
2078
+ * quietly — never the faint tone, which is what "reads everything, changes nothing" looks like. */
2079
+ declare const MISSING_TONE = "italic text-text-primary";
2080
+ /**
2081
+ * The removal's sentence: the words the control shows, then the caller's detail. One function
2082
+ * because `GrantRow` puts the same act on a trailing ✕ in its other shapes, and because a control
2083
+ * whose accessible name does not contain the words on screen cannot be fired by speech control
2084
+ * (WCAG 2.5.3) — which holds here by construction rather than by every caller remembering to write
2085
+ * the right opening.
2086
+ */
2087
+ declare const grantRemoveLabel: (detail: string | undefined, notInForce: boolean) => string;
2088
+ /**
2089
+ * The lines the menu states in place of a choice it cannot offer. The component decides which one
2090
+ * applies, because only it knows what it drew; the words are the caller's, because only the caller
2091
+ * knows what its roles are called and why its cap is where it is.
2092
+ *
2093
+ * Each is an imposed state and owes its reason on the spot, in one line
2094
+ * (Guidelines/Controls/State with a reason).
2095
+ */
2096
+ interface GrantRoleNotes {
2097
+ /** Nothing to pick, no group to name and nothing to clear. Without it the menu opens on a box. */
2098
+ empty?: React$1.ReactNode;
2099
+ /** The role in force is one `allow` excludes, so it is on the trigger and not in the list. */
2100
+ aboveCap?: React$1.ReactNode;
2101
+ /** `value` names no role in `roles` — a grant left pointing at one that was deleted. */
2102
+ missing?: React$1.ReactNode;
2103
+ }
2104
+ interface GrantRolePickerProps {
2105
+ /** The role in force. It displays even when `allow` excludes it. */
2106
+ value: string;
2107
+ roles: GrantRole[];
2108
+ onChange: (id: string) => void;
2109
+ /** The row this control answers for. The role in force is appended, so the name a screen reader
2110
+ * hears out of the row's context says both what is being set and what it is set to. */
2111
+ ariaLabel?: string;
2112
+ align?: 'start' | 'end';
2113
+ /**
2114
+ * Caps what may be picked. The current value still displays on the trigger even outside the cap,
2115
+ * so a capped grant can only be changed down rather than being silently re-pointed.
2116
+ */
2117
+ allow?: (r: GrantRole) => boolean;
2118
+ /**
2119
+ * The group whose grant is the one standing. Present means no rungs at all: a group's grant wins
2120
+ * outright, so no rung on this row would change anything, and the menu names the group instead
2121
+ * (Guidelines/Controls/Stated, not picked).
2122
+ */
2123
+ via?: string;
2124
+ /** A direct grant the group's grant overtook: the role id, struck through, with the caller's
2125
+ * reason beside it. */
2126
+ notInForce?: {
2127
+ role: string;
2128
+ why: string;
2129
+ };
2130
+ /** The row's removal, as a menu item rather than a trailing ✕, so the row ends in one control
2131
+ * whatever state it is in. Absent where there is nothing to clear. */
2132
+ onRemove?: () => void;
2133
+ /**
2134
+ * What the removal's sentence says *after* its visible words — `"Acme Store"`, or
2135
+ * `"the direct grant on Acme Store, which is not in force. Ana keeps Admin via Engineers"` minus
2136
+ * its opening. This component owns the opening, because which words the item shows depends on
2137
+ * `notInForce` and only the component knows that: handed the whole sentence, a caller has to
2138
+ * guess which opening to write, and a name that does not contain its own visible label is a
2139
+ * control a speech-control user cannot fire (WCAG 2.5.3).
2140
+ */
2141
+ removeDetail?: string;
2142
+ /** The reader may not pick here. */
2143
+ readOnly?: boolean;
2144
+ /** What the menu says where it has no choice to offer. Owed by any caller that can reach one of
2145
+ * those states. */
2146
+ notes?: GrantRoleNotes;
2147
+ /** What the trigger shows when `value` names no role in `roles`. */
2148
+ missingLabel?: string;
2149
+ className?: string;
2150
+ }
2151
+ /**
2152
+ * The one control a grant row ends in: it states the role, and everything there is to do or to know
2153
+ * about that role is behind it.
2154
+ *
2155
+ * It is a picker wherever the reader can choose, and a menu that **explains rather than offers**
2156
+ * where there is nothing to choose. Four things can be in it, and at least one of them always is:
2157
+ * the group carrying the row (`via`), the rungs, the direct grant that group overtook
2158
+ * (`notInForce`), and the row's removal (`onRemove`). Where it has no choice to offer it says why,
2159
+ * through `notes`, and the trigger drops its chevron — that mark means "there is something to pick
2160
+ * here" (Guidelines/Controls/Stated, not picked), so a menu that only explains must not wear it.
2161
+ *
2162
+ * It is not a `Select`. A select answers with one of its options; this one can also take the thing
2163
+ * it describes away, and a command sitting among options is neither a listbox nor a set of radios.
2164
+ * So it is a menu, and the removal is a menu item (Guidelines/Controls/When it isn't a Button),
2165
+ * which reddens under the pointer or the keyboard and drops the red frame a destructive `Button`
2166
+ * rests on, because a row repeated down a menu would shout (Guidelines/Controls/Destructive
2167
+ * actions).
2168
+ */
2169
+ declare const GrantRolePicker: React$1.ForwardRefExoticComponent<GrantRolePickerProps & React$1.RefAttributes<HTMLButtonElement>>;
2170
+
2171
+ /** What every shape of the row takes. The three that differ are split below. */
2172
+ interface GrantRowBase {
2173
+ /** What the grant is on — a product, a workspace, whatever the row lists. */
2174
+ name: string;
2175
+ /** The role in force, by id. */
2176
+ role: string;
2177
+ roles: GrantRole[];
2178
+ /** Absent = nothing here to remove, so no remove control. */
2179
+ onRemove?: () => void;
2180
+ /** What the picker's trigger is named after, where the row draws one. Defaults to `name`, which
2181
+ * is the row the trigger belongs to — pass this only to say it some other way. */
2182
+ ariaLabel?: string;
2183
+ /**
2184
+ * What the removal's sentence says *after* the words the control shows. The row owns the opening
2185
+ * — `"Remove"`, or `"Remove the direct grant"` where a group's grant overtook one — so the ✕ and
2186
+ * the menu item word one act one way, and the menu item's name contains its own visible label
2187
+ * (WCAG 2.5.3). Defaults to `name`.
2188
+ */
2189
+ removeDetail?: string;
2190
+ /** The group this row's standing role comes from, `''` when the direct grant stands. */
2191
+ via?: string;
2192
+ /** A direct grant the group's grant overtook: the role id and the reason it does nothing. */
2193
+ notInForce?: {
2194
+ role: string;
2195
+ why: string;
2196
+ };
2197
+ /** The reader may not manage this row: the role is stated and the controls go with it. Implies
2198
+ * `stated`. */
2199
+ readOnly?: boolean;
2200
+ /** Caps which roles the picker offers. The role in force still displays. */
2201
+ allow?: (r: GrantRole) => boolean;
2202
+ /** What the menu says where it has no choice to offer. */
2203
+ notes?: GrantRoleNotes;
2204
+ /** What a role naming nothing in `roles` reads as. */
2205
+ missingLabel?: string;
2206
+ className?: string;
2207
+ }
2208
+ /**
2209
+ * The row ends in the role control and everything it can do is inside it. The three props below are
2210
+ * `never` rather than ignored: under one control there is no second column to hold open, so a
2211
+ * reservation lines up against nothing, and `stated` names a shape this one already derives from
2212
+ * `via` — passing either used to compile and do nothing.
2213
+ */
2214
+ interface GrantRowOneControl extends GrantRowBase {
2215
+ actionsInMenu: true;
2216
+ /** This shape always draws the picker, so it always has somewhere to send the change. */
2217
+ onChange: (id: string) => void;
2218
+ stated?: never;
2219
+ reserveRemove?: never;
2220
+ reserveChevron?: never;
2221
+ }
2222
+ /** The role control sits beside the row's other trailing marks, or the role is stated in its place. */
2223
+ interface GrantRowControlsBeside extends GrantRowBase {
2224
+ actionsInMenu?: false;
2225
+ /** Absent = nothing here to change, so the role is stated rather than picked. */
2226
+ onChange?: (id: string) => void;
2227
+ /** The role is stated, not picked — a group carries this row and its role is not this row's to
2228
+ * change (Guidelines/Controls/Stated, not picked). */
2229
+ stated?: boolean;
2230
+ /** This row carries no ✕, but a sibling row does — hold the width, so the card reads as one right
2231
+ * edge rather than two. */
2232
+ reserveRemove?: boolean;
2233
+ /** This row states its role, but a sibling row picks one — hold the picker's chevron, for the same
2234
+ * reason. */
2235
+ reserveChevron?: boolean;
2236
+ }
2237
+ type GrantRowProps = GrantRowOneControl | GrantRowControlsBeside;
2238
+ /**
2239
+ * One grant, as a row: what it is on, the role it confers, and the way to change or clear it.
2240
+ *
2241
+ * The three shapes it takes are three answers to one question — whose the role is and whether the
2242
+ * reader may act on it.
2243
+ *
2244
+ * * **Picked** is the default: the role is this row's to set, and a ✕ beside it clears the grant.
2245
+ * * **Stated** (`stated`, `readOnly` which implies it, or no `onChange` at all) prints the role
2246
+ * instead of offering it, with `via` and `notInForce` under it. A group's grant wins outright, so
2247
+ * a row a group carries has nothing on it to choose; `readOnly` answers the different question of
2248
+ * whether the *reader* may act, and a carried row can still carry the ✕ that clears a direct
2249
+ * grant sitting under the group's.
2250
+ * * **One control** (`actionsInMenu`) ends the row at the role control and puts the group, the
2251
+ * overtaken grant and the removal inside it. Every row is then one line tall and none holds a
2252
+ * column open against a control a sibling might have — which is why `reserveRemove` and
2253
+ * `reserveChevron` belong to the other two shapes and not to this one.
2254
+ */
2255
+ declare const GrantRow: React$1.ForwardRefExoticComponent<GrantRowProps & React$1.RefAttributes<HTMLDivElement>>;
2256
+
2257
+ interface RemovableChipProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, 'children'> {
2258
+ /** The name on the chip. Also the thing the ✕ says it removes, so the two cannot drift. */
2259
+ label: string;
2260
+ /** Required. A chip you cannot unpick is a `Badge`. */
2261
+ onRemove: React$1.MouseEventHandler<HTMLButtonElement>;
2262
+ /**
2263
+ * The avatar or glyph. Consumer-owned on purpose: the chip needn't know a person from a group
2264
+ * from an agent — the frame and the ✕ are the same either way, and the mark that says which is a
2265
+ * decision the consuming console already made elsewhere.
2266
+ */
2267
+ leading?: React$1.ReactNode;
2268
+ /** Replaces the generated `Remove {label}` accessible name, for a console that isn't English. */
2269
+ removeLabel?: string;
2270
+ }
2271
+ /**
2272
+ * A principal you have **picked but not yet saved** — the chips that fill the recipient field of an
2273
+ * invite dialog or the member field of a new group — with a ✕ to unpick them.
2274
+ *
2275
+ * **Why it is not a `Badge`.** `Badge` renders nearly the same pixels and is a label: there is
2276
+ * nothing in it to click. This carries a control, and everything below follows from that.
2277
+ *
2278
+ * **The ✕ stays grey on hover, and that is the point.** Every other remove in this console wears its
2279
+ * danger — `Button variant="destructive"` rests on a red frame and reddens under the pointer, which
2280
+ * is how a revoke or a teardown announces what it costs (Guidelines/Destructive actions). This one does
2281
+ * not, because **taking someone out of a draft has not done anything yet**: nothing is revoked,
2282
+ * nothing is saved, and the only state it changes is a list you are still assembling. Red here
2283
+ * would charge the price of a destructive act for editing a field. It is `variant="ghost"` for that
2284
+ * reason and not by omission — if you are here to make it consistent with the other removes,
2285
+ * that consistency is the bug.
2286
+ *
2287
+ * **It needs no `TooltipProvider`.** Its ✕ sits beside the name that says what it removes, and
2288
+ * Guidelines/Icons & tooltips is explicit that an icon already next to its own label gets no
2289
+ * tooltip. So unlike {@link RemoveButton}, this renders anywhere — including a dialog a consumer
2290
+ * mounted outside an `AppShell`.
2291
+ *
2292
+ * **The frame is the chip; the fill is a plane.** `bg-bg-sunken` is the one surface token that sits
2293
+ * *below* the ground in both themes, so a chip reads as recessed on a page (`bg-bg-primary`) and
2294
+ * inside a dialog (`bg-bg-elevated`) alike — where `bg-bg-secondary`, the obvious choice, is within
2295
+ * 1.01:1 of a light dialog and disappears. The ✕'s hover plate then has to move up with it, which
2296
+ * is the one class this component sets on the kit `Button` (see the note at the call below).
2297
+ *
2298
+ * **Long names truncate rather than overflow.** The chip caps at its container's width and the
2299
+ * label truncates inside it; wrapping a row of them is the call site's job (`flex flex-wrap
2300
+ * gap-2`).
2301
+ */
2302
+ declare const RemovableChip: React$1.ForwardRefExoticComponent<RemovableChipProps & React$1.RefAttributes<HTMLSpanElement>>;
2303
+
2304
+ /** True when the viewport is narrower than the `md` breakpoint (768px). SSR-safe. */
2305
+ declare function useIsMobile(): boolean;
2306
+
2307
+ interface UseSidebarOptions {
2308
+ /** Controlled collapsed value. When provided, the hook does not own state. */
2309
+ collapsed?: boolean;
2310
+ /** Initial collapsed value in uncontrolled mode. Default false (expanded). */
2311
+ defaultCollapsed?: boolean;
2312
+ /** Called whenever the collapsed value should change (both modes). */
2313
+ onCollapsedChange?: (collapsed: boolean) => void;
2314
+ }
2315
+ interface UseSidebarResult {
2316
+ collapsed: boolean;
2317
+ setCollapsed: (collapsed: boolean) => void;
2318
+ toggle: () => void;
2319
+ }
2320
+ /**
2321
+ * Controllable sidebar collapse state. Controlled when `collapsed` is passed,
2322
+ * otherwise internal state seeded by `defaultCollapsed`. Pure — no persistence
2323
+ * or context; the host app owns persistence.
778
2324
  */
779
2325
  declare function useSidebar(options?: UseSidebarOptions): UseSidebarResult;
780
2326
 
781
- type NavRowVariant = 'rail' | 'menu';
2327
+ /** `rail` is the sidebar, `menu` a popup surface, `card` a settings line inside a `Card`. */
2328
+ type NavRowVariant = 'rail' | 'menu' | 'card';
782
2329
  interface NavRowOwnProps {
783
- /** Leading glyph. Rendered in a fixed 20px box; SVGs are normalized to 18px.
2330
+ /** Leading glyph. Rendered in a fixed 20px box with SVGs normalized to 18px — 16px and 16px on
2331
+ * `card`, where the row sits beside body text rather than in a rail.
784
2332
  * A falsy value (`null`/`false`/`0`/`''`) renders nothing — there is no reserved
785
2333
  * empty slot, so the row's content shifts left when `icon` is falsy. */
786
2334
  icon?: React$1.ReactNode;
787
2335
  label: string;
2336
+ /** A second line under `label`, in the same column: the source a row is fed from, the owner
2337
+ * behind a setting — the fact that would otherwise be crammed into the label or dropped.
2338
+ * `card` only; `rail` and `menu` are one line and ignore it.
2339
+ *
2340
+ * Dropped at render time rather than refused at the type level, unlike `children` below.
2341
+ * Refusing it means discriminating `NavRowProps` on `variant`, and that stops
2342
+ * `<NavRow variant={v} />` compiling for anyone who types `v` as the exported
2343
+ * `NavRowVariant` — the ordinary shape of a rendered nav array. A prop that is quietly
2344
+ * ignored costs less than a variant that cannot be held in a variable. */
2345
+ sub?: React$1.ReactNode;
2346
+ /** Marks the row as the current destination. `card` has no selected form — a settings line is
2347
+ * never where you are — so it reads the same either way. */
788
2348
  active?: boolean;
789
2349
  variant: NavRowVariant;
790
2350
  /** Right-aligned adornment: chevron, checkmark, action. Keeps its own size.
791
2351
  * A falsy value (`null`/`false`/`0`/`''`) renders nothing — e.g. passing
792
2352
  * `trailing={count}` with `count === 0` produces no adornment, not a "0". */
793
2353
  trailing?: React$1.ReactNode;
2354
+ /** The trailing value is an absence ("None yet") — a step quieter. */
2355
+ mutedTrailing?: boolean;
794
2356
  /** Icon-only row (collapsed rails). `label` becomes the aria-label. */
795
2357
  hideLabel?: boolean;
796
2358
  }
@@ -805,9 +2367,13 @@ type NavRowProps = NavRowOwnProps & Omit<React$1.ComponentPropsWithoutRef<'butto
805
2367
  asChild?: false;
806
2368
  children?: never;
807
2369
  });
808
- /** Nav row primitive (rail and menu variants). Composes an icon, label and trailing slot
2370
+ /** Nav row primitive (rail, menu and card variants). Composes an icon, label and trailing slot
809
2371
  * into a button, or into a single child via `asChild` (e.g. a router `<Link>`).
810
2372
  *
2373
+ * The `card` variant is the settings line that leaves the page for another section — People →
2374
+ * Members, Security → Identity. It carries no trailing mark and no underline: a section jump is
2375
+ * not an entity opening as a page, so the hover fill is the whole affordance.
2376
+ *
811
2377
  * Rail rows are designed for the `bg-surface` canvas. In the light theme `--hov-bg` is an
812
2378
  * opaque `#ffffff` plate, so a rail `NavRow` has no hover contrast on a surface that is
813
2379
  * already white — notably a `--menu-bg` plate. Use the `menu` variant there; its
@@ -877,7 +2443,7 @@ interface AppSidebarProps {
877
2443
  * `collapsible`. A collapsible rail should supply this (or `logo`): `header` is expanded-only
878
2444
  * and is never read while collapsed, so without a mark the collapsed rail shows just the pin. */
879
2445
  logoCollapsed?: React$1.ReactNode;
880
- /** Identity slot above the rail — e.g. a <SidebarProductHeader/>. Falls back to `logo`.
2446
+ /** Identity slot above the rail — e.g. an <OrgProductSwitcher/> (#266). Falls back to `logo`.
881
2447
  * Expanded-only: rendering it in the 52px collapsed rail would overflow, so the collapsed
882
2448
  * branch never reads it — supply `logoCollapsed` (or `logo`) for that state instead. */
883
2449
  header?: React$1.ReactNode;
@@ -916,6 +2482,10 @@ type SidebarProductHeaderProps = SidebarProductHeaderOwnProps & Omit<React$1.Com
916
2482
  children?: never;
917
2483
  });
918
2484
  /** Identity row for the sidebar header slot: product tile + name, opening the product menu.
2485
+ *
2486
+ * @deprecated Use {@link OrgProductSwitcher} for the sidebar header slot (#266). It is the single,
2487
+ * redesigned org·product switcher and supports both an org-level and an org/product trigger. This
2488
+ * component is kept for backward compatibility and will be removed in a future major.
919
2489
  *
920
2490
  * Deliberately inert on hover — no background, no transition — unlike the rail rows below
921
2491
  * it. `rounded-xl` is not dead weight despite nothing tinting the box: this declares no
@@ -947,14 +2517,17 @@ interface OrgProductSwitcherProps {
947
2517
  organizations: OrgProductSwitcherItem[];
948
2518
  activeOrgId: string;
949
2519
  onOrgSelect: (id: string) => void;
950
- /** Products for the ACTIVE org. The consumer re-supplies these when the org changes. */
951
- products: OrgProductSwitcherItem[];
952
- activeProductId: string;
953
- onProductSelect: (id: string) => void;
2520
+ /** Products for the ACTIVE org. The consumer re-supplies these when the org changes. Omit (or
2521
+ * leave `activeProductId` unset) for an org-level context — the trigger then shows just the org,
2522
+ * and the menu still lists any products so you can jump into one. */
2523
+ products?: OrgProductSwitcherItem[];
2524
+ activeProductId?: string;
2525
+ onProductSelect?: (id: string) => void;
954
2526
  /** Footer actions below the products (Create product, Product settings, …). The group and
955
2527
  * its divider render only when this is non-empty — the consumer owns which rows appear. */
956
2528
  actions?: OrgProductSwitcherAction[];
957
- /** Accessible name for the trigger. Defaults to `"<org> / <product>"`. */
2529
+ /** Accessible name for the trigger. Defaults to `"<org> / <product>"`, and to whatever the
2530
+ * trigger reads before an org resolves. */
958
2531
  'aria-label'?: string;
959
2532
  className?: string;
960
2533
  }
@@ -1083,20 +2656,32 @@ declare const Col: React$1.ForwardRefExoticComponent<ColProps & React$1.RefAttri
1083
2656
  /**
1084
2657
  * Dependency-free syntax highlighter for docs/consumer code snippets. A single
1085
2658
  * ordered-alternation regex per language tokenizes the source into typed runs;
1086
- * no prism/shiki. Fidelity is "good enough for short snippets", and the public
1087
- * API is stable so the engine can be swapped later. Generalized from the
1088
- * landing page's local highlighter (ui.lessly.com #62).
2659
+ * no prism/shiki, so nothing ships to a consumer's browser but this file.
2660
+ * Fidelity is "good enough for short snippets", and the public API is stable so
2661
+ * the engine can be swapped later. Generalized from the landing page's local
2662
+ * highlighter (ui.lessly.com #62).
2663
+ *
2664
+ * Rendering is line-based so the block can carry line numbers, a per-line
2665
+ * highlight wash, and the diff/terminal variants — the polish the docs' Shiki
2666
+ * block has, brought here without the build-time dependency (#263).
1089
2667
  */
1090
2668
  type CodeLang = 'tsx' | 'ts' | 'bash' | 'json' | 'css';
2669
+ type CodeVariant = 'default' | 'diff' | 'terminal';
1091
2670
  interface CodeBlockProps extends React$1.HTMLAttributes<HTMLPreElement> {
1092
2671
  code: string;
1093
2672
  lang?: CodeLang;
1094
- /** Show a copy button in the header (frames the block). */
2673
+ /** `default` plain, `diff` tints `+`/`-` lines, `terminal` dims the `$` prompt and drops copy. */
2674
+ variant?: CodeVariant;
2675
+ /** Show a copy control — in the filename header, or as an overlay in the corner when there's none. */
1095
2676
  copy?: boolean;
1096
- /** Optional filename caption in the header (frames the block). */
2677
+ /** Optional filename caption in a header row above the code. */
1097
2678
  filename?: string;
1098
2679
  /** Scroll long lines instead of wrapping (default: wrap). */
1099
2680
  scroll?: boolean;
2681
+ /** Lines to wash for emphasis, e.g. `"1,3-5"`. */
2682
+ highlightLines?: string;
2683
+ /** Show a line-number gutter. */
2684
+ showLineNumbers?: boolean;
1100
2685
  }
1101
2686
  declare const CodeBlock: React$1.ForwardRefExoticComponent<CodeBlockProps & React$1.RefAttributes<HTMLPreElement>>;
1102
2687
  type CodeProps = React$1.HTMLAttributes<HTMLElement>;
@@ -1111,65 +2696,79 @@ interface GridOverlayProps extends React$1.HTMLAttributes<HTMLDivElement> {
1111
2696
  }
1112
2697
  declare const GridOverlay: React$1.ForwardRefExoticComponent<GridOverlayProps & React$1.RefAttributes<HTMLDivElement>>;
1113
2698
 
1114
- declare const segmentChipVariants: (props?: ({
1115
- kind?: "granted" | "own" | "pending" | "available" | null | undefined;
2699
+ declare const attachmentChipVariants: (props?: ({
2700
+ state?: "attached" | "requested" | "available" | null | undefined;
1116
2701
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1117
- interface SegmentChipProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, 'children' | 'resource'>, VariantProps<typeof segmentChipVariants> {
1118
- /** The resource this segment points at, e.g. "a GitHub repo", "Ads account 123-456". */
1119
- resource: React$1.ReactNode;
1120
- /** Override the leading icon; defaults to a glyph derived from `kind`. */
2702
+ type AttachmentState = NonNullable<VariantProps<typeof attachmentChipVariants>['state']>;
2703
+ interface AttachmentChipProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, 'children'>, VariantProps<typeof attachmentChipVariants> {
2704
+ /**
2705
+ * The sub-account this attachment points at, in the provider's own words — the attachment's
2706
+ * `customerId` + `descriptiveName`, e.g. "Ads account 762-703-9086, Acme Store EU". Providers
2707
+ * without a sub-account have nothing to name here; render a status `Badge` instead of a chip.
2708
+ */
2709
+ account: React$1.ReactNode;
2710
+ /** Override the leading icon; defaults to a glyph derived from `state`. */
1121
2711
  icon?: LucideIcon;
1122
2712
  /** Hide the leading icon entirely. */
1123
2713
  hideIcon?: boolean;
1124
2714
  }
1125
- declare const SegmentChip: React$1.ForwardRefExoticComponent<SegmentChipProps & React$1.RefAttributes<HTMLSpanElement>>;
2715
+ declare const AttachmentChip: React$1.ForwardRefExoticComponent<AttachmentChipProps & React$1.RefAttributes<HTMLSpanElement>>;
1126
2716
 
1127
- type ConnectionScope = 'org' | 'org/product' | 'product';
1128
- type ConnectionAuth = 'app' | 'oauth' | 'token';
1129
- type ConnectionStatus = 'connected' | 'error' | 'disconnected';
1130
- interface ConnectionCardProps extends React$1.HTMLAttributes<HTMLDivElement> {
1131
- /** Display name, e.g. "GitHub apliteni". */
2717
+ /** Who attached the connector to the product this card is shown on. Both sides say *attached*. */
2718
+ type ConnectorOrigin = 'org' | 'product';
2719
+ /**
2720
+ * `active` is the resting state and shows no badge — almost every connector is active, so a pill on
2721
+ * it states nothing and stacks a column of identical marks down a list (#343). The two states worth
2722
+ * a badge are the ones that stop a product using the account.
2723
+ */
2724
+ type ConnectorStatus = 'active' | 'needs-reconnect' | 'not-connected';
2725
+ interface ConnectorCardProps extends React$1.HTMLAttributes<HTMLDivElement> {
2726
+ /**
2727
+ * The account name — what this connector is linked WITH, never a bare provider name and never a
2728
+ * bare "Connected" (#270). E.g. "GitHub — acme", "Google Ads — ads@acme.com".
2729
+ */
1132
2730
  name: string;
1133
- scope: ConnectionScope;
1134
- auth: ConnectionAuth;
1135
- status: ConnectionStatus;
2731
+ /** What kind of external account this is, in the provider's words: "GitHub organization". */
2732
+ kind?: string;
2733
+ /** Who attached it, on a surface where that is a fact — a product's own list. Omit on the org roster. */
2734
+ origin?: ConnectorOrigin;
2735
+ status: ConnectorStatus;
1136
2736
  /** Provider mark; falls back to a monogram box derived from `name`. */
1137
2737
  glyph?: React$1.ReactNode;
1138
- /** Override the default status label (e.g. "Token expired" for `error`). */
2738
+ /** Override the status label (e.g. "Authorisation expired" for `needs-reconnect`). */
1139
2739
  statusLabel?: string;
1140
2740
  /**
1141
- * How many products hold a segment of this connection. `undefined` renders the
1142
- * "Not granted to any product yet" default — pass it ONLY on a surface where
1143
- * that claim is true and knowable (the org roster); on a product surface pass
1144
- * neither `grantedCount` nor a footer `action` to render no footer at all.
2741
+ * How many products this connector is attached to. `undefined` renders the "Not attached to any
2742
+ * product yet" default — pass it ONLY on a surface where that claim is true and knowable (the org
2743
+ * roster); on a product surface pass neither `attachedCount` nor a footer `action` to render no
2744
+ * footer at all.
1145
2745
  */
1146
- grantedCount?: number;
2746
+ attachedCount?: number;
1147
2747
  /**
1148
2748
  * Footer action — typically a <Button> ("Manage", "Reconnect", "Connect").
1149
- * Flat mode: a disconnected card shows it in the header. Collapsible mode: the
1150
- * header is a disclosure trigger (nesting a button would be invalid), so the
1151
- * action always renders in the expanded footer instead.
2749
+ * Flat mode: a not-connected card shows it in the header. Collapsible mode: the header is a
2750
+ * disclosure trigger (nesting a button would be invalid), so the action always renders in the
2751
+ * expanded footer instead.
1152
2752
  */
1153
2753
  action?: React$1.ReactNode;
1154
2754
  /**
1155
- * Blast-radius disclosure. Some providers (GitHub, ClickUp) grant all-or-nothing
1156
- * access to the whole external org — there is no per-repo/per-space permission,
1157
- * and the vended credential genuinely reaches the whole external org. Copy passed
1158
- * here must state that blast radius honestly (e.g. "Full org access any product
1159
- * granted this connection can reach every repository"); do NOT claim the segment
1160
- * is enforced by Lessly — for these providers it is not.
2755
+ * Blast-radius disclosure. Some providers (GitHub, ClickUp) hand out all-or-nothing access to the
2756
+ * whole external org — there is no per-repo/per-space permission, and the vended credential
2757
+ * genuinely reaches everything. Copy passed here must state that blast radius honestly (e.g.
2758
+ * "Full org access any product this connector is attached to can reach every repository"); do
2759
+ * NOT claim Lessly narrows it, because for these providers it does not.
1161
2760
  */
1162
2761
  access?: React$1.ReactNode;
1163
2762
  /**
1164
- * Drawer content rendered below the card body — the per-product grants roster,
1165
- * inline requests, "+ Grant to a product". Flat mode: the caller owns visibility,
1166
- * pass children only while open (unchanged behavior). Collapsible mode: pass
1167
- * children unconditionally — the card shows them while expanded.
2763
+ * Drawer content rendered below the card body — the per-product attachment roster, inline
2764
+ * requests, "+ Attach to a product". Flat mode: the caller owns visibility, pass children only
2765
+ * while open. Collapsible mode: pass children unconditionally — the card shows them while
2766
+ * expanded.
1168
2767
  */
1169
2768
  children?: React$1.ReactNode;
1170
2769
  /**
1171
- * Disclosure mode: the header row toggles the card open/closed; the access
1172
- * notice, footer, and drawer render only while open. Collapsed by default.
2770
+ * Disclosure mode: the header row toggles the card open/closed; the access notice, footer, and
2771
+ * drawer render only while open. Collapsed by default.
1173
2772
  */
1174
2773
  collapsible?: boolean;
1175
2774
  /** Uncontrolled initial state (collapsible mode). Default: false (collapsed). */
@@ -1178,10 +2777,18 @@ interface ConnectionCardProps extends React$1.HTMLAttributes<HTMLDivElement> {
1178
2777
  open?: boolean;
1179
2778
  onOpenChange?: (open: boolean) => void;
1180
2779
  }
1181
- declare const ConnectionCard: React$1.ForwardRefExoticComponent<ConnectionCardProps & React$1.RefAttributes<HTMLDivElement>>;
2780
+ declare const ConnectorCard: React$1.ForwardRefExoticComponent<ConnectorCardProps & React$1.RefAttributes<HTMLDivElement>>;
1182
2781
 
1183
2782
  type RequestSurface = 'org' | 'product';
1184
- type RequestState = 'available' | 'pending' | 'granted';
2783
+ /**
2784
+ * Where this product stands with one connector: the org holds it and this product has not asked
2785
+ * (`available`), it has asked (`pending`), an admin said no (`denied`), or it is attached and in use
2786
+ * (`attached`).
2787
+ *
2788
+ * `sent` is the other end of the same handshake — a request this side made, waiting on someone
2789
+ * else's answer. It is the sender's own row, so the only thing it can do is take the request back.
2790
+ */
2791
+ type RequestState = 'available' | 'pending' | 'denied' | 'attached' | 'sent';
1185
2792
  interface RequestRowProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'children'> {
1186
2793
  surface: RequestSurface;
1187
2794
  /** Provider display name, e.g. "Google Ads". */
@@ -1189,16 +2796,22 @@ interface RequestRowProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, '
1189
2796
  state: RequestState;
1190
2797
  /** Provider mark; falls back to a monogram box derived from `name`. */
1191
2798
  glyph?: React$1.ReactNode;
1192
- /** Secondary line — requester + resource (org), or availability (product). */
2799
+ /** Secondary line — requester + account (org), or where the connector stands (product). */
1193
2800
  subtitle?: React$1.ReactNode;
1194
- /** The granted resource label; renders a <SegmentChip> when `state` is `granted`. */
1195
- grantedResource?: React$1.ReactNode;
2801
+ /**
2802
+ * The sub-account the attachment points at — the attachment's `customerId` + `descriptiveName`,
2803
+ * e.g. "Ads account 762-703-9086, Acme Store EU". Renders an <AttachmentChip> when `state` is
2804
+ * `attached`; providers without a sub-account leave it unset and get an "In use" status badge.
2805
+ */
2806
+ account?: React$1.ReactNode;
1196
2807
  /** Approve an org-side request. */
1197
2808
  onApprove?: () => void;
1198
2809
  /** Deny an org-side request. */
1199
2810
  onDeny?: () => void;
1200
- /** Request an available connection from the product side. */
2811
+ /** Request a connector the organization holds, from the product side. */
1201
2812
  onRequest?: () => void;
2813
+ /** Withdraw a request this side sent. Drawn for `state: 'sent'`, on either surface. */
2814
+ onRevoke?: () => void;
1202
2815
  /** Override the trailing controls entirely. */
1203
2816
  action?: React$1.ReactNode;
1204
2817
  }
@@ -1237,60 +2850,10 @@ interface FeedbackButtonProps {
1237
2850
  }
1238
2851
  declare function FeedbackButton({ onSubmit, labels, className }: FeedbackButtonProps): React$1.JSX.Element;
1239
2852
 
1240
- interface CreateProductWindowOrganization {
1241
- id: string;
1242
- name: string;
1243
- }
1244
- interface CreateProductWindowProduct {
1245
- id: string;
1246
- name: string;
1247
- slug: string;
1248
- }
1249
- type CreateProductSubmit = {
1250
- name: string;
1251
- organizationId: string;
1252
- }
1253
- /** @deprecated Emitted only by the deprecated create-new-org mode — see
1254
- * `CreateProductWindowProps.selectedOrgId`. Use `OrganizationCreateScreen` instead. */
1255
- | {
1256
- name: string;
1257
- organizationName: string;
1258
- };
1259
- interface CreateProductWindowProps {
1260
- organizations: CreateProductWindowOrganization[];
1261
- /**
1262
- * null => create-new-org mode.
1263
- *
1264
- * @deprecated The create-new-org mode is deprecated. Organization creation now goes
1265
- * through `OrganizationCreateScreen`, which collects the legal details the API needs
1266
- * (legal name, country of incorporation, beneficial owners) — this window only ever
1267
- * sends a bare `organizationName`. Pass a real org id and let the onboarding screens
1268
- * handle the org-first flow. Selecting an existing org here is unaffected.
1269
- */
1270
- selectedOrgId: string | null;
1271
- /** products of the selected org */
1272
- products: CreateProductWindowProduct[];
1273
- productsLoading?: boolean;
1274
- submitting?: boolean;
1275
- error?: string | null;
1276
- /** null when "+ Create new organization" chosen */
1277
- onOrganizationChange: (orgId: string | null) => void;
1278
- onEnterProduct: (product: CreateProductWindowProduct) => void;
1279
- onSubmit: (data: CreateProductSubmit) => void;
1280
- }
1281
- /**
1282
- * The legacy first-run window: pick an organization and name a product, in one panel.
1283
- *
1284
- * Still supported for picking an existing organization. Its **create-new-org mode**
1285
- * (`selectedOrgId: null`, or an empty `organizations` list) is deprecated — org creation
1286
- * now goes through `OrganizationCreateScreen`, followed by `ProductCreateScreen`.
1287
- */
1288
- declare function CreateProductWindow({ organizations, selectedOrgId, products, productsLoading, submitting, error, onOrganizationChange, onEnterProduct, onSubmit, }: CreateProductWindowProps): React$1.JSX.Element;
1289
-
1290
2853
  /** FYI / Important / Critical — the one severity vocabulary. */
1291
2854
  type NotificationSeverity = 'critical' | 'important' | 'fyi';
1292
2855
  /**
1293
- * How the item behaves, not how loud it is. `informational` settles when read,
2856
+ * How the item behaves, not how loud it is. `informational` is a statement,
1294
2857
  * `actionable` waits on a decision, `ephemeral` is ambient progress and never
1295
2858
  * settles.
1296
2859
  */
@@ -1310,7 +2873,14 @@ interface NotificationAction {
1310
2873
  */
1311
2874
  variant?: 'primary' | 'destructive' | 'link';
1312
2875
  }
1313
- /** A durable destination. Survives into the archive after the row settles. */
2876
+ /**
2877
+ * A durable destination. Survives into the archive after the row settles.
2878
+ *
2879
+ * `href` makes the control an anchor, so middle-click, open-in-new-tab and the
2880
+ * status-bar target come with it, and the surface's click handler fires beside it
2881
+ * rather than instead of it — the same contract `OrgProductSwitcherAction` and
2882
+ * `UserMenu` hold. Without an `href` the handler is the only thing that happens.
2883
+ */
1314
2884
  interface NotificationDeepLink {
1315
2885
  label: string;
1316
2886
  href?: string;
@@ -1324,10 +2894,15 @@ interface NotificationItem {
1324
2894
  body?: string;
1325
2895
  /** Default `informational`. */
1326
2896
  cls?: NotificationClass;
2897
+ /**
2898
+ * You have seen it. Independent of the receipt: a read row quietens and drops
2899
+ * its own mark-read control, and keeps every action it came with.
2900
+ */
1327
2901
  read?: boolean;
1328
2902
  /**
1329
2903
  * The receipt for a handled item, e.g. "Approved by artur". Its presence is
1330
- * what makes a row settled: the row dims and one-time actions drop off.
2904
+ * what makes a row settled: the row quietens further and one-time actions drop
2905
+ * off.
1331
2906
  */
1332
2907
  receipt?: string;
1333
2908
  createdAt?: string | Date;
@@ -1370,12 +2945,17 @@ declare const TOAST_DWELL: NotificationToastDwell;
1370
2945
  * Reads a stamp as a relative age. `now` is injectable so the components stay
1371
2946
  * testable and consumers can substitute an absolute or localized formatter; the
1372
2947
  * default reads the clock once during render, which is not a timer.
2948
+ *
2949
+ * Relative up to a week, then the date. Past that "how long ago" stops being the
2950
+ * question a reader is asking, and a running count answers it with a number that
2951
+ * only ever grows.
1373
2952
  */
1374
2953
  declare function formatRelativeAge(createdAt: string | Date, now?: Date): string;
1375
2954
  /**
1376
- * A settled item is one that has been dealt with: it dims, keeps its deep link
1377
- * and drops its one-time actions. Ephemeral items are ambient progressthey
1378
- * are never "handled", so they never settle.
2955
+ * A settled item is one that has been dealt with: it quietens, keeps its deep link
2956
+ * and drops its one-time actions. The receipt is what says so seeing an item is
2957
+ * not handling it, so a read row is still a row you can act on. Ephemeral items are
2958
+ * ambient progress and are never handled, so they never settle.
1379
2959
  */
1380
2960
  declare function isNotificationSettled(item: NotificationItem): boolean;
1381
2961
 
@@ -1397,6 +2977,17 @@ interface NotificationBellProps {
1397
2977
  onOpenSettings?(): void;
1398
2978
  /** Footer link. Rendered only when supplied and there is at least one item. */
1399
2979
  onOpenArchive?(): void;
2980
+ /**
2981
+ * A node at the foot of the panel, above the archive row and outside the region
2982
+ * the rows scroll in, so it stays reachable whatever the list is doing. Absent by
2983
+ * default; muted to match the archive row unless your node says otherwise.
2984
+ *
2985
+ * It composes with `onOpenArchive` rather than replacing it — supply either or
2986
+ * both. What it is for is a fact about the list that is not one of its rows: a
2987
+ * count the panel's own scope excludes, for one, which otherwise has to be
2988
+ * smuggled in as a synthetic `items` entry that the row semantics then apply to.
2989
+ */
2990
+ footer?: React$1.ReactNode;
1400
2991
  open?: boolean;
1401
2992
  onOpenChange?(open: boolean): void;
1402
2993
  /** Override the default relative-age label. */
@@ -1407,6 +2998,12 @@ declare const NotificationBell: React$1.ForwardRefExoticComponent<NotificationBe
1407
2998
 
1408
2999
  interface NotificationCenterProps {
1409
3000
  items: NotificationItem[];
3001
+ /**
3002
+ * The built-in title and description block. `false` suppresses it so a host page can own the
3003
+ * heading — the section's own `PageHeader`, say. "Read all" is a control, not part of the
3004
+ * heading, so it survives the suppression and stays above the filters.
3005
+ */
3006
+ header?: boolean;
1410
3007
  title?: string;
1411
3008
  description?: React$1.ReactNode;
1412
3009
  /** Source filter chips. Derived from `items` when omitted. */
@@ -1430,6 +3027,26 @@ interface NotificationCenterProps {
1430
3027
  }
1431
3028
  declare const NotificationCenter: React$1.ForwardRefExoticComponent<NotificationCenterProps & React$1.RefAttributes<HTMLDivElement>>;
1432
3029
 
3030
+ interface NotificationRowProps extends React$1.HTMLAttributes<HTMLDivElement> {
3031
+ item: NotificationItem;
3032
+ onItemClick?(item: NotificationItem): void;
3033
+ onActionClick?(item: NotificationItem, action: NotificationAction): void;
3034
+ /**
3035
+ * Marks the item read. Supplying it puts a quiet check control on the row when
3036
+ * the item is not read and not ephemeral.
3037
+ */
3038
+ onMarkRead?(id: string): void;
3039
+ /** Override the default relative-age label. */
3040
+ formatAge?(createdAt: Date): string;
3041
+ /**
3042
+ * The card rests on `bg-bg-surface`, which assumes an elevated parent — it is the
3043
+ * step the bell's panel gives it. On a page, whose ground is `bg-bg-primary`, that
3044
+ * step inverts sign: pass `bg-bg-elevated` to keep the row reading as raised.
3045
+ */
3046
+ className?: string;
3047
+ }
3048
+ declare const NotificationRow: React$1.ForwardRefExoticComponent<NotificationRowProps & React$1.RefAttributes<HTMLDivElement>>;
3049
+
1433
3050
  interface NotificationSettingsProps {
1434
3051
  subscriptions: NotificationSubscription[];
1435
3052
  /** Keyed by product id, plus the required `default` key. */
@@ -1452,6 +3069,19 @@ interface NotificationToastProps {
1452
3069
  showSource?: boolean;
1453
3070
  /** A short state line under the body, e.g. "Awaiting your decision — expires in 20s." */
1454
3071
  note?: React$1.ReactNode;
3072
+ /** The card's own controls: mute the source, turn its pushes off. Sits before the dismiss ✕. */
3073
+ overflow?: React$1.ReactNode;
3074
+ /** Ambient progress, 0 to 100. An ephemeral card is never handled, so it carries no actions.
3075
+ * Out of range is clamped, and a non-finite number counts as no progress at all — `done / total`
3076
+ * with `total === 0` draws no bar rather than a full one. */
3077
+ progress?: number;
3078
+ /**
3079
+ * The line under the bar. A slot, not a string, because the bar is the component's
3080
+ * and the wording is the consumer's — theirs is the run that knows whether it is
3081
+ * counting steps, bytes or minutes, and theirs is the language it is read in.
3082
+ * Defaults to `"live, n%"`; pass `null` for a bar with no line at all.
3083
+ */
3084
+ progressLabel?: React$1.ReactNode;
1455
3085
  onItemClick?(item: NotificationItem): void;
1456
3086
  onAction?(action: NotificationAction, item: NotificationItem): void;
1457
3087
  onDismiss?(item: NotificationItem): void;
@@ -1478,6 +3108,21 @@ interface NotificationToasterProps {
1478
3108
  onAction?(action: NotificationAction, item: NotificationItem): void;
1479
3109
  /** Per-item state line, e.g. a TTL countdown the consumer already tracks. */
1480
3110
  renderNote?(item: NotificationItem): React$1.ReactNode;
3111
+ /** Per-item card controls — a source menu beside the dismiss ✕. */
3112
+ renderOverflow?(item: NotificationItem): React$1.ReactNode;
3113
+ /**
3114
+ * Per-item ambient progress, 0 to 100. Read here rather than carried on the item
3115
+ * because it moves while the card is on screen, where `NotificationItem` is stable
3116
+ * data the bell and the centre read too — and neither of those draws a bar.
3117
+ */
3118
+ progressOf?(item: NotificationItem): number | undefined;
3119
+ /**
3120
+ * Per-item wording for the line under the bar. Unlike `renderNote`, whose `undefined` means
3121
+ * no note, `undefined` here means *take the card's default* `"live, n%"` — there is no way to
3122
+ * tell "this hook has no opinion about this item" apart from "this item wants no line". Return
3123
+ * `null` for a bar with no line at all.
3124
+ */
3125
+ renderProgressLabel?(item: NotificationItem): React$1.ReactNode;
1481
3126
  className?: string;
1482
3127
  }
1483
3128
  declare const NotificationToaster: React$1.ForwardRefExoticComponent<NotificationToasterProps & React$1.RefAttributes<HTMLDivElement>>;
@@ -1490,98 +3135,6 @@ declare const NotificationToaster: React$1.ForwardRefExoticComponent<Notificatio
1490
3135
  */
1491
3136
  declare const COUNTRY_OPTIONS: SelectOption[];
1492
3137
 
1493
- interface BetaGateScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title' | 'onSubmit'> {
1494
- /** Fires with the trimmed code. The screen never checks it — the caller does. */
1495
- onSubmit: (code: string) => void;
1496
- defaultCode?: string;
1497
- /** Fires with the raw field value on every keystroke — the seam a caller uses to clear
1498
- * its own `error` as the user starts correcting the code. */
1499
- onCodeChange?: (code: string) => void;
1500
- /** Focuses the access-code field on mount. On by default: the screen is one field, so
1501
- * that is where the caret belongs. Pass `false` to leave the focus alone. */
1502
- autoFocus?: boolean;
1503
- /** Disables the submit button and swaps its label while the caller's check is in flight. */
1504
- submitting?: boolean;
1505
- /** Rendered as an alert above the field — typically a rejected code. */
1506
- error?: string | null;
1507
- /** Social sign-in buttons, rendered above an "or" divider. Without it there is no divider. */
1508
- socialAuth?: React$1.ReactNode;
1509
- /** Target of the waitlist link in the default description. */
1510
- waitlistHref?: string;
1511
- /** Renders "Already have an account? Sign in" as a link. */
1512
- signInHref?: string;
1513
- /** Renders the same affordance as a button. Ignored when `signInHref` is given. */
1514
- onSignIn?: () => void;
1515
- submitLabel?: React$1.ReactNode;
1516
- /** Brand mark above the headline. */
1517
- logo?: React$1.ReactNode;
1518
- /** Rendered top-right. Defaults to the kit's own `ThemeToggle`; pass your own node to
1519
- * replace it, or `null` to drop it. */
1520
- themeToggle?: React$1.ReactNode;
1521
- /** Pass `null` to render no page heading — same meaning as on `SignupScreen`. */
1522
- title?: React$1.ReactNode;
1523
- description?: React$1.ReactNode;
1524
- /** Muted footer signature. Absent by default; pass a node to render one. */
1525
- footer?: React$1.ReactNode;
1526
- }
1527
- /**
1528
- * The gate in front of registration while the product is in closed beta: a single access
1529
- * code, optionally preceded by social sign-in. Presentational and self-contained — it never
1530
- * validates the code, never calls an API and never navigates; the caller handles the
1531
- * outcome of `onSubmit`.
1532
- */
1533
- declare function BetaGateScreen({ onSubmit, defaultCode, onCodeChange, autoFocus, submitting, error, socialAuth, waitlistHref, signInHref, onSignIn, submitLabel, logo, themeToggle, title, description, footer, ...props }: BetaGateScreenProps): React$1.JSX.Element;
1534
-
1535
- /** The submit payload — what a registration endpoint takes, minus anything the caller owns
1536
- * (the beta code, the invite, the return URL). */
1537
- interface SignupScreenSubmit {
1538
- name: string;
1539
- email: string;
1540
- password: string;
1541
- }
1542
- interface SignupScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title' | 'onSubmit'> {
1543
- onSubmit: (payload: SignupScreenSubmit) => void;
1544
- defaultValues?: Partial<SignupScreenSubmit>;
1545
- /** Disables the submit button and swaps its label while the caller's request is in flight. */
1546
- submitting?: boolean;
1547
- serverError?: string | null;
1548
- /** Field-level messages returned alongside a server error. */
1549
- violations?: string[];
1550
- /** Social sign-in buttons, rendered above an "or continue with email" divider. Not shown
1551
- * when `children` take over the body. */
1552
- socialAuth?: React$1.ReactNode;
1553
- /** Renders "Use a different code" under the form — the way back to the beta gate. */
1554
- onEditCode?: () => void;
1555
- /** Renders "Already have an account? Sign in" as a link. */
1556
- signInHref?: string;
1557
- /** Renders the same affordance as a button. Ignored when `signInHref` is given. */
1558
- onSignIn?: () => void;
1559
- submitLabel?: React$1.ReactNode;
1560
- /**
1561
- * Replaces the whole body — social auth, divider, register form and all. This is the seam
1562
- * the consumer uses to host steps the kit deliberately does not know about (MFA challenge,
1563
- * TOTP enrolment) inside the same window.
1564
- */
1565
- children?: React$1.ReactNode;
1566
- /** Brand mark above the headline. */
1567
- logo?: React$1.ReactNode;
1568
- /** Rendered top-right. Defaults to the kit's own `ThemeToggle`; pass your own node to
1569
- * replace it, or `null` to drop it. */
1570
- themeToggle?: React$1.ReactNode;
1571
- /** Pass `null` to render no page heading — for a body (MFA steps) that brings its own. */
1572
- title?: React$1.ReactNode;
1573
- description?: React$1.ReactNode;
1574
- /** Muted footer signature. Absent by default; pass a node to render one. */
1575
- footer?: React$1.ReactNode;
1576
- }
1577
- /**
1578
- * The registration window: social sign-in, then name / email / password. Presentational and
1579
- * self-contained — it never calls an API and never navigates; the caller handles the outcome
1580
- * of `onSubmit`. Password rules are checked here because they are the same rules the
1581
- * registration endpoint enforces, and failing them client-side saves a round trip.
1582
- */
1583
- declare function SignupScreen({ onSubmit, defaultValues, submitting, serverError, violations, socialAuth, onEditCode, signInHref, onSignIn, submitLabel, children, logo, themeToggle, title, description, footer, ...props }: SignupScreenProps): React$1.JSX.Element;
1584
-
1585
3138
  /** One beneficial owner, in the shape the organization API takes it. */
1586
3139
  interface BeneficialOwnerPayload {
1587
3140
  name: string;
@@ -1633,137 +3186,200 @@ interface OrganizationOnboardingFormProps {
1633
3186
  */
1634
3187
  declare function OrganizationOnboardingForm({ requireSanctionsFields, onSubmit, defaultValues, submitting, serverError, violations, countries, submitLabel, onCancel, className, }: OrganizationOnboardingFormProps): React$1.JSX.Element;
1635
3188
 
1636
- interface OrganizationCreateScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title' | 'onSubmit'> {
1637
- /** Makes the country of incorporation and the ownership confirmation, where it is
1638
- * shownmandatory. Mirrors the server-side requirement the consumer runs under. */
1639
- requireSanctionsFields: boolean;
1640
- onSubmit: (payload: OrganizationOnboardingPayload) => void;
1641
- defaultValues?: OrganizationOnboardingDefaults;
1642
- /** Disables the submit button and swaps its label while the caller's request is in flight. */
1643
- submitting?: boolean;
1644
- serverError?: string | null;
1645
- /** Field-level messages returned alongside a server error. */
1646
- violations?: string[];
1647
- /** Defaults to the built-in ISO 3166-1 alpha-2 list. */
1648
- countries?: SelectOption[];
1649
- submitLabel?: string;
1650
- /** Renders a Cancel button in the form when provided. */
1651
- onCancel?: () => void;
1652
- /** Brand mark above the headline. */
1653
- logo?: React$1.ReactNode;
1654
- /** Rendered top-right. Defaults to the kit's own `ThemeToggle`; pass your own node to
1655
- * replace it, or `null` to drop it. */
1656
- themeToggle?: React$1.ReactNode;
1657
- title?: React$1.ReactNode;
1658
- description?: React$1.ReactNode;
1659
- /** Muted footer signature. Absent by default; pass a node to render one. */
1660
- footer?: React$1.ReactNode;
3189
+ /**
3190
+ * The width steps a trailing cell may take, as literal classes. A width is picked from this map and
3191
+ * never assembled `` `w-${n}` `` is a string Tailwind's scanner never sees, so the class would
3192
+ * never be generated and the cell would size to its content instead.
3193
+ */
3194
+ declare const CELL_WIDTH: {
3195
+ readonly 20: "w-20";
3196
+ readonly 24: "w-24";
3197
+ readonly 28: "w-28";
3198
+ readonly 32: "w-32";
3199
+ };
3200
+ /** 5rem to 8rem: a date, a relative time, a short phrase like "Renews itself". */
3201
+ type ListColumnWidth = keyof typeof CELL_WIDTH;
3202
+ /**
3203
+ * One trailing column of a list, declared once and handed to both the header and every row — which
3204
+ * is the whole point of the pair. A cell that cannot ask its header for a width is two literals kept
3205
+ * in step by hand, and they drift the first time one list is edited and the one below it is not.
3206
+ */
3207
+ interface ListColumn {
3208
+ /** Which value in a row's `values` this column draws. */
3209
+ key: string;
3210
+ /** What the header says over it. */
3211
+ label: React$1.ReactNode;
3212
+ width: ListColumnWidth;
3213
+ /**
3214
+ * Drawn when the row says nothing here — a missing key, `null`, or an empty string. "Never"
3215
+ * rather than an empty cell the eye reads as a gap.
3216
+ */
3217
+ fallback?: React$1.ReactNode;
3218
+ /** One tone quieter — a column that qualifies the row rather than answering it. */
3219
+ quiet?: boolean;
3220
+ }
3221
+ interface ListHeaderProps extends React$1.HTMLAttributes<HTMLDivElement> {
3222
+ /** The label over the flexible name column — what the rows below are a list of. */
3223
+ lead: React$1.ReactNode;
3224
+ columns: readonly ListColumn[];
3225
+ /**
3226
+ * Reserve the `size-8` leading column `EntityRow` gives its `mark`. Off for a list whose rows
3227
+ * carry no mark, where the reserve would push the lead 44px off the card's own padding.
3228
+ */
3229
+ mark?: boolean;
3230
+ /**
3231
+ * Reserve the `size-4` trailing column `EntityRow` keeps for its chevron. Off for a list of
3232
+ * `opens="none"` rows, which is the one form that reserves nothing.
3233
+ */
3234
+ trailing?: boolean;
3235
+ }
3236
+ /**
3237
+ * The column header over a list of `EntityRow`s. It is not a table head: the rows stay rows you open,
3238
+ * with their hover plate, their focus ring and their one target.
3239
+ *
3240
+ * It takes the same `columns` array the rows' `ListCells` takes, so the widths are declared once and
3241
+ * two lists on one page rule their trailing columns at the same x.
3242
+ */
3243
+ declare const ListHeader: React$1.ForwardRefExoticComponent<ListHeaderProps & React$1.RefAttributes<HTMLDivElement>>;
3244
+ interface ListCellsProps extends React$1.HTMLAttributes<HTMLSpanElement> {
3245
+ columns: readonly ListColumn[];
3246
+ /** This row's answer per column `key`. A key with no value draws that column's `fallback`. */
3247
+ values: Record<string, React$1.ReactNode>;
1661
3248
  }
1662
3249
  /**
1663
- * Full-page first step of the org-first onboarding flow: the screen a user lands on when
1664
- * they have no organization yet. It is the screen wrapper around
1665
- * `OrganizationOnboardingForm` — presentational and self-contained, it never calls an API
1666
- * and never navigates; the caller handles the outcome of `onSubmit`.
3250
+ * A row's trailing cells, for `EntityRow`'s `meta` slot spans rather than divs, because `meta`
3251
+ * renders inside the row's own inline content.
3252
+ *
3253
+ * It reads the widths off the same `columns` the header was given, so a column that changes width
3254
+ * changes in both places or in neither.
1667
3255
  */
1668
- declare function OrganizationCreateScreen({ requireSanctionsFields, onSubmit, defaultValues, submitting, serverError, violations, countries, submitLabel, onCancel, logo, themeToggle, title, description, footer, ...props }: OrganizationCreateScreenProps): React$1.JSX.Element;
3256
+ declare const ListCells: React$1.ForwardRefExoticComponent<ListCellsProps & React$1.RefAttributes<HTMLSpanElement>>;
1669
3257
 
1670
- interface OrganizationUnderReviewScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title'> {
1671
- /** The only always-present action: the user cannot go anywhere else from this screen. */
1672
- onLogout: () => void;
1673
- /** Renders the secondary "Send feedback" button when provided. */
1674
- onFeedback?: () => void;
1675
- logoutLabel?: string;
1676
- feedbackLabel?: string;
1677
- /** Brand mark above the headline. */
1678
- logo?: React$1.ReactNode;
1679
- /** Rendered top-right. Defaults to the kit's own `ThemeToggle`; pass your own node to
1680
- * replace it, or `null` to drop it. */
1681
- themeToggle?: React$1.ReactNode;
1682
- title?: React$1.ReactNode;
1683
- description?: React$1.ReactNode;
1684
- /** Muted footer signature. Absent by default; pass a node to render one. */
1685
- footer?: React$1.ReactNode;
1686
- /** Extra content between the header copy and the actions — a support link, a reference
1687
- * number, whatever the product needs to add. */
1688
- children?: React$1.ReactNode;
1689
- }
3258
+ type ThemePickerBaseProps = Omit<React$1.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'>;
1690
3259
  /**
1691
- * The waiting room of the org-first onboarding flow: the screen a user lands on once their
1692
- * organization has been submitted and is not usable yet. Same login-card format as
1693
- * `OrganizationCreateScreen`.
3260
+ * Controlled or wired, and the union is what makes a caller say which.
3261
+ *
3262
+ * `value` alone used to compile: three cards that look pressable, and pressing one changed nothing,
3263
+ * because the only thing that could have moved was the handler that was not passed. So the arm that
3264
+ * takes `value` takes `onValueChange` with it.
1694
3265
  *
1695
- * The copy is deliberately neutral it states that a review is in progress and how long it
1696
- * usually takes, and nothing about why or against what. Keep it that way; the reason for the
1697
- * wait is never the user-facing story here.
3266
+ * The other arm takes neither, and is the console's own setting it reads and writes `useTheme()`,
3267
+ * so picking repaints the surface you are standing on, which is what a settings page wants.
3268
+ * `onValueChange` is still allowed there, as a notification after the console has been set.
1698
3269
  *
1699
- * Presentational and self-contained: it never calls an API and never navigates; the caller
1700
- * handles `onLogout` and `onFeedback`.
3270
+ * What the union does not catch is `value={prefs?.theme}`: a `Theme | undefined` satisfies the second
3271
+ * arm, so the call compiles and the picker is wired until the value lands. That is the call that
3272
+ * writes `<html>` behind a caller who thinks they are holding the value, and it is why `ThemePicker`
3273
+ * settles its mode at mount and warns — the type cannot reach this one, so the runtime does.
1701
3274
  */
1702
- declare function OrganizationUnderReviewScreen({ onLogout, onFeedback, logoutLabel, feedbackLabel, logo, themeToggle, title, description, footer, children, ...props }: OrganizationUnderReviewScreenProps): React$1.JSX.Element;
3275
+ type ThemePickerProps = ThemePickerBaseProps & ({
3276
+ /** The chosen theme. Nothing outside the component moves: no `<html>` class, no localStorage. */
3277
+ value: Theme;
3278
+ onValueChange: (theme: Theme) => void;
3279
+ } | {
3280
+ value?: undefined;
3281
+ onValueChange?: (theme: Theme) => void;
3282
+ });
3283
+ /**
3284
+ * Choosing the console's theme, by looking at it: Light and Dark are miniatures of the console they
3285
+ * offer, and Auto is the `Monitor` glyph, because it follows the machine and has no one console to
3286
+ * show. Auto is `system`, and it is here because `ThemeToggle` already cycles through it — a picker
3287
+ * offering only light and dark would contradict the console's own control.
3288
+ */
3289
+ declare const ThemePicker: React$1.ForwardRefExoticComponent<ThemePickerProps & React$1.RefAttributes<HTMLDivElement>>;
1703
3290
 
1704
- /** One organization the user can create the product in. */
1705
- interface ProductCreateScreenOrganization {
1706
- id: string;
1707
- name: string;
1708
- }
1709
- /** One product already living in the target organization. */
1710
- interface ProductCreateScreenProduct {
1711
- id: string;
1712
- name: string;
1713
- slug?: string;
1714
- }
1715
- /** The submit payload. The organization is implied — the screen only ever creates inside
1716
- * the organization it was given. */
1717
- interface ProductCreateScreenSubmit {
1718
- name: string;
1719
- }
1720
- interface ProductCreateScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title' | 'onSubmit'> {
1721
- /**
1722
- * @deprecated No longer rendered. The first-product screen shows no organization
1723
- * context at all, and where the user does have a choice the screen renders the
1724
- * `organizations` select instead. Kept so existing callers still type-check.
1725
- */
1726
- organizationName?: string;
1727
- /** The organizations the user can pick between. Omit (or pass an empty list) for the
1728
- * first-product screen, which shows no organization UI. Passing organizations switches
1729
- * the screen to the picker layout: select on top, that org's products, then the name. */
1730
- organizations?: ProductCreateScreenOrganization[];
1731
- /** The organization currently selected in the picker layout. */
1732
- selectedOrganizationId?: string;
1733
- /** Fires with the picked organization id. Without it the select is read-only. */
1734
- onOrganizationChange?: (organizationId: string) => void;
1735
- /** Shows a loading note in place of the products list while the caller fetches them. */
1736
- productsLoading?: boolean;
1737
- onSubmit: (data: ProductCreateScreenSubmit) => void;
1738
- defaultName?: string;
1739
- /** Disables the submit button and swaps its label while the caller's request is in flight. */
1740
- submitting?: boolean;
1741
- serverError?: string | null;
1742
- /** Products the organization already has. Omit (or pass an empty list) to hide the
1743
- * "Your products" section entirely. */
1744
- existingProducts?: ProductCreateScreenProduct[];
1745
- /** Makes each existing product a button. Without it the list is read-only. */
1746
- onOpenProduct?: (product: ProductCreateScreenProduct) => void;
1747
- /** Heading above the existing-products list. */
1748
- existingProductsLabel?: React$1.ReactNode;
1749
- submitLabel?: React$1.ReactNode;
1750
- /** Renders a Cancel button when provided. */
1751
- onCancel?: () => void;
1752
- /** Brand mark above the headline. */
1753
- logo?: React$1.ReactNode;
1754
- /** Rendered top-right. Defaults to the kit's own `ThemeToggle`; pass your own node to
1755
- * replace it, or `null` to drop it. */
1756
- themeToggle?: React$1.ReactNode;
1757
- title?: React$1.ReactNode;
1758
- description?: React$1.ReactNode;
1759
- /** Muted footer signature. Absent by default; pass a node to render one. */
1760
- footer?: React$1.ReactNode;
3291
+ interface MedallionProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, 'children'> {
3292
+ /** The glyph. The medallion owns its 24px sizing, so a caller can never leave one at the wrong step. */
3293
+ icon: LucideIcon;
3294
+ /** The payoff tone: an inverted plate for the end of a flow, not a resting state. */
3295
+ filled?: boolean;
1761
3296
  }
1762
3297
  /**
1763
- * Full-page second step of the org-first onboarding flow: create the first product inside
1764
- * an organization that already exists. Presentational and self-contained it never calls
1765
- * an API and never navigates; the caller handles the outcome of `onSubmit`.
3298
+ * The circle that stands for nothing a section, a screen or a step, never a principal. That is why
3299
+ * it is neither `GlyphAvatar` nor a `Mark`: `Guidelines/Avatars` maps person, agent and group to a
3300
+ * circle and every object to `EntityTile`'s rounded square, and an arbitrary glyph on the principal
3301
+ * mark would make a round object spellable.
3302
+ *
3303
+ * The plate is the same geometry as an `lg` `Mark` — same box, same neutral tone — because the two sit
3304
+ * side by side on a page and a reader takes a difference in either as meaning something. Each file
3305
+ * writes its own; `medallion.test.tsx` holds them together.
3306
+ *
3307
+ * One size, because every place that draws it is 48px. A size prop would only offer a smaller box
3308
+ * around the same 24px glyph.
3309
+ *
3310
+ * `filled` marks a payoff — "you're in" at the end of a challenge — with weight rather than colour,
3311
+ * so success does not reach for green (Guidelines/Colour marks actions). It is the end of a flow,
3312
+ * never a resting state, which is why a page header has no use for it. It is local to the medallion:
3313
+ * `Mark`'s tones are the identity tints, and no avatar has a filled step.
3314
+ *
3315
+ * It is a mark, not a control: no role, no name, nothing to press. A medallion that wants a click
3316
+ * wants a button around the thing it marks.
3317
+ */
3318
+ declare const Medallion: React$1.ForwardRefExoticComponent<MedallionProps & React$1.RefAttributes<HTMLSpanElement>>;
3319
+
3320
+ /**
3321
+ * A secret the console will never show again — recovery codes, a provisioning token, an agent secret
3322
+ * — held in an inset well until the person confirms they have taken it.
3323
+ *
3324
+ * The well is the emphasis and it does not fade: a sunken tone behind a `border-border-strong`
3325
+ * outline, which `Guidelines/Look/Borders` gives to an edge that is itself the point. Monochrome
3326
+ * throughout, no icon on the container, because `Guidelines/Look/Colour marks actions` leaves colour
3327
+ * to actions and this is a state.
3328
+ *
3329
+ * **The confirm is never disabled.** Before the secret has been taken it rests `ghost` on the holding
3330
+ * word; once Copy or Download has succeeded it settles to the `secondary` fill carrying the
3331
+ * affirmative the call site asked for. Both words are the same exit and both call `onConfirm`, so the
3332
+ * holding word has to name what leaving now does.
3333
+ *
3334
+ * `Copy` and `Download` are peers, not a ranked pair, so both stay `outline`
3335
+ * (`Guidelines/Controls/Button pairs`).
3336
+ *
3337
+ * Nothing here writes a file or raises a toast: `onCopied` and `onDownload` fire so the call site
3338
+ * names what was taken in its own words, and the clipboard is the one side effect the component owns.
1766
3339
  */
1767
- declare function ProductCreateScreen({ organizationName: _organizationName, organizations, selectedOrganizationId, onOrganizationChange, productsLoading, onSubmit, defaultName, submitting, serverError, existingProducts, onOpenProduct, existingProductsLabel, submitLabel, onCancel, logo, themeToggle, title, description, footer, ...props }: ProductCreateScreenProps): React$1.JSX.Element;
3340
+ interface SecretRevealProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'children'> {
3341
+ /** One value on a line, or several in two columns. */
3342
+ value: string | string[];
3343
+ /** The prose above the value: what it is, and that it will not be shown again. */
3344
+ caption: string;
3345
+ /** The affirmative, once the secret has been taken: "Done", "Done, turn on". */
3346
+ confirmLabel: string;
3347
+ /** Both words are one exit — pressed before the secret is taken, and after. */
3348
+ onConfirm: () => void;
3349
+ /**
3350
+ * The holding word, before the secret has been taken. Required, and where leaving now has a
3351
+ * consequence the word has to name it: the exit is live either way. Where closing the block is all
3352
+ * it does, `Dismiss` says so.
3353
+ */
3354
+ dismissLabel: string;
3355
+ /** Fires once the value has reached the clipboard, for the call site's own toast. */
3356
+ onCopied?: () => void;
3357
+ /**
3358
+ * Draws the Download control, and fires when it is pressed. Omit it and there is no second control:
3359
+ * recovery codes are the only secret with a file to save, so the presence of a handler is the
3360
+ * question "is there a file?" already answered.
3361
+ */
3362
+ onDownload?: () => void;
3363
+ /** Defaults to `Copy`, or `Copy all` when the value is a list. */
3364
+ copyLabel?: string;
3365
+ downloadLabel?: string;
3366
+ /**
3367
+ * Move focus to the copy control on arrival. Off by default: a page holding more than one of these
3368
+ * would fight over the focus, and a focus scrolls the page to whatever received it. Pass it where
3369
+ * the reveal is the thing that just happened.
3370
+ */
3371
+ autoFocus?: boolean;
3372
+ /**
3373
+ * A class for the layer between the well's tone and its outline, for a highlight that marks the
3374
+ * block as newly arrived. It exists as a layer of its own because such a wash typically ends on
3375
+ * `background-color: transparent` and holds it, so an element carrying both the wash and a resting
3376
+ * tone is painted transparent through the fade — the tone is on the well, the wash goes here, the
3377
+ * outline and content sit above it.
3378
+ */
3379
+ highlightClassName?: string;
3380
+ /** The same layer, for a hook that needs the element — a scroll-into-view on arrival. */
3381
+ highlightRef?: React$1.Ref<HTMLDivElement>;
3382
+ }
3383
+ declare const SecretReveal: React$1.ForwardRefExoticComponent<SecretRevealProps & React$1.RefAttributes<HTMLDivElement>>;
1768
3384
 
1769
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, type AppShellProps, AppSidebar, type AppSidebarProps, AspectRatio, AuthenticatedLayout, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, type BeneficialOwnerPayload, BetaGateScreen, type BetaGateScreenProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, COUNTRY_OPTIONS, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, type CarouselContextProps, CarouselItem, CarouselNext, type CarouselOptions, type CarouselPlugin, CarouselPrevious, type CarouselProps, Checkbox, Code, CodeBlock, type CodeBlockProps, type CodeLang, type CodeProps, Col, type ColProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, type ConnectionAuth, ConnectionCard, type ConnectionCardProps, type ConnectionScope, type ConnectionStatus, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, type CopyButtonProps, type CreateProductSubmit, CreateProductWindow, type CreateProductWindowOrganization, type CreateProductWindowProduct, type CreateProductWindowProps, DatePicker, type DatePickerProps, type DeltaDirection, type DeltaTone, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DocsLink, type DocsLinkProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, ExtensionIcon, type ExtensionIconProps, ExtensionLink, type ExtensionLinkProps, type ExtensionLinkUiMode, FeedbackButton, type FeedbackButtonLabels, type FeedbackButtonProps, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Grid, GridOverlay, type GridOverlayProps, type GridProps, HoverCard, HoverCardContent, HoverCardTrigger, InlineError, type InlineErrorProps, Input, InputAddon, type InputAddonProps, InputGroup, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Label, MenuDivider, MenuPopup, type MenuPopupProps, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, type NavItem, type NavLinkComponent, NavRow, type NavRowProps, type NavRowVariant, NavSectionLabel, type NavSectionLabelProps, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, type NotifClass, type NotificationAction, NotificationBell, type NotificationBellProps, NotificationCenter, type NotificationCenterProps, type NotificationClass, type NotificationDeepLink, type NotificationItem, type NotificationMute, type NotificationPreferences, type NotificationProduct, NotificationSettings, type NotificationSettingsProps, type NotificationSeverity, type NotificationSubscription, type NotificationThreshold, NotificationToast, type NotificationToastDwell, type NotificationToastProps, NotificationToaster, type NotificationToasterPosition, type NotificationToasterProps, OrgProductSwitcher, type OrgProductSwitcherAction, type OrgProductSwitcherItem, type OrgProductSwitcherProps, OrganizationCreateScreen, type OrganizationCreateScreenProps, type OrganizationOnboardingDefaults, OrganizationOnboardingForm, type OrganizationOnboardingFormProps, type OrganizationOnboardingPayload, OrganizationUnderReviewScreen, type OrganizationUnderReviewScreenProps, PageHeader, type PageHeaderProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProductCreateScreen, type ProductCreateScreenOrganization, type ProductCreateScreenProduct, type ProductCreateScreenProps, type ProductCreateScreenSubmit, Progress, RadioGroup, RadioGroupItem, RequestRow, type RequestRowProps, type RequestState, type RequestSurface, type ResolvedTheme, type Responsive, ScrollArea, ScrollBar, SectionIntro, type SectionIntroProps, SegmentChip, type SegmentChipProps, Select, type SelectOption, type SelectProps, Separator, type Severity, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarBackHeader, type SidebarBackHeaderProps, SidebarNav, SidebarNavLink, type SidebarNavLinkProps, type SidebarNavProps, SidebarProductHeader, type SidebarProductHeaderProps, SignupScreen, type SignupScreenProps, type SignupScreenSubmit, Skeleton, Slider, StatCard, type StatCardProps, StatusDot, type StatusDotProps, Switch, type SwitchProps, TOAST_DWELL, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, type Theme, ThemeToggle, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UseSidebarOptions, type UseSidebarResult, UserMenu, type UserMenuItem, type UserMenuProps, type UserMenuUser, alertVariants, badgeVariants, buttonVariants, cn, formatRelativeAge, isKnownExtensionIcon, isNotificationSettled, navigationMenuTriggerStyle, segmentChipVariants, severityBadgeVariant, severityLabels, statusDotVariants, toggleVariants, useCarousel, useFormField, useIsMobile, useSidebar, useTheme };
3385
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AddPicker, type AddPickerItem, type AddPickerProps, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, type AppShellProps, AppSidebar, type AppSidebarProps, AspectRatio, AttachmentChip, type AttachmentChipProps, type AttachmentState, AuthenticatedLayout, AutoHeight, type AutoHeightProps, Avatar, AvatarFallback, AvatarImage, BackLink, type BackLinkProps, Badge, type BadgeProps, type BeneficialOwnerPayload, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, COUNTRY_OPTIONS, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardNote, type CardNoteProps, type CardProps, CardTitle, type CardTitleProps, Carousel, type CarouselApi, CarouselContent, type CarouselContextProps, CarouselItem, CarouselNext, type CarouselOptions, type CarouselPlugin, CarouselPrevious, type CarouselProps, Checkbox, Code, CodeBlock, type CodeBlockProps, type CodeLang, type CodeProps, type CodeVariant, Col, type ColProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, type CommandItemProps, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, type ConfirmDialogStepUp, ConnectorCard, type ConnectorCardProps, type ConnectorOrigin, type ConnectorStatus, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, type CopyButtonProps, DatePicker, type DatePickerProps, DecorativeIcon, type DecorativeIconProps, type DeltaDirection, type DeltaTone, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DocsLink, type DocsLinkProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, EntityRow, type EntityRowOpens, type EntityRowOpensProps, type EntityRowProps, EntityTile, type EntityTileProps, ExtensionIcon, type ExtensionIconProps, ExtensionLink, type ExtensionLinkProps, type ExtensionLinkUiMode, FeedbackButton, type FeedbackButtonLabels, type FeedbackButtonProps, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GlyphAvatar, type GlyphAvatarProps, type GrantRole, type GrantRoleNotes, GrantRolePicker, type GrantRolePickerProps, GrantRow, type GrantRowProps, Grid, GridOverlay, type GridOverlayProps, type GridProps, HoverCard, HoverCardContent, HoverCardTrigger, IconHint, type IconHintProps, ImageCropDialog, type ImageCropDialogProps, type ImageCropShape, type ImageCropType, ImageCropper, type ImageCropperProps, ImageUpload, type ImageUploadProps, type ImageUploadSize, InlineError, type InlineErrorProps, Input, InputAddon, type InputAddonProps, InputGroup, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Label, ListCells, type ListCellsProps, type ListColumn, type ListColumnWidth, ListHeader, type ListHeaderProps, MISSING_TONE, Medallion, type MedallionProps, MenuDivider, MenuPopup, type MenuPopupProps, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, type NavItem, type NavLinkComponent, NavRow, type NavRowProps, type NavRowVariant, NavSectionLabel, type NavSectionLabelProps, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, type NotifClass, type NotificationAction, NotificationBell, type NotificationBellProps, NotificationCenter, type NotificationCenterProps, type NotificationClass, type NotificationDeepLink, type NotificationItem, type NotificationMute, type NotificationPreferences, type NotificationProduct, NotificationRow, type NotificationRowProps, NotificationSettings, type NotificationSettingsProps, type NotificationSeverity, type NotificationSubscription, type NotificationThreshold, NotificationToast, type NotificationToastDwell, type NotificationToastProps, NotificationToaster, type NotificationToasterPosition, type NotificationToasterProps, OptionCard, type OptionCardProps, OrgProductSwitcher, type OrgProductSwitcherAction, type OrgProductSwitcherItem, type OrgProductSwitcherProps, type OrganizationOnboardingDefaults, OrganizationOnboardingForm, type OrganizationOnboardingFormProps, type OrganizationOnboardingPayload, PageHeader, type PageHeaderProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationNext, PaginationPrevious, PersonAvatar, type PersonAvatarProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, RemovableChip, type RemovableChipProps, RemoveButton, type RemoveButtonProps, RequestRow, type RequestRowProps, type RequestState, type RequestSurface, type ResolvedTheme, type Responsive, ScrollArea, ScrollBar, SecretReveal, type SecretRevealProps, SectionIntro, type SectionIntroProps, Select, type SelectOption, type SelectProps, Separator, SettingRow, type SettingRowProps, type Severity, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarBackHeader, type SidebarBackHeaderProps, SidebarNav, SidebarNavLink, type SidebarNavLinkProps, type SidebarNavProps, SidebarProductHeader, type SidebarProductHeaderProps, Skeleton, Slider, StatCard, type StatCardProps, StatusDot, type StatusDotProps, StepUpChallenge, type StepUpChallengeProps, type StepUpMethod, type StepUpProof, Switch, type SwitchProps, TOAST_DWELL, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, type Theme, ThemePicker, type ThemePickerProps, ThemeToggle, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UseSidebarOptions, type UseSidebarResult, UserMenu, type UserMenuItem, type UserMenuProps, type UserMenuUser, WEIGHT_TONE, alertVariants, attachmentChipVariants, badgeVariants, buttonVariants, cn, formatRelativeAge, grantRemoveLabel, isKnownExtensionIcon, isNotificationSettled, navigationMenuTriggerStyle, severityBadgeVariant, severityLabels, statusDotVariants, toggleVariants, useCarousel, useFormField, useIsMobile, useSidebar, useTheme };