@sovereignfs/ui 0.41.0 → 0.54.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.
Files changed (256) hide show
  1. package/dist/Accordion.module.css +3 -0
  2. package/dist/Alert.module.css +62 -0
  3. package/dist/AspectRatio.module.css +15 -0
  4. package/dist/Badge.module.css +75 -9
  5. package/dist/Breadcrumb.module.css +49 -0
  6. package/dist/Button.module.css +12 -3
  7. package/dist/ButtonGroup.module.css +29 -0
  8. package/dist/Card.module.css +6 -0
  9. package/dist/Checkbox.module.css +3 -1
  10. package/dist/Collapsible.module.css +70 -0
  11. package/dist/Combobox.module.css +122 -0
  12. package/dist/Command.module.css +80 -0
  13. package/dist/ConfirmDialog.module.css +5 -1
  14. package/dist/DataTable.module.css +28 -0
  15. package/dist/DatePicker.module.css +6 -2
  16. package/dist/Dialog.module.css +3 -0
  17. package/dist/HoverCard.module.css +3 -0
  18. package/dist/Input.module.css +6 -1
  19. package/dist/Item.module.css +70 -0
  20. package/dist/Kbd.module.css +14 -0
  21. package/dist/Label.module.css +11 -0
  22. package/dist/LegalLinks.module.css +24 -0
  23. package/dist/Markdown.module.css +49 -0
  24. package/dist/Marker.module.css +33 -0
  25. package/dist/Menu.module.css +8 -1
  26. package/dist/Message.module.css +99 -0
  27. package/dist/MessageScroller.module.css +54 -0
  28. package/dist/MobileAppsDrawer.module.css +81 -0
  29. package/dist/MobileFooter.module.css +73 -0
  30. package/dist/MobileHeader.module.css +63 -0
  31. package/dist/NavigationMenu.module.css +53 -0
  32. package/dist/PageContainer.module.css +20 -0
  33. package/dist/Pagination.module.css +98 -0
  34. package/dist/Progress.module.css +20 -0
  35. package/dist/RadioGroup.module.css +88 -0
  36. package/dist/Resizable.module.css +70 -0
  37. package/dist/ScrollArea.module.css +20 -0
  38. package/dist/Select.module.css +7 -3
  39. package/dist/Slider.module.css +95 -0
  40. package/dist/SwipableMobileCarousel.module.css +55 -0
  41. package/dist/SwipableMobileCarouselDots.module.css +49 -0
  42. package/dist/SwipableMobileCarouselSlideParts.module.css +29 -0
  43. package/dist/Table.module.css +45 -0
  44. package/dist/Tabs.module.css +6 -1
  45. package/dist/Toggle.module.css +6 -1
  46. package/dist/Typography.module.css +47 -0
  47. package/dist/index.d.ts +1268 -8
  48. package/dist/index.js +3046 -975
  49. package/dist/tokens/primitives.css +47 -8
  50. package/package.json +13 -9
  51. package/src/components/Accordion/Accordion.module.css +3 -0
  52. package/src/components/Accordion/Accordion.stories.tsx +110 -0
  53. package/src/components/Accordion/Accordion.tsx +53 -0
  54. package/src/components/Accordion/__tests__/Accordion.test.tsx +61 -0
  55. package/src/components/Alert/Alert.module.css +62 -0
  56. package/src/components/Alert/Alert.stories.tsx +96 -0
  57. package/src/components/Alert/Alert.tsx +58 -0
  58. package/src/components/Alert/__tests__/Alert.test.tsx +75 -0
  59. package/src/components/AspectRatio/AspectRatio.module.css +15 -0
  60. package/src/components/AspectRatio/AspectRatio.stories.tsx +78 -0
  61. package/src/components/AspectRatio/AspectRatio.tsx +21 -0
  62. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +27 -0
  63. package/src/components/Badge/Badge.module.css +75 -9
  64. package/src/components/Badge/Badge.stories.tsx +109 -1
  65. package/src/components/Badge/Badge.tsx +31 -9
  66. package/src/components/Badge/__tests__/Badge.test.tsx +26 -2
  67. package/src/components/Breadcrumb/Breadcrumb.module.css +49 -0
  68. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +47 -0
  69. package/src/components/Breadcrumb/Breadcrumb.tsx +57 -0
  70. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +52 -0
  71. package/src/components/Button/Button.module.css +12 -3
  72. package/src/components/Button/Button.stories.tsx +3 -2
  73. package/src/components/Button/Button.tsx +1 -1
  74. package/src/components/Button/__tests__/Button.test.tsx +10 -0
  75. package/src/components/ButtonGroup/ButtonGroup.module.css +29 -0
  76. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +57 -0
  77. package/src/components/ButtonGroup/ButtonGroup.tsx +27 -0
  78. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +29 -0
  79. package/src/components/Card/Card.module.css +6 -0
  80. package/src/components/Checkbox/Checkbox.module.css +3 -1
  81. package/src/components/Collapsible/Collapsible.module.css +70 -0
  82. package/src/components/Collapsible/Collapsible.stories.tsx +62 -0
  83. package/src/components/Collapsible/Collapsible.tsx +66 -0
  84. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +71 -0
  85. package/src/components/Combobox/Combobox.module.css +122 -0
  86. package/src/components/Combobox/Combobox.stories.tsx +79 -0
  87. package/src/components/Combobox/Combobox.tsx +186 -0
  88. package/src/components/Combobox/__tests__/Combobox.test.tsx +158 -0
  89. package/src/components/Command/Command.module.css +80 -0
  90. package/src/components/Command/Command.stories.tsx +104 -0
  91. package/src/components/Command/Command.tsx +168 -0
  92. package/src/components/Command/__tests__/Command.test.tsx +162 -0
  93. package/src/components/ConfirmDialog/ConfirmDialog.module.css +5 -1
  94. package/src/components/ContextMenu/ContextMenu.stories.tsx +81 -0
  95. package/src/components/ContextMenu/ContextMenu.tsx +100 -0
  96. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +87 -0
  97. package/src/components/DataTable/DataTable.module.css +28 -0
  98. package/src/components/DataTable/DataTable.stories.tsx +74 -0
  99. package/src/components/DataTable/DataTable.tsx +154 -0
  100. package/src/components/DataTable/__tests__/DataTable.test.tsx +123 -0
  101. package/src/components/DatePicker/DatePicker.module.css +6 -2
  102. package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +58 -0
  103. package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +45 -0
  104. package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +100 -0
  105. package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +119 -0
  106. package/src/components/Dialog/Dialog.module.css +3 -0
  107. package/src/components/Dialog/Dialog.tsx +8 -59
  108. package/src/components/Drawer/Drawer.stories.tsx +44 -0
  109. package/src/components/Drawer/Drawer.tsx +18 -56
  110. package/src/components/Drawer/__tests__/Drawer.test.tsx +22 -0
  111. package/src/components/HoverCard/HoverCard.module.css +3 -0
  112. package/src/components/HoverCard/HoverCard.stories.tsx +66 -0
  113. package/src/components/HoverCard/HoverCard.tsx +111 -0
  114. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +99 -0
  115. package/src/components/Icon/icons/circle-check.tsx +21 -0
  116. package/src/components/Icon/icons/circle-x.tsx +22 -0
  117. package/src/components/Icon/icons/index.ts +16 -0
  118. package/src/components/Icon/icons/menu.tsx +22 -0
  119. package/src/components/Icon/icons/smartphone.tsx +21 -0
  120. package/src/components/Input/Input.module.css +6 -1
  121. package/src/components/Item/Item.module.css +70 -0
  122. package/src/components/Item/Item.stories.tsx +62 -0
  123. package/src/components/Item/Item.tsx +54 -0
  124. package/src/components/Item/__tests__/Item.test.tsx +39 -0
  125. package/src/components/Kbd/Kbd.module.css +14 -0
  126. package/src/components/Kbd/Kbd.stories.tsx +32 -0
  127. package/src/components/Kbd/Kbd.tsx +12 -0
  128. package/src/components/Kbd/__tests__/Kbd.test.tsx +14 -0
  129. package/src/components/Label/Label.module.css +11 -0
  130. package/src/components/Label/Label.stories.tsx +40 -0
  131. package/src/components/Label/Label.tsx +24 -0
  132. package/src/components/Label/__tests__/Label.test.tsx +32 -0
  133. package/src/components/LegalLinks/LegalLinks.module.css +24 -0
  134. package/src/components/LegalLinks/LegalLinks.stories.tsx +22 -0
  135. package/src/components/LegalLinks/LegalLinks.tsx +40 -0
  136. package/src/components/Markdown/Markdown.module.css +49 -0
  137. package/src/components/Markdown/Markdown.stories.tsx +30 -0
  138. package/src/components/Markdown/Markdown.tsx +168 -0
  139. package/src/components/Marker/Marker.module.css +33 -0
  140. package/src/components/Marker/Marker.stories.tsx +39 -0
  141. package/src/components/Marker/Marker.tsx +34 -0
  142. package/src/components/Marker/__tests__/Marker.test.tsx +23 -0
  143. package/src/components/Menu/Menu.module.css +8 -1
  144. package/src/components/Menu/Menu.tsx +30 -8
  145. package/src/components/Menubar/Menubar.stories.tsx +52 -0
  146. package/src/components/Menubar/Menubar.tsx +42 -0
  147. package/src/components/Menubar/__tests__/Menubar.test.tsx +45 -0
  148. package/src/components/Message/Message.module.css +99 -0
  149. package/src/components/Message/Message.stories.tsx +79 -0
  150. package/src/components/Message/Message.tsx +41 -0
  151. package/src/components/Message/__tests__/Message.test.tsx +46 -0
  152. package/src/components/MessageScroller/MessageScroller.module.css +54 -0
  153. package/src/components/MessageScroller/MessageScroller.stories.tsx +84 -0
  154. package/src/components/MessageScroller/MessageScroller.tsx +72 -0
  155. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +105 -0
  156. package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +81 -0
  157. package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +78 -0
  158. package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +80 -0
  159. package/src/components/MobileFooter/MobileFooter.module.css +73 -0
  160. package/src/components/MobileFooter/MobileFooter.stories.tsx +47 -0
  161. package/src/components/MobileFooter/MobileFooter.tsx +109 -0
  162. package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +71 -0
  163. package/src/components/MobileHeader/MobileHeader.module.css +63 -0
  164. package/src/components/MobileHeader/MobileHeader.stories.tsx +57 -0
  165. package/src/components/MobileHeader/MobileHeader.tsx +77 -0
  166. package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +58 -0
  167. package/src/components/NavTabs/NavTabs.tsx +39 -11
  168. package/src/components/NavigationMenu/NavigationMenu.module.css +53 -0
  169. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +58 -0
  170. package/src/components/NavigationMenu/NavigationMenu.tsx +125 -0
  171. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +93 -0
  172. package/src/components/OfflineGate/OfflineGate.tsx +44 -0
  173. package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +66 -0
  174. package/src/components/PageContainer/PageContainer.module.css +20 -0
  175. package/src/components/PageContainer/PageContainer.tsx +31 -0
  176. package/src/components/PageContainer/__tests__/PageContainer.test.tsx +37 -0
  177. package/src/components/PageHeader/PageHeader.tsx +16 -2
  178. package/src/components/Pagination/Pagination.module.css +98 -0
  179. package/src/components/Pagination/Pagination.stories.tsx +49 -0
  180. package/src/components/Pagination/Pagination.tsx +87 -0
  181. package/src/components/Pagination/__tests__/Pagination.test.tsx +56 -0
  182. package/src/components/Progress/Progress.module.css +20 -0
  183. package/src/components/Progress/Progress.stories.tsx +40 -0
  184. package/src/components/Progress/Progress.tsx +35 -0
  185. package/src/components/Progress/__tests__/Progress.test.tsx +31 -0
  186. package/src/components/RadioGroup/RadioGroup.module.css +88 -0
  187. package/src/components/RadioGroup/RadioGroup.stories.tsx +69 -0
  188. package/src/components/RadioGroup/RadioGroup.tsx +99 -0
  189. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +59 -0
  190. package/src/components/Resizable/Resizable.module.css +70 -0
  191. package/src/components/Resizable/Resizable.stories.tsx +82 -0
  192. package/src/components/Resizable/Resizable.tsx +313 -0
  193. package/src/components/Resizable/__tests__/Resizable.test.tsx +128 -0
  194. package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +24 -0
  195. package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +73 -0
  196. package/src/components/ScrollArea/ScrollArea.module.css +20 -0
  197. package/src/components/ScrollArea/ScrollArea.stories.tsx +57 -0
  198. package/src/components/ScrollArea/ScrollArea.tsx +27 -0
  199. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +39 -0
  200. package/src/components/Select/Select.module.css +7 -3
  201. package/src/components/Sheet/Sheet.tsx +9 -51
  202. package/src/components/Slider/Slider.module.css +95 -0
  203. package/src/components/Slider/Slider.stories.tsx +64 -0
  204. package/src/components/Slider/Slider.tsx +77 -0
  205. package/src/components/Slider/__tests__/Slider.test.tsx +45 -0
  206. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +55 -0
  207. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +227 -0
  208. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +35 -0
  209. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +42 -0
  210. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +18 -0
  211. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +21 -0
  212. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +29 -0
  213. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +133 -0
  214. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +61 -0
  215. package/src/components/SwipableMobileCarousel/context.ts +13 -0
  216. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +49 -0
  217. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +62 -0
  218. package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +63 -0
  219. package/src/components/Table/Table.module.css +45 -0
  220. package/src/components/Table/Table.stories.tsx +125 -0
  221. package/src/components/Table/Table.tsx +51 -0
  222. package/src/components/Table/__tests__/Table.test.tsx +50 -0
  223. package/src/components/Tabs/Tabs.module.css +6 -1
  224. package/src/components/Toggle/Toggle.module.css +6 -1
  225. package/src/components/Typography/Typography.module.css +47 -0
  226. package/src/components/Typography/Typography.stories.tsx +62 -0
  227. package/src/components/Typography/Typography.tsx +30 -0
  228. package/src/components/Typography/__tests__/Typography.test.tsx +34 -0
  229. package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +126 -0
  230. package/src/hooks/__tests__/useIsOffline.test.tsx +53 -0
  231. package/src/hooks/__tests__/useOfflineTileState.test.tsx +69 -0
  232. package/src/hooks/__tests__/useResponsiveLayout.test.tsx +87 -0
  233. package/src/hooks/__tests__/useSnapCarousel.test.tsx +93 -0
  234. package/src/hooks/__tests__/useSwipeReveal.test.tsx +110 -0
  235. package/src/hooks/index.ts +18 -0
  236. package/src/hooks/useCarouselRouteSync.ts +92 -0
  237. package/src/hooks/useIsOffline.ts +41 -0
  238. package/src/hooks/useOfflineTileState.ts +45 -0
  239. package/src/hooks/useResponsiveLayout.ts +36 -0
  240. package/src/hooks/useSnapCarousel.ts +79 -0
  241. package/src/hooks/useSwipeReveal.ts +107 -0
  242. package/src/index.ts +141 -3
  243. package/src/overlay-shell.ts +94 -0
  244. package/src/stories/DesignSystemOverview.stories.tsx +936 -3
  245. package/src/stories/DeviceOnlyGate.stories.tsx +35 -0
  246. package/src/stories/DeviceStorageKeyGate.stories.tsx +57 -0
  247. package/src/stories/InteractionHooks.stories.tsx +483 -0
  248. package/src/stories/MobilePatterns.stories.tsx +255 -4
  249. package/src/stories/NavTabs.stories.tsx +18 -0
  250. package/src/stories/OfflineGate.stories.tsx +42 -0
  251. package/src/stories/PageContainer.stories.tsx +37 -0
  252. package/src/stories/PageHeader.stories.tsx +11 -0
  253. package/src/stories/ResponsiveSurface.stories.tsx +47 -0
  254. package/src/stories/SwipableMobileCarousel.stories.tsx +304 -0
  255. package/src/stories/TokenGallery.stories.tsx +177 -16
  256. package/src/tokens/primitives.css +47 -8
