@lovett/ui 0.0.10 → 0.0.11
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 +666 -13
- package/dist/index.js +1835 -344
- package/dist/index.js.map +1 -1
- package/dist/styles.css +16 -2
- package/dist/theme-v2.css +228 -0
- package/dist/tokens.css +9 -0
- package/package.json +1 -1
- package/src/__tests__/anchor.test.tsx +422 -0
- package/src/__tests__/combobox.test.tsx +677 -0
- package/src/__tests__/dropdown-menu.test.tsx +418 -0
- package/src/__tests__/helpers/geometry.ts +58 -0
- package/src/__tests__/layer-stack.test.tsx +228 -0
- package/src/__tests__/popover.test.tsx +460 -0
- package/src/__tests__/select.test.tsx +543 -0
- package/src/__tests__/tooltip.test.tsx +355 -0
- package/src/calculator-shell-v2.tsx +19 -39
- package/src/combobox.tsx +796 -0
- package/src/dropdown-menu.tsx +142 -152
- package/src/index.ts +106 -0
- package/src/lib/anchor.ts +427 -0
- package/src/lib/focus.ts +32 -0
- package/src/lib/layer-stack.ts +188 -0
- package/src/lib/refs.ts +31 -0
- package/src/metric-card.tsx +57 -22
- package/src/modal.tsx +31 -48
- package/src/popover.tsx +407 -0
- package/src/select.tsx +646 -0
- package/src/stat-row.tsx +108 -70
- package/src/styles.css +16 -2
- package/src/tokens.css +9 -0
- package/src/tooltip.tsx +297 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
|
-
import react__default, { HTMLAttributes, ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, TextareaHTMLAttributes, CSSProperties, RefObject, ComponentProps, ComponentType, FormHTMLAttributes, FormEvent } from 'react';
|
|
3
|
+
import react__default, { HTMLAttributes, ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, TextareaHTMLAttributes, CSSProperties, RefObject, ComponentProps, ComponentType, RefAttributes, ReactElement, Ref, FormHTMLAttributes, FormEvent } from 'react';
|
|
4
4
|
import { Toaster as Toaster$1 } from 'sonner';
|
|
5
5
|
export { toast } from 'sonner';
|
|
6
6
|
import { DndContext, DragEndEvent } from '@dnd-kit/core';
|
|
@@ -160,6 +160,69 @@ interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
|
160
160
|
}
|
|
161
161
|
declare const Textarea: react.ForwardRefExoticComponent<TextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
162
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Modal — a centered floating panel on top of a backdrop. Built on
|
|
165
|
+
* `.ds-card-surface` so it inherits the premium card chrome (border,
|
|
166
|
+
* radius, multi-layer shadow with inner highlight in light mode).
|
|
167
|
+
*
|
|
168
|
+
* Two layout modes:
|
|
169
|
+
*
|
|
170
|
+
* 1. Flat children (back-compat) — pass content directly:
|
|
171
|
+
*
|
|
172
|
+
* <Modal title="..." onClose={...}>
|
|
173
|
+
* <p>body</p>
|
|
174
|
+
* <Button>action</Button>
|
|
175
|
+
* </Modal>
|
|
176
|
+
*
|
|
177
|
+
* 2. Shell / Tray pattern (recommended) — body in a recessed tray,
|
|
178
|
+
* action buttons on the outer-card bottom strip below the tray:
|
|
179
|
+
*
|
|
180
|
+
* <Modal title="..." onClose={...}>
|
|
181
|
+
* <Modal.Tray>
|
|
182
|
+
* <p>body content sits in a recessed shelf</p>
|
|
183
|
+
* <textarea ... />
|
|
184
|
+
* </Modal.Tray>
|
|
185
|
+
* <Modal.Footer>
|
|
186
|
+
* <Button variant="ghost" onClick={onClose}>Cancel</Button>
|
|
187
|
+
* <Button>Confirm</Button>
|
|
188
|
+
* </Modal.Footer>
|
|
189
|
+
* </Modal>
|
|
190
|
+
*
|
|
191
|
+
* Accessibility. The panel is a `role="dialog" aria-modal="true"` region
|
|
192
|
+
* named by its own `<h2>` (`aria-labelledby`), or by the `ariaLabel` prop
|
|
193
|
+
* when a caller renders a titleless modal. Opening moves focus to the
|
|
194
|
+
* panel — so a screen reader announces the dialog's name — and closing
|
|
195
|
+
* RESTORES focus to whatever was focused before it opened. Tab and
|
|
196
|
+
* Shift+Tab wrap inside the panel; Escape closes.
|
|
197
|
+
*
|
|
198
|
+
* Callers that want a specific control focused on open mark it
|
|
199
|
+
* `data-autofocus`; anything else and the panel itself takes focus.
|
|
200
|
+
*
|
|
201
|
+
* WHY A FOCUS TRAP AND NOT `inert` ON THE APP ROOT. Modal renders INLINE
|
|
202
|
+
* in the React tree — it is a descendant of `#root`, not a portal — so
|
|
203
|
+
* `inert` on the app root would make the modal itself inert. Portaling it
|
|
204
|
+
* to `document.body` to unlock that would move all 59 consuming files off
|
|
205
|
+
* the `.cs-frame`-scoped token layer and out of their current stacking /
|
|
206
|
+
* inheritance context, which is a much larger change than an a11y fix
|
|
207
|
+
* should make. Inerting `document.body`'s other children is also wrong:
|
|
208
|
+
* `DropdownMenu`, `Popover`, `TagChipInput` and `FolderTreePicker` portal
|
|
209
|
+
* their content THERE, so a select inside a modal would go dead. Focus trap
|
|
210
|
+
* it is — the keyboard hole is closed; pointer and AT virtual-cursor access
|
|
211
|
+
* to the background remains, which is the documented residual.
|
|
212
|
+
*
|
|
213
|
+
* Escape and dismiss order come from the shared layer stack
|
|
214
|
+
* (`lib/layer-stack.ts`): the topmost open surface — modal, menu or
|
|
215
|
+
* popover — answers Escape alone.
|
|
216
|
+
*/
|
|
217
|
+
/**
|
|
218
|
+
* Dismiss order lives in the shared layer stack (`lib/layer-stack.ts`),
|
|
219
|
+
* which this file used to own as a module-level `openPanels` array. Only
|
|
220
|
+
* the topmost layer answers Escape, so nested modals do not both close on
|
|
221
|
+
* one keypress — and now a DropdownMenu or Popover opened from inside a
|
|
222
|
+
* modal closes on its own first, leaving the modal open. The Tab trap asks
|
|
223
|
+
* for the topmost MODAL (`isTopOfKind`), so a popover above it does not
|
|
224
|
+
* switch the trap off.
|
|
225
|
+
*/
|
|
163
226
|
interface ModalProps {
|
|
164
227
|
isOpen: boolean;
|
|
165
228
|
onClose: () => void;
|
|
@@ -885,8 +948,13 @@ interface MetricCardProps {
|
|
|
885
948
|
labelPosition?: 'top' | 'bottom';
|
|
886
949
|
/** Optional className override for the outer container. */
|
|
887
950
|
className?: string;
|
|
951
|
+
/** Make the whole card a copy-to-clipboard button. */
|
|
952
|
+
copyable?: boolean;
|
|
953
|
+
/** What a copyable card writes. Defaults to `value` when it is a string;
|
|
954
|
+
* REQUIRED when `value` is a node (there is nothing else to copy). */
|
|
955
|
+
copyValue?: string;
|
|
888
956
|
}
|
|
889
|
-
declare function MetricCard({ value, label, tone, icon, labelPosition, className, }: MetricCardProps): react_jsx_runtime.JSX.Element;
|
|
957
|
+
declare function MetricCard({ value, label, tone, icon, labelPosition, className, copyable, copyValue, }: MetricCardProps): react_jsx_runtime.JSX.Element;
|
|
890
958
|
|
|
891
959
|
/**
|
|
892
960
|
* ProgressBar — labeled fill bar.
|
|
@@ -1221,8 +1289,242 @@ interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'typ
|
|
|
1221
1289
|
}
|
|
1222
1290
|
declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLInputElement>>;
|
|
1223
1291
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1292
|
+
/**
|
|
1293
|
+
* Dismiss-layer stack — the ONE "topmost layer wins" registry shared by
|
|
1294
|
+
* Modal, DropdownMenu and Popover (and, next, ContextMenu / Select /
|
|
1295
|
+
* Combobox / Tooltip / CommandPalette).
|
|
1296
|
+
*
|
|
1297
|
+
* Extracted from modal.tsx's module-level `openPanels` array so every
|
|
1298
|
+
* dismissable surface participates in the same order. Before this, a
|
|
1299
|
+
* DropdownMenu opened from inside a Modal answered Escape at the same time
|
|
1300
|
+
* the Modal did — two document listeners, one keypress, both closed. Now a
|
|
1301
|
+
* single document `keydown` listener dispatches Escape to the top of the
|
|
1302
|
+
* stack ONLY, then stops propagation so window-level handlers (the chat
|
|
1303
|
+
* conversation drawer's Escape, lens hotkey maps) do not treat a consumed
|
|
1304
|
+
* Escape as theirs — which is what DropdownMenu's own listener already did.
|
|
1305
|
+
*
|
|
1306
|
+
* Promoted per ADR-0030 Decision G (meta-ads-audit-dashboard task manager:
|
|
1307
|
+
* every picker, sheet and palette needs one dismiss order). First consumer
|
|
1308
|
+
* is the workspace app: Modal (51 files), DropdownMenu (137 call sites) and
|
|
1309
|
+
* Popover all register here.
|
|
1310
|
+
*
|
|
1311
|
+
* Two kinds. A `modal` layer also owns a focus trap, and that trap must not
|
|
1312
|
+
* switch off because a `popover` opened above it — so Modal asks
|
|
1313
|
+
* `isTopOfKind()` for Tab handling while Escape always goes to `isTop()`.
|
|
1314
|
+
* Order is push order, which under React is effect order: a surface that
|
|
1315
|
+
* mounts or opens later sits above one that opened earlier.
|
|
1316
|
+
*
|
|
1317
|
+
* Usage (a dismissable surface):
|
|
1318
|
+
*
|
|
1319
|
+
* const layer = useLayer({
|
|
1320
|
+
* enabled: open,
|
|
1321
|
+
* kind: 'popover',
|
|
1322
|
+
* elementRef: contentRef,
|
|
1323
|
+
* onEscape: () => setOpen(false),
|
|
1324
|
+
* })
|
|
1325
|
+
* useOutsideClick([triggerRef, contentRef], () => setOpen(false), {
|
|
1326
|
+
* enabled: open,
|
|
1327
|
+
* layer, // clicks inside a layer stacked ABOVE this one are not "outside"
|
|
1328
|
+
* })
|
|
1329
|
+
*
|
|
1330
|
+
* `useEscapeKey(handler, { enabled })` is the one-liner for anything that
|
|
1331
|
+
* only needs Escape.
|
|
1332
|
+
*/
|
|
1333
|
+
|
|
1334
|
+
type LayerKind = 'modal' | 'popover';
|
|
1335
|
+
interface LayerHandle {
|
|
1336
|
+
/** True while no layer of ANY kind sits above this one. */
|
|
1337
|
+
isTop(): boolean;
|
|
1338
|
+
/** True while no layer of the SAME kind sits above this one. */
|
|
1339
|
+
isTopOfKind(): boolean;
|
|
1340
|
+
/**
|
|
1341
|
+
* True when `node` is inside the element of a layer stacked above this
|
|
1342
|
+
* one — a nested Select's listbox, a Combobox inside a Popover. Outside-
|
|
1343
|
+
* click handlers treat those as inside.
|
|
1344
|
+
*/
|
|
1345
|
+
containsInLayerAbove(node: Node): boolean;
|
|
1346
|
+
}
|
|
1347
|
+
interface UseLayerOptions {
|
|
1348
|
+
/** Register while true; pop when it turns false or the owner unmounts. */
|
|
1349
|
+
enabled: boolean;
|
|
1350
|
+
kind: LayerKind;
|
|
1351
|
+
/**
|
|
1352
|
+
* The surface's root element. Read lazily, so a ref that is filled in
|
|
1353
|
+
* after the layer registers (portal content) still resolves.
|
|
1354
|
+
*/
|
|
1355
|
+
elementRef?: RefObject<HTMLElement | null>;
|
|
1356
|
+
/** Called when this layer is topmost and Escape is pressed. */
|
|
1357
|
+
onEscape: (event: KeyboardEvent) => void;
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Register a dismiss layer for as long as `enabled` holds. `onEscape` is
|
|
1361
|
+
* read through a ref, so an inline arrow does not re-register the layer
|
|
1362
|
+
* (and does not reorder it) on every render.
|
|
1363
|
+
*/
|
|
1364
|
+
declare function useLayer(options: UseLayerOptions): LayerHandle;
|
|
1365
|
+
interface UseEscapeKeyOptions {
|
|
1366
|
+
/** Default true. */
|
|
1367
|
+
enabled?: boolean;
|
|
1368
|
+
/** Default `popover`. */
|
|
1369
|
+
kind?: LayerKind;
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Escape-only participant in the layer stack. Fires `onEscape` only while
|
|
1373
|
+
* this is the topmost layer; a layer that opens later takes over until it
|
|
1374
|
+
* closes.
|
|
1375
|
+
*/
|
|
1376
|
+
declare function useEscapeKey(onEscape: (event: KeyboardEvent) => void, options?: UseEscapeKeyOptions): LayerHandle;
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* Anchored positioning — the ONE measure / flip / clamp routine behind every
|
|
1380
|
+
* floating surface in @lovett/ui.
|
|
1381
|
+
*
|
|
1382
|
+
* Four primitives (DropdownMenu, FilterDropdown, FolderTreePicker,
|
|
1383
|
+
* TagChipInput) each hand-rolled the same `useLayoutEffect` +
|
|
1384
|
+
* `getBoundingClientRect` + clamp + resize/scroll-listener block, with four
|
|
1385
|
+
* slightly different gaps: no flip at a viewport edge; no clamp; measuring in
|
|
1386
|
+
* a passive effect so the first paint was wrong; `top`/`bottom` only. This
|
|
1387
|
+
* module is the single implementation. DropdownMenu is rebuilt on it in the
|
|
1388
|
+
* same change; the other three keep their local copies for now (follow-up).
|
|
1389
|
+
*
|
|
1390
|
+
* Promoted per ADR-0030 Decision G (meta-ads-audit-dashboard task manager)
|
|
1391
|
+
* with the workspace app as the first consumer — DropdownMenu and Popover
|
|
1392
|
+
* position through this hook, so every menu in the app is on it. Select /
|
|
1393
|
+
* Combobox / Tooltip / ContextMenu build on it next.
|
|
1394
|
+
*
|
|
1395
|
+
* No Floating UI, no Popper (CLAUDE.md §1 allowed deps). Three pieces:
|
|
1396
|
+
* • `computeAnchoredPosition` — pure math, unit-tested without a DOM.
|
|
1397
|
+
* • `useAnchoredPosition` — measures, positions, tracks resize / scroll /
|
|
1398
|
+
* size changes. Anchor is an element (`anchorRef`) OR a virtual rect
|
|
1399
|
+
* (`anchorRect`) — ContextMenu passes the right-click point as
|
|
1400
|
+
* `{ left: e.clientX, top: e.clientY, width: 0, height: 0 }`.
|
|
1401
|
+
* • `useOutsideClick` — pointerdown outside a set of targets, aware of
|
|
1402
|
+
* layers stacked above (a nested Select's listbox is not "outside").
|
|
1403
|
+
*
|
|
1404
|
+
* Two-phase render, unchanged from the DropdownMenu it replaces: the first
|
|
1405
|
+
* paint measures the content parked at (-99999, -99999) with
|
|
1406
|
+
* `visibility: hidden`, the layout effect computes the real coordinates, and
|
|
1407
|
+
* the second paint reveals it. Components gate their entry animation on
|
|
1408
|
+
* `positioned` so `.ds-enter-pop` never plays from the parked location.
|
|
1409
|
+
*
|
|
1410
|
+
* Token discipline: the hook emits geometry only (`position: fixed` +
|
|
1411
|
+
* `left` / `top` in px). Surface colour, radius, shadow, padding and the
|
|
1412
|
+
* motion class stay with the component.
|
|
1413
|
+
*
|
|
1414
|
+
* Usage:
|
|
1415
|
+
*
|
|
1416
|
+
* const { ref, style, placement, positioned } =
|
|
1417
|
+
* useAnchoredPosition<HTMLDivElement>({
|
|
1418
|
+
* anchorRef: triggerRef,
|
|
1419
|
+
* side: 'bottom',
|
|
1420
|
+
* align: 'start',
|
|
1421
|
+
* offset: 6,
|
|
1422
|
+
* enabled: open,
|
|
1423
|
+
* })
|
|
1424
|
+
* return createPortal(
|
|
1425
|
+
* <div
|
|
1426
|
+
* ref={ref}
|
|
1427
|
+
* style={style}
|
|
1428
|
+
* data-side={placement?.side}
|
|
1429
|
+
* className={cn(positioned && 'ds-enter-pop')}
|
|
1430
|
+
* >
|
|
1431
|
+
* …
|
|
1432
|
+
* </div>,
|
|
1433
|
+
* document.body,
|
|
1434
|
+
* )
|
|
1435
|
+
*/
|
|
1436
|
+
|
|
1437
|
+
type AnchorSide = 'top' | 'bottom' | 'left' | 'right';
|
|
1438
|
+
type AnchorAlign = 'start' | 'center' | 'end';
|
|
1439
|
+
/** Viewport-relative rect. `DOMRect` satisfies it; so does a point. */
|
|
1440
|
+
interface AnchorRect {
|
|
1441
|
+
readonly left: number;
|
|
1442
|
+
readonly top: number;
|
|
1443
|
+
readonly width: number;
|
|
1444
|
+
readonly height: number;
|
|
1445
|
+
}
|
|
1446
|
+
interface AnchorSize {
|
|
1447
|
+
readonly width: number;
|
|
1448
|
+
readonly height: number;
|
|
1449
|
+
}
|
|
1450
|
+
/** The side and alignment actually used after flipping. */
|
|
1451
|
+
interface AnchorPlacement {
|
|
1452
|
+
readonly side: AnchorSide;
|
|
1453
|
+
readonly align: AnchorAlign;
|
|
1454
|
+
}
|
|
1455
|
+
interface AnchoredPositionOptions {
|
|
1456
|
+
/** Preferred side of the anchor. Default `bottom`. */
|
|
1457
|
+
side?: AnchorSide;
|
|
1458
|
+
/** Alignment along the anchor's cross axis. Default `start`. */
|
|
1459
|
+
align?: AnchorAlign;
|
|
1460
|
+
/** Gap between anchor and floating element along `side`, px. Default 6. */
|
|
1461
|
+
offset?: number;
|
|
1462
|
+
/** Shift along the alignment axis, px. Default 0. */
|
|
1463
|
+
alignOffset?: number;
|
|
1464
|
+
/**
|
|
1465
|
+
* Flip to the opposite side when the preferred side cannot fit and the
|
|
1466
|
+
* opposite side fits — or simply has more room. Default true.
|
|
1467
|
+
*/
|
|
1468
|
+
flip?: boolean;
|
|
1469
|
+
/** Keep the floating element inside the viewport, `gutter` px in. Default true. */
|
|
1470
|
+
clampToViewport?: boolean;
|
|
1471
|
+
/** Viewport inset used by both flip and clamp, px. Default 8. */
|
|
1472
|
+
gutter?: number;
|
|
1473
|
+
}
|
|
1474
|
+
interface AnchoredPosition {
|
|
1475
|
+
readonly left: number;
|
|
1476
|
+
readonly top: number;
|
|
1477
|
+
readonly placement: AnchorPlacement;
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Pure placement math. Given the anchor rect, the floating element's size
|
|
1481
|
+
* and the viewport size, returns fixed-position coordinates plus the
|
|
1482
|
+
* placement actually used. No DOM — this is what the tests pin.
|
|
1483
|
+
*/
|
|
1484
|
+
declare function computeAnchoredPosition(anchor: AnchorRect, floating: AnchorSize, viewport: AnchorSize, options?: AnchoredPositionOptions): AnchoredPosition;
|
|
1485
|
+
interface UseAnchoredPositionOptions extends AnchoredPositionOptions {
|
|
1486
|
+
/** Element to anchor to. Ignored while `anchorRect` is non-null. */
|
|
1487
|
+
anchorRef?: RefObject<Element | null>;
|
|
1488
|
+
/** Virtual anchor (a right-click point, a text caret). Wins over `anchorRef`. */
|
|
1489
|
+
anchorRect?: AnchorRect | null;
|
|
1490
|
+
/** Measure and track while true. Default true. */
|
|
1491
|
+
enabled?: boolean;
|
|
1492
|
+
}
|
|
1493
|
+
interface UseAnchoredPositionResult<T extends HTMLElement> {
|
|
1494
|
+
/** Attach to the floating element. */
|
|
1495
|
+
ref: (node: T | null) => void;
|
|
1496
|
+
/** The same node as a ref object — for `contains()` checks. */
|
|
1497
|
+
floatingRef: RefObject<T | null>;
|
|
1498
|
+
/** `position: fixed` + coordinates; hidden and parked off-screen until measured. */
|
|
1499
|
+
style: CSSProperties;
|
|
1500
|
+
/** Side / align actually used, or null until measured. */
|
|
1501
|
+
placement: AnchorPlacement | null;
|
|
1502
|
+
/** True once real coordinates are applied. Gate entry motion on this. */
|
|
1503
|
+
positioned: boolean;
|
|
1504
|
+
/** Re-measure now (after content you know changed size, for example). */
|
|
1505
|
+
update: () => void;
|
|
1506
|
+
}
|
|
1507
|
+
declare function useAnchoredPosition<T extends HTMLElement = HTMLElement>(options: UseAnchoredPositionOptions): UseAnchoredPositionResult<T>;
|
|
1508
|
+
type OutsideClickTarget = RefObject<Element | null> | Element | null | undefined;
|
|
1509
|
+
interface UseOutsideClickOptions {
|
|
1510
|
+
/** Default true. */
|
|
1511
|
+
enabled?: boolean;
|
|
1512
|
+
/**
|
|
1513
|
+
* This surface's dismiss layer. When given, a pointerdown inside any layer
|
|
1514
|
+
* stacked ABOVE it (a Select opened from inside a Popover) is treated as
|
|
1515
|
+
* inside, not outside.
|
|
1516
|
+
*/
|
|
1517
|
+
layer?: LayerHandle;
|
|
1518
|
+
}
|
|
1519
|
+
/**
|
|
1520
|
+
* Calls `onOutside` on a `pointerdown` whose target is inside none of
|
|
1521
|
+
* `targets`. Handler and targets are read through refs, so inline arrays
|
|
1522
|
+
* and arrows do not re-subscribe the listener.
|
|
1523
|
+
*/
|
|
1524
|
+
declare function useOutsideClick(targets: ReadonlyArray<OutsideClickTarget>, onOutside: (event: PointerEvent) => void, options?: UseOutsideClickOptions): void;
|
|
1525
|
+
|
|
1526
|
+
type Align = AnchorAlign;
|
|
1527
|
+
type Side = AnchorSide;
|
|
1226
1528
|
interface DropdownMenuProps {
|
|
1227
1529
|
/** Controlled open state. Omit for internal state. */
|
|
1228
1530
|
open?: boolean;
|
|
@@ -1242,31 +1544,35 @@ interface DropdownMenuTriggerProps extends ButtonHTMLAttributes<HTMLButtonElemen
|
|
|
1242
1544
|
* secondary Button visual (rounded-xl + `--bg-card` fill + 1px
|
|
1243
1545
|
* `--border`). Set `unstyled` to wrap your own button shape.
|
|
1244
1546
|
*/
|
|
1245
|
-
declare
|
|
1547
|
+
declare const DropdownMenuTrigger: react.ForwardRefExoticComponent<DropdownMenuTriggerProps & react.RefAttributes<HTMLButtonElement>>;
|
|
1246
1548
|
interface DropdownMenuContentProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
1247
1549
|
children: ReactNode;
|
|
1248
1550
|
/** Horizontal alignment relative to the trigger. Default `start`. */
|
|
1249
1551
|
align?: Align;
|
|
1250
1552
|
/** Pixel offset along the alignment axis. Default 0. */
|
|
1251
1553
|
alignOffset?: number;
|
|
1252
|
-
/**
|
|
1554
|
+
/**
|
|
1555
|
+
* Preferred side of the trigger. Default `bottom`. Flips to the opposite
|
|
1556
|
+
* side when it cannot fit (before the 2026-09-05 rebuild it was clamped
|
|
1557
|
+
* over its own trigger instead; only that no-room case differs).
|
|
1558
|
+
*/
|
|
1253
1559
|
side?: Side;
|
|
1254
1560
|
/** Pixel offset along the side axis. Default 6. */
|
|
1255
1561
|
sideOffset?: number;
|
|
1256
1562
|
}
|
|
1257
|
-
declare
|
|
1563
|
+
declare const DropdownMenuContent: react.ForwardRefExoticComponent<DropdownMenuContentProps & react.RefAttributes<HTMLDivElement>>;
|
|
1258
1564
|
interface DropdownMenuItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
1259
1565
|
variant?: 'default' | 'destructive';
|
|
1260
1566
|
/** Pad-left compensation so items with no leading icon align with
|
|
1261
1567
|
* items that have one. */
|
|
1262
1568
|
inset?: boolean;
|
|
1263
1569
|
}
|
|
1264
|
-
declare
|
|
1570
|
+
declare const DropdownMenuItem: react.ForwardRefExoticComponent<DropdownMenuItemProps & react.RefAttributes<HTMLButtonElement>>;
|
|
1265
1571
|
interface DropdownMenuCheckboxItemProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> {
|
|
1266
1572
|
checked?: boolean;
|
|
1267
1573
|
onCheckedChange?: (checked: boolean) => void;
|
|
1268
1574
|
}
|
|
1269
|
-
declare
|
|
1575
|
+
declare const DropdownMenuCheckboxItem: react.ForwardRefExoticComponent<DropdownMenuCheckboxItemProps & react.RefAttributes<HTMLButtonElement>>;
|
|
1270
1576
|
declare function DropdownMenuSeparator({ className, ...rest }: HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
1271
1577
|
interface DropdownMenuLabelProps extends HTMLAttributes<HTMLDivElement> {
|
|
1272
1578
|
inset?: boolean;
|
|
@@ -1441,6 +1747,347 @@ type DataGridDropIndicatorProps = {
|
|
|
1441
1747
|
};
|
|
1442
1748
|
declare function DataGridDropIndicator({ dropIndicatorLeft, dragTableRect, }: DataGridDropIndicatorProps): react_jsx_runtime.JSX.Element | null;
|
|
1443
1749
|
|
|
1750
|
+
/**
|
|
1751
|
+
* The popover surface chrome, shared with DropdownMenuContent so a menu and
|
|
1752
|
+
* a popover read as the same family. Inline rather than a stylesheet class
|
|
1753
|
+
* because the surface tokens are internal and the primitives already own
|
|
1754
|
+
* them here (Kbd, DropdownMenu follow the same pattern).
|
|
1755
|
+
*/
|
|
1756
|
+
declare const POPOVER_SURFACE_STYLE: CSSProperties;
|
|
1757
|
+
interface PopoverProps {
|
|
1758
|
+
/** Controlled open state. Omit for internal state. */
|
|
1759
|
+
open?: boolean;
|
|
1760
|
+
defaultOpen?: boolean;
|
|
1761
|
+
/** Fires whenever open transitions. */
|
|
1762
|
+
onOpenChange?: (open: boolean) => void;
|
|
1763
|
+
/**
|
|
1764
|
+
* Virtual anchor. When non-null, Content positions against this rect
|
|
1765
|
+
* instead of the Trigger — a right-click point, a caret, a cell.
|
|
1766
|
+
*/
|
|
1767
|
+
anchorRect?: AnchorRect | null;
|
|
1768
|
+
children: ReactNode;
|
|
1769
|
+
}
|
|
1770
|
+
declare function PopoverRoot({ open: controlledOpen, defaultOpen, onOpenChange, anchorRect, children, }: PopoverProps): react_jsx_runtime.JSX.Element;
|
|
1771
|
+
interface PopoverTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
1772
|
+
/**
|
|
1773
|
+
* Render the single child element as the trigger instead of a `<button>`.
|
|
1774
|
+
* The child receives the ref, click handler and ARIA attributes; the DOM
|
|
1775
|
+
* stays one element. It must be focusable and keyboard-operable on its
|
|
1776
|
+
* own (a `<button>`, an `<a href>`, or `role="button"` + `tabIndex={0}` +
|
|
1777
|
+
* Enter / Space handling): Trigger adds no role, tabIndex or key handler.
|
|
1778
|
+
*/
|
|
1779
|
+
asChild?: boolean;
|
|
1780
|
+
}
|
|
1781
|
+
interface PopoverContentProps extends Omit<HTMLAttributes<HTMLDivElement>, 'role' | 'children'> {
|
|
1782
|
+
children: ReactNode;
|
|
1783
|
+
/** Preferred side of the anchor. Default `bottom`. Flips when it cannot fit. */
|
|
1784
|
+
side?: AnchorSide;
|
|
1785
|
+
/** Alignment along the anchor's cross axis. Default `start`. */
|
|
1786
|
+
align?: AnchorAlign;
|
|
1787
|
+
/** Gap from the anchor, px. Default 6. */
|
|
1788
|
+
offset?: number;
|
|
1789
|
+
/** Shift along the alignment axis, px. Default 0. */
|
|
1790
|
+
alignOffset?: number;
|
|
1791
|
+
/** Default true. */
|
|
1792
|
+
flip?: boolean;
|
|
1793
|
+
/** Default true. */
|
|
1794
|
+
clampToViewport?: boolean;
|
|
1795
|
+
/**
|
|
1796
|
+
* `dialog` (default) — a named, non-modal dialog; give it `aria-label` or
|
|
1797
|
+
* `aria-labelledby`. `none` — no role attribute, for content that is
|
|
1798
|
+
* itself the widget.
|
|
1799
|
+
*/
|
|
1800
|
+
role?: 'dialog' | 'none';
|
|
1801
|
+
/** Skip the surface chrome (background / border / shadow / radius / padding). */
|
|
1802
|
+
unstyled?: boolean;
|
|
1803
|
+
}
|
|
1804
|
+
declare const Popover: typeof PopoverRoot & {
|
|
1805
|
+
Trigger: react.ForwardRefExoticComponent<PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
|
|
1806
|
+
Content: react.ForwardRefExoticComponent<PopoverContentProps & react.RefAttributes<HTMLDivElement>>;
|
|
1807
|
+
};
|
|
1808
|
+
|
|
1809
|
+
type SelectSize = 'sm' | 'md';
|
|
1810
|
+
interface SelectOption<T extends string = string> {
|
|
1811
|
+
value: T;
|
|
1812
|
+
label: string;
|
|
1813
|
+
/** Secondary line under the label. */
|
|
1814
|
+
description?: string;
|
|
1815
|
+
/** Leading adornment — a Lucide icon, an avatar, a colour dot. */
|
|
1816
|
+
icon?: ReactNode;
|
|
1817
|
+
/** Rendered but not selectable; skipped by the arrow keys and type-ahead. */
|
|
1818
|
+
disabled?: boolean;
|
|
1819
|
+
}
|
|
1820
|
+
interface SelectProps<T extends string = string> extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'defaultValue' | 'onChange' | 'role'> {
|
|
1821
|
+
options: ReadonlyArray<SelectOption<T>>;
|
|
1822
|
+
/** Controlled value; `null` = nothing selected. Omit for internal state. */
|
|
1823
|
+
value?: T | null;
|
|
1824
|
+
defaultValue?: T | null;
|
|
1825
|
+
/** Fires when the user picks a DIFFERENT option. */
|
|
1826
|
+
onValueChange?: (value: T) => void;
|
|
1827
|
+
/** Shown while nothing is selected. Default "Select…". */
|
|
1828
|
+
placeholder?: string;
|
|
1829
|
+
/** Control height — matches `<Input inputSize>`. Default `md`. */
|
|
1830
|
+
size?: SelectSize;
|
|
1831
|
+
/** Error chrome (`is-error`) + `aria-invalid` on the trigger. A caller's own `aria-invalid` wins. */
|
|
1832
|
+
error?: boolean;
|
|
1833
|
+
/** Controlled open state. Omit for internal state. */
|
|
1834
|
+
open?: boolean;
|
|
1835
|
+
defaultOpen?: boolean;
|
|
1836
|
+
onOpenChange?: (open: boolean) => void;
|
|
1837
|
+
/** Preferred side for the listbox. Default `bottom`; flips when it cannot fit. */
|
|
1838
|
+
side?: AnchorSide;
|
|
1839
|
+
/** Alignment along the trigger's edge. Default `start`. */
|
|
1840
|
+
align?: AnchorAlign;
|
|
1841
|
+
/** Extra classes on the listbox surface. */
|
|
1842
|
+
listboxClassName?: string;
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* The listbox popup chrome, shared with Combobox so the two lists read as
|
|
1846
|
+
* one family (Popover / DropdownMenu share `POPOVER_SURFACE_STYLE` the same
|
|
1847
|
+
* way).
|
|
1848
|
+
*/
|
|
1849
|
+
declare const LISTBOX_CLASS = "fixed z-[100] max-h-[min(60vh,20rem)] overflow-y-auto rounded-[var(--radius-lg)] p-1.5 outline-none";
|
|
1850
|
+
interface ListboxOptionProps {
|
|
1851
|
+
id: string;
|
|
1852
|
+
label: string;
|
|
1853
|
+
description?: string | undefined;
|
|
1854
|
+
icon?: ReactNode;
|
|
1855
|
+
/** Trailing count — tabular, muted. */
|
|
1856
|
+
count?: number | undefined;
|
|
1857
|
+
selected: boolean;
|
|
1858
|
+
highlighted: boolean;
|
|
1859
|
+
disabled?: boolean | undefined;
|
|
1860
|
+
onSelect: () => void;
|
|
1861
|
+
onHighlight: () => void;
|
|
1862
|
+
/** Replaces the default body (icon / label / description / count). The check mark stays. */
|
|
1863
|
+
children?: ReactNode;
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* One row of a listbox — used by Select and Combobox. A `<button>` rather
|
|
1867
|
+
* than a `<div role="option">` so it is clickable without a keyboard handler
|
|
1868
|
+
* of its own; `tabIndex={-1}` keeps it out of the tab order (the trigger /
|
|
1869
|
+
* input owns the keyboard, per `aria-activedescendant`). Disabled rows use
|
|
1870
|
+
* `aria-disabled`, NOT the `disabled` attribute: a disabled control swallows
|
|
1871
|
+
* the mousedown the listbox prevents to keep focus on the trigger / in the
|
|
1872
|
+
* input, so clicking one would blur the Combobox and close the list.
|
|
1873
|
+
*/
|
|
1874
|
+
declare function ListboxOption({ id, label, description, icon, count, selected, highlighted, disabled, onSelect, onHighlight, children, }: ListboxOptionProps): react_jsx_runtime.JSX.Element;
|
|
1875
|
+
/**
|
|
1876
|
+
* `forwardRef` erases the component's type parameter (it is instantiated at
|
|
1877
|
+
* `string` above). This assertion restores the generic signature so
|
|
1878
|
+
* `onValueChange` narrows to the union of the option values a caller
|
|
1879
|
+
* passed; it changes nothing at runtime.
|
|
1880
|
+
*/
|
|
1881
|
+
declare const Select: <T extends string = string>(props: SelectProps<T> & RefAttributes<HTMLButtonElement>) => ReactElement | null;
|
|
1882
|
+
|
|
1883
|
+
/**
|
|
1884
|
+
* Combobox — a text input that filters a listbox; single- or multi-select.
|
|
1885
|
+
*
|
|
1886
|
+
* WAI-ARIA APG "editable combobox with list autocomplete": the `<input>` is
|
|
1887
|
+
* `role="combobox"` with `aria-autocomplete="list"`, `aria-expanded`,
|
|
1888
|
+
* `aria-controls` and `aria-activedescendant`; the popup is `role="listbox"`
|
|
1889
|
+
* (`aria-multiselectable` in multi mode) of `role="option"` rows, optionally
|
|
1890
|
+
* inside `role="group"` sections with a heading. DOM focus never leaves the
|
|
1891
|
+
* input: a mousedown in the list is prevented, so clicking an option keeps
|
|
1892
|
+
* the caret where it was.
|
|
1893
|
+
*
|
|
1894
|
+
* Filtering is client-side by default (case-insensitive substring over label
|
|
1895
|
+
* and description) and starts only once the user TYPES — opening a
|
|
1896
|
+
* single-select that already holds a value shows the whole list, not the one
|
|
1897
|
+
* row matching the selected label. Async-friendly: pass `shouldFilter={false}`
|
|
1898
|
+
* to show `options` exactly as given, read the query through
|
|
1899
|
+
* `onInputValueChange`, fetch, and flip `loading` while you wait. The
|
|
1900
|
+
* component never fetches anything itself.
|
|
1901
|
+
*
|
|
1902
|
+
* Single mode: picking an option sets it and closes; the input shows the
|
|
1903
|
+
* selected label; the label text is selected on focus so typing replaces it;
|
|
1904
|
+
* leaving the field (blur / outside click) with the text deliberately emptied
|
|
1905
|
+
* clears the value (`onValueChange(null)`), while Escape closes and reverts.
|
|
1906
|
+
* Multi mode: selected options render as chips ahead of the input; picking
|
|
1907
|
+
* toggles and keeps the list open; Backspace on an empty input removes the
|
|
1908
|
+
* last chip. Keep the selected options present in `options` (a chip whose
|
|
1909
|
+
* option has scrolled out of an async result set falls back to its raw
|
|
1910
|
+
* value as the label).
|
|
1911
|
+
*
|
|
1912
|
+
* Keyboard: ArrowDown / ArrowUp open the list and move the highlight
|
|
1913
|
+
* (disabled options are skipped, no wrap), Enter picks the highlighted
|
|
1914
|
+
* option, Escape closes (through the shared layer stack — a Combobox in a
|
|
1915
|
+
* Popover in a Modal peels one layer per keypress), Tab and blur close.
|
|
1916
|
+
* Home / End are left to the caret.
|
|
1917
|
+
*
|
|
1918
|
+
* Promoted per ADR-0030 Decision G (meta-ads-audit-dashboard task manager:
|
|
1919
|
+
* the row / card / context-menu / palette pickers are all "popover + search +
|
|
1920
|
+
* live counts", which is exactly `count` on each option). Second consumer is
|
|
1921
|
+
* the workspace app: `lenses/sem-spec/components/location-autocomplete.tsx`
|
|
1922
|
+
* hand-rolls this role, and TagChipInput carries the chip model this one
|
|
1923
|
+
* generalises.
|
|
1924
|
+
*
|
|
1925
|
+
* Token discipline: the shell is `.input-shell` (INTERNAL `--bg-input` /
|
|
1926
|
+
* `--border-input`, owned by styles.css); the listbox shares
|
|
1927
|
+
* `LISTBOX_CLASS` + `POPOVER_SURFACE_STYLE` with Select; chips are public
|
|
1928
|
+
* `--surface-overlay` on `--foreground`; counts and group headings
|
|
1929
|
+
* `--text-muted`. Geometry from `useAnchoredPosition`, motion from
|
|
1930
|
+
* `.ds-enter-pop` gated on `positioned` (prefers-reduced-motion honoured in
|
|
1931
|
+
* styles.css).
|
|
1932
|
+
*
|
|
1933
|
+
* TODO(tokens): the type / size literals here (`text-[12px]` chips,
|
|
1934
|
+
* `max-w-[12rem]`, `text-[12.5px]` and `text-[11px] tracking-[0.4px]` in
|
|
1935
|
+
* the list, `minWidth: '6rem'`) mirror dropdown-menu.tsx and sit off the
|
|
1936
|
+
* spacing scale; snap them once a type-scale token exists (review
|
|
1937
|
+
* 2026-09-05, MINOR).
|
|
1938
|
+
*
|
|
1939
|
+
* Usage:
|
|
1940
|
+
*
|
|
1941
|
+
* <Combobox
|
|
1942
|
+
* aria-label="Assignee"
|
|
1943
|
+
* placeholder="Search people…"
|
|
1944
|
+
* options={people.map((p) => ({ value: p.id, label: p.name, count: p.openTasks }))}
|
|
1945
|
+
* value={assigneeId}
|
|
1946
|
+
* onValueChange={setAssigneeId}
|
|
1947
|
+
* />
|
|
1948
|
+
*
|
|
1949
|
+
* <Combobox
|
|
1950
|
+
* multiple
|
|
1951
|
+
* aria-label="Statuses"
|
|
1952
|
+
* groups={[{ id: 'open', label: 'Open' }, { id: 'closed', label: 'Closed' }]}
|
|
1953
|
+
* options={statuses} // each with `group: 'open' | 'closed'`
|
|
1954
|
+
* value={selected}
|
|
1955
|
+
* onValueChange={setSelected}
|
|
1956
|
+
* renderOption={(o, { selected }) => <StatusRow status={o} checked={selected} />}
|
|
1957
|
+
* />
|
|
1958
|
+
*
|
|
1959
|
+
* // Async: the consumer owns the query and the fetch.
|
|
1960
|
+
* <Combobox shouldFilter={false} loading={isFetching} options={results}
|
|
1961
|
+
* inputValue={query} onInputValueChange={setQuery} … />
|
|
1962
|
+
*/
|
|
1963
|
+
|
|
1964
|
+
type ComboboxSize = 'sm' | 'md';
|
|
1965
|
+
interface ComboboxOption<T extends string = string> {
|
|
1966
|
+
value: T;
|
|
1967
|
+
label: string;
|
|
1968
|
+
/** Secondary line under the label. Searched by the default filter. */
|
|
1969
|
+
description?: string;
|
|
1970
|
+
/** Leading adornment — a Lucide icon, an avatar, a colour dot. */
|
|
1971
|
+
icon?: ReactNode;
|
|
1972
|
+
/** Rendered but not selectable; skipped by the arrow keys. */
|
|
1973
|
+
disabled?: boolean;
|
|
1974
|
+
/** Live count at the row's trailing edge (tasks per status, per assignee). */
|
|
1975
|
+
count?: number;
|
|
1976
|
+
/** Key into `groups`. Ungrouped options render first. */
|
|
1977
|
+
group?: string;
|
|
1978
|
+
}
|
|
1979
|
+
interface ComboboxGroup {
|
|
1980
|
+
id: string;
|
|
1981
|
+
label: string;
|
|
1982
|
+
}
|
|
1983
|
+
interface ComboboxOptionState {
|
|
1984
|
+
selected: boolean;
|
|
1985
|
+
highlighted: boolean;
|
|
1986
|
+
/** The query the list is currently filtered by ('' when unfiltered). */
|
|
1987
|
+
query: string;
|
|
1988
|
+
}
|
|
1989
|
+
interface ComboboxBaseProps<T extends string> {
|
|
1990
|
+
options: ReadonlyArray<ComboboxOption<T>>;
|
|
1991
|
+
/**
|
|
1992
|
+
* Group order and labels. Options whose `group` is not listed here render
|
|
1993
|
+
* in a trailing group labelled by the key; omit `groups` entirely to
|
|
1994
|
+
* derive groups from the options in order of first appearance.
|
|
1995
|
+
*/
|
|
1996
|
+
groups?: ReadonlyArray<ComboboxGroup>;
|
|
1997
|
+
/** Shows a spinner in the shell and `loadingMessage` while the list is empty. */
|
|
1998
|
+
loading?: boolean;
|
|
1999
|
+
placeholder?: string;
|
|
2000
|
+
/** Control height — matches `<Input inputSize>`. Default `md`. */
|
|
2001
|
+
size?: ComboboxSize;
|
|
2002
|
+
disabled?: boolean;
|
|
2003
|
+
/** Error chrome (`is-error`) on the shell + `aria-invalid` on the input. */
|
|
2004
|
+
error?: boolean;
|
|
2005
|
+
/** Controlled query text. Omit for internal state. */
|
|
2006
|
+
inputValue?: string;
|
|
2007
|
+
defaultInputValue?: string;
|
|
2008
|
+
onInputValueChange?: (value: string) => void;
|
|
2009
|
+
/** Filter `options` by the query on the client. Default true; false for async. */
|
|
2010
|
+
shouldFilter?: boolean;
|
|
2011
|
+
/** Custom match. Default: case-insensitive substring over label + description. */
|
|
2012
|
+
filter?: (option: ComboboxOption<T>, query: string) => boolean;
|
|
2013
|
+
/** Default "No results". */
|
|
2014
|
+
emptyMessage?: ReactNode;
|
|
2015
|
+
/** Default "Loading…". */
|
|
2016
|
+
loadingMessage?: ReactNode;
|
|
2017
|
+
/** Replaces the default row body (icon / label / description / count). The check mark stays. */
|
|
2018
|
+
renderOption?: (option: ComboboxOption<T>, state: ComboboxOptionState) => ReactNode;
|
|
2019
|
+
/** Controlled open state. Omit for internal state. */
|
|
2020
|
+
open?: boolean;
|
|
2021
|
+
onOpenChange?: (open: boolean) => void;
|
|
2022
|
+
/** Preferred side for the listbox. Default `bottom`; flips when it cannot fit. */
|
|
2023
|
+
side?: AnchorSide;
|
|
2024
|
+
/** Default `start`. */
|
|
2025
|
+
align?: AnchorAlign;
|
|
2026
|
+
/** id of the `<input>`, for `<label htmlFor>`. */
|
|
2027
|
+
id?: string;
|
|
2028
|
+
/**
|
|
2029
|
+
* Focus the input on mount. Also marks it `data-autofocus`: inside a
|
|
2030
|
+
* Popover the popover does the focusing, once its content is positioned.
|
|
2031
|
+
*/
|
|
2032
|
+
autoFocus?: boolean;
|
|
2033
|
+
'aria-label'?: string;
|
|
2034
|
+
'aria-labelledby'?: string;
|
|
2035
|
+
/** Extra classes on the `.input-shell`. */
|
|
2036
|
+
className?: string;
|
|
2037
|
+
/** Extra classes on the listbox surface. */
|
|
2038
|
+
listboxClassName?: string;
|
|
2039
|
+
}
|
|
2040
|
+
interface ComboboxSingleProps<T extends string = string> extends ComboboxBaseProps<T> {
|
|
2041
|
+
multiple?: false;
|
|
2042
|
+
/** Controlled value; `null` = nothing selected. */
|
|
2043
|
+
value?: T | null;
|
|
2044
|
+
defaultValue?: T | null;
|
|
2045
|
+
/** `null` when the user empties the field and leaves it. */
|
|
2046
|
+
onValueChange?: (value: T | null) => void;
|
|
2047
|
+
}
|
|
2048
|
+
interface ComboboxMultipleProps<T extends string = string> extends ComboboxBaseProps<T> {
|
|
2049
|
+
multiple: true;
|
|
2050
|
+
value?: ReadonlyArray<T>;
|
|
2051
|
+
defaultValue?: ReadonlyArray<T>;
|
|
2052
|
+
onValueChange?: (value: T[]) => void;
|
|
2053
|
+
}
|
|
2054
|
+
type ComboboxProps<T extends string = string> = ComboboxSingleProps<T> | ComboboxMultipleProps<T>;
|
|
2055
|
+
/**
|
|
2056
|
+
* `forwardRef` erases the component's type parameter (it is instantiated at
|
|
2057
|
+
* `string` above). This assertion restores the generic signature so
|
|
2058
|
+
* `onValueChange` narrows to the union of the option values a caller
|
|
2059
|
+
* passed; it changes nothing at runtime.
|
|
2060
|
+
*/
|
|
2061
|
+
declare const Combobox: <T extends string = string>(props: ComboboxProps<T> & RefAttributes<HTMLInputElement>) => ReactElement | null;
|
|
2062
|
+
|
|
2063
|
+
interface TooltipProps {
|
|
2064
|
+
/** The tip's content. Nothing renders (children pass through untouched) when null. */
|
|
2065
|
+
content: ReactNode;
|
|
2066
|
+
/** Exactly one element — it becomes the trigger. */
|
|
2067
|
+
children: ReactElement<TooltipTriggerProps>;
|
|
2068
|
+
/** Default `top`. Flips when it cannot fit. */
|
|
2069
|
+
side?: AnchorSide;
|
|
2070
|
+
/** Default `center`. */
|
|
2071
|
+
align?: AnchorAlign;
|
|
2072
|
+
/** Gap from the trigger, px. Default 6. */
|
|
2073
|
+
offset?: number;
|
|
2074
|
+
/** Hover-open delay, ms. Default 300. Focus opens immediately. */
|
|
2075
|
+
openDelay?: number;
|
|
2076
|
+
/** Close delay, ms. Default 0. */
|
|
2077
|
+
closeDelay?: number;
|
|
2078
|
+
/** Controlled open state. Omit for internal state. */
|
|
2079
|
+
open?: boolean;
|
|
2080
|
+
defaultOpen?: boolean;
|
|
2081
|
+
onOpenChange?: (open: boolean) => void;
|
|
2082
|
+
/** Extra classes on the tip surface. */
|
|
2083
|
+
className?: string;
|
|
2084
|
+
}
|
|
2085
|
+
/** What the cloned trigger element must accept. */
|
|
2086
|
+
type TooltipTriggerProps = HTMLAttributes<HTMLElement> & {
|
|
2087
|
+
ref?: Ref<HTMLElement>;
|
|
2088
|
+
};
|
|
2089
|
+
declare function Tooltip({ content, children, side, align, offset, openDelay, closeDelay, open: openProp, defaultOpen, onOpenChange, className, }: TooltipProps): react_jsx_runtime.JSX.Element;
|
|
2090
|
+
|
|
1444
2091
|
interface DropdownButtonItem {
|
|
1445
2092
|
/** Stable id for keying. If omitted, the index is used (avoid for
|
|
1446
2093
|
* long lists where order can change). */
|
|
@@ -2236,8 +2883,8 @@ interface CalculatorShellV2Props {
|
|
|
2236
2883
|
copyReport?: string | (() => string);
|
|
2237
2884
|
/** STUBBED (D9) — typed, not read this ADR. */
|
|
2238
2885
|
prefill?: CalcPrefill;
|
|
2239
|
-
/** "vs. benchmark" rail.
|
|
2240
|
-
*
|
|
2886
|
+
/** "vs. benchmark" rail. Rendered only when provided (the Amendment 1 E
|
|
2887
|
+
* placeholder is retired — ADR-145 amendment). */
|
|
2241
2888
|
benchmarkSlot?: ReactNode;
|
|
2242
2889
|
}
|
|
2243
2890
|
declare function CalculatorShellV2({ eyebrow, title, icon, layout, inputs, result, footerNote, actions, assumptions, copyReport, benchmarkSlot, }: CalculatorShellV2Props): react_jsx_runtime.JSX.Element;
|
|
@@ -2252,12 +2899,18 @@ interface StatRowStep {
|
|
|
2252
2899
|
/** The single pivotal tile — rendered in `--accent` instead of
|
|
2253
2900
|
* `--brand-ink`. At most one step should set this. */
|
|
2254
2901
|
pivotal?: boolean;
|
|
2902
|
+
/** What a copyable tile writes to the clipboard. Defaults to `value`;
|
|
2903
|
+
* set it when the display is rounded (e.g. "833.3K") and the exact
|
|
2904
|
+
* figure is what the user wants. */
|
|
2905
|
+
copyValue?: string;
|
|
2255
2906
|
}
|
|
2256
2907
|
interface StatRowProps {
|
|
2257
2908
|
steps: StatRowStep[];
|
|
2909
|
+
/** Make every tile's figure a copy-to-clipboard button. */
|
|
2910
|
+
copyable?: boolean;
|
|
2258
2911
|
className?: string;
|
|
2259
2912
|
}
|
|
2260
|
-
declare function StatRow({ steps, className }: StatRowProps): react_jsx_runtime.JSX.Element;
|
|
2913
|
+
declare function StatRow({ steps, copyable, className }: StatRowProps): react_jsx_runtime.JSX.Element;
|
|
2261
2914
|
|
|
2262
2915
|
/**
|
|
2263
2916
|
* Slider — single-value numeric slider (ADR-076 D8).
|
|
@@ -2691,4 +3344,4 @@ declare namespace index {
|
|
|
2691
3344
|
export { type index_CarouselCardView as CarouselCardView, type index_CarouselViewProps as CarouselViewProps, index_CreativeMedia as CreativeMedia, index_InstagramExplorePreview as InstagramExplorePreview, index_InstagramFeedCarousel as InstagramFeedCarousel, index_InstagramFeedPreview as InstagramFeedPreview, index_MetaFeedCarousel as MetaFeedCarousel, index_MetaFeedPreview as MetaFeedPreview, index_MetaInstreamPreview as MetaInstreamPreview, index_MetaMessengerPreview as MetaMessengerPreview, index_MetaReelPreview as MetaReelPreview, index_MetaRightColumnPreview as MetaRightColumnPreview, index_MetaSearchPreview as MetaSearchPreview, index_MetaStoryPreview as MetaStoryPreview, index_PLACEMENT_CONFIGS as PLACEMENT_CONFIGS, type index_PlacementPreview as PlacementPreview, type index_PreviewAdData as PreviewAdData, type index_PreviewConfiguration as PreviewConfiguration, type index_PreviewDevice as PreviewDevice, type index_PreviewPlacement as PreviewPlacement, type index_PreviewPlatform as PreviewPlatform };
|
|
2692
3345
|
}
|
|
2693
3346
|
|
|
2694
|
-
export { AccordionCompound as Accordion, type AccordionProps, type AccordionSectionProps, AllocationSparkbar, type AllocationSparkbarProps, AppScroll, BRAND_ICONS, Badge, type BadgeProps, type BadgeTone, BrandFacebook, BrandIcon, type BrandIconKey, type BrandIconProps, BrandInstagram, BrandLinkedIn, BrandLogoTile, type BrandLogoTileProps, type BrandLogoTileSize, BrandMessenger, BrandMeta, BrandNextdoor, BrandPinterest, BrandSnapchat, BrandTikTok, BulkActionBar, type BulkActionBarProps, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type ButtonShape, type ButtonSize, type ButtonVariant, type CalcLayout, type CalcPrefill, CalculatorShell, type CalculatorShellProps, CalculatorShellV2, type CalculatorShellV2Props, Card, Checkbox, type CheckboxProps, ChipNav, type ChipNavItem, Choropleth, type ChoroplethProps, CodeBlock, type CodeBlockProps, CollapsibleCard, type CollapsibleCardProps, CompletionRing, type CompletionRingProps, CopyField, type CopyFieldProps, type Crumb, DataGrid, type DataGridColumn, DataGridColumnOptionsMenu, DataGridDragOverlay, type DataGridDrawerPanelProps, DataGridDropIndicator, type DataGridIcon, type DataGridProps, type DataGridRowBase, type DataGridSortState, DataGridToolbar, type DataGridToolbarProps, type DataGridToolbarRenderProps, DetailSection, DeviceFrame, type DeviceFrameProps, DragHandle, DropdownButton, type DropdownButtonItem, type DropdownButtonProps, DropdownMenu, DropdownMenuCheckboxItem, type DropdownMenuCheckboxItemProps, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, type DropdownMenuLabelProps, type DropdownMenuProps, DropdownMenuSeparator, DropdownMenuTrigger, type DropdownMenuTriggerProps, type EditingCell, EmptyPlaceholder, EmptyState, type EmptyStateProps, FOLDER_COLOR_KEYS, FileDropZone, FilePreviewGrid, FilePreviewItem, FileThumbnail, FileUploadButton, FilterBar, type FilterBarCountProps, type FilterBarProps, type FilterBarSearchProps, FilterDropdown, type FilterDropdownProps, type FilterOption, FloatingDrawer, type FloatingDrawerProps, FloatingStatusBar, type FloatingStatusBarProps, type FloatingStatusTone, FolderCard, type FolderCardProps, type FolderColorKey, type FolderTreeNode, FolderTreePicker, type FolderTreePickerProps, FrameStack, type FrameStackProps, HEADER_HEIGHT, HeroFormCardCompound as HeroFormCard, type HeroFormCardAdvancedProps, type HeroFormCardBannerProps, type HeroFormCardFieldProps, type HeroFormCardProps, type HeroFormCardSectionProps, type HomeCrumb, HomeCrumbLink, IconTile, IdentityLabel, IdentityValue, Input, type InputProps, type InputSize, Kbd, type KbdProps, ListItem, MarkdownCode, MarkdownRenderer, type MarkdownRendererProps, MenuButton, type MenuButtonEntry, type MenuButtonItem, type MenuButtonProps, type MenuButtonSeparator, MetaCell, type MetaCellProps, index as MetaPreviews, MetricCard, type MetricCardProps, type MetricCardTone, MicrosoftLogo, type MicrosoftLogoProps, Modal, OptionTile, OptionTileGroup, type OptionTileGroupProps, type OptionTileProps, PLACEMENT_CONFIGS, PageHeaderHost, PageHeaderSlotProvider, PageHero, type PageHeroProps, PageShell, Pagination, type PaginationProps, type PendingFile, PillButton, type PillButtonProps, type PlacementPreview, type PreviewAdData, type PreviewConfiguration, type PreviewDevice, type PreviewPlacement, type PreviewPlatform, PS as ProfileSection, type ProfileSectionProps, ProgressBar, type ProgressBarProps, Radio, RadioGroup, type RadioGroupProps, type RadioProps, RangeSlider, type RangeSliderProps, ResizableHandle, type ResizableHandleProps, ResizablePane, type ResizablePaneProps, type RgbTuple, SECTION_SCROLL_OFFSET, SearchBar, type SearchBarProps, SectionLabel, SegmentedPill, type SegmentedPillItem, type SegmentedPillProps, Shell, type ShellProps, ShellStat, type ShellStatProps, type ShellStatTone, type ShellSubCardProps, type ShellTrayBodyProps, type ShellTrayFooterProps, type ShellTrayHeaderProps, type ShellTrayProps, Slider, type SliderProps, SortableItem, SortableList, SortableTable, type Column as SortableTableColumn, type SortableTableProps, StatRow, type StatRowProps, type StatRowStep, StatsGrid, type StatsGridProps, StepLoader, type StepLoaderProps, type StepLoaderStep, type Tab, Tabs, type TabsProps, TagChipInput, type TagChipInputProps, TagRow, TextInput, Textarea, TextareaInput, type TextareaProps, Toaster, TokenBadge, type TokenBadgeProps, type UploadResult, type UseFileUploadOptions, ValueChip, type ValueChipProps, type WcagBadge, bestTextOn, cn, contrastRatio, copyText, folderColorVar, formatCurrency, formatNumber, formatPercent, formatRatio, hasBrandIcon, hexToRgbTuple, hslString, relativeLuminance, rgbCss, rgbString, useBreadcrumbHome, useFileUpload, wcagBadges };
|
|
3347
|
+
export { AccordionCompound as Accordion, type AccordionProps, type AccordionSectionProps, AllocationSparkbar, type AllocationSparkbarProps, type AnchorAlign, type AnchorPlacement, type AnchorRect, type AnchorSide, type AnchorSize, type AnchoredPosition, type AnchoredPositionOptions, AppScroll, BRAND_ICONS, Badge, type BadgeProps, type BadgeTone, BrandFacebook, BrandIcon, type BrandIconKey, type BrandIconProps, BrandInstagram, BrandLinkedIn, BrandLogoTile, type BrandLogoTileProps, type BrandLogoTileSize, BrandMessenger, BrandMeta, BrandNextdoor, BrandPinterest, BrandSnapchat, BrandTikTok, BulkActionBar, type BulkActionBarProps, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type ButtonShape, type ButtonSize, type ButtonVariant, type CalcLayout, type CalcPrefill, CalculatorShell, type CalculatorShellProps, CalculatorShellV2, type CalculatorShellV2Props, Card, Checkbox, type CheckboxProps, ChipNav, type ChipNavItem, Choropleth, type ChoroplethProps, CodeBlock, type CodeBlockProps, CollapsibleCard, type CollapsibleCardProps, Combobox, type ComboboxGroup, type ComboboxMultipleProps, type ComboboxOption, type ComboboxOptionState, type ComboboxProps, type ComboboxSingleProps, type ComboboxSize, CompletionRing, type CompletionRingProps, CopyField, type CopyFieldProps, type Crumb, DataGrid, type DataGridColumn, DataGridColumnOptionsMenu, DataGridDragOverlay, type DataGridDrawerPanelProps, DataGridDropIndicator, type DataGridIcon, type DataGridProps, type DataGridRowBase, type DataGridSortState, DataGridToolbar, type DataGridToolbarProps, type DataGridToolbarRenderProps, DetailSection, DeviceFrame, type DeviceFrameProps, DragHandle, DropdownButton, type DropdownButtonItem, type DropdownButtonProps, DropdownMenu, DropdownMenuCheckboxItem, type DropdownMenuCheckboxItemProps, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, type DropdownMenuLabelProps, type DropdownMenuProps, DropdownMenuSeparator, DropdownMenuTrigger, type DropdownMenuTriggerProps, type EditingCell, EmptyPlaceholder, EmptyState, type EmptyStateProps, FOLDER_COLOR_KEYS, FileDropZone, FilePreviewGrid, FilePreviewItem, FileThumbnail, FileUploadButton, FilterBar, type FilterBarCountProps, type FilterBarProps, type FilterBarSearchProps, FilterDropdown, type FilterDropdownProps, type FilterOption, FloatingDrawer, type FloatingDrawerProps, FloatingStatusBar, type FloatingStatusBarProps, type FloatingStatusTone, FolderCard, type FolderCardProps, type FolderColorKey, type FolderTreeNode, FolderTreePicker, type FolderTreePickerProps, FrameStack, type FrameStackProps, HEADER_HEIGHT, HeroFormCardCompound as HeroFormCard, type HeroFormCardAdvancedProps, type HeroFormCardBannerProps, type HeroFormCardFieldProps, type HeroFormCardProps, type HeroFormCardSectionProps, type HomeCrumb, HomeCrumbLink, IconTile, IdentityLabel, IdentityValue, Input, type InputProps, type InputSize, Kbd, type KbdProps, LISTBOX_CLASS, type LayerHandle, type LayerKind, ListItem, ListboxOption, type ListboxOptionProps, MarkdownCode, MarkdownRenderer, type MarkdownRendererProps, MenuButton, type MenuButtonEntry, type MenuButtonItem, type MenuButtonProps, type MenuButtonSeparator, MetaCell, type MetaCellProps, index as MetaPreviews, MetricCard, type MetricCardProps, type MetricCardTone, MicrosoftLogo, type MicrosoftLogoProps, Modal, OptionTile, OptionTileGroup, type OptionTileGroupProps, type OptionTileProps, type OutsideClickTarget, PLACEMENT_CONFIGS, POPOVER_SURFACE_STYLE, PageHeaderHost, PageHeaderSlotProvider, PageHero, type PageHeroProps, PageShell, Pagination, type PaginationProps, type PendingFile, PillButton, type PillButtonProps, type PlacementPreview, Popover, type PopoverContentProps, type PopoverProps, type PopoverTriggerProps, type PreviewAdData, type PreviewConfiguration, type PreviewDevice, type PreviewPlacement, type PreviewPlatform, PS as ProfileSection, type ProfileSectionProps, ProgressBar, type ProgressBarProps, Radio, RadioGroup, type RadioGroupProps, type RadioProps, RangeSlider, type RangeSliderProps, ResizableHandle, type ResizableHandleProps, ResizablePane, type ResizablePaneProps, type RgbTuple, SECTION_SCROLL_OFFSET, SearchBar, type SearchBarProps, SectionLabel, SegmentedPill, type SegmentedPillItem, type SegmentedPillProps, Select, type SelectOption, type SelectProps, type SelectSize, Shell, type ShellProps, ShellStat, type ShellStatProps, type ShellStatTone, type ShellSubCardProps, type ShellTrayBodyProps, type ShellTrayFooterProps, type ShellTrayHeaderProps, type ShellTrayProps, Slider, type SliderProps, SortableItem, SortableList, SortableTable, type Column as SortableTableColumn, type SortableTableProps, StatRow, type StatRowProps, type StatRowStep, StatsGrid, type StatsGridProps, StepLoader, type StepLoaderProps, type StepLoaderStep, type Tab, Tabs, type TabsProps, TagChipInput, type TagChipInputProps, TagRow, TextInput, Textarea, TextareaInput, type TextareaProps, Toaster, TokenBadge, type TokenBadgeProps, Tooltip, type TooltipProps, type TooltipTriggerProps, type UploadResult, type UseAnchoredPositionOptions, type UseAnchoredPositionResult, type UseEscapeKeyOptions, type UseFileUploadOptions, type UseLayerOptions, type UseOutsideClickOptions, ValueChip, type ValueChipProps, type WcagBadge, bestTextOn, cn, computeAnchoredPosition, contrastRatio, copyText, folderColorVar, formatCurrency, formatNumber, formatPercent, formatRatio, hasBrandIcon, hexToRgbTuple, hslString, relativeLuminance, rgbCss, rgbString, useAnchoredPosition, useBreadcrumbHome, useEscapeKey, useFileUpload, useLayer, useOutsideClick, wcagBadges };
|