gridsmith-ui 0.6.7 → 0.8.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
@@ -105,8 +105,10 @@ interface DropdownProps {
105
105
  error?: boolean;
106
106
  /** When multiple, show removable chips below the trigger. Defaults to true. Set false in toolbar contexts where chips are shown elsewhere. */
107
107
  showChips?: boolean;
108
+ /** Accessible name for the trigger, for when there is no visible `label` (e.g. in a toolbar). */
109
+ "aria-label"?: string;
108
110
  }
109
- declare function Dropdown({ options, value, onChange, label, disabled, placeholder, multiple, searchable, size, className, ref, container, error, showChips, }: DropdownProps): react_jsx_runtime.JSX.Element;
111
+ declare function Dropdown({ options, value, onChange, label, disabled, placeholder, multiple, searchable, size, className, ref, container, error, showChips, "aria-label": ariaLabel, }: DropdownProps): react_jsx_runtime.JSX.Element;
110
112
 
111
113
  interface ComboboxOption {
112
114
  value: string;
@@ -409,14 +411,33 @@ interface FormContextValue {
409
411
  submitted: boolean;
410
412
  }
411
413
  declare function useFormContext(): FormContextValue;
414
+ /** An invalid field as the form finds it in its own DOM after a submit. */
415
+ interface FormFieldError {
416
+ id: string;
417
+ label: string;
418
+ message: string;
419
+ }
412
420
  interface FormWrapperProps {
413
421
  onSubmit: (errors: FormErrors) => void;
414
422
  validationMode?: ValidationMode;
415
423
  children: ReactNode;
424
+ /**
425
+ * The buttons row (submit, cancel) with a clear gap above the last field — never a hand-rolled flex row under it
426
+ * (bench round 3, R12). Right-aligned like CardFooter and the overlay footers; `actionsAlign="start"` for a narrow form.
427
+ */
428
+ actions?: ReactNode;
429
+ actionsAlign?: "start" | "end";
430
+ /** After a failed submit, scroll to and focus the first invalid field (default on). */
431
+ focusFirstError?: boolean;
432
+ /**
433
+ * When two or more fields are invalid after a submit, an error summary above the form links to each (default on).
434
+ * A function renders your own from the list.
435
+ */
436
+ errorSummary?: boolean | ((errors: FormFieldError[]) => ReactNode);
416
437
  className?: string;
417
438
  ref?: React.Ref<HTMLFormElement>;
418
439
  }
419
- declare function FormWrapper({ onSubmit, validationMode, children, className, ref }: FormWrapperProps): react_jsx_runtime.JSX.Element;
440
+ declare function FormWrapper({ onSubmit, validationMode, children, actions, actionsAlign, focusFirstError, errorSummary, className, ref }: FormWrapperProps): react_jsx_runtime.JSX.Element;
420
441
 
421
442
  interface TransferItem {
422
443
  id: string;
@@ -474,7 +495,11 @@ interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {
474
495
  menuItems?: DropdownMenuEntry[];
475
496
  }
476
497
  declare const CardHeader: react.ForwardRefExoticComponent<CardHeaderProps & react.RefAttributes<HTMLDivElement>>;
477
- declare const CardTitle: react.ForwardRefExoticComponent<HTMLAttributes<HTMLHeadingElement> & react.RefAttributes<HTMLHeadingElement>>;
498
+ interface CardTitleProps extends HTMLAttributes<HTMLHeadingElement> {
499
+ /** Max lines before clamping (with the full title on hover). Default 2, like CardDescription; 1 truncates on one line; 0 = no limit. */
500
+ lines?: number;
501
+ }
502
+ declare const CardTitle: react.ForwardRefExoticComponent<CardTitleProps & react.RefAttributes<HTMLHeadingElement>>;
478
503
  interface CardDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {
479
504
  /** Max lines before clamping. Default 2. Set to 0 for no limit. */
480
505
  lines?: number;
@@ -486,6 +511,8 @@ declare const CardFooter: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDiv
486
511
  interface Trend {
487
512
  direction: "up" | "down" | "flat";
488
513
  value: string;
514
+ /** Whether the change is good news. Default: up = positive, down = negative, flat = neutral. Pass "positive" for a falling cost or overdue count, "negative" for rising churn or errors. */
515
+ sentiment?: "positive" | "negative" | "neutral";
489
516
  }
490
517
  interface StatsCardProps {
491
518
  value: string | number;
@@ -526,7 +553,8 @@ interface DescriptionListProps {
526
553
  columns?: 1 | 2 | 3 | 4;
527
554
  size?: DescriptionListSize;
528
555
  dividers?: boolean;
529
- stackBelow?: "sm" | "md" | "lg";
556
+ /** Below this breakpoint a multi-column list becomes one column. Default "sm" when columns > 1 (a phone never shows two columns of pairs); "none" keeps the columns at every width. */
557
+ stackBelow?: "sm" | "md" | "lg" | "none";
530
558
  className?: string;
531
559
  }
532
560
  declare const DescriptionList: react.ForwardRefExoticComponent<DescriptionListProps & react.RefAttributes<HTMLDListElement>>;
@@ -709,7 +737,15 @@ interface AvatarGroupProps {
709
737
  declare function AvatarGroup({ items, max, size, ring, onOverflowClick, className }: AvatarGroupProps): react_jsx_runtime.JSX.Element;
710
738
 
711
739
  interface EmptyStateProps {
712
- icon?: ReactNode;
740
+ /**
741
+ * An icon name from the theme's pack ("inbox", "filter") or an element. A
742
+ * name is the easy path: the state renders it at the frame's size. An `Icon`
743
+ * element is resized to match; any other element is rendered as given. A
744
+ * string that is not an icon name is a type error, not a printed word.
745
+ * (The Sprint 22 bench saw builders pass names into a ReactNode prop and
746
+ * React print the word — 14 Sep 2026.)
747
+ */
748
+ icon?: IconName | Exclude<ReactNode, string>;
713
749
  /** How the icon is framed: the neutral circle (default), or none when the icon element brings its own frame. */
714
750
  iconFrame?: "circle" | "none";
715
751
  title: string;
@@ -726,6 +762,73 @@ interface EmptyStateProps {
726
762
  }
727
763
  declare function EmptyState({ icon, iconFrame, title, description, action, variant, bordered, className }: EmptyStateProps): react_jsx_runtime.JSX.Element;
728
764
 
765
+ interface SkipLinkProps {
766
+ /** The id of the main region (AppShell names its <main> "main"). */
767
+ href?: string;
768
+ children?: string;
769
+ className?: string;
770
+ }
771
+ /**
772
+ * The first focusable element on a page with repeated navigation: invisible
773
+ * until it receives keyboard focus, then a small floating button that jumps
774
+ * past the sidebar and navbar to the main content (WCAG 2.4.1). AppShell
775
+ * renders one by default; a page outside AppShell composes it first.
776
+ */
777
+ declare function SkipLink({ href, children, className }: SkipLinkProps): react_jsx_runtime.JSX.Element;
778
+
779
+ interface TableToolbarFilterOption {
780
+ value: string;
781
+ label: string;
782
+ }
783
+ interface TableToolbarActiveFilter {
784
+ id: string;
785
+ label: string;
786
+ onRemove: () => void;
787
+ }
788
+ interface TableToolbarProps {
789
+ /** The search box. `label` is its accessible name and the default placeholder. */
790
+ search?: {
791
+ value: string;
792
+ onChange: (value: string) => void;
793
+ label: string;
794
+ placeholder?: string;
795
+ };
796
+ /** The one filter worth showing inline: a SegmentedControl, or a Dropdown when the toolbar is narrow. */
797
+ primaryFilter?: {
798
+ label: string;
799
+ options: TableToolbarFilterOption[];
800
+ value: string;
801
+ onChange: (value: string) => void;
802
+ };
803
+ /** Further filters, one click away behind the Filters button. */
804
+ filters?: ReactNode;
805
+ filtersOpen?: boolean;
806
+ onFiltersOpenChange?: (open: boolean) => void;
807
+ /** Shown on the Filters button while the row is collapsed. */
808
+ activeFilterCount?: number;
809
+ /** Chips for the filters in force, each removable. */
810
+ activeFilters?: TableToolbarActiveFilter[];
811
+ onClearAll?: () => void;
812
+ /** How many rows match; shown with `resultNoun`. */
813
+ resultCount?: number;
814
+ resultNoun?: [singular: string, plural: string];
815
+ /** Utility actions on the right — an overflow DropdownMenu, an export button. Primary actions belong in the PageHeader. */
816
+ actions?: ReactNode;
817
+ size?: "sm" | "md";
818
+ /** Container width below which the primary filter becomes a Dropdown. */
819
+ compactBreakpoint?: number;
820
+ className?: string;
821
+ }
822
+ /**
823
+ * The toolbar above a table or list: search, one inline filter, further
824
+ * filters behind a Filters button, the result count with removable chips for
825
+ * the filters in force, and utility actions on the right. The corpus's
826
+ * progressive-disclosure toolbar (search#1, search#3, search#12) as one
827
+ * component, so a page never hand-rolls the row. Primary actions belong in
828
+ * the PageHeader, not here.
829
+ */
830
+ declare function TableToolbar({ search, primaryFilter, filters, filtersOpen, onFiltersOpenChange, activeFilterCount, activeFilters, onClearAll, resultCount, resultNoun, actions, size, compactBreakpoint, className, }: TableToolbarProps): react_jsx_runtime.JSX.Element;
831
+
729
832
  interface TimelineItem {
730
833
  title: string;
731
834
  description?: string;
@@ -735,19 +838,24 @@ interface TimelineItem {
735
838
  }
736
839
  interface TimelineProps {
737
840
  items: TimelineItem[];
841
+ /** "responsive" lays the items out horizontally only when they fit at minItemWidth each, else vertically. */
738
842
  orientation?: "vertical" | "horizontal" | "responsive";
843
+ /** The least width a horizontal item gets before the row scrolls (a structural size, not a design value). */
844
+ minItemWidth?: number;
739
845
  className?: string;
740
846
  ref?: Ref<HTMLDivElement>;
741
847
  }
742
- declare function Timeline({ items, orientation, className, ref }: TimelineProps): react_jsx_runtime.JSX.Element;
848
+ declare function Timeline({ items, orientation, minItemWidth, className, ref }: TimelineProps): react_jsx_runtime.JSX.Element;
743
849
 
744
850
  interface CodeBlockProps {
745
851
  code: string;
746
852
  language?: string;
747
853
  showLineNumbers?: boolean;
854
+ /** Wrap long lines instead of scrolling sideways. Default: on for a single-line snippet (a tracking tag, a command), off for multi-line code. */
855
+ wrap?: boolean;
748
856
  className?: string;
749
857
  }
750
- declare function CodeBlock({ code, language, showLineNumbers, className, }: CodeBlockProps): react_jsx_runtime.JSX.Element;
858
+ declare function CodeBlock({ code, language, showLineNumbers, wrap, className, }: CodeBlockProps): react_jsx_runtime.JSX.Element;
751
859
 
752
860
  interface CollapsibleProps {
753
861
  open?: boolean;
@@ -1011,7 +1119,7 @@ interface AsidePanelProps {
1011
1119
  * returns to the opener, an outside click does nothing, drafts survive closing.
1012
1120
  * Below `collapseBelow` it becomes the overlay Drawer; on phones the Sheet.
1013
1121
  */
1014
- declare function AsidePanel({ open, onClose, side, width, position, navbarFloating, sidebarFloating, collapseBelow, keepMounted, resizable, maxWidth, labelledBy, id, children, className, }: AsidePanelProps): react_jsx_runtime.JSX.Element;
1122
+ declare function AsidePanel({ open, onClose, side, width, position, navbarFloating: navbarFloatingProp, sidebarFloating: sidebarFloatingProp, collapseBelow, keepMounted, resizable, maxWidth, labelledBy, id, children, className, }: AsidePanelProps): react_jsx_runtime.JSX.Element;
1015
1123
 
1016
1124
  interface StackedListItem {
1017
1125
  id: string | number;
@@ -1038,6 +1146,8 @@ interface StackedListProps {
1038
1146
  flush?: boolean;
1039
1147
  /** The current row in a master-detail list. Its treatment follows the theme's in-page vertical active style (rail, tint or pill), like Tabs. */
1040
1148
  selectedId?: string | number;
1149
+ /** How an interactive row answers the pointer: "tint" (default) shades the row; "title" colours the title, for article lists (a knowledge base, a changelog). */
1150
+ hover?: "tint" | "title";
1041
1151
  className?: string;
1042
1152
  }
1043
1153
  declare const StackedList: react.ForwardRefExoticComponent<StackedListProps & react.RefAttributes<HTMLUListElement>>;
@@ -1176,6 +1286,137 @@ declare const Tabs: typeof TabsRoot & {
1176
1286
  Content: typeof TabsContent;
1177
1287
  };
1178
1288
 
1289
+ /**
1290
+ * The theme's shell-level decisions, carried once by AppShell so that
1291
+ * PageHeader and PageContainer can render a page the way the builder preview
1292
+ * renders it without the page passing a single flag (Sprint 25, 14 Sep 2026).
1293
+ *
1294
+ * The generated shell passes the object the template emits; the builder
1295
+ * preview passes the same values from the theme state. Every field is
1296
+ * optional: a page's own props always win over the theme, and a header
1297
+ * outside any shell falls back to the component defaults it always had.
1298
+ */
1299
+ type ChromePosition = "flush" | "floating";
1300
+ type ThemePageHeaderVariant = "default" | "colourful" | "minimal" | "tabs-integrated";
1301
+ type ThemePageHeaderBehavior = "static" | "snapping";
1302
+ type ThemePageHeaderIntensity = "subtle" | "bold";
1303
+ type ThemeBreadcrumbPosition = "inline" | "contained";
1304
+ type ThemeBreadcrumbStyle = "default" | "pill";
1305
+ type ThemeBreadcrumbSeparator = "chevron" | "slash" | "dot" | "arrow";
1306
+ type ThemeSettingsLayout = "sidebar" | "tabs";
1307
+ interface AppShellTheme {
1308
+ /** Where the navbar sits; a floating navbar's gutter is the gap above a floating header. Confirmed by the rendered Navbar. */
1309
+ navbarPosition?: ChromePosition;
1310
+ /** Where the sidebar sits; a floating sidebar's gutter is the gap beside a floating header. Confirmed by the rendered Sidebar. */
1311
+ sidebarPosition?: ChromePosition;
1312
+ pageHeader?: {
1313
+ variant?: ThemePageHeaderVariant;
1314
+ behavior?: ThemePageHeaderBehavior;
1315
+ position?: ChromePosition;
1316
+ /** Colourful only. */
1317
+ intensity?: ThemePageHeaderIntensity;
1318
+ /** Colourful on the home page only; other pages take `otherPagesVariant`. The shell decides which page is home. */
1319
+ colourfulHomeOnly?: boolean;
1320
+ otherPagesVariant?: "default" | "minimal";
1321
+ };
1322
+ breadcrumbs?: {
1323
+ /** Inline in the header, or a contained strip the container renders above it. */
1324
+ position?: ThemeBreadcrumbPosition;
1325
+ style?: ThemeBreadcrumbStyle;
1326
+ separator?: ThemeBreadcrumbSeparator;
1327
+ };
1328
+ /** The customer's settings.layout preference: a rail of sections beside the panel, or horizontal tabs above it. SettingsLayout reads it. */
1329
+ settingsLayout?: ThemeSettingsLayout;
1330
+ }
1331
+
1332
+ interface SettingsSection {
1333
+ id: string;
1334
+ label: string;
1335
+ icon?: IconName;
1336
+ /** Heading above this section in the rail; the option group in the collapsed Dropdown. */
1337
+ group?: string;
1338
+ disabled?: boolean;
1339
+ }
1340
+ interface SettingsLayoutProps {
1341
+ sections: SettingsSection[];
1342
+ /** The selected section id. */
1343
+ value: string;
1344
+ onChange: (id: string) => void;
1345
+ /**
1346
+ * 'sidebar': a rail of sections beside the panel; 'tabs': horizontal tabs above it.
1347
+ * Default: the shell theme's settings.layout preference, else 'sidebar'. A page passes nothing.
1348
+ */
1349
+ layout?: ThemeSettingsLayout;
1350
+ /** Width of the rail in px (sidebar layout). */
1351
+ railWidth?: number;
1352
+ /**
1353
+ * Below this width of the layout itself (not the viewport) the rail becomes a Dropdown. Default: the rail plus a
1354
+ * usable panel (railWidth + 480). Measured on the layout, so a narrow PageContainer or a sidebar shell counts.
1355
+ */
1356
+ collapseBelow?: number;
1357
+ /** Accessible name of the section navigation. */
1358
+ "aria-label"?: string;
1359
+ /** The panel: the selected section's content. */
1360
+ children: ReactNode;
1361
+ className?: string;
1362
+ }
1363
+ /**
1364
+ * The settings page composition (Sprint 25.2, R8): a rail of sections beside
1365
+ * the panel, sticky while the page scrolls, or horizontal tabs above it — the
1366
+ * customer's settings.layout preference decides which, the component decides
1367
+ * the breakpoints. The collapse is measured on the layout's own width (a narrow
1368
+ * PageContainer, a sidebar shell): when the rail would leave too little for the
1369
+ * panel it becomes a Dropdown above the panel; a vertical rail never sits above
1370
+ * the content (settings#10).
1371
+ *
1372
+ * The rail is a Tabs (vertical) styled by the theme's in-page vertical style;
1373
+ * the page assembles the sections' contents and nothing else.
1374
+ */
1375
+ declare function SettingsLayout({ sections, value, onChange, layout: layoutProp, railWidth, collapseBelow, "aria-label": ariaLabel, children, className, }: SettingsLayoutProps): react_jsx_runtime.JSX.Element;
1376
+
1377
+ interface SplitViewProps {
1378
+ /** The list (an inbox, a queue): it scrolls on its own. */
1379
+ list: ReactNode;
1380
+ /** The selected item (a thread, a record): it fills the height and scrolls on its own. */
1381
+ detail: ReactNode;
1382
+ /** Context beside the detail (a contact, properties). Collapses to a toggle that opens it in a Drawer when the layout is narrower than `asideCollapseBelow`. */
1383
+ aside?: ReactNode;
1384
+ /** Names the aside's toggle and Drawer. */
1385
+ asideTitle?: string;
1386
+ /**
1387
+ * Below `collapseBelow` the list shows alone; with `detailOpen` the detail replaces it, with a Back button that calls
1388
+ * `onDetailClose` (detailMode "stack"). The page owns the selection, so it owns this flag.
1389
+ */
1390
+ detailOpen?: boolean;
1391
+ onDetailClose?: () => void;
1392
+ /** "stack" (default): the detail stacks over the list below the collapse width. "route": the app navigates to the detail's own route instead, and this renders the list alone there. */
1393
+ detailMode?: "stack" | "route";
1394
+ backLabel?: string;
1395
+ /** Percent of the width the list takes; the divider is draggable. */
1396
+ listWidth?: number;
1397
+ listMinWidth?: number;
1398
+ asideWidth?: number;
1399
+ /** Below this width of the layout itself (px) the list and detail stop sitting side by side. */
1400
+ collapseBelow?: number;
1401
+ /** Below this width of the layout itself (px) the aside becomes a toggle. */
1402
+ asideCollapseBelow?: number;
1403
+ /** A bordered, rounded surface (inside a page with padding) instead of edge to edge (filling <main>). */
1404
+ bordered?: boolean;
1405
+ "aria-label"?: string;
1406
+ className?: string;
1407
+ }
1408
+ /**
1409
+ * The reading-pane composition (Sprint 25.2, R3): one surface with dividers —
1410
+ * list, detail and an optional aside — that fills the height it is given (an
1411
+ * AppShell's <main> already gives it) and never three cards with gaps. The
1412
+ * panels compose ResizablePanelGroup, so the dividers drag. Below the collapse
1413
+ * width, measured on the layout itself, the list shows alone and the detail
1414
+ * stacks over it (or the app routes to it); the aside collapses to a toggle.
1415
+ * The page owns the selection and assembles the contents; keyboard movement
1416
+ * through the list is the list's job (StackedList selectedId).
1417
+ */
1418
+ declare function SplitView({ list, detail, aside, asideTitle, detailOpen, onDetailClose, detailMode, backLabel, listWidth, listMinWidth, asideWidth, collapseBelow, asideCollapseBelow, bordered, "aria-label": ariaLabel, className, }: SplitViewProps): react_jsx_runtime.JSX.Element;
1419
+
1179
1420
  interface BreadcrumbItem$1 {
1180
1421
  label: string;
1181
1422
  href?: string;
@@ -1329,8 +1570,15 @@ interface SegmentedControlProps {
1329
1570
  */
1330
1571
  onHoverChange?: (value: string | null) => void;
1331
1572
  className?: string;
1573
+ /** Accessible name for the radiogroup, for when there is no visible label (e.g. in a toolbar). */
1574
+ "aria-label"?: string;
1575
+ /**
1576
+ * Above this many options the control renders a Dropdown with the same value, onChange and options — a row of
1577
+ * eleven segments runs off the page (bench round 3). Default 6; raise it only where the row is known to fit.
1578
+ */
1579
+ maxOptions?: number;
1332
1580
  }
1333
- declare function SegmentedControl({ value, onChange, options, size, variant, fullWidth, onHoverChange, className, }: SegmentedControlProps): react_jsx_runtime.JSX.Element;
1581
+ declare function SegmentedControl({ value, onChange, options, size, variant, fullWidth, onHoverChange, className, "aria-label": ariaLabel, maxOptions, }: SegmentedControlProps): react_jsx_runtime.JSX.Element;
1334
1582
 
1335
1583
  interface BottomNavItem {
1336
1584
  label: string;
@@ -1375,7 +1623,7 @@ interface PageHeaderProps {
1375
1623
  intensity?: PageHeaderIntensity;
1376
1624
  /** Colourful: background image URL — overlaid with accent colour */
1377
1625
  backgroundImage?: string;
1378
- /** Colourful: extra bottom padding (px) for content overlap. Content below should use -mt-[value] to pull up. */
1626
+ /** Colourful: extra bottom padding (px) for content overlap. PageContainer pulls the content up by the same amount; the page adds no negative margin. */
1379
1627
  overlapHeight?: number;
1380
1628
  /** Snapping: content shown only when expanded */
1381
1629
  expandedContent?: ReactNode;
@@ -1514,6 +1762,10 @@ interface DialogProps {
1514
1762
  description?: string;
1515
1763
  children?: ReactNode;
1516
1764
  footer?: ReactNode;
1765
+ /** The content has unsaved changes: Escape, the backdrop and the close control ask before discarding, inside the dialog (Sprint 25.2, C1). */
1766
+ dirty?: boolean;
1767
+ /** Called when the user chooses to discard, before onClose. */
1768
+ onDiscard?: () => void;
1517
1769
  variant?: "default" | "destructive";
1518
1770
  size?: DialogSize;
1519
1771
  alert?: boolean;
@@ -1529,7 +1781,7 @@ interface DialogProps {
1529
1781
  */
1530
1782
  onSubmit?: () => void;
1531
1783
  }
1532
- declare function Dialog({ open, onClose, title, description, children, footer, variant, size, alert, container, onSubmit }: DialogProps): react.ReactPortal | null;
1784
+ declare function Dialog({ open, onClose: onCloseProp, title, description, children, footer, variant, size, alert, container, onSubmit, dirty, onDiscard }: DialogProps): react.ReactPortal | null;
1533
1785
 
1534
1786
  interface DrawerProps {
1535
1787
  open: boolean;
@@ -1579,18 +1831,27 @@ interface DrawerProps {
1579
1831
  */
1580
1832
  resizable?: boolean;
1581
1833
  maxWidth?: string;
1834
+ /** The content has unsaved changes: every close path asks before discarding, inside the drawer (Sprint 25.2, C1). */
1835
+ dirty?: boolean;
1836
+ /** Called when the user chooses to discard, before onClose. */
1837
+ onDiscard?: () => void;
1582
1838
  }
1583
1839
  declare function Drawer(props: DrawerProps): react_jsx_runtime.JSX.Element;
1584
1840
 
1585
- interface TooltipProps {
1841
+ interface TooltipProps extends Omit<HTMLAttributes<HTMLElement>, "content"> {
1586
1842
  content: ReactNode;
1587
1843
  children: ReactNode;
1588
1844
  side?: Side;
1589
1845
  delay?: number;
1590
1846
  className?: string;
1591
1847
  container?: Element | DocumentFragment;
1848
+ /**
1849
+ * A Tooltip can itself be the child of a Slot — `<DropdownMenu trigger={<Tooltip …><Button/></Tooltip>}>` —
1850
+ * so the ref and handlers a parent merges onto it are passed through to its own trigger (14 Sep 2026).
1851
+ */
1852
+ ref?: Ref<HTMLElement>;
1592
1853
  }
1593
- declare function Tooltip({ content, children, side, delay, className, container }: TooltipProps): react_jsx_runtime.JSX.Element;
1854
+ declare function Tooltip({ content, children, side, delay, className, container, ref: forwardedRef, ...slotProps }: TooltipProps): react_jsx_runtime.JSX.Element;
1594
1855
 
1595
1856
  interface PopoverProps {
1596
1857
  open: boolean;
@@ -1662,6 +1923,8 @@ interface SheetProps {
1662
1923
  title?: ReactNode;
1663
1924
  children: ReactNode;
1664
1925
  footer?: ReactNode;
1926
+ /** A strip between the content and the footer (the Drawer's unsaved-changes question). */
1927
+ confirm?: ReactNode;
1665
1928
  /** Heights the sheet snaps to, as fractions of the viewport (or container). Default [0.5, 0.92]. */
1666
1929
  snapPoints?: number[];
1667
1930
  /** Render inside this element (absolute positioning, no body scroll lock) instead of document.body. */
@@ -1675,7 +1938,7 @@ interface SheetProps {
1675
1938
  /** id of the element that names the dialog when no title is rendered. */
1676
1939
  labelledBy?: string;
1677
1940
  }
1678
- declare function Sheet({ open, onClose, title, children, footer, snapPoints, container, flush, keepMounted, id, labelledBy }: SheetProps): react.ReactPortal | null;
1941
+ declare function Sheet({ open, onClose, title, children, footer, confirm, snapPoints, container, flush, keepMounted, id, labelledBy }: SheetProps): react.ReactPortal | null;
1679
1942
 
1680
1943
  interface Notification {
1681
1944
  id: string;
@@ -1894,6 +2157,16 @@ interface AppShellContextValue {
1894
2157
  * element, where a body-level ToastProvider cannot see it.
1895
2158
  */
1896
2159
  container: HTMLElement | null;
2160
+ /** The theme's shell-level decisions (Sprint 25). PageHeader and PageContainer resolve their defaults from it. */
2161
+ theme: AppShellTheme | null;
2162
+ /** The current route is the home page (`currentPath === homePath`); decides `colourfulHomeOnly`. */
2163
+ isHome: boolean;
2164
+ /** The rendered Navbar floats (registered by the Navbar; the theme's `navbarPosition` until it has). */
2165
+ navbarFloating: boolean;
2166
+ /** The rendered Sidebar floats, and is a sidebar rather than a drawer: false below md and in stacked layouts. */
2167
+ sidebarFloating: boolean;
2168
+ /** Called by Sidebar and Navbar so the shell knows the chrome that is actually rendered. Returns the unregister. */
2169
+ registerChrome: (kind: "navbar" | "sidebar", position: ChromePosition) => () => void;
1897
2170
  }
1898
2171
  declare function useAppShell(): AppShellContextValue | null;
1899
2172
  type AppShellLayout = "sidebar" | "stacked" | "sidebar-header" | "multi-column";
@@ -1910,6 +2183,12 @@ interface AppShellProps {
1910
2183
  mobileMenuFlush?: boolean;
1911
2184
  navbar?: ReactNode;
1912
2185
  mobileNav?: ReactNode;
2186
+ /** Rendered below the page content inside the scrolling region and pinned to the bottom on short pages. Ignored when `scrollable` is false. */
2187
+ footer?: ReactNode;
2188
+ /** Render a SkipLink as the first focusable element (default true); it targets `mainId`. */
2189
+ skipLink?: boolean;
2190
+ /** The id of the <main> region the skip link jumps to. */
2191
+ mainId?: string;
1913
2192
  /** A docked AsidePanel rendered beside the content column: the page narrows to make room. Rendered at every width — the panel decides its own fallbacks. */
1914
2193
  aside?: ReactNode;
1915
2194
  /** Which side of the content the aside sits on. Default "right". Pass the same value to the AsidePanel. */
@@ -1924,6 +2203,12 @@ interface AppShellProps {
1924
2203
  className?: string;
1925
2204
  /** When false, main area won't scroll — use for full-height layouts like ResizablePanelGroup. Default true. */
1926
2205
  scrollable?: boolean;
2206
+ /** The theme's shell-level decisions: what the generated shell passes once so pages carry nothing (Sprint 25). */
2207
+ theme?: AppShellTheme;
2208
+ /** The current route's path, so the shell knows which page is home. */
2209
+ currentPath?: string;
2210
+ /** The home page's path. Default "/". */
2211
+ homePath?: string;
1927
2212
  }
1928
2213
  declare const AppShell: react.ForwardRefExoticComponent<AppShellProps & react.RefAttributes<HTMLDivElement>>;
1929
2214
 
@@ -1937,11 +2222,31 @@ interface PageContainerProps {
1937
2222
  /** Lower-level max-width escape hatch. Use `width` for standard cases. */
1938
2223
  maxWidth?: MaxWidth;
1939
2224
  padding?: Padding;
2225
+ /**
2226
+ * Vertical padding of the content column. With a PageHeader as a direct child the header owns the space under the
2227
+ * navbar, so only the bottom value applies; without one the default is the usual top and bottom padding.
2228
+ */
1940
2229
  verticalPadding?: VerticalPadding;
1941
2230
  centered?: boolean;
1942
2231
  children: ReactNode;
1943
2232
  className?: string;
2233
+ /**
2234
+ * Wraps the PageHeader the container found among its children — for previews that need a badge or a ref on it.
2235
+ * The header keeps reading the container's context through the wrapper. The wrapper must not form a box
2236
+ * (`display: contents`): a snapping header sticks within its containing block, which has to be this container.
2237
+ */
2238
+ renderHeader?: (header: ReactNode) => ReactNode;
1944
2239
  }
2240
+ /**
2241
+ * The page's width constraint, and — when a PageHeader is among its direct
2242
+ * children — the page's composition: the header is placed inside the column
2243
+ * (default, minimal, tabs-integrated) or above it spanning the page
2244
+ * (colourful, snapping, floating), contained breadcrumbs become a strip above
2245
+ * the header, a floating header's content is inset by the shell gutter, and a
2246
+ * colourful overlap pulls the content up. The decisions come from the theme
2247
+ * the AppShell carries; a page writes `<PageContainer><PageHeader title />…`
2248
+ * and nothing else (Sprint 25).
2249
+ */
1945
2250
  declare const PageContainer: react.ForwardRefExoticComponent<PageContainerProps & react.RefAttributes<HTMLDivElement>>;
1946
2251
 
1947
2252
  interface SectionHeadingProps {
@@ -2013,4 +2318,4 @@ interface UseTextOverflowResult {
2013
2318
  */
2014
2319
  declare function useTextOverflow(options?: UseTextOverflowOptions): UseTextOverflowResult;
2015
2320
 
2016
- export { Accordion, ActionPanel, ActionPanelGroup, Alert, type AlertPlacement, AppShell, type AppShellContextValue, AsidePanel, type AsidePanelProps, type AsidePanelSide, Avatar, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarStatus, Badge, type BadgePaletteColor, type BadgeSize, type BadgeVariant, BottomNav, type BottomNavItem, type BreadcrumbItem$1 as BreadcrumbItem, Breadcrumbs, type BreadcrumbsSeparator, type BreadcrumbsSize, type BreadcrumbsVariant, BreakpointKey, BulkActionBar, Button, ButtonSizeContext, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, type CardSelectType, CardTitle, type CardVariant, Carousel, type ChatMessage, type ChatMessageAction, type ChatMessageLayout, ChatMessageList, type ChatMessageSender, type ChatMessageSource, type ChatMessageStatus, ChatPanel, type ChatPanelProps, type ChatPanelStatusTone, Checkbox, CheckboxGroup, CheckboxGroupItem, CodeBlock, Collapsible, ColorPicker, type Column, Combobox, CommandPalette, ContextMenu, CornerPanel, type CornerPanelEdge, type CornerPanelProps, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, type DateRange, DateRangePicker, type DateRangePickerProps, type DateRangePreset, type DescriptionItem, DescriptionList, type DescriptionListOrientation, type DescriptionListSize, Dialog, Divider, Dock, Drawer, Dropdown, DropdownMenu, type DropdownMenuDivider, type DropdownMenuEntry, type DropdownMenuItem, EmptyState, Field, type FieldControlProps, type FieldProps, FileUpload, FormWrapper, HoverCard, InlineFieldError, Input, Kbd, Label, Launcher, type LauncherEdge, type LauncherProps, type LauncherVariant, type LauncherWhenOpen, Link, type LinkProps, MentionInput, MobileHeaderMenu, type MobileHeaderMenuItemData, type MobileHeaderMenuType, NavItem, type NavItemProps, type NavItemType, NavMenu, type NavMenuItem, Navbar, type NavbarSize, type NavbarType, type NavbarVariant, NotificationCenter, NumberInput, PageContainer, type PageContainerWidth, PageHeader, type PageHeaderBehavior, type PageHeaderIntensity, type PageHeaderProps, type PageHeaderVariant, Pagination, PinInput, Popover, Progress, type PromiseToastMessages, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, Sheet, Sidebar, type SidebarContextValue, type SidebarItem, SidebarNav, type SidebarNavSize, type SidebarPosition, type SidebarSection, type SidebarType, Skeleton, SliderRange, Spinner, StackedList, StatsCard, StatusDot, type StatusDotVariant, Stepper, type Tab, Table, type TableDensity, type TableProps, Tabs, Tag, TagInput, type TagPaletteColor, type TagVariant, TextOverflow, type TextOverflowProps, Textarea, TimePicker, Timeline, Toast, type ToastAction, type ToastApi, type ToastOptions, type ToastPosition, ToastProvider, type ToastVariant, Toggle, Tooltip, Tour, TransferList, TreeView, type UseTextOverflowOptions, type UseTextOverflowResult, useAppShell, useFormContext, useSidebar, useTextOverflow, useToast };
2321
+ export { Accordion, ActionPanel, ActionPanelGroup, Alert, type AlertPlacement, AppShell, type AppShellContextValue, type AppShellTheme, AsidePanel, type AsidePanelProps, type AsidePanelSide, Avatar, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarStatus, Badge, type BadgePaletteColor, type BadgeSize, type BadgeVariant, BottomNav, type BottomNavItem, type BreadcrumbItem$1 as BreadcrumbItem, Breadcrumbs, type BreadcrumbsSeparator, type BreadcrumbsSize, type BreadcrumbsVariant, BreakpointKey, BulkActionBar, Button, ButtonSizeContext, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, type CardSelectType, CardTitle, type CardVariant, Carousel, type ChatMessage, type ChatMessageAction, type ChatMessageLayout, ChatMessageList, type ChatMessageSender, type ChatMessageSource, type ChatMessageStatus, ChatPanel, type ChatPanelProps, type ChatPanelStatusTone, Checkbox, CheckboxGroup, CheckboxGroupItem, CodeBlock, Collapsible, ColorPicker, type Column, Combobox, CommandPalette, ContextMenu, CornerPanel, type CornerPanelEdge, type CornerPanelProps, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, type DateRange, DateRangePicker, type DateRangePickerProps, type DateRangePreset, type DescriptionItem, DescriptionList, type DescriptionListOrientation, type DescriptionListSize, Dialog, Divider, Dock, Drawer, Dropdown, DropdownMenu, type DropdownMenuDivider, type DropdownMenuEntry, type DropdownMenuItem, EmptyState, Field, type FieldControlProps, type FieldProps, FileUpload, FormWrapper, HoverCard, InlineFieldError, Input, Kbd, Label, Launcher, type LauncherEdge, type LauncherProps, type LauncherVariant, type LauncherWhenOpen, Link, type LinkProps, MentionInput, MobileHeaderMenu, type MobileHeaderMenuItemData, type MobileHeaderMenuType, NavItem, type NavItemProps, type NavItemType, NavMenu, type NavMenuItem, Navbar, type NavbarSize, type NavbarType, type NavbarVariant, NotificationCenter, NumberInput, PageContainer, type PageContainerWidth, PageHeader, type PageHeaderBehavior, type PageHeaderIntensity, type PageHeaderProps, type PageHeaderVariant, Pagination, PinInput, Popover, Progress, type PromiseToastMessages, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, type SettingsLayoutProps, type SettingsSection, Sheet, Sidebar, type SidebarContextValue, type SidebarItem, SidebarNav, type SidebarNavSize, type SidebarPosition, type SidebarSection, type SidebarType, Skeleton, SkipLink, SliderRange, Spinner, SplitView, type SplitViewProps, StackedList, StatsCard, StatusDot, type StatusDotVariant, Stepper, type Tab, Table, type TableDensity, type TableProps, TableToolbar, type TableToolbarActiveFilter, type TableToolbarFilterOption, Tabs, Tag, TagInput, type TagPaletteColor, type TagVariant, TextOverflow, type TextOverflowProps, Textarea, TimePicker, Timeline, Toast, type ToastAction, type ToastApi, type ToastOptions, type ToastPosition, ToastProvider, type ToastVariant, Toggle, Tooltip, Tour, TransferList, TreeView, type Trend, type UseTextOverflowOptions, type UseTextOverflowResult, useAppShell, useFormContext, useSidebar, useTextOverflow, useToast };