package/dist/index.d.ts CHANGED
@@ -1,12 +1,51 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, ButtonHTMLAttributes, SelectHTMLAttributes, ReactElement, CSSProperties, InputHTMLAttributes, TextareaHTMLAttributes, HTMLAttributes, PointerEvent, MouseEvent, KeyboardEvent } from 'react';
2
+ import { ReactNode, ButtonHTMLAttributes, SelectHTMLAttributes, ReactElement, CSSProperties, InputHTMLAttributes, TextareaHTMLAttributes, HTMLAttributes, TdHTMLAttributes, ThHTMLAttributes, LabelHTMLAttributes, ElementType, PointerEvent, KeyboardEvent, MouseEvent, RefObject } from 'react';
3
+
4
+ interface LegalLinksProps {
5
+ privacyHref?: string;
6
+ tosHref?: string;
7
+ /** Renders a linked item. Defaults to a plain `<a href>`, which causes a
8
+ * full page reload — pass Next's `<Link>` (or equivalent) to keep
9
+ * navigation client-side. Not needed for a full-reload navigation away
10
+ * from a standalone auth page, but matters if this is ever mounted inside
11
+ * an SPA-like shell. */
12
+ renderLink?: (href: string, label: string) => ReactNode;
13
+ className?: string;
14
+ }
15
+ declare function LegalLinks({ privacyHref, tosHref, renderLink, className, }: LegalLinksProps): react.JSX.Element;
16
+
17
+ interface MarkdownProps {
18
+ /** Raw markdown source. Supports the subset used by Sovereign's own
19
+ * long-form content pages: headings (#/##/###), paragraphs, **bold**,
20
+ * *italic*, `code`, [links](url), unordered lists (-), and blockquotes
21
+ * (>), including soft-wrapped continuation lines within a paragraph or
22
+ * list item. Not a general-purpose CommonMark parser — no tables,
23
+ * images, ordered lists, or nested blocks. */
24
+ content: string;
25
+ className?: string;
26
+ }
27
+ /** Renders a constrained markdown subset (see MarkdownProps) as styled React
28
+ * elements built from Typography — no HTML string injection. Meant for
29
+ * long-form, first-party content pages (privacy policy, terms of service)
30
+ * sourced from a single markdown file, not for rendering arbitrary or
31
+ * user-supplied markdown. */
32
+ declare function Markdown({ content, className }: MarkdownProps): react.JSX.Element;
3
33
 
4
34
  type BadgeVariant = 'role' | 'status' | 'mono';
35
+ type BadgeSize = 'sm' | 'md' | 'lg';
5
36
  type BadgeStatus = 'active' | 'enabled' | 'deactivated' | 'failed' | 'invited' | 'pending' | 'neutral';
6
37
  interface BadgeProps {
7
38
  variant?: BadgeVariant;
39
+ /** 'sm' | 'md' (default) | 'lg'. 'md' is the badge's original — and until
40
+ * now, only — size, so the default renders unchanged. */
41
+ size?: BadgeSize;
8
42
  /** Only relevant when variant="status" — determines the dot colour. */
9
43
  status?: BadgeStatus;
44
+ /** Forces ALL CAPS display regardless of the case `children` is passed
45
+ * in. Defaults to `true` — every existing badge in the app relies on
46
+ * this. Set `false` for a title-case badge that renders exactly the text
47
+ * passed in (e.g. "Owner" instead of "OWNER"). */
48
+ uppercase?: boolean;
10
49
  children: ReactNode;
11
50
  }
12
51
  /**
@@ -15,10 +54,13 @@ interface BadgeProps {
15
54
  * - `role` neutral surface + border, semibold — for Owner / Admin / User
16
55
  * - `status` tinted chip with leading colour dot — for Active / Deactivated / etc.
17
56
  * - `mono` monospace font, neutral surface — for platform / community / v0.1.0
57
+ *
58
+ * Three sizes (`sm`/`md`/`lg`, default `md`). ALL CAPS by default
59
+ * (`uppercase`) — set `uppercase={false}` for a title-case badge instead.
18
60
  */
19
- declare function Badge({ variant, status, children }: BadgeProps): react.JSX.Element;
61
+ declare function Badge({ variant, size, status, uppercase, children, }: BadgeProps): react.JSX.Element;
20
62
 
21
- type IconName = 'house' | 'settings' | 'log-out' | 'chevron-right' | 'chevron-left' | 'chevron-down' | 'chevron-up' | 'x' | 'check' | 'plus' | 'trash-2' | 'pencil' | 'rotate-ccw' | 'search' | 'user' | 'shield' | 'lock' | 'eye' | 'eye-off' | 'mail' | 'bell' | 'activity' | 'package' | 'grid-2x2' | 'info' | 'alert-triangle' | 'calendar' | 'sliders-horizontal' | 'ellipsis-vertical' | 'file' | 'upload' | 'external-link' | 'banana' | 'apple' | 'carrot' | 'egg' | 'beef' | 'fish' | 'coffee' | 'wine' | 'beer' | 'cookie' | 'pizza' | 'candy' | 'salad' | 'milk' | 'drumstick' | 'croissant' | 'cup-soda' | 'spray-can' | 'snowflake' | 'shopping-basket';
63
+ type IconName = 'house' | 'settings' | 'log-out' | 'smartphone' | 'chevron-right' | 'chevron-left' | 'chevron-down' | 'chevron-up' | 'menu' | 'x' | 'check' | 'plus' | 'trash-2' | 'pencil' | 'rotate-ccw' | 'search' | 'user' | 'shield' | 'lock' | 'eye' | 'eye-off' | 'mail' | 'bell' | 'activity' | 'package' | 'grid-2x2' | 'info' | 'alert-triangle' | 'circle-check' | 'circle-x' | 'calendar' | 'sliders-horizontal' | 'ellipsis-vertical' | 'file' | 'upload' | 'external-link' | 'banana' | 'apple' | 'carrot' | 'egg' | 'beef' | 'fish' | 'coffee' | 'wine' | 'beer' | 'cookie' | 'pizza' | 'candy' | 'salad' | 'milk' | 'drumstick' | 'croissant' | 'cup-soda' | 'spray-can' | 'snowflake' | 'shopping-basket';
22
64
 
23
65
  /** Decorative icon — visually meaningful but described by surrounding text. */
24
66
  type DecorativeProps = {
@@ -194,7 +236,7 @@ interface PopoverProps {
194
236
  declare function Popover({ trigger, open, onClose, align, width, panelStyle, 'aria-label': ariaLabel, children, }: PopoverProps): react.JSX.Element;
195
237
 
196
238
  type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'destructive';
197
- type ButtonSize = 'sm' | 'md';
239
+ type ButtonSize = 'sm' | 'md' | 'lg';
198
240
  interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
199
241
  variant?: ButtonVariant;
200
242
  size?: ButtonSize;
@@ -362,6 +404,12 @@ interface DrawerProps {
362
404
  * "half screen or less" convention for Drawer, this is the only other
363
405
  * supported size; taller content should use `Sheet` instead. */
364
406
  snapHeight?: 'content' | 'half';
407
+ /** Renders a built-in `OverlayHeader` (title + close) below the grab
408
+ * handle. Omit when the content supplies its own header, or none is
409
+ * needed at all — e.g. the mobile shell's Apps drawer, whose grab handle
410
+ * and swipe-down/scrim-tap dismissal are enough on their own. Mirrors
411
+ * `Sheet`'s identical `title` prop. */
412
+ title?: string;
365
413
  children: ReactNode;
366
414
  }
367
415
  /**
@@ -386,7 +434,7 @@ interface DrawerProps {
386
434
  * scroll, the same reasoning behind the tasks plugin's edge-zone-only
387
435
  * swipe-to-reveal technique.
388
436
  */
389
- declare function Drawer({ open, onClose, 'aria-label': ariaLabel, snapHeight, children, }: DrawerProps): react.JSX.Element | null;
437
+ declare function Drawer({ open, onClose, 'aria-label': ariaLabel, snapHeight, title, children, }: DrawerProps): react.JSX.Element | null;
390
438
 
391
439
  interface OverlayHeaderProps {
392
440
  /** Overlay title, shown between the optional back button and the trailing
@@ -569,6 +617,17 @@ interface MenuProps {
569
617
  * Selecting an item both closes the menu and calls its `onSelect` — a
570
618
  * consumer's `onSelect` never needs to call `onClose` itself.
571
619
  */
620
+ /**
621
+ * MenuEntries — the `<ul role="menu">` item list itself, factored out of
622
+ * `Menu` so other adaptive-surface components (e.g. `ContextMenu`) can
623
+ * render the exact same items/destructive/checked/icon markup inside their
624
+ * own positioning shell, instead of re-deriving it and risking drift.
625
+ */
626
+ declare function MenuEntries({ items, onSelect, }: {
627
+ items: MenuEntry[];
628
+ /** Called after an item's own onSelect — typically the surface's onClose. */
629
+ onSelect: (entry: MenuItem) => void;
630
+ }): react.JSX.Element;
572
631
  declare function Menu({ trigger, open, onClose, items, 'aria-label': ariaLabel, align }: MenuProps): react.JSX.Element;
573
632
 
574
633
  interface ToastItem {
@@ -633,8 +692,132 @@ interface PageHeaderProps {
633
692
  description?: string;
634
693
  action?: ReactNode;
635
694
  className?: string;
695
+ /** Heading level for the title. Defaults to `1` for standalone use; pass
696
+ * `2` or `3` when the page already sits under a shell/plugin `<h1>`, to
697
+ * avoid a duplicate top-level heading. Visual style is unchanged at every
698
+ * level — only the rendered tag changes. */
699
+ headingLevel?: 1 | 2 | 3;
636
700
  }
637
- declare function PageHeader({ title, description, action, className }: PageHeaderProps): react.JSX.Element;
701
+ declare function PageHeader({ title, description, action, className, headingLevel, }: PageHeaderProps): react.JSX.Element;
702
+
703
+ interface PageContainerProps extends HTMLAttributes<HTMLDivElement> {
704
+ /** Constrains and centers content width. Adds no padding of its own — the
705
+ * runtime shell already pads plugin content. Defaults to 'md'. */
706
+ maxWidth?: 'sm' | 'md' | 'lg' | 'full';
707
+ children: ReactNode;
708
+ }
709
+ declare function PageContainer({ maxWidth, className, children, ...rest }: PageContainerProps): react.JSX.Element;
710
+
711
+ interface MobileHeaderProps extends HTMLAttributes<HTMLDivElement> {
712
+ /** The brand/logo element — already a complete, clickable link home (e.g. an
713
+ * instance logo wrapped in the consumer's own router `Link`). Always
714
+ * rendered. `MobileHeader` stays router-agnostic, so this is provided
715
+ * fully built rather than as a bare icon + href. Optional — omit it to get
716
+ * a default "S" badge (matching the runtime shell's own fallback brand
717
+ * icon when no instance logo is configured), sized and styled to the same
718
+ * 36px/radius-md convention a custom logo is expected to follow. */
719
+ logo?: ReactNode;
720
+ /** Optional contextual title rendered beside the logo (e.g. the active
721
+ * plugin's name). Absent by default — this is the one overridable part of
722
+ * the header. See RFC 0088. */
723
+ title?: string;
724
+ /** Notification bell — always rendered; not overridable.
725
+ * TODO: this is just an icon slot today (the consumer wires up its own
726
+ * click handler/content) — it doesn't yet accommodate a full notification
727
+ * feature (unread badge, dropdown panel, etc. — see the runtime shell's
728
+ * own NotificationBell). Deferred; revisit once a plugin actually needs
729
+ * more than a bare bell icon here. */
730
+ bell: ReactNode;
731
+ /** Avatar / account menu trigger — always rendered; not overridable. */
732
+ avatarMenu: ReactNode;
733
+ }
734
+ /**
735
+ * The mobile header bar: brand/logo (always shown), an optional contextual
736
+ * title, and a fixed bell + avatar-menu cluster. Owns its own chrome —
737
+ * background, border-bottom, sticky positioning, safe-area-aware padding,
738
+ * and a 768px max-width (so it never stretches full-bleed if mounted outside
739
+ * an actual mobile viewport) — matching the runtime shell's own mobile
740
+ * header exactly, since this component is meant to replace that hand-rolled
741
+ * markup. Presentational only — no data fetching; the consumer supplies
742
+ * `bell`/`avatarMenu` (and, optionally, `logo`) as already-wired components
743
+ * (their own sizing — 36px logo/avatar, 44px bell tap target — is the
744
+ * consumer's responsibility, matching the reference implementation in the
745
+ * runtime shell). See RFC 0088 for the immutable/overridable boundary this
746
+ * enforces.
747
+ */
748
+ declare function MobileHeader({ logo, title, bell, avatarMenu, className, ...rest }: MobileHeaderProps): react.JSX.Element;
749
+
750
+ interface FooterIcon {
751
+ icon: ReactNode;
752
+ label: string;
753
+ href?: string;
754
+ onClick?: () => void;
755
+ active?: boolean;
756
+ }
757
+ interface MobileFooterProps extends HTMLAttributes<HTMLElement> {
758
+ /** Opens the app drawer/launcher. Always rendered as the centered slot;
759
+ * not overridable. */
760
+ onOpenApps: () => void;
761
+ /** Custom launcher icon (e.g. a plugin-supplied image). Defaults to a
762
+ * generic grid icon. */
763
+ launcherIcon?: ReactNode;
764
+ /** Whether the launcher's own drawer is currently open (applies the
765
+ * pressed/active visual state). */
766
+ launcherOpen?: boolean;
767
+ /** 1 or 2 icons rendered to the left of the centered launcher. */
768
+ leftIcons: FooterIcon[];
769
+ /** 1 or 2 icons rendered to the right of the centered launcher. Must match
770
+ * `leftIcons.length` — the launcher stays visually centered, so a mismatch
771
+ * is flagged (dev-mode only, never thrown) rather than silently allowed. */
772
+ rightIcons: FooterIcon[];
773
+ }
774
+ /**
775
+ * The mobile footer bar: a centered, fixed "Apps" launcher flanked by 1 or 2
776
+ * overridable icons on each side (3 or 5 total, matching standard
777
+ * iOS/Android bottom-nav conventions). Owns its own chrome — background,
778
+ * border-top, safe-area-aware bottom padding, and a 768px max-width (so it
779
+ * never stretches full-bleed if mounted outside an actual mobile viewport)
780
+ * — matching the runtime shell's own mobile footer (MobileNav) exactly,
781
+ * since this component is meant to replace that hand-rolled markup.
782
+ * Presentational only — no data fetching; the consumer owns the
783
+ * drawer/overlay `onOpenApps` opens. See RFC 0088 for the
784
+ * immutable/overridable boundary this enforces.
785
+ */
786
+ declare function MobileFooter({ onOpenApps, launcherIcon, launcherOpen, leftIcons, rightIcons, className, ...rest }: MobileFooterProps): react.JSX.Element;
787
+
788
+ interface MobileAppsDrawerItem {
789
+ /** Stable identity for this tile — used as the React key. */
790
+ key: string;
791
+ icon: ReactNode;
792
+ label: string;
793
+ /** Renders an `<a>` when set; otherwise a `<button>` calling `onClick`. */
794
+ href?: string;
795
+ onClick?: () => void;
796
+ }
797
+ interface MobileAppsDrawerProps {
798
+ open: boolean;
799
+ onClose: () => void;
800
+ /** Accessible name for the drawer panel — required since there's no
801
+ * visible title to fall back to (Drawer's grab handle plus swipe-down /
802
+ * scrim-tap already cover dismissal, so no header row is rendered). */
803
+ 'aria-label': string;
804
+ /** The grid tiles — supplied by the consumer (e.g. installed plugins,
805
+ * a plugin's own sections). MobileAppsDrawer owns only the drawer
806
+ * chrome/grid layout, never the item list itself. */
807
+ items: MobileAppsDrawerItem[];
808
+ }
809
+ /**
810
+ * The mobile "Apps" drawer: a bottom sheet with a 3-column grid of icon
811
+ * tiles — same tile size (56px, radius 14px) and grid layout as the runtime
812
+ * shell's own Apps drawer (MobileNav's Drawer content), generalized so the
813
+ * tile list comes from the consumer (the shell passes installed plugins; a
814
+ * plugin composing its own MobileFooter launcher passes whatever its own
815
+ * "apps" are, e.g. a section index) rather than being hardcoded to plugins
816
+ * specifically. No header row (title/close button) — Drawer's own grab
817
+ * handle plus swipe-down/scrim-tap dismissal are enough, and a header ate
818
+ * into the limited vertical space a launcher grid needs most.
819
+ */
820
+ declare function MobileAppsDrawer({ open, onClose, items, ...rest }: MobileAppsDrawerProps): react.JSX.Element;
638
821
 
639
822
  interface EmptyStateProps {
640
823
  icon?: IconName;
@@ -645,6 +828,121 @@ interface EmptyStateProps {
645
828
  }
646
829
  declare function EmptyState({ icon, heading, description, action, className }: EmptyStateProps): react.JSX.Element;
647
830
 
831
+ interface OfflineGateProps {
832
+ children: ReactNode;
833
+ /** Defaults to a generic "this section" phrasing — pass the surface's own name. */
834
+ surfaceName?: string;
835
+ className?: string;
836
+ }
837
+ /**
838
+ * OfflineGate — blocks administrative/settings surfaces from rendering
839
+ * (possibly stale) cached content while the device has no network, showing an
840
+ * explanatory empty state instead (research 0012, epic task 2.32).
841
+ *
842
+ * Distinct from `OfflineBanner`: the banner is an informational overlay that
843
+ * coexists with normal content everywhere in the shell. This is a hard block
844
+ * for surfaces where operating against stale data is actively wrong — e.g. a
845
+ * Console user list or an Account billing page reflects a point-in-time
846
+ * snapshot the moment it's server-rendered, and any cached copy replayed
847
+ * later has no way to signal that it may already be stale. `OfflineGate`
848
+ * doesn't try to tell staleness apart from freshness; it removes the
849
+ * question by not rendering the content at all while offline.
850
+ *
851
+ * `children` is rendered unconditionally while online, so this adds no cost
852
+ * to the common case — it only decides what to show, never how the wrapped
853
+ * content itself is fetched or cached.
854
+ */
855
+ declare function OfflineGate({ children, surfaceName, className }: OfflineGateProps): react.JSX.Element;
856
+
857
+ interface DeviceOnlyGateProps {
858
+ children: ReactNode;
859
+ /** Defaults to a generic "this app" phrasing — pass the plugin's own name. */
860
+ surfaceName?: string;
861
+ /**
862
+ * The caller's own `isDeviceOnlyTierAvailable()` result (from
863
+ * `@sovereignfs/sdk/device-client`) — taken as a plain boolean rather than
864
+ * computed inside this component, so `@sovereignfs/ui` never depends on
865
+ * `@sovereignfs/sdk` (this package must stay usable standalone, outside the
866
+ * plugin runtime — RFC 0073).
867
+ */
868
+ available: boolean;
869
+ className?: string;
870
+ }
871
+ /**
872
+ * DeviceOnlyGate — blocks a `device-only`-tier plugin's content from
873
+ * rendering on a surface that cannot provide the durable, encrypted,
874
+ * device-auth-gated store that tier requires, showing an explanatory empty
875
+ * state instead of a broken screen (research 0012, epic tasks 2.33 + 3.36).
876
+ *
877
+ * A `device-only` plugin wraps its own root content in this the same way
878
+ * Console and Account wrap theirs in `OfflineGate` — an opt-in pattern each
879
+ * surface applies to itself, not a platform-level route gate. The launcher
880
+ * tile's own "Phone only" badge (`useOfflineTileState`) is advisory UI on top
881
+ * of this; this component is the actual gate, since a user can always reach a
882
+ * route directly (a bookmark, a deep link) without passing through the
883
+ * launcher tile at all.
884
+ *
885
+ * **Not a security boundary.** Availability here is a capability signal, not
886
+ * an authorization check — the real protection for `device-only` data is
887
+ * that it is encrypted and the key requires device auth to release (epic task
888
+ * 1.22), so it stays inaccessible regardless of whether this gate is present,
889
+ * bypassed, or simply never reached (e.g. a hand-crafted request against the
890
+ * plugin's own API routes).
891
+ */
892
+ declare function DeviceOnlyGate({ children, surfaceName, available, className, }: DeviceOnlyGateProps): react.JSX.Element;
893
+
894
+ /**
895
+ * `'checking'` covers the moment before the caller's own async status check
896
+ * resolves — same transitional-state pattern `EncryptionSection`'s local
897
+ * `LocalState` uses, so this gate never flashes an empty state before the
898
+ * real answer is known. `'no-device-auth'` is the hard-block case (RFC 0093
899
+ * §5, epic task 1.22): the environment supports the tier, but this device
900
+ * has no passcode, fingerprint, or face unlock configured, so a key cannot
901
+ * be created here at all — distinct from `'not-set-up'`, where it can.
902
+ */
903
+ type DeviceStorageKeyGateStatus = 'checking' | 'unsupported' | 'no-device-auth' | 'not-set-up' | 'set-up';
904
+ interface DeviceStorageKeyGateProps {
905
+ children: ReactNode;
906
+ /** Defaults to a generic "This app" phrasing — pass the plugin's own name. */
907
+ surfaceName?: string;
908
+ /**
909
+ * The caller's own `getDeviceStorageKeyStatus()` result (from
910
+ * `@sovereignfs/sdk/device-only-storage`) — taken as a plain status rather
911
+ * than computed inside this component, so `@sovereignfs/ui` never depends
912
+ * on `@sovereignfs/sdk` (same boundary `DeviceOnlyGate`'s `available` prop
913
+ * draws — this package must stay usable standalone, outside the plugin
914
+ * runtime — RFC 0073).
915
+ */
916
+ status: DeviceStorageKeyGateStatus;
917
+ /**
918
+ * Rendered under the "not set up" message — typically a link to Account →
919
+ * Security. Not built in here: this package depends on no router, so the
920
+ * caller supplies its own navigable element (a plain `<a>`, a framework
921
+ * `<Link>`, whatever the host app uses).
922
+ */
923
+ setupAction?: ReactNode;
924
+ className?: string;
925
+ }
926
+ /**
927
+ * DeviceStorageKeyGate — blocks a `device-only`-tier plugin's content until
928
+ * the user has set up their Device Storage Key (RFC 0093 §2, epic task
929
+ * 1.22). Distinct from `DeviceOnlyGate`: that one checks whether the *tier
930
+ * itself* is available on this surface (native shell, secure-storage bridge
931
+ * present); this one checks whether the user has actually completed the
932
+ * one-time, per-device enrollment that tier depends on. A `device-only`
933
+ * plugin typically wants both — `DeviceOnlyGate` outermost (no point
934
+ * checking enrollment on a surface that cannot offer the tier at all), this
935
+ * gate inside it.
936
+ *
937
+ * Enrollment is centralized and decoupled from any single plugin (RFC 0093
938
+ * §2): a plugin that finds no key set up does not run its own enrollment
939
+ * ceremony inline. It stops here and points the user at Account → Security —
940
+ * the one place enrollment happens for every `device-only` plugin on this
941
+ * device — via `setupAction`, the same opt-in, self-applied pattern
942
+ * `OfflineGate`/`DeviceOnlyGate` already use for their own surfaces.
943
+ */
944
+ declare function DeviceStorageKeyGate({ children, surfaceName, status, setupAction, className, }: DeviceStorageKeyGateProps): react.JSX.Element | null;
945
+
648
946
  interface SpinnerProps {
649
947
  size?: 'sm' | 'md' | 'lg';
650
948
  label?: string;
@@ -665,12 +963,25 @@ interface NavTabItem {
665
963
  href: string;
666
964
  active?: boolean;
667
965
  }
966
+ /** Props to spread onto a consumer-supplied link element — keeps NavTabs' own
967
+ * class names and a11y attributes in sync with whatever the consumer renders. */
968
+ interface NavTabLinkProps {
969
+ href: string;
970
+ className: string;
971
+ 'aria-current': 'page' | undefined;
972
+ children: ReactNode;
973
+ }
668
974
  interface NavTabsProps {
669
975
  items: NavTabItem[];
670
976
  className?: string;
671
977
  'aria-label'?: string;
978
+ /** Render a tab as something other than a plain `<a href>` — e.g. Next's
979
+ * `<Link replace>` inside an overlay-shell plugin, where a full page
980
+ * navigation would break the dialog's history contract. Receives the item
981
+ * plus the class name/aria attributes NavTabs would otherwise apply. */
982
+ renderLink?: (item: NavTabItem, linkProps: NavTabLinkProps) => ReactNode;
672
983
  }
673
- declare function NavTabs({ items, className, 'aria-label': ariaLabel }: NavTabsProps): react.JSX.Element;
984
+ declare function NavTabs({ items, className, 'aria-label': ariaLabel, renderLink }: NavTabsProps): react.JSX.Element;
674
985
 
675
986
  interface TooltipProps {
676
987
  content: string;
@@ -689,6 +1000,595 @@ interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'typ
689
1000
  }
690
1001
  declare function Checkbox({ checked, onChange, label, strikeThrough, disabled, className, id, ...rest }: CheckboxProps): react.JSX.Element;
691
1002
 
1003
+ interface RadioGroupItem {
1004
+ label: string;
1005
+ value: string;
1006
+ disabled?: boolean;
1007
+ }
1008
+ interface RadioGroupProps {
1009
+ items: RadioGroupItem[];
1010
+ value: string;
1011
+ onChange: (value: string) => void;
1012
+ /** Groups the underlying native radios. Auto-generated when omitted —
1013
+ * only pass this to participate in a native, non-React form submission. */
1014
+ name?: string;
1015
+ /** Disables every item. Use `items[].disabled` to disable one. */
1016
+ disabled?: boolean;
1017
+ id?: string;
1018
+ className?: string;
1019
+ 'aria-label'?: string;
1020
+ 'aria-labelledby'?: string;
1021
+ 'aria-describedby'?: string;
1022
+ 'aria-invalid'?: boolean;
1023
+ required?: boolean;
1024
+ }
1025
+ /**
1026
+ * RadioGroup — single-select list of options.
1027
+ *
1028
+ * Renders real `<input type="radio">` elements sharing one `name`, visually
1029
+ * hidden behind a custom circle (same technique as `Checkbox`). Keyboard
1030
+ * arrow-key navigation between options is native browser behavior for
1031
+ * grouped radio inputs — nothing to hand-roll here.
1032
+ */
1033
+ declare function RadioGroup({ items, value, onChange, name, disabled, id, className, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, required, }: RadioGroupProps): react.JSX.Element;
1034
+
1035
+ interface SliderProps {
1036
+ value: number;
1037
+ onChange: (value: number) => void;
1038
+ min: number;
1039
+ max: number;
1040
+ step?: number;
1041
+ /** Renders a visible label above the track. Omit and pass `aria-label`
1042
+ * instead for a standalone, unlabeled slider. */
1043
+ label?: string;
1044
+ disabled?: boolean;
1045
+ id?: string;
1046
+ className?: string;
1047
+ 'aria-label'?: string;
1048
+ 'aria-describedby'?: string;
1049
+ 'aria-invalid'?: boolean;
1050
+ required?: boolean;
1051
+ }
1052
+ /**
1053
+ * Slider — single-thumb range input.
1054
+ *
1055
+ * A native `<input type="range">` under custom track/thumb styling — arrow
1056
+ * key (adjust by `step`), Home/End (jump to min/max), and touch-drag
1057
+ * support all come from the browser, nothing hand-rolled. Dual-thumb/range
1058
+ * selection is out of scope until a consumer needs it.
1059
+ */
1060
+ declare function Slider({ value, onChange, min, max, step, label, disabled, id, className, 'aria-label': ariaLabel, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, required, }: SliderProps): react.JSX.Element;
1061
+
1062
+ interface ProgressProps {
1063
+ /** 0–100. Values outside that range are clamped. */
1064
+ value: number;
1065
+ /** Accessible name — Progress has no visible text of its own. */
1066
+ label?: string;
1067
+ id?: string;
1068
+ className?: string;
1069
+ }
1070
+ /**
1071
+ * Progress — determinate bar.
1072
+ *
1073
+ * `role="progressbar"` with `aria-valuenow`/`aria-valuemin`/`aria-valuemax`
1074
+ * so screen readers announce the current value. Indeterminate state is out
1075
+ * of scope until a consumer needs it.
1076
+ */
1077
+ declare function Progress({ value, label, id, className }: ProgressProps): react.JSX.Element;
1078
+
1079
+ interface TableProps {
1080
+ children: ReactNode;
1081
+ className?: string;
1082
+ }
1083
+ /**
1084
+ * Table — thin, styled wrappers around the native table elements.
1085
+ *
1086
+ * Not a data grid: no sort, filter, or virtualization. `Table` wraps its
1087
+ * content in a horizontally-scrolling container (masked-edge fade, hidden
1088
+ * scrollbar — same technique as `NavTabs`) so a table wider than its
1089
+ * container scrolls instead of overflowing the page, at any viewport size.
1090
+ */
1091
+ declare function Table({ children, className }: TableProps): react.JSX.Element;
1092
+ declare function TableHead({ children }: {
1093
+ children: ReactNode;
1094
+ }): react.JSX.Element;
1095
+ declare function TableBody({ children }: {
1096
+ children: ReactNode;
1097
+ }): react.JSX.Element;
1098
+ declare function TableRow({ children }: {
1099
+ children: ReactNode;
1100
+ }): react.JSX.Element;
1101
+ declare function TableHeaderCell({ children, ...rest }: ThHTMLAttributes<HTMLTableCellElement>): react.JSX.Element;
1102
+ declare function TableCell({ children, ...rest }: TdHTMLAttributes<HTMLTableCellElement>): react.JSX.Element;
1103
+
1104
+ type AlertVariant = 'info' | 'success' | 'warning' | 'error' | 'neutral';
1105
+ interface AlertProps {
1106
+ variant: AlertVariant;
1107
+ heading?: string;
1108
+ /** Leading icon next to the heading. Defaults to a per-variant icon (see
1109
+ * `DEFAULT_ICON`) — pass an `IconName` to override it, or `false` to
1110
+ * suppress the icon entirely. Purely decorative: the variant's colour and
1111
+ * `heading`/`children` text already carry the meaning. */
1112
+ icon?: IconName | false;
1113
+ children: ReactNode;
1114
+ id?: string;
1115
+ className?: string;
1116
+ }
1117
+ /**
1118
+ * Alert — inline, non-dismissible banner.
1119
+ *
1120
+ * Distinct from `Toast` (transient, auto-dismissing) and `SystemBanner`
1121
+ * (instance-wide): Alert is for in-context messaging — form-level errors,
1122
+ * or explaining an empty/blocked state.
1123
+ *
1124
+ * `role="alert"` for `error` (interrupts screen readers immediately, since
1125
+ * an error demands attention); `role="status"` for the other variants
1126
+ * (announced politely, without interrupting).
1127
+ */
1128
+ declare function Alert({ variant, heading, icon, children, id, className }: AlertProps): react.JSX.Element;
1129
+
1130
+ interface BreadcrumbItem {
1131
+ label: string;
1132
+ /** Omit for the current page — rendered as plain text with aria-current. */
1133
+ href?: string;
1134
+ }
1135
+ interface BreadcrumbProps {
1136
+ items: BreadcrumbItem[];
1137
+ /** Renders a linked item. Defaults to a plain `<a href>`, which causes a
1138
+ * full page reload — pass Next's `<Link>` (or equivalent) to keep
1139
+ * navigation client-side, which matters inside overlay-shell plugins
1140
+ * where a full reload breaks the router.back()-driven dismiss flow. */
1141
+ renderLink?: (item: BreadcrumbItem, children: ReactNode) => ReactNode;
1142
+ className?: string;
1143
+ 'aria-label'?: string;
1144
+ }
1145
+ declare function Breadcrumb({ items, renderLink, className, 'aria-label': ariaLabel, }: BreadcrumbProps): react.JSX.Element;
1146
+
1147
+ interface PaginationProps {
1148
+ /** 1-indexed current page. */
1149
+ page: number;
1150
+ totalPages: number;
1151
+ onChange: (page: number) => void;
1152
+ className?: string;
1153
+ 'aria-label'?: string;
1154
+ }
1155
+ declare function Pagination({ page, totalPages, onChange, className, 'aria-label': ariaLabel, }: PaginationProps): react.JSX.Element;
1156
+
1157
+ interface KbdProps {
1158
+ children: ReactNode;
1159
+ className?: string;
1160
+ }
1161
+ /** Kbd — inline keyboard-key styling. Renders a real `<kbd>` element. */
1162
+ declare function Kbd({ children, className }: KbdProps): react.JSX.Element;
1163
+
1164
+ interface CollapsibleProps {
1165
+ open: boolean;
1166
+ onOpenChange: (open: boolean) => void;
1167
+ trigger: ReactNode;
1168
+ children: ReactNode;
1169
+ id?: string;
1170
+ className?: string;
1171
+ }
1172
+ /**
1173
+ * Collapsible — single expand/collapse primitive. Independently useful
1174
+ * (e.g. a "show more" toggle), and composed internally by `Accordion`.
1175
+ *
1176
+ * The expand/collapse animation uses `grid-template-rows: 0fr` → `1fr`
1177
+ * rather than animating `height`, which can't transition to/from `auto`
1178
+ * in CSS without JS-measuring pixel heights. Collapsed content stays in
1179
+ * the DOM (so no layout jump on re-open) but is marked `inert` — removed
1180
+ * from the tab order and the accessibility tree — so it isn't reachable
1181
+ * while hidden.
1182
+ */
1183
+ declare function Collapsible({ open, onOpenChange, trigger, children, id, className, }: CollapsibleProps): react.JSX.Element;
1184
+
1185
+ interface AccordionItem {
1186
+ id: string;
1187
+ trigger: ReactNode;
1188
+ content: ReactNode;
1189
+ }
1190
+ interface AccordionProps {
1191
+ items: AccordionItem[];
1192
+ /** `single` closes other sections when one opens. `multiple` allows any
1193
+ * number of sections open at once. */
1194
+ type: 'single' | 'multiple';
1195
+ openIds: string[];
1196
+ onOpenIdsChange: (openIds: string[]) => void;
1197
+ className?: string;
1198
+ }
1199
+ /**
1200
+ * Accordion — one or more `Collapsible` sections.
1201
+ *
1202
+ * Keyboard support (Enter/Space toggles the focused trigger) comes from
1203
+ * `Collapsible`'s real `<button>` — no arrow-key roving-tabindex handling
1204
+ * here, since accordion sections aren't a roving-tabindex widget per the
1205
+ * WAI-ARIA accordion pattern (each trigger is independently Tab-focusable).
1206
+ */
1207
+ declare function Accordion({ items, type, openIds, onOpenIdsChange, className }: AccordionProps): react.JSX.Element;
1208
+
1209
+ interface AspectRatioProps {
1210
+ /** Width / height, e.g. 16 / 9 or 1. */
1211
+ ratio: number;
1212
+ children: ReactNode;
1213
+ className?: string;
1214
+ }
1215
+ /** AspectRatio — constrains content (image, video, embed) to a fixed ratio. */
1216
+ declare function AspectRatio({ ratio, children, className }: AspectRatioProps): react.JSX.Element;
1217
+
1218
+ interface ButtonGroupProps {
1219
+ /** Adjacent Button elements. */
1220
+ children: ReactNode;
1221
+ className?: string;
1222
+ 'aria-label'?: string;
1223
+ }
1224
+ /**
1225
+ * ButtonGroup — visually joins adjacent `Button`s into one control (shared
1226
+ * border, connected corners). Targets its children's rendered `<button>`/
1227
+ * `<a>` elements directly rather than requiring a special child component,
1228
+ * so it works with plain `Button`.
1229
+ */
1230
+ declare function ButtonGroup({ children, className, 'aria-label': ariaLabel }: ButtonGroupProps): react.JSX.Element;
1231
+
1232
+ interface ItemProps {
1233
+ leading?: ReactNode;
1234
+ title: ReactNode;
1235
+ description?: ReactNode;
1236
+ trailing?: ReactNode;
1237
+ /** Renders as a button when given; a plain row otherwise. */
1238
+ onClick?: () => void;
1239
+ disabled?: boolean;
1240
+ className?: string;
1241
+ }
1242
+ /**
1243
+ * Item — generic row primitive: leading slot, title + optional description,
1244
+ * trailing slot. The building block for settings rows, list rows, and
1245
+ * menu-adjacent rows that don't fit `Menu`'s own item shape.
1246
+ */
1247
+ declare function Item({ leading, title, description, trailing, onClick, disabled, className, }: ItemProps): react.JSX.Element;
1248
+
1249
+ interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
1250
+ disabled?: boolean;
1251
+ }
1252
+ /**
1253
+ * Label — standalone accessible form label, independent of `FormField`.
1254
+ * Use `FormField` when a control needs hint/error text too; use `Label`
1255
+ * directly for a bare label (e.g. next to a `Checkbox` group heading).
1256
+ */
1257
+ declare function Label({ disabled, className, children, ...rest }: LabelProps): react.JSX.Element;
1258
+
1259
+ interface ScrollAreaProps {
1260
+ children: ReactNode;
1261
+ /** Constrains the scrollable direction; content taller/wider than this scrolls. */
1262
+ maxHeight?: string | number;
1263
+ maxWidth?: string | number;
1264
+ className?: string;
1265
+ }
1266
+ /**
1267
+ * ScrollArea — a styled scrollable container (thin, token-colored scrollbar
1268
+ * instead of the OS default). Native overflow scrolling underneath — no
1269
+ * virtualization, no custom scroll physics.
1270
+ */
1271
+ declare function ScrollArea({ children, maxHeight, maxWidth, className }: ScrollAreaProps): react.JSX.Element;
1272
+
1273
+ type TypographyVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'body' | 'caption' | 'label';
1274
+ interface TypographyProps {
1275
+ variant: TypographyVariant;
1276
+ children: ReactNode;
1277
+ /** Override the rendered tag while keeping the variant's visual style —
1278
+ * e.g. `variant="h1" as="div"` to avoid a second `<h1>` on a page that
1279
+ * already has one. */
1280
+ as?: ElementType;
1281
+ className?: string;
1282
+ }
1283
+ /** Typography — text bound to the design system's font-size/weight scale. */
1284
+ declare function Typography({ variant, children, as, className }: TypographyProps): react.JSX.Element;
1285
+
1286
+ interface MarkerProps {
1287
+ /** The number shown in the marker, e.g. 1, 2, 3. */
1288
+ index: number;
1289
+ /** Accessible label describing the citation, e.g. "Source: Notes". */
1290
+ label: string;
1291
+ /** Reveals source details (e.g. opens a source trace panel) when given. */
1292
+ onClick?: () => void;
1293
+ className?: string;
1294
+ }
1295
+ /**
1296
+ * Marker — inline citation/reference marker, for attributing part of an
1297
+ * assistant's answer to a source (matches RFC 0040's "source trace" —
1298
+ * Harness shows which plugin/data source informed an answer).
1299
+ */
1300
+ declare function Marker({ index, label, onClick, className }: MarkerProps): react.JSX.Element;
1301
+
1302
+ type MessageSender = 'user' | 'assistant' | 'tool';
1303
+ interface MessageProps {
1304
+ /** Matches the three roles Sovereign Harness stores per RFC 0040:
1305
+ * user, assistant, and tool messages. Named `sender`, not `role`, to
1306
+ * avoid colliding with the ARIA `role` attribute in JSX tooling. */
1307
+ sender: MessageSender;
1308
+ children?: ReactNode;
1309
+ /** Shows a "thinking" indicator instead of children — before the first
1310
+ * token of a streaming response arrives. Once content starts streaming
1311
+ * in, pass it as children and stop passing `pending`. */
1312
+ pending?: boolean;
1313
+ /** Rendered in a small row below the bubble — e.g. "Forget this" (RFC
1314
+ * 0040's per-message memory action), "Copy", "Regenerate". */
1315
+ actions?: ReactNode;
1316
+ className?: string;
1317
+ }
1318
+ /** Message — a single chat turn. Content is caller-controlled `ReactNode`
1319
+ * (markdown rendering, if any, is the consumer's choice, not baked in here). */
1320
+ declare function Message({ sender, children, pending, actions, className }: MessageProps): react.JSX.Element;
1321
+
1322
+ interface MessageScrollerProps {
1323
+ children: ReactNode;
1324
+ className?: string;
1325
+ }
1326
+ /**
1327
+ * MessageScroller — auto-scrolling chat container.
1328
+ *
1329
+ * Scrolls to the newest message automatically, but only while the user is
1330
+ * already near the bottom. If they've scrolled up to read history, new
1331
+ * content does not yank them back down — a "New messages" button appears
1332
+ * instead, matching the pattern every chat product (Slack, Discord,
1333
+ * ChatGPT) already uses.
1334
+ */
1335
+ declare function MessageScroller({ children, className }: MessageScrollerProps): react.JSX.Element;
1336
+
1337
+ interface HoverCardProps {
1338
+ /** The element that opens the card — cloned with hover/focus handlers
1339
+ * (desktop) or a tap handler (touch). */
1340
+ trigger: ReactElement;
1341
+ children: ReactNode;
1342
+ align?: 'left' | 'right';
1343
+ width?: number | 'trigger';
1344
+ 'aria-label': string;
1345
+ }
1346
+ /**
1347
+ * HoverCard — hover-triggered popover on desktop, tap-to-toggle on touch.
1348
+ *
1349
+ * Built on `Popover` rather than reimplementing positioning/collision
1350
+ * detection: this only adds the hover-intent open/close timing (avoids
1351
+ * flicker on an accidental mouse pass-over, and gives the pointer time to
1352
+ * travel from the trigger to the card itself across the gap between them)
1353
+ * and the touch fallback. Also opens on keyboard focus and closes on blur —
1354
+ * a hover-only trigger is a WCAG failure, since keyboard users can't hover.
1355
+ */
1356
+ declare function HoverCard({ trigger, children, align, width, 'aria-label': ariaLabel, }: HoverCardProps): react.JSX.Element;
1357
+
1358
+ interface ContextMenuProps {
1359
+ /** The element that gets right-click (desktop) / long-press (touch)
1360
+ * behavior — cloned with the trigger handlers, rendered as-is otherwise.
1361
+ * Typed with `<any>` props (not a bare `ReactElement`, whose implicit
1362
+ * `unknown` props type makes `cloneElement` reject *both* branches of
1363
+ * the long-press/onContextMenu union below — an interface value like
1364
+ * `LongPressHandlers` isn't assignable to an indexed props type without
1365
+ * its own index signature) — the standard, narrowly-scoped escape hatch
1366
+ * for "clone an arbitrary child with props not known ahead of time". */
1367
+ children: ReactElement<any>;
1368
+ items: MenuEntry[];
1369
+ 'aria-label': string;
1370
+ }
1371
+ /**
1372
+ * ContextMenu — right-click menu on desktop, long-press on touch.
1373
+ *
1374
+ * Desktop positioning reuses `Popover`'s existing collision-detection logic
1375
+ * rather than reimplementing it: the panel is wrapped in a zero-size,
1376
+ * `position: fixed` anchor placed at the click coordinates, so `Popover`
1377
+ * measures and flips against *that* point exactly as it would a normal
1378
+ * trigger element.
1379
+ *
1380
+ * Touch uses `useLongPress` (which already handles the OS's own long-press
1381
+ * callout/context-menu suppression) and opens the same items in a `Drawer`
1382
+ * bottom sheet — the same adaptive-surface split `Menu` already uses,
1383
+ * because a floating panel positioned at a touch point isn't a pattern
1384
+ * touch interfaces have in the first place.
1385
+ */
1386
+ declare function ContextMenu({ children, items, 'aria-label': ariaLabel }: ContextMenuProps): react.JSX.Element;
1387
+
1388
+ interface NavigationMenuItem {
1389
+ label: string;
1390
+ /** A plain link with no flyout — mutually exclusive with `content`. */
1391
+ href?: string;
1392
+ /** Flyout panel content shown when this item is triggered. Pass a
1393
+ * function instead of a plain node when the content needs to close its
1394
+ * own flyout after an action (e.g. `Menubar`'s menu items) — it receives
1395
+ * a `close` callback. */
1396
+ content?: ReactNode | ((close: () => void) => ReactNode);
1397
+ }
1398
+ interface NavigationMenuProps {
1399
+ items: NavigationMenuItem[];
1400
+ /** Renders a plain-link item's anchor. Defaults to `<a href>`, which
1401
+ * causes a full page reload — pass Next's `<Link>` (or equivalent) to
1402
+ * keep navigation client-side. */
1403
+ renderLink?: (href: string, children: ReactNode) => ReactNode;
1404
+ 'aria-label'?: string;
1405
+ }
1406
+ /**
1407
+ * NavigationMenu — top-level nav bar where some items open a flyout panel.
1408
+ *
1409
+ * Desktop-oriented by design — a hover-triggered flyout bar has no mobile
1410
+ * equivalent (Research 0004); it renders as-is on touch rather than
1411
+ * attempting a redesign no consumer has asked for yet.
1412
+ *
1413
+ * Each flyout is its own `Popover` instance rather than one shared
1414
+ * positioned panel, reusing its collision detection per item. Once one
1415
+ * flyout is open, moving the pointer to a sibling trigger switches directly
1416
+ * to that one — standard menu-bar behavior — and ArrowLeft/ArrowRight move
1417
+ * focus between top-level triggers (a roving-tabindex bar, per the
1418
+ * WAI-ARIA menu pattern), Escape closes.
1419
+ */
1420
+ declare function NavigationMenu({ items, renderLink, 'aria-label': ariaLabel, }: NavigationMenuProps): react.JSX.Element;
1421
+
1422
+ interface MenubarMenu {
1423
+ label: string;
1424
+ items: MenuEntry[];
1425
+ }
1426
+ interface MenubarProps {
1427
+ menus: MenubarMenu[];
1428
+ 'aria-label'?: string;
1429
+ }
1430
+ /**
1431
+ * Menubar — desktop app-style menu bar (File / Edit / View...). A thin
1432
+ * composition of `NavigationMenu` (top-level triggers, per-item flyout
1433
+ * positioning, hover-switches-when-one-is-open, arrow-key navigation) with
1434
+ * `MenuEntries` (the same item list markup `Menu`'s dropdowns use) as each
1435
+ * item's flyout content — no positioning or list-rendering logic
1436
+ * duplicated from either.
1437
+ */
1438
+ declare function Menubar({ menus, 'aria-label': ariaLabel }: MenubarProps): react.JSX.Element;
1439
+
1440
+ interface CommandItem {
1441
+ id: string;
1442
+ label: string;
1443
+ onSelect: () => void;
1444
+ icon?: IconName;
1445
+ /** Section header this item is grouped under. */
1446
+ group?: string;
1447
+ /** Extra searchable text beyond the label (keywords, description). */
1448
+ keywords?: string;
1449
+ }
1450
+ interface CommandProps {
1451
+ open: boolean;
1452
+ onClose: () => void;
1453
+ items: CommandItem[];
1454
+ placeholder?: string;
1455
+ 'aria-label'?: string;
1456
+ }
1457
+ /**
1458
+ * Command — a ⌘K-style palette. Opened via `Dialog`, which supplies the
1459
+ * modal shell (scrim, panel, mobile full-screen sheet, focus handling) —
1460
+ * this only adds the search input, filtering, and arrow-key/Enter
1461
+ * selection on top of it. Controlled (`open`/`onClose`): the consumer wires
1462
+ * up their own global shortcut listener to flip `open` — a DS primitive
1463
+ * shouldn't own a document-level keydown listener itself.
1464
+ */
1465
+ declare function Command({ open, onClose, items, placeholder, 'aria-label': ariaLabel, }: CommandProps): react.JSX.Element;
1466
+
1467
+ type ResizableDirection = 'horizontal' | 'vertical';
1468
+ interface ResizablePanelProps {
1469
+ /** Initial size as a percentage of the group's main axis. Defaults to an
1470
+ * equal split across all panels in the group. */
1471
+ defaultSize?: number;
1472
+ /** Minimum size as a percentage. Defaults to 10. */
1473
+ minSize?: number;
1474
+ /** Maximum size as a percentage. Defaults to 90. */
1475
+ maxSize?: number;
1476
+ children?: ReactNode;
1477
+ className?: string;
1478
+ /** Injected by ResizablePanelGroup — not part of the public API. */
1479
+ style?: CSSProperties;
1480
+ }
1481
+ /** One pane of a ResizablePanelGroup. Sizing is computed and injected by the
1482
+ * group (via defaultSize/minSize/maxSize read off this element's props) —
1483
+ * this component only renders the scrollable content box. */
1484
+ declare function ResizablePanel({ children, className, style }: ResizablePanelProps): react.JSX.Element;
1485
+ interface ResizableHandleProps {
1486
+ 'aria-label'?: string;
1487
+ /** Injected by ResizablePanelGroup — not part of the public API. */
1488
+ direction?: ResizableDirection;
1489
+ onPointerDown?: (e: PointerEvent<HTMLDivElement>) => void;
1490
+ onKeyDown?: (e: KeyboardEvent<HTMLDivElement>) => void;
1491
+ 'aria-valuenow'?: number;
1492
+ 'aria-valuemin'?: number;
1493
+ 'aria-valuemax'?: number;
1494
+ }
1495
+ /** The draggable divider between two ResizablePanels. Placed directly
1496
+ * between the two ResizablePanel elements it resizes — the group pairs each
1497
+ * handle with its preceding and following panel by position.
1498
+ *
1499
+ * A `div` with `role="separator"` and `tabIndex=0` (the WAI-ARIA "window
1500
+ * splitter" pattern), not a `<button>` — `separator` is a non-interactive
1501
+ * role, and a native button's implicit role can't be overridden to it. */
1502
+ declare function ResizableHandle({ 'aria-label': ariaLabel, direction, onPointerDown, onKeyDown, 'aria-valuenow': valueNow, 'aria-valuemin': valueMin, 'aria-valuemax': valueMax, }: ResizableHandleProps): react.JSX.Element;
1503
+ interface ResizablePanelGroupProps {
1504
+ direction: ResizableDirection;
1505
+ /** Alternating ResizablePanel / ResizableHandle elements — N panels
1506
+ * separated by N-1 handles. */
1507
+ children: ReactNode;
1508
+ className?: string;
1509
+ }
1510
+ /**
1511
+ * ResizablePanelGroup — a row or column of resizable panes (editor layouts,
1512
+ * multi-pane inspectors). Each handle resizes only its two immediate
1513
+ * neighbor panels (drag redistributes size between them, clamped to both
1514
+ * panels' own min/max, so their combined size is a fixed invariant for the
1515
+ * duration of one drag) — the same handle-local model most resizable-panel
1516
+ * implementations use, rather than redistributing across the whole group.
1517
+ *
1518
+ * Desktop-oriented, like NavigationMenu — a drag handle has no direct touch
1519
+ * equivalent; panels render at their default sizes on touch rather than
1520
+ * attempting a redesign no consumer has asked for yet. For a two-pane
1521
+ * layout that also needs a mobile single-column fallback, use SplitPane
1522
+ * instead.
1523
+ *
1524
+ * `direction="vertical"` needs a definite-height ancestor — percentage
1525
+ * flex-basis on a column's children only resolves against one.
1526
+ */
1527
+ declare function ResizablePanelGroup({ direction, children, className }: ResizablePanelGroupProps): react.JSX.Element;
1528
+
1529
+ type SortDirection = 'asc' | 'desc';
1530
+ interface DataTableColumn<T> {
1531
+ key: string;
1532
+ header: string;
1533
+ sortable?: boolean;
1534
+ /** Cell content. Defaults to String(row[key]) when omitted. */
1535
+ render?: (row: T) => ReactNode;
1536
+ /** Value compared when sorting by this column. Defaults to row[key].
1537
+ * Required if `key` isn't a property on T (a computed/joined column). */
1538
+ sortValue?: (row: T) => string | number;
1539
+ align?: 'start' | 'end';
1540
+ }
1541
+ interface DataTableProps<T> {
1542
+ columns: DataTableColumn<T>[];
1543
+ data: T[];
1544
+ getRowKey: (row: T) => string;
1545
+ /** Initial sort — uncontrolled after mount, like Table itself has no
1546
+ * externally-controlled state. */
1547
+ defaultSortKey?: string;
1548
+ defaultSortDirection?: SortDirection;
1549
+ emptyMessage?: string;
1550
+ className?: string;
1551
+ }
1552
+ /**
1553
+ * DataTable — sortable table built on Table's own primitives (no
1554
+ * virtualization or filtering — those stay out of scope, matching Table's
1555
+ * own "not a data grid" boundary). Column-driven: pass `columns` + `data`
1556
+ * rather than composing `<TableRow>`/`<TableCell>` by hand.
1557
+ *
1558
+ * Sort state is internal (uncontrolled) and click-cycles
1559
+ * ascending → descending → unsorted for a sortable column, mirroring the
1560
+ * "toggle → toggle → clear" pattern most sortable tables use rather than
1561
+ * being permanently stuck in whichever direction was clicked last.
1562
+ */
1563
+ declare function DataTable<T>({ columns, data, getRowKey, defaultSortKey, defaultSortDirection, emptyMessage, className, }: DataTableProps<T>): react.JSX.Element;
1564
+
1565
+ interface ComboboxOption {
1566
+ value: string;
1567
+ label: string;
1568
+ }
1569
+ interface ComboboxProps {
1570
+ options: ComboboxOption[];
1571
+ value: string | null;
1572
+ onChange: (value: string) => void;
1573
+ placeholder?: string;
1574
+ searchPlaceholder?: string;
1575
+ emptyMessage?: string;
1576
+ 'aria-label': string;
1577
+ disabled?: boolean;
1578
+ className?: string;
1579
+ }
1580
+ /**
1581
+ * Combobox — a searchable single-select: `Popover` on desktop, a bottom-sheet
1582
+ * `Drawer` on mobile (the platform's standard adaptive-surface pattern,
1583
+ * matching `Menu` and `DatePicker`). For a fixed, short option list where
1584
+ * search adds no value, use `Select`'s native `<select>` instead — this is
1585
+ * for option lists long enough that typing to filter beats scanning.
1586
+ *
1587
+ * The trigger is built in, like `DatePicker` — a combobox is a form field,
1588
+ * not an arbitrary action-menu trigger.
1589
+ */
1590
+ declare function Combobox({ options, value, onChange, placeholder, searchPlaceholder, emptyMessage, 'aria-label': ariaLabel, disabled, className, }: ComboboxProps): react.JSX.Element;
1591
+
692
1592
  interface DragHandleRowProps extends HTMLAttributes<HTMLDivElement> {
693
1593
  children: ReactNode;
694
1594
  /** Pass drag-listener and drag-control props from dnd-kit here. */
@@ -1099,6 +1999,57 @@ declare const MOBILE_BREAKPOINT_PX = 768;
1099
1999
  */
1100
2000
  declare function useIsMobile(breakpointPx?: number): boolean;
1101
2001
 
2002
+ /**
2003
+ * useIsOffline — whether the browser currently has no network connection.
2004
+ *
2005
+ * SSR-safe: always initialises to `false` (online) so the server-rendered HTML
2006
+ * matches the first client render, then reads the real `navigator.onLine`
2007
+ * value in `useEffect`. This picks up the case where the page loaded already
2008
+ * offline (e.g. served from the service-worker cache) at the cost of an
2009
+ * imperceptible one-frame delay before the offline state appears — the same
2010
+ * trade-off `OfflineBanner` makes, which this hook was extracted from so every
2011
+ * consumer shares one connectivity source instead of re-deriving it slightly
2012
+ * differently (research 0012, epic task 2.32).
2013
+ *
2014
+ * Reflects only `navigator.onLine` — true whenever the OS reports a network
2015
+ * interface is up, even without real upstream connectivity (e.g. Wi-Fi with no
2016
+ * internet). That is a known limitation of the browser API itself, not of this
2017
+ * hook; there is currently no better cross-browser signal available.
2018
+ */
2019
+ declare function useIsOffline(): boolean;
2020
+
2021
+ /**
2022
+ * The two reasons an app tile can be non-interactive, kept structurally
2023
+ * distinct because they have different causes and must never read as the same
2024
+ * thing to a user (research 0012, epic task 2.33):
2025
+ *
2026
+ * - `'connectivity-dimmed'` — a no-offline-tier app, dimmed only while the
2027
+ * device is **actually offline right now**. Reactive and temporary; clears
2028
+ * the instant connectivity returns.
2029
+ * - `'capability-restricted'` — a `device-only` app on a surface without the
2030
+ * durable, encrypted, device-auth-gated store it needs. Static and
2031
+ * unrelated to connectivity — it stays restricted even when fully online,
2032
+ * and must never say "offline" to a user who plainly isn't.
2033
+ */
2034
+ type OfflineTileState = 'connectivity-dimmed' | 'capability-restricted' | null;
2035
+ /**
2036
+ * Which of the two states, if any, applies to an app tile given its declared
2037
+ * offline tier.
2038
+ *
2039
+ * `deviceOnlyAvailable` is the caller's own
2040
+ * `isDeviceOnlyTierAvailable()` result (from
2041
+ * `@sovereignfs/sdk/device-client`) — deliberately taken as a plain boolean
2042
+ * parameter rather than computed inside this hook, so `@sovereignfs/ui` never
2043
+ * depends on `@sovereignfs/sdk` (this package must stay usable standalone,
2044
+ * outside the plugin runtime — RFC 0073).
2045
+ *
2046
+ * An `offline-first` app is never restricted by either state: that tier's
2047
+ * whole point is working with no network, so it stays fully interactive both
2048
+ * online and offline. A `device-only` app that *is* available behaves the
2049
+ * same way — the restriction is about availability, not connectivity.
2050
+ */
2051
+ declare function useOfflineTileState(offline: 'offline-first' | 'device-only' | undefined, deviceOnlyAvailable: boolean): OfflineTileState;
2052
+
1102
2053
  interface CommitOnEnterOrBlurHandlers {
1103
2054
  onKeyDown: (e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
1104
2055
  onBlur: () => void;
@@ -1127,4 +2078,313 @@ interface CommitOnEnterOrBlurHandlers {
1127
2078
  */
1128
2079
  declare function useCommitOnEnterOrBlur(onCommit: () => void): CommitOnEnterOrBlurHandlers;
1129
2080
 
1130
- export { Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeStatus, type BadgeVariant, BalanceChip, type BalanceChipProps, type BannerVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Calendar, type CalendarProps, Card, type CardProps, CheckableListRow, type CheckableListRowProps, Checkbox, type CheckboxProps, CodeTextarea, type CodeTextareaProps, type CommitOnEnterOrBlurHandlers, ConfirmDialog, type ConfirmDialogProps, CurrencyInput, type CurrencyInputProps, DatePicker, type DatePickerProps, Dialog, type DialogProps, type DialogSize, DragHandleRow, type DragHandleRowProps, Drawer, type DrawerProps, EmptyState, type EmptyStateProps, FileDropzone, type FileDropzoneProps, FormField, type FormFieldProps, type FormFieldRenderProps, Icon, type IconName, IconPicker, type IconPickerProps, type IconProps, Input, type InputProps, type LongPressHandlers, MOBILE_BREAKPOINT_PX, MemberMultiSelect, type MemberMultiSelectOption, type MemberMultiSelectProps, Menu, type MenuEntry, type MenuItem, type MenuLabel, type MenuProps, type MenuSeparator, type NavTabItem, NavTabs, type NavTabsProps, OverlayHeader, type OverlayHeaderProps, PageHeader, type PageHeaderProps, Popover, type PopoverProps, QuantityStepper, type QuantityStepperProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectProps, Sheet, type SheetProps, Spinner, type SpinnerProps, type SplitMethod, SplitMethodSelector, type SplitMethodSelectorProps, SplitPane, type SplitPaneProps, StatusBadge, type StatusBadgeProps, type StatusBadgeStatus, SuggestionInput, type SuggestionInputProps, type SuggestionOption, SystemBanner, type SystemBannerProps, type TabItem, Tabs, type TabsProps, TagInput, type TagInputProps, Textarea, type TextareaProps, type ToastContextValue, type ToastItem, ToastProvider, Toggle, type ToggleProps, Tooltip, type TooltipProps, type UseLongPressOptions, useCommitOnEnterOrBlur, useDoubleTapHandler, useIsMobile, useLongPress, useOverlaySecondRow, useSingleOrDoubleTap, useToast };
2081
+ interface UseSwipeRevealOptions {
2082
+ /** Max reveal distance in px — the row translates by `-revealWidth` when open. */
2083
+ revealWidth: number;
2084
+ /** Whether the reveal is currently open. Controlled by the caller so a
2085
+ * list of rows can coordinate "only one open at a time" — this hook has
2086
+ * no open state of its own. */
2087
+ open: boolean;
2088
+ /** Called when a drag releases past the halfway point — the caller should
2089
+ * set `open` to true. */
2090
+ onOpen: () => void;
2091
+ /** Called when a drag releases before the halfway point — the caller
2092
+ * should set `open` to false. */
2093
+ onClose: () => void;
2094
+ /** Skip entirely (hooks can't be called conditionally). */
2095
+ disabled?: boolean;
2096
+ }
2097
+ interface UseSwipeRevealHandlers {
2098
+ onPointerDown: (e: PointerEvent) => void;
2099
+ onPointerMove: (e: PointerEvent) => void;
2100
+ onPointerUp: (e: PointerEvent) => void;
2101
+ onPointerCancel: (e: PointerEvent) => void;
2102
+ }
2103
+ interface UseSwipeRevealResult {
2104
+ /** Attach to the swipeable row element — the hook writes a live transform
2105
+ * to it directly during the drag (not via React state) so the row tracks
2106
+ * the finger at 60fps with no re-render per pointermove. */
2107
+ rowRef: RefObject<HTMLDivElement | null>;
2108
+ /** Spread onto the row's pointer event handlers. */
2109
+ handlers: UseSwipeRevealHandlers;
2110
+ }
2111
+ /**
2112
+ * useSwipeReveal — horizontal swipe-to-reveal (e.g. Done/Delete actions
2113
+ * behind a list row), extracted from `sovereign-tasks`'s `TaskItem`/
2114
+ * `ListSidebar`, which independently hand-rolled the identical gesture twice
2115
+ * with only `revealWidth` differing (RFC 0079, epic task 9.20).
2116
+ *
2117
+ * Axis-locks on the first 8px of movement (so a vertical scroll or the
2118
+ * carousel's own horizontal swipe-between-slides gesture isn't hijacked by a
2119
+ * diagonal drag) and only resolves to open/closed on release, past the
2120
+ * halfway point of `revealWidth`.
2121
+ */
2122
+ declare function useSwipeReveal({ revealWidth, open, onOpen, onClose, disabled, }: UseSwipeRevealOptions): UseSwipeRevealResult;
2123
+
2124
+ interface UseSnapCarouselOptions {
2125
+ /** Total number of slides — settle detection clamps to this range. */
2126
+ itemCount: number;
2127
+ /** Called when the user's scroll gesture settles on a different slide
2128
+ * index than the last one reported. */
2129
+ onSettle?: (index: number) => void;
2130
+ /** Debounce delay (ms) after the last `scroll` event before checking where
2131
+ * the container settled. Default 120 — matches the value this hook was
2132
+ * extracted from. Debounced rather than keyed to the `scrollend` event,
2133
+ * which pre-17.4 iOS Safari/WKWebView doesn't support. */
2134
+ debounceMs?: number;
2135
+ }
2136
+ interface UseSnapCarouselResult {
2137
+ /** Attach to the `scroll-snap-type: x` scroll container. */
2138
+ scrollRef: RefObject<HTMLDivElement | null>;
2139
+ /** Imperatively scrolls the container to a slide index. */
2140
+ scrollToIndex: (index: number, behavior?: ScrollBehavior) => void;
2141
+ }
2142
+ /**
2143
+ * useSnapCarousel — debounced "settled slide" detection over a native
2144
+ * `scroll-snap-type: x` container, extracted from `sovereign-tasks`'s
2145
+ * `MobileTasksCarousel` and independently reimplemented in
2146
+ * `sovereign-shopper`'s `MobileShopperCarousel` (RFC 0079, epic task 9.20).
2147
+ * Gives swipe-between-slides physics for free via native scroll-snap, with
2148
+ * this hook only handling "which slide did we land on."
2149
+ */
2150
+ declare function useSnapCarousel({ itemCount, onSettle, debounceMs, }: UseSnapCarouselOptions): UseSnapCarouselResult;
2151
+
2152
+ interface UseResponsiveLayoutOptions<TWeb, TMobile> {
2153
+ web: TWeb;
2154
+ mobile: TMobile;
2155
+ breakpointPx?: number;
2156
+ }
2157
+ interface UseResponsiveLayoutResult<TWeb, TMobile> {
2158
+ isMobile: boolean;
2159
+ value: TWeb | TMobile;
2160
+ }
2161
+ /**
2162
+ * useResponsiveLayout — picks between a `web` and `mobile` value for the
2163
+ * current viewport, built on `useIsMobile` (same breakpoint/SSR-safe-default
2164
+ * behavior, not reimplemented here). Generic over the value type so it works
2165
+ * for JSX (the common case — forking an entire component tree, not just a
2166
+ * class name) or any other per-breakpoint value a plugin wants to pick
2167
+ * without repeating the isMobile-ternary boilerplate every call site.
2168
+ *
2169
+ * This formalizes the `if (isMobile) return <mobile/>; return <web/>;` fork
2170
+ * plugins have hand-rolled per-plugin (e.g. a `MobileAwareShell` component
2171
+ * that swaps an entire routed page tree for a client-only mobile one) —
2172
+ * see `ResponsiveSurface` for the equivalent as a plain JSX component.
2173
+ */
2174
+ declare function useResponsiveLayout<TWeb, TMobile>({ web, mobile, breakpointPx, }: UseResponsiveLayoutOptions<TWeb, TMobile>): UseResponsiveLayoutResult<TWeb, TMobile>;
2175
+
2176
+ interface UseCarouselRouteSyncOptions {
2177
+ /** Maps the current pathname to a slide index — the caller's own routing
2178
+ * logic (e.g. special-casing a virtual "starred" slide), unchanged from
2179
+ * whatever a plugin already has today. This hook has no idea what a
2180
+ * plugin's routes look like, by design — it never imports a router. */
2181
+ indexForPathname: (pathname: string) => number;
2182
+ /** Inverse mapping — given a settled slide index, the path to navigate to. */
2183
+ pathForIndex: (index: number) => string;
2184
+ /** The current pathname. The caller reads this via their own router (e.g.
2185
+ * `usePathname()` from `next/navigation`) and passes it in every render —
2186
+ * this package stays framework-generic and has zero runtime dependencies. */
2187
+ pathname: string;
2188
+ /** Called when this hook wants to navigate — typically
2189
+ * `(path) => router.replace(path, { scroll: false })`. */
2190
+ onNavigate: (path: string) => void;
2191
+ }
2192
+ interface UseCarouselRouteSyncResult {
2193
+ /** Feed directly into SwipableMobileCarousel's `activeIndex` prop. */
2194
+ activeIndex: number;
2195
+ /** Feed directly into SwipableMobileCarousel's `onSettle` prop. */
2196
+ onSettle: (index: number) => void;
2197
+ }
2198
+ /**
2199
+ * useCarouselRouteSync — centralizes the pathname↔slide-index mapping and the
2200
+ * "was this pathname change our own settle, or an external navigation"
2201
+ * distinction that carousel-driving plugins otherwise hand-roll per plugin
2202
+ * (a tapped `<Link>`, browser back/forward, vs. this hook's own
2203
+ * `router.replace` after a swipe settles). Router-agnostic on purpose: the
2204
+ * caller owns the actual `usePathname()`/`router.replace()` calls and only
2205
+ * hands this hook plain values/callbacks.
2206
+ *
2207
+ * Deliberately does not own neighbor-prefetch (SwipableMobileCarousel's
2208
+ * `prefetchDistance`/mount-window covers that) or scroll mechanics (the
2209
+ * carousel component reacts to `activeIndex` changes itself) — this hook is
2210
+ * pathname↔index mapping only, keeping routing glue decoupled from
2211
+ * data-fetching and DOM scrolling.
2212
+ */
2213
+ declare function useCarouselRouteSync({ indexForPathname, pathForIndex, pathname, onNavigate, }: UseCarouselRouteSyncOptions): UseCarouselRouteSyncResult;
2214
+
2215
+ interface ResponsiveSurfaceProps {
2216
+ web: ReactNode;
2217
+ mobile: ReactNode;
2218
+ breakpointPx?: number;
2219
+ }
2220
+ /**
2221
+ * ResponsiveSurface — thin JSX convenience wrapper around
2222
+ * `useResponsiveLayout` for the common two-tree case: render an entirely
2223
+ * different component tree below the breakpoint, not a CSS squeeze of the
2224
+ * same one. Renders only whichever side is active — the other tree is never
2225
+ * mounted.
2226
+ *
2227
+ * This does not replace a plugin's own shell component (e.g. a
2228
+ * `MobileAwareShell` that also threads plugin-specific props like a refresh
2229
+ * signal) — those stay a thin per-plugin wrapper around this.
2230
+ */
2231
+ declare function ResponsiveSurface({ web, mobile, breakpointPx }: ResponsiveSurfaceProps): react.JSX.Element;
2232
+
2233
+ interface SwipableMobileCarouselDotsProps {
2234
+ count: number;
2235
+ activeIndex: number;
2236
+ onJump: (index: number) => void;
2237
+ /** Per-dot accessible names, e.g. ["Lists", "Starred", "Groceries"]. Falls
2238
+ * back to "Slide N of count" for any index without one. */
2239
+ labels?: (string | undefined)[];
2240
+ /** Labels the whole group — required, no generic fallback (mirrors
2241
+ * SwipableMobileCarousel's own required aria-label). */
2242
+ 'aria-label': string;
2243
+ className?: string;
2244
+ }
2245
+ /**
2246
+ * SwipableMobileCarouselDots — a real, tappable, labeled slide indicator.
2247
+ * Standalone (not carousel-only): reusable anywhere a set of positions needs
2248
+ * a dot indicator (e.g. an image gallery, an onboarding stepper), and is also
2249
+ * SwipableMobileCarousel's default `renderIndicator`.
2250
+ *
2251
+ * Replaces the `aria-hidden`, non-interactive dots pattern both
2252
+ * sovereign-tasks and sovereign-shopper currently hand-roll — every dot here
2253
+ * is a real `role="tab"` button with its own accessible name, reachable by
2254
+ * keyboard. No roving tabIndex/arrow-key handling: `Tabs` (this library's
2255
+ * other `role="tablist"` component) has none either, so this stays
2256
+ * consistent with it rather than gold-plating past its sibling.
2257
+ */
2258
+ declare function SwipableMobileCarouselDots({ count, activeIndex, onJump, labels, 'aria-label': ariaLabel, className, }: SwipableMobileCarouselDotsProps): react.JSX.Element;
2259
+
2260
+ interface SwipableMobileCarouselIndicatorProps {
2261
+ count: number;
2262
+ activeIndex: number;
2263
+ labels: (string | undefined)[];
2264
+ onJump: (index: number) => void;
2265
+ }
2266
+ interface SwipableMobileCarouselProps {
2267
+ /** Controlled active slide index — the caller owns this (typically via
2268
+ * useCarouselRouteSync, or plain useState). */
2269
+ activeIndex: number;
2270
+ /** Called when a swipe gesture settles on a different index, or when the
2271
+ * reorder-jump fix re-snaps after the active slide's position changes.
2272
+ * The caller is responsible for updating `activeIndex` in response. */
2273
+ onSettle: (index: number) => void;
2274
+ /** How many slides on each side of the active one stay mounted. Default 1
2275
+ * matches both sovereign-tasks' and sovereign-shopper's existing "swipe
2276
+ * never shows a spinner" behavior. Slides outside this window keep their
2277
+ * DOM slot (so scroll-snap's position-based indexing stays correct) but
2278
+ * their children are not mounted at all. */
2279
+ prefetchDistance?: number;
2280
+ /** Passed straight through to the internal useSnapCarousel. */
2281
+ settleDebounceMs?: number;
2282
+ /** Required — labels the scroller region for assistive tech. No generic
2283
+ * fallback, since one would be wrong for every actual consumer. */
2284
+ 'aria-label': string;
2285
+ /** Renders the indicator. Defaults to SwipableMobileCarouselDots. Pass
2286
+ * `null` to render no indicator at all. */
2287
+ renderIndicator?: null | ((props: SwipableMobileCarouselIndicatorProps) => ReactNode);
2288
+ className?: string;
2289
+ /** Must be SwipableMobileCarouselSlide elements (nullish/boolean children
2290
+ * are safely skipped for conditional slides). A dev-mode warning is
2291
+ * logged for any other child type — see resolveSlides below. */
2292
+ children: ReactNode;
2293
+ }
2294
+ /**
2295
+ * SwipableMobileCarousel — a compound component for swiping between full-
2296
+ * width slides (each an independent route/view on mobile), wrapping
2297
+ * useSnapCarousel. This library's first compound component: every other
2298
+ * component here is flat/prop-based, but slide content is large, arbitrary,
2299
+ * per-plugin subtrees that need a header-known/body-loading split an
2300
+ * array-of-objects prop would only express with worse JSX ergonomics.
2301
+ *
2302
+ * Owns rendering and mount-window mechanics only — it has no opinion on
2303
+ * where slide data lives. Do NOT: (a) aggregate cross-slide data inside a
2304
+ * SwipableMobileCarouselSlideBody (that recomputes on every slide render
2305
+ * regardless of which slide is active — belongs in the parent, which
2306
+ * already knows every slide exists); (b) mount a detail overlay (Sheet,
2307
+ * Dialog) inside a Slide's children — mount it as a sibling of
2308
+ * SwipableMobileCarousel instead, controlled by the same state that would
2309
+ * otherwise drive a routed page's overlay. sovereign-tasks' current
2310
+ * hand-rolled carousel does both and is measurably laggier than
2311
+ * sovereign-shopper's equivalent, which keeps its overlay in the routed pane.
2312
+ */
2313
+ declare function SwipableMobileCarousel({ activeIndex, onSettle, prefetchDistance, settleDebounceMs, 'aria-label': ariaLabel, renderIndicator, className, children, }: SwipableMobileCarouselProps): react.JSX.Element;
2314
+
2315
+ interface SwipableMobileCarouselSlideProps {
2316
+ /** Stable identity for this slide, independent of its position among
2317
+ * siblings — required. This is what makes SwipableMobileCarousel's
2318
+ * reorder-jump fix possible: a plain array index can't distinguish "this
2319
+ * slide moved to position 2" from "this slide was removed and a
2320
+ * different one is now at position 2." Reuse whatever id the caller
2321
+ * already keys their `.map()` on (e.g. a list's own id). */
2322
+ slideKey: string;
2323
+ /** Accessible label surfaced to the default dots indicator (e.g.
2324
+ * "Groceries"). Falls back to "Slide N of count" if omitted — omitting it
2325
+ * logs a dev-mode warning, since every real slide usually has a title
2326
+ * available synchronously already. */
2327
+ label?: string;
2328
+ /** SwipableMobileCarouselSlideHeader/Body/Footer, in any order/subset. */
2329
+ children: ReactNode;
2330
+ }
2331
+ /**
2332
+ * SwipableMobileCarouselSlide — a single slide of a SwipableMobileCarousel.
2333
+ * Renders its children only while within the carousel's mount window (the
2334
+ * active slide ± its configured prefetchDistance); outside that window it
2335
+ * renders nothing, matching both sovereign-tasks and sovereign-shopper's
2336
+ * existing "never fetch/render a non-neighbor slide" behavior, now
2337
+ * centralized instead of hand-rolled per plugin.
2338
+ */
2339
+ declare function SwipableMobileCarouselSlide({ children }: SwipableMobileCarouselSlideProps): react.JSX.Element | null;
2340
+
2341
+ interface SwipableMobileCarouselSlideHeaderProps {
2342
+ children: ReactNode;
2343
+ className?: string;
2344
+ }
2345
+ /**
2346
+ * SwipableMobileCarouselSlideHeader — always renders its children, no
2347
+ * loading concept. Meant for content already known synchronously (a list's
2348
+ * title, color, item count from data the caller already has) so it can
2349
+ * render immediately even while SwipableMobileCarouselSlideBody's own
2350
+ * content is still loading — see that component's doc comment.
2351
+ */
2352
+ declare function SwipableMobileCarouselSlideHeader({ children, className, }: SwipableMobileCarouselSlideHeaderProps): react.JSX.Element;
2353
+
2354
+ interface SwipableMobileCarouselSlideBodyProps {
2355
+ children: ReactNode;
2356
+ /** While true, renders `loadingFallback` INSTEAD OF children — scoped to
2357
+ * just this region, not the whole slide. This is what fixes the
2358
+ * "whole slide blanks out, title included, until its own fetch resolves"
2359
+ * bug: a caller renders `<SwipableMobileCarouselSlideHeader>` from
2360
+ * already-known metadata unconditionally, and gates only this component's
2361
+ * `loading` on the slower fetch — the natural way to compose
2362
+ * Header/Body/Footer as siblings already produces that behavior, instead
2363
+ * of gating the entire slide behind one boolean. */
2364
+ loading?: boolean;
2365
+ loadingFallback?: ReactNode;
2366
+ className?: string;
2367
+ }
2368
+ /**
2369
+ * SwipableMobileCarouselSlideBody — the scrollable region of a slide.
2370
+ *
2371
+ * Deliberately does not set `touch-action: pan-y` on its scroll container
2372
+ * (see SwipableMobileCarouselSlideParts.module.css's `.body` rule) — that
2373
+ * would intersect-to-empty against the carousel's own horizontal
2374
+ * touch-action handling (docs/architecture-rules.md's touch-action
2375
+ * intersection rule), breaking both the vertical scroll here and the
2376
+ * horizontal swipe between slides.
2377
+ */
2378
+ declare function SwipableMobileCarouselSlideBody({ children, loading, loadingFallback, className, }: SwipableMobileCarouselSlideBodyProps): react.JSX.Element;
2379
+
2380
+ interface SwipableMobileCarouselSlideFooterProps {
2381
+ children: ReactNode;
2382
+ className?: string;
2383
+ }
2384
+ /**
2385
+ * SwipableMobileCarouselSlideFooter — always renders its children, no
2386
+ * loading concept. See SwipableMobileCarouselSlideHeader's doc comment.
2387
+ */
2388
+ declare function SwipableMobileCarouselSlideFooter({ children, className, }: SwipableMobileCarouselSlideFooterProps): react.JSX.Element;
2389
+
2390
+ export { Accordion, type AccordionItem, type AccordionProps, Alert, type AlertProps, type AlertVariant, AspectRatio, type AspectRatioProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeStatus, type BadgeVariant, BalanceChip, type BalanceChipProps, type BannerVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type ButtonSize, type ButtonVariant, Calendar, type CalendarProps, Card, type CardProps, CheckableListRow, type CheckableListRowProps, Checkbox, type CheckboxProps, CodeTextarea, type CodeTextareaProps, Collapsible, type CollapsibleProps, Combobox, type ComboboxOption, type ComboboxProps, Command, type CommandItem, type CommandProps, type CommitOnEnterOrBlurHandlers, ConfirmDialog, type ConfirmDialogProps, ContextMenu, type ContextMenuProps, CurrencyInput, type CurrencyInputProps, DataTable, type DataTableColumn, type DataTableProps, DatePicker, type DatePickerProps, DeviceOnlyGate, type DeviceOnlyGateProps, DeviceStorageKeyGate, type DeviceStorageKeyGateProps, type DeviceStorageKeyGateStatus, Dialog, type DialogProps, type DialogSize, DragHandleRow, type DragHandleRowProps, Drawer, type DrawerProps, EmptyState, type EmptyStateProps, FileDropzone, type FileDropzoneProps, type FooterIcon, FormField, type FormFieldProps, type FormFieldRenderProps, HoverCard, type HoverCardProps, Icon, type IconName, IconPicker, type IconPickerProps, type IconProps, Input, type InputProps, Item, type ItemProps, Kbd, type KbdProps, Label, type LabelProps, LegalLinks, type LegalLinksProps, type LongPressHandlers, MOBILE_BREAKPOINT_PX, Markdown, type MarkdownProps, Marker, type MarkerProps, MemberMultiSelect, type MemberMultiSelectOption, type MemberMultiSelectProps, Menu, MenuEntries, type MenuEntry, type MenuItem, type MenuLabel, type MenuProps, type MenuSeparator, Menubar, type MenubarMenu, type MenubarProps, Message, type MessageProps, MessageScroller, type MessageScrollerProps, type MessageSender, MobileAppsDrawer, type MobileAppsDrawerItem, type MobileAppsDrawerProps, MobileFooter, type MobileFooterProps, MobileHeader, type MobileHeaderProps, type NavTabItem, type NavTabLinkProps, NavTabs, type NavTabsProps, NavigationMenu, type NavigationMenuItem, type NavigationMenuProps, OfflineGate, type OfflineGateProps, type OfflineTileState, OverlayHeader, type OverlayHeaderProps, PageContainer, type PageContainerProps, PageHeader, type PageHeaderProps, Pagination, type PaginationProps, Popover, type PopoverProps, Progress, type ProgressProps, QuantityStepper, type QuantityStepperProps, RadioGroup, type RadioGroupItem, type RadioGroupProps, type ResizableDirection, ResizableHandle, type ResizableHandleProps, ResizablePanel, ResizablePanelGroup, type ResizablePanelGroupProps, type ResizablePanelProps, ResponsiveSurface, type ResponsiveSurfaceProps, ScrollArea, type ScrollAreaProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectProps, Sheet, type SheetProps, Slider, type SliderProps, type SortDirection, Spinner, type SpinnerProps, type SplitMethod, SplitMethodSelector, type SplitMethodSelectorProps, SplitPane, type SplitPaneProps, StatusBadge, type StatusBadgeProps, type StatusBadgeStatus, SuggestionInput, type SuggestionInputProps, type SuggestionOption, SwipableMobileCarousel, SwipableMobileCarouselDots, type SwipableMobileCarouselDotsProps, type SwipableMobileCarouselIndicatorProps, type SwipableMobileCarouselProps, SwipableMobileCarouselSlide, SwipableMobileCarouselSlideBody, type SwipableMobileCarouselSlideBodyProps, SwipableMobileCarouselSlideFooter, type SwipableMobileCarouselSlideFooterProps, SwipableMobileCarouselSlideHeader, type SwipableMobileCarouselSlideHeaderProps, type SwipableMobileCarouselSlideProps, SystemBanner, type SystemBannerProps, type TabItem, Table, TableBody, TableCell, TableHead, TableHeaderCell, type TableProps, TableRow, Tabs, type TabsProps, TagInput, type TagInputProps, Textarea, type TextareaProps, type ToastContextValue, type ToastItem, ToastProvider, Toggle, type ToggleProps, Tooltip, type TooltipProps, Typography, type TypographyProps, type TypographyVariant, type UseCarouselRouteSyncOptions, type UseCarouselRouteSyncResult, type UseLongPressOptions, type UseResponsiveLayoutOptions, type UseResponsiveLayoutResult, type UseSnapCarouselOptions, type UseSnapCarouselResult, type UseSwipeRevealHandlers, type UseSwipeRevealOptions, type UseSwipeRevealResult, useCarouselRouteSync, useCommitOnEnterOrBlur, useDoubleTapHandler, useIsMobile, useIsOffline, useLongPress, useOfflineTileState, useOverlaySecondRow, useResponsiveLayout, useSingleOrDoubleTap, useSnapCarousel, useSwipeReveal, useToast };