@elabs-ai/components-ui 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (449) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/dist/index.d.ts +4497 -0
  4. package/dist/index.js +15192 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/cn.d.ts +10 -0
  7. package/dist/lib/cn.js +20 -0
  8. package/dist/lib/cn.js.map +1 -0
  9. package/package.json +106 -0
  10. package/src/blocks/sidebar-02/app-sidebar.tsx +160 -0
  11. package/src/blocks/sidebar-02/logo.tsx +18 -0
  12. package/src/blocks/sidebar-02/nav-main.tsx +13 -0
  13. package/src/blocks/sidebar-02/nav-notifications.tsx +7 -0
  14. package/src/blocks/sidebar-02/sidebar-02.stories.tsx +23 -0
  15. package/src/blocks/sidebar-02/team-switcher.tsx +7 -0
  16. package/src/blocks/sidebar-04/app-sidebar.tsx +236 -0
  17. package/src/blocks/sidebar-04/mail-context.tsx +29 -0
  18. package/src/blocks/sidebar-04/nav-user.tsx +6 -0
  19. package/src/blocks/sidebar-04/sidebar-04.stories.tsx +150 -0
  20. package/src/blocks/sidebar-05/app-sidebar.tsx +375 -0
  21. package/src/blocks/sidebar-05/sidebar-05.stories.tsx +18 -0
  22. package/src/blocks/sidebar-05/team-switcher.tsx +6 -0
  23. package/src/blocks-comparison-table.stories.tsx +165 -0
  24. package/src/components/accordion/accordion.stories.tsx +71 -0
  25. package/src/components/accordion/accordion.test.tsx +18 -0
  26. package/src/components/accordion/accordion.tsx +49 -0
  27. package/src/components/accordion/index.ts +1 -0
  28. package/src/components/advanced-group/advanced-group.stories.tsx +143 -0
  29. package/src/components/advanced-group/advanced-group.test.tsx +81 -0
  30. package/src/components/advanced-group/advanced-group.tsx +111 -0
  31. package/src/components/advanced-group/index.ts +2 -0
  32. package/src/components/alert/alert.stories.tsx +156 -0
  33. package/src/components/alert/alert.test.tsx +57 -0
  34. package/src/components/alert/alert.tsx +91 -0
  35. package/src/components/alert/index.ts +8 -0
  36. package/src/components/alert-dialog/alert-dialog.stories.tsx +73 -0
  37. package/src/components/alert-dialog/alert-dialog.tsx +104 -0
  38. package/src/components/alert-dialog/index.ts +12 -0
  39. package/src/components/app-shell/app-shell.stories.tsx +61 -0
  40. package/src/components/app-shell/app-shell.tsx +31 -0
  41. package/src/components/app-shell/index.ts +1 -0
  42. package/src/components/app-sidebar/app-sidebar.stories.tsx +121 -0
  43. package/src/components/app-sidebar/app-sidebar.test.tsx +55 -0
  44. package/src/components/app-sidebar/app-sidebar.tsx +53 -0
  45. package/src/components/app-sidebar/index.ts +1 -0
  46. package/src/components/aspect-ratio/aspect-ratio.stories.tsx +46 -0
  47. package/src/components/aspect-ratio/aspect-ratio.tsx +3 -0
  48. package/src/components/aspect-ratio/index.ts +1 -0
  49. package/src/components/attribution-panel/attribution-panel.stories.tsx +83 -0
  50. package/src/components/attribution-panel/attribution-panel.test.tsx +123 -0
  51. package/src/components/attribution-panel/attribution-panel.tsx +191 -0
  52. package/src/components/attribution-panel/attribution-types.ts +44 -0
  53. package/src/components/attribution-panel/attributions.generated.ts +1422 -0
  54. package/src/components/attribution-panel/index.ts +3 -0
  55. package/src/components/avatar/avatar.stories.tsx +45 -0
  56. package/src/components/avatar/avatar.test.tsx +13 -0
  57. package/src/components/avatar/avatar.tsx +46 -0
  58. package/src/components/avatar/index.ts +1 -0
  59. package/src/components/badge/badge.stories.tsx +44 -0
  60. package/src/components/badge/badge.test.tsx +10 -0
  61. package/src/components/badge/badge.tsx +28 -0
  62. package/src/components/badge/index.ts +1 -0
  63. package/src/components/bento-grid/bento-grid.stories.tsx +165 -0
  64. package/src/components/bento-grid/bento-grid.test.tsx +119 -0
  65. package/src/components/bento-grid/bento-grid.tsx +339 -0
  66. package/src/components/bento-grid/index.ts +9 -0
  67. package/src/components/bounded-number/bounded-number.stories.tsx +118 -0
  68. package/src/components/bounded-number/bounded-number.test.tsx +73 -0
  69. package/src/components/bounded-number/bounded-number.tsx +110 -0
  70. package/src/components/bounded-number/index.ts +1 -0
  71. package/src/components/breadcrumb/breadcrumb.stories.tsx +47 -0
  72. package/src/components/breadcrumb/breadcrumb.test.tsx +17 -0
  73. package/src/components/breadcrumb/breadcrumb.tsx +86 -0
  74. package/src/components/breadcrumb/index.ts +9 -0
  75. package/src/components/button/button.stories.tsx +70 -0
  76. package/src/components/button/button.test.tsx +50 -0
  77. package/src/components/button/button.tsx +63 -0
  78. package/src/components/button/index.ts +1 -0
  79. package/src/components/button-group/button-group.stories.tsx +45 -0
  80. package/src/components/button-group/button-group.tsx +70 -0
  81. package/src/components/button-group/index.ts +6 -0
  82. package/src/components/calendar/calendar.stories.tsx +95 -0
  83. package/src/components/calendar/calendar.test.tsx +140 -0
  84. package/src/components/calendar/calendar.tsx +70 -0
  85. package/src/components/calendar/index.ts +1 -0
  86. package/src/components/card/card.stories.tsx +438 -0
  87. package/src/components/card/card.test.tsx +153 -0
  88. package/src/components/card/card.tsx +332 -0
  89. package/src/components/card/index.ts +13 -0
  90. package/src/components/carousel/carousel.stories.tsx +102 -0
  91. package/src/components/carousel/carousel.tsx +225 -0
  92. package/src/components/carousel/index.ts +8 -0
  93. package/src/components/change-review/change-review.stories.tsx +288 -0
  94. package/src/components/change-review/change-review.test.tsx +261 -0
  95. package/src/components/change-review/change-review.tsx +637 -0
  96. package/src/components/change-review/index.ts +23 -0
  97. package/src/components/checkbox/checkbox.stories.tsx +119 -0
  98. package/src/components/checkbox/checkbox.test.tsx +40 -0
  99. package/src/components/checkbox/checkbox.tsx +34 -0
  100. package/src/components/checkbox/index.ts +1 -0
  101. package/src/components/collapsible/collapsible.stories.tsx +62 -0
  102. package/src/components/collapsible/collapsible.tsx +22 -0
  103. package/src/components/collapsible/index.ts +1 -0
  104. package/src/components/collapsible-panel/index.ts +8 -0
  105. package/src/components/collapsible-panel/use-collapsible-panel.test.tsx +93 -0
  106. package/src/components/collapsible-panel/use-collapsible-panel.ts +159 -0
  107. package/src/components/color-picker/color-picker.stories.tsx +93 -0
  108. package/src/components/color-picker/color-picker.test.tsx +79 -0
  109. package/src/components/color-picker/color-picker.tsx +341 -0
  110. package/src/components/color-picker/index.ts +1 -0
  111. package/src/components/combobox/combobox.stories.tsx +154 -0
  112. package/src/components/combobox/combobox.test.tsx +246 -0
  113. package/src/components/combobox/combobox.tsx +210 -0
  114. package/src/components/combobox/index.ts +1 -0
  115. package/src/components/command/command.stories.tsx +371 -0
  116. package/src/components/command/command.test.tsx +280 -0
  117. package/src/components/command/command.tsx +301 -0
  118. package/src/components/command/index.ts +13 -0
  119. package/src/components/confirm-dialog/confirm-dialog.stories.tsx +183 -0
  120. package/src/components/confirm-dialog/confirm-dialog.test.tsx +147 -0
  121. package/src/components/confirm-dialog/confirm-dialog.tsx +146 -0
  122. package/src/components/confirm-dialog/index.ts +2 -0
  123. package/src/components/context-menu/context-menu.stories.tsx +70 -0
  124. package/src/components/context-menu/context-menu.tsx +172 -0
  125. package/src/components/context-menu/index.ts +16 -0
  126. package/src/components/copyable-value/copyable-value.stories.tsx +80 -0
  127. package/src/components/copyable-value/copyable-value.test.tsx +128 -0
  128. package/src/components/copyable-value/copyable-value.tsx +101 -0
  129. package/src/components/copyable-value/index.ts +1 -0
  130. package/src/components/date-picker/date-picker.stories.tsx +42 -0
  131. package/src/components/date-picker/date-picker.tsx +49 -0
  132. package/src/components/date-picker/index.ts +1 -0
  133. package/src/components/date-range-picker/date-range-picker.stories.tsx +151 -0
  134. package/src/components/date-range-picker/date-range-picker.test.tsx +62 -0
  135. package/src/components/date-range-picker/date-range-picker.tsx +126 -0
  136. package/src/components/date-range-picker/index.ts +6 -0
  137. package/src/components/descriptions/descriptions.stories.tsx +43 -0
  138. package/src/components/descriptions/descriptions.test.tsx +41 -0
  139. package/src/components/descriptions/descriptions.tsx +95 -0
  140. package/src/components/descriptions/index.ts +6 -0
  141. package/src/components/dialog/dialog.stories.tsx +728 -0
  142. package/src/components/dialog/dialog.test.tsx +285 -0
  143. package/src/components/dialog/dialog.tsx +340 -0
  144. package/src/components/dialog/index.ts +18 -0
  145. package/src/components/dialog/use-dialog-dismiss-guard.test.tsx +80 -0
  146. package/src/components/dialog/use-dialog-dismiss-guard.ts +109 -0
  147. package/src/components/drawer/drawer.stories.tsx +76 -0
  148. package/src/components/drawer/drawer.tsx +85 -0
  149. package/src/components/drawer/index.ts +11 -0
  150. package/src/components/dropdown-menu/dropdown-menu.stories.tsx +176 -0
  151. package/src/components/dropdown-menu/dropdown-menu.test.tsx +109 -0
  152. package/src/components/dropdown-menu/dropdown-menu.tsx +179 -0
  153. package/src/components/dropdown-menu/index.ts +17 -0
  154. package/src/components/empty-state/empty-state.stories.tsx +54 -0
  155. package/src/components/empty-state/empty-state.test.tsx +11 -0
  156. package/src/components/empty-state/empty-state.tsx +30 -0
  157. package/src/components/empty-state/index.ts +1 -0
  158. package/src/components/error-state/error-state.stories.tsx +51 -0
  159. package/src/components/error-state/error-state.tsx +27 -0
  160. package/src/components/error-state/index.ts +1 -0
  161. package/src/components/expand-dialog/expand-dialog.stories.tsx +246 -0
  162. package/src/components/expand-dialog/expand-dialog.test.tsx +185 -0
  163. package/src/components/expand-dialog/expand-dialog.tsx +387 -0
  164. package/src/components/expand-dialog/index.ts +11 -0
  165. package/src/components/field-row/field-row.stories.tsx +114 -0
  166. package/src/components/field-row/field-row.test.tsx +188 -0
  167. package/src/components/field-row/field-row.tsx +115 -0
  168. package/src/components/field-row/index.ts +1 -0
  169. package/src/components/file-upload/file-upload.stories.tsx +183 -0
  170. package/src/components/file-upload/file-upload.test.tsx +169 -0
  171. package/src/components/file-upload/file-upload.tsx +459 -0
  172. package/src/components/file-upload/index.ts +13 -0
  173. package/src/components/form/form.stories.tsx +71 -0
  174. package/src/components/form/form.tsx +141 -0
  175. package/src/components/form/index.ts +10 -0
  176. package/src/components/hover-card/hover-card.stories.tsx +57 -0
  177. package/src/components/hover-card/hover-card.tsx +25 -0
  178. package/src/components/hover-card/index.ts +1 -0
  179. package/src/components/icon-button/icon-button.stories.tsx +108 -0
  180. package/src/components/icon-button/icon-button.test.tsx +93 -0
  181. package/src/components/icon-button/icon-button.tsx +139 -0
  182. package/src/components/icon-button/index.ts +1 -0
  183. package/src/components/input/index.ts +1 -0
  184. package/src/components/input/input.stories.tsx +44 -0
  185. package/src/components/input/input.test.tsx +19 -0
  186. package/src/components/input/input.tsx +26 -0
  187. package/src/components/input-group/index.ts +11 -0
  188. package/src/components/input-group/input-group.stories.tsx +87 -0
  189. package/src/components/input-group/input-group.test.tsx +48 -0
  190. package/src/components/input-group/input-group.tsx +170 -0
  191. package/src/components/input-otp/index.ts +1 -0
  192. package/src/components/input-otp/input-otp.stories.tsx +66 -0
  193. package/src/components/input-otp/input-otp.tsx +68 -0
  194. package/src/components/kbd/index.ts +1 -0
  195. package/src/components/kbd/kbd.stories.tsx +45 -0
  196. package/src/components/kbd/kbd.tsx +20 -0
  197. package/src/components/key-value-editor/index.ts +1 -0
  198. package/src/components/key-value-editor/key-value-editor.stories.tsx +130 -0
  199. package/src/components/key-value-editor/key-value-editor.test.tsx +231 -0
  200. package/src/components/key-value-editor/key-value-editor.tsx +263 -0
  201. package/src/components/label/index.ts +1 -0
  202. package/src/components/label/label.stories.tsx +35 -0
  203. package/src/components/label/label.tsx +19 -0
  204. package/src/components/link-preview/index.ts +2 -0
  205. package/src/components/link-preview/link-preview.stories.tsx +178 -0
  206. package/src/components/link-preview/link-preview.test.tsx +123 -0
  207. package/src/components/link-preview/link-preview.tsx +194 -0
  208. package/src/components/list-editor/index.ts +1 -0
  209. package/src/components/list-editor/list-editor.stories.tsx +119 -0
  210. package/src/components/list-editor/list-editor.test.tsx +96 -0
  211. package/src/components/list-editor/list-editor.tsx +192 -0
  212. package/src/components/loading-state/index.ts +1 -0
  213. package/src/components/loading-state/loading-state.stories.tsx +38 -0
  214. package/src/components/loading-state/loading-state.tsx +26 -0
  215. package/src/components/locale-provider/index.ts +8 -0
  216. package/src/components/locale-provider/locale-provider.stories.tsx +83 -0
  217. package/src/components/locale-provider/locale-provider.test.tsx +238 -0
  218. package/src/components/locale-provider/locale-provider.tsx +187 -0
  219. package/src/components/locale-provider/messages.ts +300 -0
  220. package/src/components/match-highlight/index.ts +7 -0
  221. package/src/components/match-highlight/match-highlight.stories.tsx +146 -0
  222. package/src/components/match-highlight/match-highlight.test.tsx +202 -0
  223. package/src/components/match-highlight/match-highlight.tsx +145 -0
  224. package/src/components/mention-input/index.ts +28 -0
  225. package/src/components/mention-input/mention-input-mirror.stories.tsx +171 -0
  226. package/src/components/mention-input/mention-input.stories.tsx +463 -0
  227. package/src/components/mention-input/mention-input.test.tsx +617 -0
  228. package/src/components/mention-input/mention-input.tsx +1102 -0
  229. package/src/components/mention-input/mention-value.test.ts +253 -0
  230. package/src/components/mention-input/mention-value.ts +193 -0
  231. package/src/components/menubar/index.ts +17 -0
  232. package/src/components/menubar/menubar.stories.tsx +67 -0
  233. package/src/components/menubar/menubar.tsx +198 -0
  234. package/src/components/metric-card/index.ts +1 -0
  235. package/src/components/metric-card/metric-card.stories.tsx +224 -0
  236. package/src/components/metric-card/metric-card.test.tsx +198 -0
  237. package/src/components/metric-card/metric-card.tsx +229 -0
  238. package/src/components/model-picker/index.ts +11 -0
  239. package/src/components/model-picker/model-picker-state.ts +85 -0
  240. package/src/components/model-picker/model-picker.stories.tsx +128 -0
  241. package/src/components/model-picker/model-picker.test.tsx +241 -0
  242. package/src/components/model-picker/model-picker.tsx +270 -0
  243. package/src/components/nav-main/index.ts +1 -0
  244. package/src/components/nav-main/nav-main.tsx +147 -0
  245. package/src/components/nav-notifications/index.ts +5 -0
  246. package/src/components/nav-notifications/nav-notifications.test.tsx +15 -0
  247. package/src/components/nav-notifications/nav-notifications.tsx +70 -0
  248. package/src/components/nav-user/index.ts +1 -0
  249. package/src/components/nav-user/nav-user.test.tsx +29 -0
  250. package/src/components/nav-user/nav-user.tsx +114 -0
  251. package/src/components/navigation-menu/index.ts +10 -0
  252. package/src/components/navigation-menu/navigation-menu.stories.tsx +92 -0
  253. package/src/components/navigation-menu/navigation-menu.tsx +99 -0
  254. package/src/components/number-input/index.ts +1 -0
  255. package/src/components/number-input/number-input.stories.tsx +120 -0
  256. package/src/components/number-input/number-input.test.tsx +96 -0
  257. package/src/components/number-input/number-input.tsx +219 -0
  258. package/src/components/page-shell/index.ts +1 -0
  259. package/src/components/page-shell/page-shell.stories.tsx +105 -0
  260. package/src/components/page-shell/page-shell.test.tsx +57 -0
  261. package/src/components/page-shell/page-shell.tsx +62 -0
  262. package/src/components/pagination/index.ts +9 -0
  263. package/src/components/pagination/pagination.stories.tsx +57 -0
  264. package/src/components/pagination/pagination.tsx +77 -0
  265. package/src/components/popover/index.ts +1 -0
  266. package/src/components/popover/popover.stories.tsx +28 -0
  267. package/src/components/popover/popover.test.tsx +16 -0
  268. package/src/components/popover/popover.tsx +29 -0
  269. package/src/components/progress/index.ts +1 -0
  270. package/src/components/progress/progress.stories.tsx +80 -0
  271. package/src/components/progress/progress.test.tsx +35 -0
  272. package/src/components/progress/progress.tsx +50 -0
  273. package/src/components/radio-group/index.ts +1 -0
  274. package/src/components/radio-group/radio-group.stories.tsx +75 -0
  275. package/src/components/radio-group/radio-group.test.tsx +16 -0
  276. package/src/components/radio-group/radio-group.tsx +33 -0
  277. package/src/components/rating/index.ts +1 -0
  278. package/src/components/rating/rating.stories.tsx +111 -0
  279. package/src/components/rating/rating.test.tsx +41 -0
  280. package/src/components/rating/rating.tsx +226 -0
  281. package/src/components/resizable/index.ts +1 -0
  282. package/src/components/resizable/resizable.stories.tsx +25 -0
  283. package/src/components/resizable/resizable.tsx +40 -0
  284. package/src/components/reveal/index.ts +7 -0
  285. package/src/components/reveal/reveal.stories.tsx +90 -0
  286. package/src/components/reveal/reveal.test.tsx +43 -0
  287. package/src/components/reveal/reveal.tsx +95 -0
  288. package/src/components/revision-timeline/index.ts +10 -0
  289. package/src/components/revision-timeline/revision-timeline.stories.tsx +785 -0
  290. package/src/components/revision-timeline/revision-timeline.test.tsx +509 -0
  291. package/src/components/revision-timeline/revision-timeline.tsx +1107 -0
  292. package/src/components/scroll-area/index.ts +1 -0
  293. package/src/components/scroll-area/scroll-area.stories.tsx +45 -0
  294. package/src/components/scroll-area/scroll-area.tsx +43 -0
  295. package/src/components/section-header/index.ts +1 -0
  296. package/src/components/section-header/section-header.stories.tsx +20 -0
  297. package/src/components/section-header/section-header.tsx +36 -0
  298. package/src/components/segmented-field/index.ts +5 -0
  299. package/src/components/segmented-field/segmented-field.stories.tsx +121 -0
  300. package/src/components/segmented-field/segmented-field.test.tsx +163 -0
  301. package/src/components/segmented-field/segmented-field.tsx +235 -0
  302. package/src/components/select/index.ts +10 -0
  303. package/src/components/select/select.stories.tsx +106 -0
  304. package/src/components/select/select.test.tsx +98 -0
  305. package/src/components/select/select.tsx +230 -0
  306. package/src/components/separator/index.ts +2 -0
  307. package/src/components/separator/separator.stories.tsx +87 -0
  308. package/src/components/separator/separator.tsx +51 -0
  309. package/src/components/sheet/index.ts +12 -0
  310. package/src/components/sheet/sheet.stories.tsx +65 -0
  311. package/src/components/sheet/sheet.tsx +109 -0
  312. package/src/components/sidebar/index.ts +27 -0
  313. package/src/components/sidebar/sidebar.stories.tsx +69 -0
  314. package/src/components/sidebar/sidebar.test.tsx +43 -0
  315. package/src/components/sidebar/sidebar.tsx +688 -0
  316. package/src/components/skeleton/index.ts +1 -0
  317. package/src/components/skeleton/skeleton.stories.tsx +28 -0
  318. package/src/components/skeleton/skeleton.tsx +15 -0
  319. package/src/components/slider/index.ts +1 -0
  320. package/src/components/slider/slider.stories.tsx +211 -0
  321. package/src/components/slider/slider.test.tsx +168 -0
  322. package/src/components/slider/slider.tsx +136 -0
  323. package/src/components/slider-number/index.ts +1 -0
  324. package/src/components/slider-number/slider-number.stories.tsx +123 -0
  325. package/src/components/slider-number/slider-number.test.tsx +165 -0
  326. package/src/components/slider-number/slider-number.tsx +191 -0
  327. package/src/components/sonner/index.ts +1 -0
  328. package/src/components/sonner/sonner.stories.tsx +124 -0
  329. package/src/components/sonner/sonner.test.tsx +76 -0
  330. package/src/components/sonner/sonner.tsx +101 -0
  331. package/src/components/spinner/index.ts +1 -0
  332. package/src/components/spinner/spinner.stories.tsx +27 -0
  333. package/src/components/spinner/spinner.tsx +19 -0
  334. package/src/components/split-panel/index.ts +1 -0
  335. package/src/components/split-panel/split-panel.stories.tsx +60 -0
  336. package/src/components/split-panel/split-panel.test.tsx +38 -0
  337. package/src/components/split-panel/split-panel.tsx +95 -0
  338. package/src/components/state-panel/index.ts +1 -0
  339. package/src/components/state-panel/state-panel.stories.tsx +80 -0
  340. package/src/components/state-panel/state-panel.test.tsx +64 -0
  341. package/src/components/state-panel/state-panel.tsx +167 -0
  342. package/src/components/status-badge/index.ts +18 -0
  343. package/src/components/status-badge/status-badge.stories.tsx +132 -0
  344. package/src/components/status-badge/status-badge.test.tsx +189 -0
  345. package/src/components/status-badge/status-badge.tsx +330 -0
  346. package/src/components/switch/index.ts +1 -0
  347. package/src/components/switch/switch.stories.tsx +58 -0
  348. package/src/components/switch/switch.test.tsx +12 -0
  349. package/src/components/switch/switch.tsx +29 -0
  350. package/src/components/table/index.ts +10 -0
  351. package/src/components/table/table.stories.tsx +53 -0
  352. package/src/components/table/table.test.tsx +17 -0
  353. package/src/components/table/table.tsx +106 -0
  354. package/src/components/tabs/index.ts +1 -0
  355. package/src/components/tabs/tabs.stories.tsx +267 -0
  356. package/src/components/tabs/tabs.test.tsx +94 -0
  357. package/src/components/tabs/tabs.tsx +170 -0
  358. package/src/components/tag-input/index.ts +1 -0
  359. package/src/components/tag-input/tag-input.stories.tsx +120 -0
  360. package/src/components/tag-input/tag-input.test.tsx +97 -0
  361. package/src/components/tag-input/tag-input.tsx +253 -0
  362. package/src/components/team-switcher/index.ts +1 -0
  363. package/src/components/team-switcher/team-switcher.test.tsx +39 -0
  364. package/src/components/team-switcher/team-switcher.tsx +100 -0
  365. package/src/components/textarea/index.ts +1 -0
  366. package/src/components/textarea/textarea.stories.tsx +42 -0
  367. package/src/components/textarea/textarea.tsx +24 -0
  368. package/src/components/theme-switcher/index.ts +2 -0
  369. package/src/components/theme-switcher/theme-switcher.stories.tsx +146 -0
  370. package/src/components/theme-switcher/theme-switcher.test.tsx +253 -0
  371. package/src/components/theme-switcher/theme-switcher.tsx +280 -0
  372. package/src/components/theme-switcher/use-theme-transition.ts +62 -0
  373. package/src/components/timeline/index.ts +13 -0
  374. package/src/components/timeline/timeline.stories.tsx +99 -0
  375. package/src/components/timeline/timeline.test.tsx +196 -0
  376. package/src/components/timeline/timeline.tsx +188 -0
  377. package/src/components/toggle/index.ts +1 -0
  378. package/src/components/toggle/toggle.stories.tsx +116 -0
  379. package/src/components/toggle/toggle.test.tsx +119 -0
  380. package/src/components/toggle/toggle.tsx +64 -0
  381. package/src/components/toggle-group/index.ts +1 -0
  382. package/src/components/toggle-group/toggle-group.stories.tsx +110 -0
  383. package/src/components/toggle-group/toggle-group.tsx +59 -0
  384. package/src/components/toolbar/index.ts +14 -0
  385. package/src/components/toolbar/toolbar.stories.tsx +126 -0
  386. package/src/components/toolbar/toolbar.test.tsx +73 -0
  387. package/src/components/toolbar/toolbar.tsx +177 -0
  388. package/src/components/tooltip/index.ts +1 -0
  389. package/src/components/tooltip/tooltip.stories.tsx +67 -0
  390. package/src/components/tooltip/tooltip.tsx +27 -0
  391. package/src/components/top-nav/index.ts +1 -0
  392. package/src/components/top-nav/top-nav.stories.tsx +18 -0
  393. package/src/components/top-nav/top-nav.tsx +34 -0
  394. package/src/components/transfer/index.ts +2 -0
  395. package/src/components/transfer/transfer.stories.tsx +162 -0
  396. package/src/components/transfer/transfer.test.tsx +177 -0
  397. package/src/components/transfer/transfer.tsx +481 -0
  398. package/src/components/tree/index.ts +6 -0
  399. package/src/components/tree/tree.stories.tsx +618 -0
  400. package/src/components/tree/tree.test.tsx +699 -0
  401. package/src/components/tree/tree.tsx +1149 -0
  402. package/src/components/tree/use-tree-keyboard.ts +314 -0
  403. package/src/components/tree-select/index.ts +1 -0
  404. package/src/components/tree-select/tree-select.stories.tsx +127 -0
  405. package/src/components/tree-select/tree-select.test.tsx +40 -0
  406. package/src/components/tree-select/tree-select.tsx +137 -0
  407. package/src/components/typography/index.ts +31 -0
  408. package/src/components/typography/prose.test.tsx +48 -0
  409. package/src/components/typography/prose.tsx +194 -0
  410. package/src/components/typography/typography.stories.tsx +244 -0
  411. package/src/components/typography/typography.test.tsx +140 -0
  412. package/src/components/typography/typography.tsx +126 -0
  413. package/src/components/view-toolbar/index.ts +10 -0
  414. package/src/components/view-toolbar/view-toolbar.stories.tsx +342 -0
  415. package/src/components/view-toolbar/view-toolbar.test.tsx +262 -0
  416. package/src/components/view-toolbar/view-toolbar.tsx +320 -0
  417. package/src/components/virtual-select/index.ts +2 -0
  418. package/src/components/virtual-select/use-virtual-listbox.ts +132 -0
  419. package/src/components/virtual-select/virtual-select.stories.tsx +203 -0
  420. package/src/components/virtual-select/virtual-select.test.tsx +106 -0
  421. package/src/components/virtual-select/virtual-select.tsx +361 -0
  422. package/src/components/wizard/index.ts +12 -0
  423. package/src/components/wizard/wizard.stories.tsx +148 -0
  424. package/src/components/wizard/wizard.test.tsx +67 -0
  425. package/src/components/wizard/wizard.tsx +354 -0
  426. package/src/decoration.stories.tsx +236 -0
  427. package/src/index.ts +174 -0
  428. package/src/lib/cn.test.ts +39 -0
  429. package/src/lib/cn.ts +31 -0
  430. package/src/lib/compact-number.ts +61 -0
  431. package/src/lib/document-address.test.ts +75 -0
  432. package/src/lib/document-address.ts +265 -0
  433. package/src/lib/download.ts +93 -0
  434. package/src/lib/file-icon.test.ts +45 -0
  435. package/src/lib/file-icon.ts +58 -0
  436. package/src/lib/file-kind.test.ts +98 -0
  437. package/src/lib/file-kind.ts +303 -0
  438. package/src/lib/file-source.test.ts +217 -0
  439. package/src/lib/file-source.ts +269 -0
  440. package/src/lib/merge-refs.test.ts +37 -0
  441. package/src/lib/merge-refs.ts +17 -0
  442. package/src/lib/streamdown-translations.ts +99 -0
  443. package/src/lib/use-copy-to-clipboard.ts +75 -0
  444. package/src/lib/use-mobile.ts +16 -0
  445. package/src/motion.stories.tsx +266 -0
  446. package/src/taste-profile.test.tsx +252 -0
  447. package/src/templates-object-detail-hub.stories.tsx +466 -0
  448. package/src/templates-screen-states.stories.tsx +306 -0
  449. package/src/templates-settings.stories.tsx +245 -0
@@ -0,0 +1,4497 @@
1
+ import { ClassValue } from 'clsx';
2
+ import { LucideIcon, LucideProps } from 'lucide-react';
3
+ import * as react from 'react';
4
+ import react__default, { HTMLAttributes, ReactNode, InputHTMLAttributes, ButtonHTMLAttributes, ComponentProps, ComponentPropsWithoutRef, ReactElement, TextareaHTMLAttributes, TdHTMLAttributes, ThHTMLAttributes, LiHTMLAttributes, AnchorHTMLAttributes, OlHTMLAttributes } from 'react';
5
+ import * as AccordionPrimitive from '@radix-ui/react-accordion';
6
+ import * as class_variance_authority_types from 'class-variance-authority/types';
7
+ import * as _radix_ui_react_separator from '@radix-ui/react-separator';
8
+ import { VariantProps } from 'class-variance-authority';
9
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
10
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
11
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
12
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
13
+ import { DayPicker, DateRange } from 'react-day-picker';
14
+ export { DateRange } from 'react-day-picker';
15
+ import useEmblaCarousel, { UseEmblaCarouselType } from 'embla-carousel-react';
16
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
17
+ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
18
+ import { Command as Command$1 } from 'cmdk';
19
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
20
+ import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
21
+ import * as vaul from 'vaul';
22
+ import { Drawer as Drawer$1 } from 'vaul';
23
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
24
+ import * as _radix_ui_react_slot from '@radix-ui/react-slot';
25
+ import * as _radix_ui_react_label from '@radix-ui/react-label';
26
+ import * as react_hook_form from 'react-hook-form';
27
+ import { FieldValues, FieldPath, ControllerProps } from 'react-hook-form';
28
+ import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
29
+ import * as input_otp from 'input-otp';
30
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
31
+ import * as MenubarPrimitive from '@radix-ui/react-menubar';
32
+ export { Group as MenubarGroup, Menu as MenubarMenu, Portal as MenubarPortal, RadioGroup as MenubarRadioGroup, Sub as MenubarSub } from '@radix-ui/react-menubar';
33
+ import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
34
+ import * as ProgressPrimitive from '@radix-ui/react-progress';
35
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
36
+ import * as ResizablePrimitive from 'react-resizable-panels';
37
+ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
38
+ import * as SelectPrimitive from '@radix-ui/react-select';
39
+ import * as SliderPrimitive from '@radix-ui/react-slider';
40
+ import { Toaster as Toaster$1 } from 'sonner';
41
+ export { toast } from 'sonner';
42
+ import * as SwitchPrimitive from '@radix-ui/react-switch';
43
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
44
+ import { ThemeName } from '@elabs-ai/components-tokens';
45
+ import * as TogglePrimitive from '@radix-ui/react-toggle';
46
+ import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
47
+ import * as ToolbarPrimitive from '@radix-ui/react-toolbar';
48
+ import { Virtualizer } from '@tanstack/react-virtual';
49
+
50
+ /**
51
+ * Merge class names with conflict resolution. `clsx` handles conditionals;
52
+ * `tailwind-merge` ensures later Tailwind utilities win (e.g. `p-2 p-4` -> `p-4`).
53
+ * Use this in every component that accepts a `className` prop.
54
+ */
55
+ declare function cn(...inputs: ClassValue[]): string;
56
+
57
+ /** Returns true when the viewport is below the mobile breakpoint (768px). */
58
+ declare function useIsMobile(): boolean;
59
+
60
+ /**
61
+ * Browser file-download helpers — the single home for the
62
+ * `Blob`/URL → hidden `<a download>` → click → revoke dance that was previously
63
+ * copy-pasted across `@elabs-ai/components-ai` (ConversationDownload), `@elabs-ai/components-data`
64
+ * (downloadCsv) and now `@elabs-ai/components-ai` Gallery.
65
+ *
66
+ * Pure DOM mechanics, no React, no other deps — and SSR-guarded
67
+ * (`typeof document === "undefined"` → no-op) so it's safe to import from
68
+ * dependency-light modules. The CONTENT (CSV serialization, markdown export,
69
+ * image source) stays with each caller; this only triggers the save.
70
+ */
71
+ /**
72
+ * Trigger a download for an in-memory `Blob`. No-op in non-DOM environments.
73
+ * Revokes the object URL immediately after the click (the browser captures the
74
+ * download synchronously, mirroring the prior call sites).
75
+ */
76
+ declare function downloadBlob(blob: Blob, filename: string): void;
77
+ /**
78
+ * Trigger a download for an existing `url` (an http(s)/relative URL, or a
79
+ * `data:`/`blob:` URI). No-op in non-DOM environments.
80
+ *
81
+ * Same-origin / `blob:` / `data:` → a direct `<a download>` (honors `filename`).
82
+ * Cross-origin → the browser ignores the `download` filename, so we `fetch` the
83
+ * bytes and save via {@link downloadBlob}. This requires the server to allow CORS;
84
+ * on failure (CORS/opaque/offline) we fall back to opening the source in a new
85
+ * tab so the user still gets the asset. Fire-and-forget: `void downloadUrl(...)`.
86
+ */
87
+ declare function downloadUrl(url: string, filename?: string): Promise<void>;
88
+
89
+ /** How long the transient "copied" state stays true before it resets. */
90
+ declare const COPY_FEEDBACK_MS = 1500;
91
+ interface UseCopyToClipboardOptions {
92
+ /** ms the `copied` flag stays true. Default: {@link COPY_FEEDBACK_MS}. */
93
+ resetAfterMs?: number;
94
+ }
95
+ interface CopyToClipboard {
96
+ /** True for `resetAfterMs` after a successful copy. */
97
+ copied: boolean;
98
+ /** Writes `text` to the clipboard. Resolves `false` when it could not. */
99
+ copy: (text: string) => Promise<boolean>;
100
+ }
101
+ /**
102
+ * Copy-to-clipboard with a transient confirmation flag.
103
+ *
104
+ * One implementation for the whole library — the copy button in
105
+ * `@elabs-ai/components-editor` and `CopyableValue` share it, so the
106
+ * timing, the unmount cleanup and the "no clipboard here" answer are defined
107
+ * once instead of re-derived per component.
108
+ *
109
+ * `navigator.clipboard` is absent under SSR, in jsdom, and in any insecure
110
+ * (non-`https`, non-`localhost`) context. That is reported as `false` rather
111
+ * than thrown: a copy affordance failing is a papercut, not a crash, and the
112
+ * caller decides whether to say anything about it. The deprecated
113
+ * `document.execCommand("copy")` fallback is deliberately not used.
114
+ */
115
+ declare function useCopyToClipboard(options?: UseCopyToClipboardOptions): CopyToClipboard;
116
+
117
+ /**
118
+ * The one file-type resolver for the whole library — extension + MIME → a
119
+ * COARSE, CLOSED category.
120
+ *
121
+ * Before this existed the repo had three competing, package-private ideas of
122
+ * "what kind of file is this": `ContextAssetType`
123
+ * (`markdown|code|sql|csv|image`, `@elabs-ai/components-ai`),
124
+ * `AttachmentMediaCategory` (six MIME buckets, same package) and
125
+ * `UploadFile` (no kind at all, `@elabs-ai/components-ui`). None could
126
+ * see the others, so each grew its own icon map and its own gaps.
127
+ *
128
+ * ## Why the category is closed and coarse (ADR 0024 §4)
129
+ *
130
+ * {@link FileCategory} answers "what SHAPE of thing is this" — enough to pick an
131
+ * icon, a label, or a fallback surface. It is deliberately NOT the routing key
132
+ * for a renderer. Fine-grained format matching (`.docx` vs `.odt`,
133
+ * `.tsx` vs `.rs`) belongs to the adapter manifests in the package that owns the
134
+ * parsers, so adding a format never means editing this file — and never means a
135
+ * `@elabs-ai/components-ui` release.
136
+ *
137
+ * Pure data + string handling: no React, no DOM, no other deps.
138
+ */
139
+ /**
140
+ * Coarse file shape. CLOSED — adding a member is a breaking change for any
141
+ * consumer with an exhaustive `switch`, so extend the adapter manifests instead.
142
+ */
143
+ type FileCategory = "image" | "video" | "audio" | "document" | "spreadsheet" | "presentation" | "code" | "text" | "data" | "archive" | "unknown";
144
+ /** What {@link resolveFileKind} knows about a file before anything reads it. */
145
+ interface FileKind {
146
+ /** Coarse shape, for icons, labels and fallback surfaces. */
147
+ category: FileCategory;
148
+ /**
149
+ * Best-known MIME type. The caller's value wins when it is meaningful;
150
+ * otherwise inferred from the extension, else `"application/octet-stream"`.
151
+ */
152
+ mediaType: string;
153
+ /** Lowercased extension WITHOUT the dot (`"pdf"`), or `""` when there is none. */
154
+ extension: string;
155
+ }
156
+ /**
157
+ * Lowercased extension without the dot. `""` when the name has none, is a
158
+ * dotfile (`.gitignore` — the whole name is the "extension" to a human, but it
159
+ * is not a format), or ends in a dot.
160
+ */
161
+ declare function extensionOf(name: string): string;
162
+ /**
163
+ * Best-known MIME for a filename, from its extension alone.
164
+ * `undefined` when the extension is unknown — callers decide the fallback.
165
+ */
166
+ declare function mediaTypeFromName(name: string): string | undefined;
167
+ /**
168
+ * Resolve what a file is from its name and (optionally) the MIME the source
169
+ * reported. Never throws; unknown input resolves to
170
+ * `{ category: "unknown", mediaType: "application/octet-stream", extension: "" }`.
171
+ *
172
+ * A caller-supplied `mediaType` wins over the extension EXCEPT where the
173
+ * extension is strictly more specific — `report.csv` served as `text/plain`
174
+ * still resolves to `"data"`, because servers routinely under-specify.
175
+ */
176
+ declare function resolveFileKind(name: string, mediaType?: string): FileKind;
177
+
178
+ /**
179
+ * One input model for "a file", whatever the app happens to be holding.
180
+ *
181
+ * The library previously had three: a `File` (upload), a `string` of content
182
+ * (chat assets), and a bare URL (attachments) — so every surface that wanted to
183
+ * render a file first had to guess which of the three it had. {@link FileSource}
184
+ * is the union all of them collapse into, and {@link normalizeFileSource} turns
185
+ * any member into one uniform reader.
186
+ *
187
+ * Two things this fixes beyond the merge:
188
+ *
189
+ * - **Authenticated remote files work.** The `url` variant carries
190
+ * `init?: RequestInit`, so headers, credentials and an abort signal reach the
191
+ * fetch. A viewer that can only take a naked URL cannot open anything behind
192
+ * auth, which is most enterprise content.
193
+ * - **Alt text has a home.** Every binary variant takes `alt`, so an image or a
194
+ * rendered page can be described without a parallel prop channel.
195
+ *
196
+ * Pure DOM/platform mechanics: no React, no other deps. SSR-safe to import;
197
+ * only {@link ResolvedFileSource.url} needs a browser, and it says so.
198
+ */
199
+
200
+ /** Any file the library can be handed. Discriminated on `kind`. */
201
+ type FileSource =
202
+ /** A user-picked file. Name and MIME come from the platform. */
203
+ {
204
+ kind: "file";
205
+ file: File;
206
+ alt?: string;
207
+ }
208
+ /** In-memory bytes that already have a `Blob` wrapper (a generated export, a decoded attachment). */
209
+ | {
210
+ kind: "blob";
211
+ blob: Blob;
212
+ name: string;
213
+ mediaType?: string;
214
+ alt?: string;
215
+ }
216
+ /**
217
+ * A remote file. `init` is passed straight to `fetch` — this is how auth
218
+ * headers, `credentials` and an `AbortSignal` reach the request.
219
+ */
220
+ | {
221
+ kind: "url";
222
+ url: string;
223
+ name?: string;
224
+ mediaType?: string;
225
+ alt?: string;
226
+ init?: RequestInit;
227
+ }
228
+ /** Raw bytes with no wrapper (a worker result, a WASM output). */
229
+ | {
230
+ kind: "buffer";
231
+ buffer: ArrayBuffer;
232
+ name: string;
233
+ mediaType: string;
234
+ alt?: string;
235
+ }
236
+ /** Content the app already has as a string (an agent's markdown, a code snippet). */
237
+ | {
238
+ kind: "text";
239
+ text: string;
240
+ name: string;
241
+ mediaType?: string;
242
+ };
243
+ /**
244
+ * A {@link FileSource} with its identity resolved and its bytes reachable the
245
+ * same way regardless of where they came from.
246
+ *
247
+ * Reads are memoized on success, so `text()` after `bytes()` costs nothing and a
248
+ * remote file is fetched once. A failed read is NOT cached — a retry re-runs it.
249
+ */
250
+ interface ResolvedFileSource {
251
+ /** Display name, always non-empty. Derived from the URL path when the caller gave none. */
252
+ readonly name: string;
253
+ /** Best-known MIME, resolved from the declared type then the extension. */
254
+ readonly mediaType: string;
255
+ /** Coarse shape, for icons/labels/fallbacks. Not a renderer routing key. */
256
+ readonly category: FileCategory;
257
+ /** Lowercased extension without the dot, or `""`. */
258
+ readonly extension: string;
259
+ /** Author-supplied description, for images and rendered pages. */
260
+ readonly alt?: string;
261
+ /** Byte length when known up front. `undefined` for `text` and un-fetched `url` sources. */
262
+ readonly size?: number;
263
+ /** The full contents as bytes. */
264
+ bytes(signal?: AbortSignal): Promise<ArrayBuffer>;
265
+ /** The full contents decoded as UTF-8. */
266
+ text(signal?: AbortSignal): Promise<string>;
267
+ /**
268
+ * A URL usable as an `<img>`/`<video>`/`<iframe>` src.
269
+ *
270
+ * A public `url` source returns its own URL unchanged, so the browser streams
271
+ * it and no full read happens. Every other source (and any `url` source with
272
+ * an `init`, which the element could not replay) mints an object URL — release
273
+ * it with {@link revoke}. Browser only: rejects where `URL.createObjectURL`
274
+ * does not exist.
275
+ */
276
+ url(signal?: AbortSignal): Promise<string>;
277
+ /** Release any object URL this reader minted. Idempotent; safe to call unconditionally. */
278
+ revoke(): void;
279
+ }
280
+ /**
281
+ * Turn any {@link FileSource} into a uniform reader.
282
+ *
283
+ * Cheap and synchronous — it resolves identity only. Nothing is read, fetched or
284
+ * decoded until a `bytes()` / `text()` / `url()` call.
285
+ */
286
+ declare function normalizeFileSource(source: FileSource): ResolvedFileSource;
287
+
288
+ /**
289
+ * One glyph per {@link FileCategory} — the single icon map for file-shaped UI.
290
+ *
291
+ * Supersedes two package-private maps that could not see each other:
292
+ * `PRODUCED_ASSET_ICONS` (`@elabs-ai/components-ai` file-tree, keyed by
293
+ * the five-member `ContextAssetType`) and `mediaCategoryIcons` (same package,
294
+ * attachments, keyed by six MIME buckets) — so the same `.csv` drew a table glyph
295
+ * in one surface and a generic document glyph in the other.
296
+ *
297
+ * Lucide per `.claude/rules/icons.md`: these are generic UI glyphs, not product
298
+ * vocabulary, so nothing here belongs in
299
+ * `@elabs-ai/components-icons`.
300
+ *
301
+ * Values only — this module holds component REFERENCES, it renders nothing.
302
+ * Icons inherit color from `currentColor`; the category is never carried by hue
303
+ * alone, so a caller must still supply a text label or an `aria-label` on the
304
+ * control (WCAG 1.4.1).
305
+ */
306
+
307
+ /** The glyph for each coarse file shape. Exhaustive over {@link FileCategory}. */
308
+ declare const FILE_CATEGORY_ICONS: Readonly<Record<FileCategory, LucideIcon>>;
309
+ /**
310
+ * The glyph for a file, resolved from its name and (optionally) MIME.
311
+ * Falls back to the generic file glyph rather than throwing.
312
+ */
313
+ declare function fileIconFor(name: string, mediaType?: string): LucideIcon;
314
+
315
+ /**
316
+ * How one part of a document is addressed.
317
+ *
318
+ * A viewer that can only open a file answers "here is the document". A viewer
319
+ * that can be pointed at a PART of one answers "here is the sentence that
320
+ * claim came from" — the RAG-citation case, and the same machinery behind
321
+ * find-in-document.
322
+ *
323
+ * ## Why this lives in `@elabs-ai/components-ui`
324
+ *
325
+ * The producer of an address (a chat answer's citation, in
326
+ * `@elabs-ai/components-ai`) and its consumer (the file viewer, in
327
+ * `@elabs-ai/components-viewer`) are Layer-2 siblings that may not
328
+ * import each other. `ui` is the only layer both reach, which is exactly why
329
+ * `FileSource` and `MatchRange` already live here. This module is a
330
+ * dependency-free leaf: types plus pure string functions, no React.
331
+ *
332
+ * ## Three kinds, one union
333
+ *
334
+ * Real producers disagree about what they can emit, so the union carries all
335
+ * three rather than forcing everyone through the weakest:
336
+ *
337
+ * - **`quote`** — the snippet text. The only kind that survives crossing a tool
338
+ * boundary: an indexing pipeline's character offsets are computed against ITS
339
+ * extraction of the PDF, never against ours, so its numbers are meaningless
340
+ * here while its text still is. Lossy (a repeated phrase is ambiguous) and the
341
+ * most useful.
342
+ * - **`range`** — exact character offsets, and exact only against the SAME text
343
+ * projection: `AdapterDocument.text` as this build's adapter produced it. Use
344
+ * it when both ends are ours (find-in-document, a second pass over a document
345
+ * already open).
346
+ * - **`rect`** — page-relative boxes, `0..1` fractions of the page. Needs no
347
+ * text at all, which is what makes it the answer for a scanned page, a chart,
348
+ * a photo region, or any layout-analysis model whose output is geometry.
349
+ *
350
+ * ## The rule that lets this union grow
351
+ *
352
+ * A consumer matches only the kinds it declared it honours and reports the rest
353
+ * as unsupported — it never writes an exhaustive `switch` with a `never`
354
+ * fallthrough. That is what lets a fourth kind (a spreadsheet `cell` address,
355
+ * say) be added later without breaking every consumer that predates it.
356
+ */
357
+ /** The address kinds, as a value — for capability declarations and iteration. */
358
+ declare const DOCUMENT_ADDRESS_KINDS: readonly ["quote", "range", "rect"];
359
+ /** Which way a part of a document is addressed. */
360
+ type DocumentAddressKind = (typeof DOCUMENT_ADDRESS_KINDS)[number];
361
+ /**
362
+ * A box on a page, as fractions of that page's own box.
363
+ *
364
+ * Fractions, not pixels, because the page is not a fixed size: it rescales with
365
+ * zoom, with the pane's width and with the device's pixel ratio. A consumer
366
+ * multiplies by the page element's live measured size at paint time, so the box
367
+ * stays put through every one of those. Origin is top-left (CSS), so `y` grows
368
+ * downward — matching the DOM rather than the PDF's own bottom-left space.
369
+ */
370
+ interface DocumentRect {
371
+ /** Distance from the page's left edge, `0..1`. */
372
+ x: number;
373
+ /** Distance from the page's TOP edge, `0..1`. */
374
+ y: number;
375
+ /** Fraction of the page's width. */
376
+ width: number;
377
+ /** Fraction of the page's height. */
378
+ height: number;
379
+ }
380
+ /**
381
+ * Address by the text itself — the interoperable kind.
382
+ *
383
+ * Matching is done on the normalized form of both sides
384
+ * ({@link normalizeQuoteText}), so a quote survives the whitespace, quote-glyph
385
+ * and casing differences that every extractor introduces.
386
+ */
387
+ interface QuoteAddress {
388
+ kind: "quote";
389
+ /** The passage to find. Whitespace and quote glyphs need not match exactly. */
390
+ text: string;
391
+ /**
392
+ * Which occurrence to take when the passage appears more than once, 1-based.
393
+ * Omitted means the first — or the one nearest {@link QuoteAddress.near},
394
+ * when that is given.
395
+ */
396
+ occurrence?: number;
397
+ /**
398
+ * A hint about where to look. It disambiguates repeats rather than restricting
399
+ * the search: the occurrence closest to it wins, and a passage that turns out
400
+ * to be elsewhere is still found.
401
+ */
402
+ near?: {
403
+ /**
404
+ * 1-based page (or slide) the passage is expected on.
405
+ *
406
+ * Advisory, and deliberately NOT used to navigate: the viewer turns to the
407
+ * page the passage was actually located on, so a stale hint cannot send a
408
+ * reader to a blank page. Only {@link QuoteAddress.near.offset} takes part in
409
+ * tie-breaking today; a renderer may read this off the address if it wants
410
+ * more.
411
+ */
412
+ page?: number;
413
+ /** Approximate character offset the passage is expected near. */
414
+ offset?: number;
415
+ };
416
+ }
417
+ /**
418
+ * Address by character offsets into `AdapterDocument.text`, half-open
419
+ * `[start, end)` — the same convention as `MatchRange`.
420
+ *
421
+ * Only meaningful against the text projection THIS build produced. An offset
422
+ * from a foreign pipeline is not this kind; it is a {@link QuoteAddress}.
423
+ */
424
+ interface RangeAddress {
425
+ kind: "range";
426
+ start: number;
427
+ end: number;
428
+ /**
429
+ * 1-based page hint, when the producer knows it. Advisory only — the viewer
430
+ * derives the page from the offsets against its own index, so a hint that
431
+ * disagrees cannot misdirect the pager.
432
+ */
433
+ page?: number;
434
+ }
435
+ /** Address by geometry — one or more boxes on one page. */
436
+ interface RectAddress {
437
+ kind: "rect";
438
+ /** 1-based page (or slide) number. */
439
+ page: number;
440
+ /**
441
+ * The boxes making up this one addressed part. An array, not a single box,
442
+ * because a real passage wraps: a sentence spanning three lines is three
443
+ * boxes, and a two-column paragraph is more. Painting them as one shape each
444
+ * is what avoids stitching DOM ranges together.
445
+ */
446
+ rects: readonly DocumentRect[];
447
+ }
448
+ /** Which part of a document something refers to. */
449
+ type DocumentAddress = QuoteAddress | RangeAddress | RectAddress;
450
+ /**
451
+ * The result of normalizing, with the way back.
452
+ *
453
+ * `offsets` has one more entry than `text` has characters: `offsets[i]` is the
454
+ * index in the ORIGINAL string where normalized character `i` came from, and
455
+ * the final entry is one past the last character that survived — NOT the
456
+ * original's length, which would drag trailing whitespace into every range that
457
+ * runs to the end. So a normalized range `[a, b)` maps back to
458
+ * `[offsets[a], offsets[b])` with no arithmetic, which is the whole point of
459
+ * building the map rather than searching twice.
460
+ */
461
+ interface NormalizedText {
462
+ text: string;
463
+ offsets: readonly number[];
464
+ }
465
+ /**
466
+ * Fold a string to its canonical match key, keeping a map back to the original.
467
+ *
468
+ * Every rule is a collapse, a drop or a 1:1 swap — never an expansion — so the
469
+ * map stays monotone and a range maps back exactly. That constraint is why
470
+ * ligatures (`fi`) and the ellipsis character are deliberately left alone: both
471
+ * would be 1:many, and a fuzzier match is not worth an offset map that can no
472
+ * longer be trusted.
473
+ *
474
+ * What it does: collapses every whitespace run to one space and trims; drops
475
+ * zero-width characters and soft hyphens; straightens curly quotes and dashes;
476
+ * folds case — a citation is matched case-insensitively, and that is a property
477
+ * of the match key rather than a flag every caller has to remember.
478
+ */
479
+ declare function normalizeQuoteTextWithOffsets(input: string): NormalizedText;
480
+ /**
481
+ * The canonical match key for a quote — {@link normalizeQuoteTextWithOffsets}
482
+ * without the map, for comparing or de-duplicating two quotes.
483
+ */
484
+ declare function normalizeQuoteText(input: string): string;
485
+
486
+ /**
487
+ * Every key of `StreamdownTranslations` as of streamdown@2.5.0.
488
+ *
489
+ * Kept explicit rather than derived from `defaultTranslations`, so the list is
490
+ * readable data here and checkable against the real type over in `ai`.
491
+ */
492
+ declare const STREAMDOWN_TRANSLATION_KEYS: readonly ["close", "copied", "copyCode", "copyLink", "copyTable", "copyTableAsCsv", "copyTableAsMarkdown", "copyTableAsTsv", "downloadDiagram", "downloadDiagramAsMmd", "downloadDiagramAsPng", "downloadDiagramAsSvg", "downloadFile", "downloadImage", "downloadTable", "downloadTableAsCsv", "downloadTableAsMarkdown", "exitFullscreen", "externalLinkWarning", "imageNotAvailable", "mermaidFormatMmd", "mermaidFormatPng", "mermaidFormatSvg", "openExternalLink", "openLink", "tableFormatCsv", "tableFormatMarkdown", "tableFormatTsv", "viewFullscreen"];
493
+ type StreamdownTranslationKey = (typeof STREAMDOWN_TRANSLATION_KEYS)[number];
494
+ /** What Streamdown's `translations` prop takes, expressed without importing it. */
495
+ type StreamdownTranslationMap = Record<StreamdownTranslationKey, string>;
496
+ /**
497
+ * Resolve every Streamdown label through `t()`.
498
+ *
499
+ * Provider-optional, like `useLocale()` itself: with no `<LocaleProvider>` every
500
+ * key resolves to the shipped English default.
501
+ *
502
+ * Memoization matters — Streamdown puts `translations` into a React context, so
503
+ * a fresh object per render would re-render every code block and table in the
504
+ * document. The map is memoized on `t`, which is stable per locale.
505
+ */
506
+ declare function useStreamdownTranslations(): StreamdownTranslationMap;
507
+
508
+ declare const Accordion: react.ForwardRefExoticComponent<(AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps) & react.RefAttributes<HTMLDivElement>>;
509
+ declare const AccordionItem: react.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
510
+ declare const AccordionTrigger: react.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
511
+ declare const AccordionContent: react.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
512
+
513
+ interface AdvancedGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
514
+ /** The disclosure's label. Defaults to "Advanced". */
515
+ title?: ReactNode;
516
+ /**
517
+ * What is hidden inside, shown ONLY while collapsed — so a reader can tell
518
+ * whether the group holds defaults or edits without opening it.
519
+ */
520
+ summary?: ReactNode;
521
+ /** Shorthand summary: renders "N changed" when `summary` is not given. */
522
+ changedCount?: number;
523
+ /** Uncontrolled initial state. Collapsed by default — that is the point. */
524
+ defaultOpen?: boolean;
525
+ /** Controlled open state. */
526
+ open?: boolean;
527
+ /** Fires on every open/close, controlled or not. */
528
+ onOpenChange?: (open: boolean) => void;
529
+ }
530
+ /**
531
+ * A collapsed-by-default group of secondary settings (#341).
532
+ *
533
+ * Long dialogs go wrong in one of two ways: everything is visible (so nothing
534
+ * reads as primary), or the extras are hidden with no hint that they were
535
+ * touched. `AdvancedGroup` takes the third option — hidden, but SUMMARISED:
536
+ * while collapsed it shows what is inside ("3 changed"), and the summary
537
+ * disappears once the group is open and the values speak for themselves.
538
+ *
539
+ * A preset over `Collapsible`, not a new disclosure primitive: Radix keeps the
540
+ * trigger/content wiring, `aria-expanded`, and keyboard operation.
541
+ *
542
+ * ```tsx
543
+ * <AdvancedGroup changedCount={3}>
544
+ * <Field … />
545
+ * </AdvancedGroup>
546
+ * ```
547
+ */
548
+ declare function AdvancedGroup({ className, title, summary, changedCount, defaultOpen, open: openProp, onOpenChange, children, ...props }: AdvancedGroupProps): react.JSX.Element;
549
+
550
+ type InputProps = InputHTMLAttributes<HTMLInputElement>;
551
+ declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
552
+
553
+ declare const buttonVariants: (props?: ({
554
+ variant?: "link" | "default" | "secondary" | "outline" | "destructive" | "outline-subtle" | "ghost" | null | undefined;
555
+ size?: "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | null | undefined;
556
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
557
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
558
+ /** Render the child element as the button (Radix Slot) instead of a <button>. */
559
+ asChild?: boolean;
560
+ }
561
+ declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
562
+
563
+ declare const TooltipProvider: react.FC<TooltipPrimitive.TooltipProviderProps>;
564
+ declare const Tooltip: react.FC<TooltipPrimitive.TooltipProps>;
565
+ declare const TooltipTrigger: react.ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & react.RefAttributes<HTMLButtonElement>>;
566
+ declare const TooltipContent: react.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
567
+
568
+ type SidebarContextProps = {
569
+ state: "expanded" | "collapsed";
570
+ open: boolean;
571
+ setOpen: (open: boolean) => void;
572
+ openMobile: boolean;
573
+ setOpenMobile: (open: boolean) => void;
574
+ isMobile: boolean;
575
+ toggleSidebar: () => void;
576
+ };
577
+ declare function useSidebar(): SidebarContextProps;
578
+ declare const SidebarProvider: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLDivElement> & react.HTMLAttributes<HTMLDivElement> & {
579
+ defaultOpen?: boolean;
580
+ open?: boolean;
581
+ onOpenChange?: (open: boolean) => void;
582
+ }, "ref"> & react.RefAttributes<HTMLDivElement>>;
583
+ declare const Sidebar: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLDivElement> & react.HTMLAttributes<HTMLDivElement> & {
584
+ side?: "left" | "right";
585
+ variant?: "sidebar" | "floating" | "inset";
586
+ collapsible?: "offcanvas" | "icon" | "none";
587
+ }, "ref"> & react.RefAttributes<HTMLDivElement>>;
588
+ declare const SidebarTrigger: react.ForwardRefExoticComponent<Omit<ButtonProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
589
+ declare const SidebarRail: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
590
+ declare const SidebarInset: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
591
+ declare const SidebarInput: react.ForwardRefExoticComponent<Omit<InputProps & react.RefAttributes<HTMLInputElement>, "ref"> & react.RefAttributes<HTMLInputElement>>;
592
+ declare const SidebarHeader: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
593
+ declare const SidebarFooter: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
594
+ declare const SidebarSeparator: react.ForwardRefExoticComponent<Omit<Omit<_radix_ui_react_separator.SeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
595
+ tone?: "strong" | "subtle" | null | undefined;
596
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
597
+ declare const SidebarContent: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
598
+ declare const SidebarGroup: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
599
+ declare const SidebarGroupLabel: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLDivElement> & react.HTMLAttributes<HTMLDivElement> & {
600
+ asChild?: boolean;
601
+ }, "ref"> & react.RefAttributes<HTMLDivElement>>;
602
+ declare const SidebarGroupAction: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLButtonElement> & react.ButtonHTMLAttributes<HTMLButtonElement> & {
603
+ asChild?: boolean;
604
+ }, "ref"> & react.RefAttributes<HTMLButtonElement>>;
605
+ declare const SidebarGroupContent: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
606
+ declare const SidebarMenu: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & react.RefAttributes<HTMLUListElement>>;
607
+ declare const SidebarMenuItem: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & react.RefAttributes<HTMLLIElement>>;
608
+ declare const sidebarMenuButtonVariants: (props?: ({
609
+ variant?: "default" | "outline" | null | undefined;
610
+ size?: "default" | "sm" | "lg" | null | undefined;
611
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
612
+ declare const SidebarMenuButton: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLButtonElement> & react.ButtonHTMLAttributes<HTMLButtonElement> & {
613
+ asChild?: boolean;
614
+ isActive?: boolean;
615
+ tooltip?: string | ComponentProps<typeof TooltipContent>;
616
+ } & VariantProps<(props?: ({
617
+ variant?: "default" | "outline" | null | undefined;
618
+ size?: "default" | "sm" | "lg" | null | undefined;
619
+ } & class_variance_authority_types.ClassProp) | undefined) => string>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
620
+ declare const SidebarMenuAction: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLButtonElement> & react.ButtonHTMLAttributes<HTMLButtonElement> & {
621
+ asChild?: boolean;
622
+ showOnHover?: boolean;
623
+ }, "ref"> & react.RefAttributes<HTMLButtonElement>>;
624
+ declare const SidebarMenuBadge: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
625
+ declare function SidebarMenuSkeleton({ className, showIcon, ...props }: ComponentProps<"div"> & {
626
+ showIcon?: boolean;
627
+ }): react.JSX.Element;
628
+ declare const SidebarMenuSub: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & react.RefAttributes<HTMLUListElement>>;
629
+ declare const SidebarMenuSubItem: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & react.RefAttributes<HTMLLIElement>>;
630
+ declare const SidebarMenuSubButton: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLAnchorElement> & react.AnchorHTMLAttributes<HTMLAnchorElement> & {
631
+ asChild?: boolean;
632
+ size?: "sm" | "md";
633
+ isActive?: boolean;
634
+ }, "ref"> & react.RefAttributes<HTMLAnchorElement>>;
635
+
636
+ interface AppSidebarProps extends ComponentProps<typeof Sidebar> {
637
+ /**
638
+ * Content rendered inside `<SidebarHeader>`. Typically a `TeamSwitcher`
639
+ * or a logo + title combination.
640
+ */
641
+ header?: ReactNode;
642
+ /**
643
+ * Content rendered inside `<SidebarFooter>`. Typically a `NavUser` or
644
+ * a `TeamSwitcher` placed at the bottom.
645
+ */
646
+ footer?: ReactNode;
647
+ /**
648
+ * Main navigation content rendered inside `<SidebarContent>`. Pass one or
649
+ * more `<SidebarGroup>` / `<SidebarMenu>` compositions here.
650
+ */
651
+ children?: ReactNode;
652
+ }
653
+ /**
654
+ * Parameterized application sidebar shell. Composes `@radix-ui` `Sidebar`
655
+ * primitives with typed `header`, `footer`, and `children` slots.
656
+ *
657
+ * Registry blocks (`sidebar-02`, `sidebar-04`, `sidebar-05`) should import
658
+ * this instead of constructing the `Sidebar` → `SidebarHeader` →
659
+ * `SidebarContent` → `SidebarFooter` skeleton themselves.
660
+ *
661
+ * @example
662
+ * ```tsx
663
+ * <AppSidebar
664
+ * header={<TeamSwitcher teams={teams} />}
665
+ * footer={<NavUser user={currentUser} />}
666
+ * >
667
+ * <SidebarGroup>…</SidebarGroup>
668
+ * </AppSidebar>
669
+ * ```
670
+ */
671
+ declare const AppSidebar: react.ForwardRefExoticComponent<Omit<AppSidebarProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
672
+
673
+ declare const alertVariants: (props?: ({
674
+ variant?: "default" | "success" | "warning" | "destructive" | "info" | null | undefined;
675
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
676
+ declare const Alert: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
677
+ variant?: "default" | "success" | "warning" | "destructive" | "info" | null | undefined;
678
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLDivElement>>;
679
+ interface AlertTitleProps extends HTMLAttributes<HTMLHeadingElement> {
680
+ /**
681
+ * Render at a different heading level to fit the surrounding document
682
+ * outline (#329). The visual (`mb-1 font-medium leading-none
683
+ * tracking-tight`) is identical at every level. @default "h5"
684
+ */
685
+ as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
686
+ }
687
+ declare const AlertTitle: react.ForwardRefExoticComponent<AlertTitleProps & react.RefAttributes<HTMLHeadingElement>>;
688
+ interface AlertDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {
689
+ /**
690
+ * Cap the line length to a readable prose measure (`max-w-prose`, ~65ch)
691
+ * for genuine paragraph content (#339). Off by default — short,
692
+ * label-style descriptions should stay full width.
693
+ */
694
+ measure?: boolean;
695
+ }
696
+ declare const AlertDescription: react.ForwardRefExoticComponent<AlertDescriptionProps & react.RefAttributes<HTMLParagraphElement>>;
697
+
698
+ declare const AlertDialog: react.FC<AlertDialogPrimitive.AlertDialogProps>;
699
+ declare const AlertDialogTrigger: react.ForwardRefExoticComponent<AlertDialogPrimitive.AlertDialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
700
+ declare const AlertDialogPortal: react.FC<AlertDialogPrimitive.AlertDialogPortalProps>;
701
+ declare const AlertDialogContent: react.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
702
+ declare function AlertDialogHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
703
+ declare function AlertDialogFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
704
+ declare const AlertDialogTitle: react.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogTitleProps & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<HTMLHeadingElement>>;
705
+ declare const AlertDialogDescription: react.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<HTMLParagraphElement>>;
706
+ declare const AlertDialogAction: react.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogActionProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
707
+ declare const AlertDialogCancel: react.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogCancelProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
708
+
709
+ interface AppShellProps {
710
+ /** Persistent left navigation (often a <Sidebar />). */
711
+ sidebar?: ReactNode;
712
+ /** Top bar (often a <TopNav />). */
713
+ topNav?: ReactNode;
714
+ children: ReactNode;
715
+ className?: string;
716
+ /** Class for the scrolling main content region. */
717
+ mainClassName?: string;
718
+ }
719
+ /**
720
+ * App-first layout: fixed-height viewport with an optional sidebar, a top bar,
721
+ * and a scrollable main region. Pure layout — bring your own nav components.
722
+ */
723
+ declare function AppShell({ sidebar, topNav, children, className, mainClassName }: AppShellProps): react.JSX.Element;
724
+
725
+ declare const AspectRatio: react.ForwardRefExoticComponent<AspectRatioPrimitive.AspectRatioProps & react.RefAttributes<HTMLDivElement>>;
726
+
727
+ /**
728
+ * The shape of one third-party notice rendered by `AttributionPanel`.
729
+ *
730
+ * Hand-written (the DATA is generated, the type is not) so the generated module
731
+ * type-checks against a real contract and a malformed entry fails `typecheck`
732
+ * rather than rendering blank.
733
+ */
734
+ /**
735
+ * What is being credited — also the panel's grouping and render order.
736
+ *
737
+ * - `data` — content served at runtime (basemap tiles, map data). Usually
738
+ * the notices a licence actually OBLIGES us to display.
739
+ * - `source` — code adapted or vendored into brand-ui (shadcn/ui, mapcn, …).
740
+ * - `font` — a self-hosted webfont shipped in the tokens package.
741
+ * - `dependency` — an npm runtime dependency of a distributable package.
742
+ */
743
+ type AttributionCategory = "data" | "source" | "font" | "dependency";
744
+ interface Attribution {
745
+ /** Stable key — the npm name, `font:<face>`, or the curated source's id. */
746
+ id: string;
747
+ category: AttributionCategory;
748
+ /** Display name. */
749
+ name: string;
750
+ /** Resolved npm version, when the entry is a package. */
751
+ version: string | null;
752
+ /** SPDX identifier where one exists, else the terms' name. */
753
+ license: string;
754
+ /** The copyright line to display verbatim, when the source provides one. */
755
+ copyright: string | null;
756
+ /** Canonical link (homepage, repository, or licence page). */
757
+ url: string | null;
758
+ /** The `@elabs-ai/components-*` packages this reaches a consumer through. */
759
+ usedBy: readonly string[];
760
+ /**
761
+ * True when a licence or provider terms OBLIGE the notice to be displayed
762
+ * (ODbL, the OFL, provider terms) — as opposed to a courtesy credit. Required
763
+ * notices render first and are visually marked.
764
+ */
765
+ required: boolean;
766
+ /** Short human explanation of what it is used for. */
767
+ note: string | null;
768
+ }
769
+
770
+ declare const ATTRIBUTIONS: readonly Attribution[];
771
+
772
+ declare const CATEGORY_LABEL: Record<AttributionCategory, string>;
773
+ interface AttributionPanelProps extends HTMLAttributes<HTMLElement> {
774
+ /**
775
+ * The notices to render. Defaults to the GENERATED dataset
776
+ * (`scripts/gen-attributions.mjs`), which is what keeps this panel accurate
777
+ * without anyone maintaining a list — override only to scope or to test.
778
+ */
779
+ attributions?: readonly Attribution[];
780
+ /** Restrict to these categories, in the panel's own order. Default: all. */
781
+ categories?: readonly AttributionCategory[];
782
+ /**
783
+ * Restrict to notices reachable through these packages — e.g. an app that only
784
+ * uses `…-ui` need not credit MapLibre's basemap providers. Matched against
785
+ * each entry's `usedBy`. Default: all.
786
+ */
787
+ packages?: readonly string[];
788
+ /** Show only the notices a licence obliges us to display. */
789
+ requiredOnly?: boolean;
790
+ /**
791
+ * Cap the body height and scroll inside it. Omit to let the panel grow and
792
+ * leave scrolling to the container (a Dialog body, a settings pane).
793
+ */
794
+ maxHeight?: number | string;
795
+ }
796
+ /**
797
+ * The single surface where brand-ui's third-party notices are displayed —
798
+ * OSS dependencies, adapted source, self-hosted fonts, and the map data/tile
799
+ * credits that a licence actually obliges the product to show.
800
+ *
801
+ * The content is GENERATED from the repo (`pnpm gen:attributions`, gated by
802
+ * `pnpm attributions:check`), so it cannot drift from what is actually shipped
803
+ * the way a hand-kept credits page does.
804
+ *
805
+ * **Why this exists:** `MapCanvas` disables MapLibre's in-map attribution
806
+ * control by default, and the flow canvases hide the React Flow badge. The
807
+ * React Flow badge is an MIT project's request and carries no condition, but the
808
+ * default Carto basemap's OpenStreetMap data is ODbL-licensed and the credit is
809
+ * REQUIRED — mounting this panel somewhere a user can reach (an About dialog, a
810
+ * settings pane, a footer link) is what keeps that obligation met while the map
811
+ * corner stays clean. Ship it, or turn the in-map control back on.
812
+ */
813
+ declare const AttributionPanel: react.ForwardRefExoticComponent<AttributionPanelProps & react.RefAttributes<HTMLElement>>;
814
+
815
+ declare const Avatar: react.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & react.RefAttributes<HTMLSpanElement>, "ref"> & react.RefAttributes<HTMLSpanElement>>;
816
+ declare const AvatarImage: react.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & react.RefAttributes<HTMLImageElement>, "ref"> & react.RefAttributes<HTMLImageElement>>;
817
+ declare const AvatarFallback: react.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & react.RefAttributes<HTMLSpanElement>, "ref"> & react.RefAttributes<HTMLSpanElement>>;
818
+
819
+ declare const badgeVariants: (props?: ({
820
+ variant?: "default" | "secondary" | "outline" | "success" | "warning" | "destructive" | "info" | null | undefined;
821
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
822
+ interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
823
+ }
824
+ declare function Badge({ className, variant, ...props }: BadgeProps): react.JSX.Element;
825
+
826
+ interface BentoGridProps extends HTMLAttributes<HTMLDivElement> {
827
+ /** Additional className merged via cn(). */
828
+ className?: string;
829
+ /**
830
+ * Enable the cursor-following spotlight on every tile in this grid. Individual
831
+ * tiles can still opt out (or in) with their own `spotlight` prop. Disabled
832
+ * entirely under OS `prefers-reduced-motion` regardless of this prop.
833
+ * @default false
834
+ */
835
+ spotlight?: boolean;
836
+ }
837
+ /**
838
+ * Responsive CSS-grid container.
839
+ * - 1 column on mobile, 2 on sm, 4 on lg.
840
+ * - `grid-auto-flow: dense` fills in gaps left by spanning tiles.
841
+ * - `auto-rows-[14rem]` gives a baseline row height (14rem ≈ 224px); tiles can
842
+ * span multiple rows via the `size` / `span.row` API.
843
+ * - Carries the grid-wide `spotlight` default for its tiles (opt-in).
844
+ */
845
+ declare const BentoGrid: react.ForwardRefExoticComponent<BentoGridProps & react.RefAttributes<HTMLDivElement>>;
846
+ /**
847
+ * Size preset → [colSpan, rowSpan].
848
+ *
849
+ * | size | cols | rows | purpose |
850
+ * |-------|------|------|------------------------------------------------------------|
851
+ * | sm | 1 | 1 | Supporting: compact metric or icon tile |
852
+ * | md | 2 | 1 | Supporting: wider but single-row |
853
+ * | lg | 2 | 2 | Featured: 2×2 block |
854
+ * | hero | 2 | 2 | Hero: 2×2 + gradient emphasis wash |
855
+ *
856
+ * On a 1-column layout (mobile) ALL col spans clamp to 1 automatically via
857
+ * CSS `min()` in `gridColumn`. Row spans are always honoured.
858
+ */
859
+ type BentoGridSize = "sm" | "md" | "lg" | "hero";
860
+ declare const bentoGridItemVariants: (props?: ({
861
+ hero?: boolean | null | undefined;
862
+ interactive?: boolean | null | undefined;
863
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
864
+ type BentoGridItemVariants = VariantProps<typeof bentoGridItemVariants>;
865
+ interface BentoGridItemProps extends HTMLAttributes<HTMLDivElement>, BentoGridItemVariants {
866
+ /**
867
+ * Size preset. Resolves to a col + row span. Overridden by explicit `span`.
868
+ * @default "sm"
869
+ */
870
+ size?: BentoGridSize;
871
+ /**
872
+ * Explicit grid span. Wins over `size`. Spans clamp gracefully on narrow
873
+ * layouts — a `col: 4` on a 2-col grid becomes `span min(4, 2)`.
874
+ */
875
+ span?: {
876
+ col?: number;
877
+ row?: number;
878
+ };
879
+ /**
880
+ * Enable the cursor-following spotlight gradient on this tile. Omit to inherit
881
+ * the parent `BentoGrid`'s `spotlight` (itself `false` by default) — so the
882
+ * effect is opt-in, per grid or per tile. Disabled entirely under OS
883
+ * `prefers-reduced-motion` regardless of this prop.
884
+ * @default false (inherited from BentoGrid)
885
+ */
886
+ spotlight?: boolean;
887
+ }
888
+ /**
889
+ * A single bento tile. Composes `Card`, rests flat, lifts to `shadow-lg` on
890
+ * hover, and adds the OPT-IN spotlight overlay.
891
+ *
892
+ * Spotlight:
893
+ * - Sets `--bento-x` / `--bento-y` CSS custom properties on `onMouseMove`
894
+ * via a direct style set (no layout reads in render — uses
895
+ * `getBoundingClientRect` in the event handler only, never during paint).
896
+ * - An absolutely-positioned `pointer-events-none aria-hidden` overlay paints
897
+ * `radial-gradient(… at var(--bento-x) var(--bento-y), color-mix(--primary), transparent)`.
898
+ * - Revealed on hover via opacity transition gated by `duration-base ease-standard`.
899
+ * - Suppressed with `motion-reduce:hidden` — cursor-following IS motion.
900
+ */
901
+ declare const BentoGridItem: react.ForwardRefExoticComponent<BentoGridItemProps & react.RefAttributes<HTMLDivElement>>;
902
+
903
+ interface NumberInputProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
904
+ /** Controlled value. Pass `null` to represent an empty state. */
905
+ value?: number | null;
906
+ /** Uncontrolled default value. */
907
+ defaultValue?: number | null;
908
+ /** Called when the numeric value changes. */
909
+ onValueChange?: (value: number | null) => void;
910
+ /** Minimum allowed value. */
911
+ min?: number;
912
+ /** Maximum allowed value. */
913
+ max?: number;
914
+ /** Step increment/decrement amount (default 1). */
915
+ step?: number;
916
+ /**
917
+ * When true (default), the value is clamped to [min, max] on blur.
918
+ * Clamping does NOT happen per-keystroke — only on blur.
919
+ */
920
+ clamp?: boolean;
921
+ /** Intl.NumberFormat options used to format the displayed value. */
922
+ formatOptions?: Intl.NumberFormatOptions;
923
+ /** Placeholder text for the underlying input. */
924
+ placeholder?: string;
925
+ /** Whether the input is disabled. */
926
+ disabled?: boolean;
927
+ /** Whether the input is read-only. */
928
+ readOnly?: boolean;
929
+ /** Name attribute forwarded to the underlying <input>. */
930
+ name?: string;
931
+ /** id attribute forwarded to the underlying <input>. */
932
+ id?: string;
933
+ /** aria-label forwarded to the underlying <input>. */
934
+ "aria-label"?: string;
935
+ /** aria-labelledby forwarded to the underlying <input>. */
936
+ "aria-labelledby"?: string;
937
+ /** aria-describedby forwarded to the underlying <input>. */
938
+ "aria-describedby"?: string;
939
+ /** aria-invalid forwarded to the underlying <input>. */
940
+ "aria-invalid"?: boolean | "true" | "false" | "grammar" | "spelling";
941
+ /** aria-required forwarded to the underlying <input>. */
942
+ "aria-required"?: boolean | "true" | "false";
943
+ }
944
+ /**
945
+ * NumberInput — a numeric stepper that composes InputGroup + two step buttons.
946
+ *
947
+ * Controlled via `value`/`onValueChange`; uncontrolled via `defaultValue`.
948
+ * Keyboard ↑/↓ = ±step; Shift+↑/↓ = ±step×10. Clamps on blur (not per keystroke).
949
+ */
950
+ declare const NumberInput: react.ForwardRefExoticComponent<NumberInputProps & react.RefAttributes<HTMLDivElement>>;
951
+
952
+ interface BoundedNumberProps extends NumberInputProps {
953
+ /**
954
+ * Content shown in place of the value when the field is empty (`null`) and
955
+ * not focused — e.g. "No limit" for a capped setting with no cap set.
956
+ * Defaults to "No limit".
957
+ */
958
+ emptyLabel?: ReactNode;
959
+ }
960
+ /**
961
+ * BoundedNumber — a `NumberInput` preset for a bounded numeric where "empty"
962
+ * has a semantic meaning ("No limit") instead of reading as a blank box.
963
+ *
964
+ * Written reuse verdict (see #373): this wraps `NumberInput` rather than
965
+ * reimplementing anything. `NumberInput` already does everything the value
966
+ * needs — blur-only clamping (`clamp`, default true) and `null` as a real,
967
+ * distinct empty state (`commit(null)` on empty blur). The only missing
968
+ * behaviour is rendering that empty state as a meaningful label instead of a
969
+ * blank input, which is exactly what this preset adds: an absolutely
970
+ * positioned, `pointer-events-none` overlay shown only while the value is
971
+ * `null` AND the field is not focused, so the underlying input stays fully
972
+ * clickable/typable and still round-trips to `null` on an empty blur.
973
+ */
974
+ declare const BoundedNumber: react.ForwardRefExoticComponent<BoundedNumberProps & react.RefAttributes<HTMLDivElement>>;
975
+
976
+ declare const Breadcrumb: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & react.RefAttributes<HTMLElement>>;
977
+ declare const BreadcrumbList: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.OlHTMLAttributes<HTMLOListElement>, HTMLOListElement>, "ref"> & react.RefAttributes<HTMLOListElement>>;
978
+ declare const BreadcrumbItem: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & react.RefAttributes<HTMLLIElement>>;
979
+ declare const BreadcrumbLink: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLAnchorElement> & react.AnchorHTMLAttributes<HTMLAnchorElement> & {
980
+ asChild?: boolean;
981
+ }, "ref"> & react.RefAttributes<HTMLAnchorElement>>;
982
+ declare const BreadcrumbPage: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & react.RefAttributes<HTMLSpanElement>>;
983
+ declare function BreadcrumbSeparator({ children, className, ...props }: ComponentProps<"li">): react.JSX.Element;
984
+ declare function BreadcrumbEllipsis({ className, ...props }: ComponentProps<"span">): react.JSX.Element;
985
+
986
+ declare const buttonGroupVariants: (props?: ({
987
+ orientation?: "horizontal" | "vertical" | null | undefined;
988
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
989
+ declare const ButtonGroup: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLDivElement> & react.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
990
+ orientation?: "horizontal" | "vertical" | null | undefined;
991
+ } & class_variance_authority_types.ClassProp) | undefined) => string>, "ref"> & react.RefAttributes<HTMLDivElement>>;
992
+ declare const ButtonGroupText: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLDivElement> & react.HTMLAttributes<HTMLDivElement> & {
993
+ asChild?: boolean;
994
+ }, "ref"> & react.RefAttributes<HTMLDivElement>>;
995
+ declare const ButtonGroupSeparator: react.ForwardRefExoticComponent<Omit<Omit<_radix_ui_react_separator.SeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
996
+ tone?: "strong" | "subtle" | null | undefined;
997
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
998
+
999
+ type CalendarProps = React.ComponentProps<typeof DayPicker>;
1000
+ /** Date picker calendar (react-day-picker v9), themed with brand tokens. */
1001
+ declare function Calendar({ className, classNames, showOutsideDays, ...props }: CalendarProps): react.JSX.Element;
1002
+
1003
+ declare const cardVariants: (props?: ({
1004
+ interactive?: boolean | null | undefined;
1005
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1006
+ interface CardProps extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof cardVariants> {
1007
+ /**
1008
+ * Optional detail-panel content. **Undefined → a plain card** (today's single `<div>` —
1009
+ * no grid, no panel, zero behaviour change).
1010
+ */
1011
+ detail?: ReactNode;
1012
+ /** Which edge the detail panel sits on. @default "side" */
1013
+ detailPlacement?: "side" | "bottom";
1014
+ /**
1015
+ * `fixed` (default, accessible) → panel always visible. `hover` → hidden at rest, revealed
1016
+ * on hover **and** keyboard `focus-within` at a FIXED outer footprint (the main content
1017
+ * yields the space; no surrounding reflow). Use `hover` for **supplementary** detail only —
1018
+ * essential content must use `fixed`. @default "fixed"
1019
+ */
1020
+ detailReveal?: "fixed" | "hover";
1021
+ /** Detail track size (any CSS length). @default "16rem" (side) / "auto" (bottom) */
1022
+ detailSize?: string;
1023
+ /** Accessible label for the detail region. @default "Details" */
1024
+ detailLabel?: string;
1025
+ }
1026
+ declare const Card: react.ForwardRefExoticComponent<CardProps & react.RefAttributes<HTMLDivElement>>;
1027
+ declare const CardHeader: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
1028
+ interface CardTitleProps extends HTMLAttributes<HTMLElement> {
1029
+ /**
1030
+ * Render as a different element — pick the semantic heading level so a
1031
+ * card that titles a real page section contributes to the document outline
1032
+ * (#328). The visual (`text-title leading-none`) is identical regardless of
1033
+ * tag. @default "div"
1034
+ */
1035
+ as?: "div" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
1036
+ }
1037
+ declare const CardTitle: react.ForwardRefExoticComponent<CardTitleProps & react.RefAttributes<HTMLDivElement>>;
1038
+ interface CardDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {
1039
+ /**
1040
+ * Cap the line length to a readable prose measure (`max-w-prose`, ~65ch)
1041
+ * for genuine paragraph content (#339). Off by default — short,
1042
+ * subtitle-style descriptions should stay full width.
1043
+ */
1044
+ measure?: boolean;
1045
+ }
1046
+ declare const CardDescription: react.ForwardRefExoticComponent<CardDescriptionProps & react.RefAttributes<HTMLParagraphElement>>;
1047
+ declare const CardAction: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
1048
+ declare const CardContent: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
1049
+ declare const CardFooter: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
1050
+
1051
+ type CarouselApi = UseEmblaCarouselType[1];
1052
+ type CarouselOptions = NonNullable<Parameters<typeof useEmblaCarousel>[0]>;
1053
+ type CarouselPlugin = NonNullable<Parameters<typeof useEmblaCarousel>[1]>;
1054
+ interface CarouselProps {
1055
+ opts?: CarouselOptions;
1056
+ plugins?: CarouselPlugin;
1057
+ orientation?: "horizontal" | "vertical";
1058
+ setApi?: (api: CarouselApi) => void;
1059
+ }
1060
+ /**
1061
+ * Root carousel region. Carries `role="region" aria-roledescription="carousel"`
1062
+ * plus an `aria-label` — it defaults to `"Carousel"` so the region always has an
1063
+ * accessible name (issue #279), but **consumers should pass a specific
1064
+ * `aria-label`** (e.g. `"Product photos"`) describing what the carousel actually
1065
+ * shows, since AT users otherwise can't distinguish multiple carousels on a page.
1066
+ */
1067
+ declare const Carousel: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & CarouselProps & react.RefAttributes<HTMLDivElement>>;
1068
+ declare const CarouselContent: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
1069
+ declare const CarouselItem: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
1070
+ declare function CarouselPrevious({ className, ...props }: ComponentProps<typeof Button>): react.JSX.Element;
1071
+ declare function CarouselNext({ className, ...props }: ComponentProps<typeof Button>): react.JSX.Element;
1072
+
1073
+ /** Who / what proposed the change set (presentational only; never fetches). */
1074
+ interface ChangeProvenance {
1075
+ /** Display name of the person or agent author. */
1076
+ author?: string;
1077
+ /** Model or tool identifier (e.g. "claude-sonnet-4-6"). */
1078
+ model?: string;
1079
+ /** ISO-8601 or human-readable timestamp. */
1080
+ timestamp?: string;
1081
+ /** Free-form note, e.g. commit hash or run ID. */
1082
+ note?: string;
1083
+ }
1084
+ /** Status of a single change hunk. Drives the accent-rail colour and icon. */
1085
+ type ChangeHunkStatus = "added" | "removed" | "modified";
1086
+ /** A single proposed change in the review set. */
1087
+ interface ChangeHunk {
1088
+ /** Unique identifier for this hunk (used in the approved set). */
1089
+ id: string;
1090
+ /** Short title shown in the hunk header (e.g. filename or section label). */
1091
+ title?: string;
1092
+ /** The content before the proposed edit. */
1093
+ before?: ReactNode;
1094
+ /** The content after the proposed edit (the proposal). */
1095
+ after?: ReactNode;
1096
+ /** Change type — drives accent rail + icon. @default "modified" */
1097
+ status?: ChangeHunkStatus;
1098
+ /** Per-hunk provenance override (overrides the review-level provenance). */
1099
+ provenance?: ChangeProvenance;
1100
+ }
1101
+ /** State surface exposed by the ChangeReview context. */
1102
+ interface ChangeReviewState {
1103
+ /** Set of currently-approved hunk IDs. */
1104
+ approved: ReadonlySet<string>;
1105
+ /** Total number of hunks. */
1106
+ totalCount: number;
1107
+ /** Number of approved hunks. */
1108
+ approvedCount: number;
1109
+ /** True when every hunk is approved. */
1110
+ allApproved: boolean;
1111
+ /** True when no hunk is approved. */
1112
+ noneApproved: boolean;
1113
+ }
1114
+ /** Actions exposed by the ChangeReview context. */
1115
+ interface ChangeReviewActions {
1116
+ /** Toggle the approval state of a single hunk. */
1117
+ toggle: (id: string, next: boolean) => void;
1118
+ /** Approve all hunks. */
1119
+ approveAll: () => void;
1120
+ /** Reject (un-approve) all hunks. */
1121
+ rejectAll: () => void;
1122
+ }
1123
+ /**
1124
+ * Hunk-status accent rail — the separation grammar's accent-rail channel: ONE
1125
+ * focal gesture (the status rail) on a neutral card ground (`bg-card` + the
1126
+ * subtle, redundant-exempt `border-border` hairline). NO colored wash and NO
1127
+ * redundant colored border — the slop the "AI card" look is built from. Status
1128
+ * reads from the rail + the header icon + the StatusBadge (never color alone).
1129
+ * Approval is signalled by the StatusBadge + the filled toggle (no ring wash).
1130
+ */
1131
+ declare const hunkVariants: (props?: ({
1132
+ status?: "added" | "removed" | "modified" | null | undefined;
1133
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1134
+ interface ChangeReviewProviderProps {
1135
+ hunks: ChangeHunk[];
1136
+ /**
1137
+ * Controlled approved set. Pass `Set<string>` or a string array.
1138
+ * When provided, the component is controlled and `onToggle` / `onApproveAll` /
1139
+ * `onRejectAll` are the only way to update the state.
1140
+ */
1141
+ approved?: Set<string> | string[];
1142
+ onToggle?: (id: string, next: boolean) => void;
1143
+ onApproveAll?: () => void;
1144
+ onRejectAll?: () => void;
1145
+ children: ReactNode;
1146
+ }
1147
+ /**
1148
+ * Lifts the approval state. Can be controlled (pass `approved`) or uncontrolled.
1149
+ * Derive `isControlled = approved !== undefined`.
1150
+ */
1151
+ declare function ChangeReviewProvider({ hunks, approved: approvedProp, onToggle, onApproveAll, onRejectAll, children, }: ChangeReviewProviderProps): react.JSX.Element;
1152
+ type ChangeReviewHeaderProps = HTMLAttributes<HTMLDivElement>;
1153
+ /**
1154
+ * Count summary ("3 of 5 approved") + Approve all / Reject all bulk actions.
1155
+ * `aria-controls` is intentionally omitted — screen readers reach the list
1156
+ * naturally in DOM order.
1157
+ */
1158
+ declare const ChangeReviewHeader: react.ForwardRefExoticComponent<ChangeReviewHeaderProps & react.RefAttributes<HTMLDivElement>>;
1159
+ interface ChangeReviewProvenanceProps extends HTMLAttributes<HTMLDivElement> {
1160
+ /**
1161
+ * Structured provenance object OR any ReactNode for custom rendering.
1162
+ * When a `ChangeProvenance` object is passed, a default attribution line
1163
+ * is rendered. Pass a ReactNode for full control.
1164
+ */
1165
+ provenance: ReactNode | ChangeProvenance;
1166
+ }
1167
+ /**
1168
+ * Quiet attribution line showing who/what proposed the change set.
1169
+ * Uses `text-muted-foreground` and small typography — it should not compete
1170
+ * with the hunks themselves.
1171
+ */
1172
+ declare const ChangeReviewProvenance: react.ForwardRefExoticComponent<ChangeReviewProvenanceProps & react.RefAttributes<HTMLDivElement>>;
1173
+ type ChangeReviewListProps = HTMLAttributes<HTMLOListElement>;
1174
+ /**
1175
+ * Ordered list of change hunks. Uses `<ol>` so AT users can navigate by
1176
+ * item number ("item 2 of 5"). Renders a StatePanel when the list is empty.
1177
+ */
1178
+ declare const ChangeReviewList: react.ForwardRefExoticComponent<ChangeReviewListProps & react.RefAttributes<HTMLOListElement>>;
1179
+ interface ChangeReviewHunkProps extends Omit<HTMLAttributes<HTMLLIElement>, "children">, Omit<VariantProps<typeof hunkVariants>, "approved"> {
1180
+ hunk: ChangeHunk;
1181
+ /**
1182
+ * Override the default before/after layout. Receives the hunk data and
1183
+ * current approval state. Return `null` to suppress the default content area.
1184
+ */
1185
+ renderHunk?: (hunk: ChangeHunk, state: {
1186
+ approved: boolean;
1187
+ }) => ReactNode;
1188
+ }
1189
+ /**
1190
+ * A single change hunk row.
1191
+ *
1192
+ * Approval state is signalled with TWO non-color cues:
1193
+ * - icon: Check (approved) vs plain toggle (pending)
1194
+ * - label: "Approved" badge vs "Approve" button text
1195
+ * This ensures the state is clear in all three themes including the low-chroma
1196
+ * monochrome surfaces (colorblind-safe).
1197
+ */
1198
+ declare const ChangeReviewHunk: react.ForwardRefExoticComponent<ChangeReviewHunkProps & react.RefAttributes<HTMLLIElement>>;
1199
+ interface ChangeReviewProps extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "onToggle"> {
1200
+ /** The proposed changes to review. */
1201
+ hunks: ChangeHunk[];
1202
+ /**
1203
+ * Controlled approved set. Pass `Set<string>` or a string array.
1204
+ * When omitted the component manages approval state internally (uncontrolled).
1205
+ */
1206
+ approved?: Set<string> | string[];
1207
+ /** Called when the user toggles a single hunk's approval state. */
1208
+ onToggle?: (id: string, next: boolean) => void;
1209
+ /** Called when the user clicks "Approve all". */
1210
+ onApproveAll?: () => void;
1211
+ /** Called when the user clicks "Reject all". */
1212
+ onRejectAll?: () => void;
1213
+ /**
1214
+ * Provenance to show above the hunk list. Accepts a `ChangeProvenance`
1215
+ * object (renders default attribution) or any ReactNode.
1216
+ */
1217
+ provenance?: ReactNode | ChangeProvenance;
1218
+ /**
1219
+ * Override the per-hunk body renderer (passed through to each `ChangeReviewHunk`).
1220
+ */
1221
+ renderHunk?: ChangeReviewHunkProps["renderHunk"];
1222
+ }
1223
+ /**
1224
+ * Convenience composition that wires Provider → Header → Provenance → List → Hunks.
1225
+ * For custom layouts compose the parts manually via `ChangeReview.Provider`,
1226
+ * `ChangeReview.Header`, etc.
1227
+ */
1228
+ declare const ChangeReview: react.ForwardRefExoticComponent<ChangeReviewProps & react.RefAttributes<HTMLDivElement>>;
1229
+
1230
+ declare const Checkbox: react.ForwardRefExoticComponent<Omit<CheckboxPrimitive.CheckboxProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
1231
+
1232
+ declare const Collapsible: react.ForwardRefExoticComponent<CollapsiblePrimitive.CollapsibleProps & react.RefAttributes<HTMLDivElement>>;
1233
+ declare const CollapsibleTrigger: react.ForwardRefExoticComponent<CollapsiblePrimitive.CollapsibleTriggerProps & react.RefAttributes<HTMLButtonElement>>;
1234
+ declare const CollapsibleContent: react.ForwardRefExoticComponent<Omit<CollapsiblePrimitive.CollapsibleContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1235
+
1236
+ type CollapsiblePanelSide = "left" | "right";
1237
+ type CollapsiblePanelState = "expanded" | "collapsed";
1238
+ interface UseCollapsiblePanelOptions {
1239
+ /** Which edge the panel lives on. Default `"left"`. */
1240
+ side?: CollapsiblePanelSide;
1241
+ /** Controlled open state (`isControlled = open !== undefined`). */
1242
+ open?: boolean;
1243
+ /** Uncontrolled initial open state. Default `true`. */
1244
+ defaultOpen?: boolean;
1245
+ /** Called with the next open state on `setOpen`/`toggle`. */
1246
+ onOpenChange?: (open: boolean) => void;
1247
+ /**
1248
+ * Literal expanded-width utility (e.g. `"w-(--sidebar-width)"`). Must be a
1249
+ * literal in the consumer's source so Tailwind generates it.
1250
+ */
1251
+ widthClassName?: string;
1252
+ /**
1253
+ * Literal collapsed-state utility for the gap spacer (e.g.
1254
+ * `"group-data-[collapsible=offcanvas]:w-0"`).
1255
+ */
1256
+ spacerCollapsedClassName?: string;
1257
+ /**
1258
+ * Literal off-screen slide utilities for the fixed container, keyed by side
1259
+ * (e.g. `left: "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"`).
1260
+ */
1261
+ containerSlideClassNames?: Record<CollapsiblePanelSide, string>;
1262
+ }
1263
+ /** Data attributes for the panel's `group` element. */
1264
+ interface CollapsiblePanelAttrs {
1265
+ "data-state": CollapsiblePanelState;
1266
+ "data-side": CollapsiblePanelSide;
1267
+ }
1268
+ interface UseCollapsiblePanelReturn {
1269
+ /** Resolved open state (controlled prop wins). */
1270
+ open: boolean;
1271
+ /** `"expanded"` when open, `"collapsed"` when closed. */
1272
+ state: CollapsiblePanelState;
1273
+ side: CollapsiblePanelSide;
1274
+ /** Set the open state (accepts a value or an updater fn). */
1275
+ setOpen: (open: boolean | ((open: boolean) => boolean)) => void;
1276
+ toggle: () => void;
1277
+ /** `data-state`/`data-side` for the group element wrapping both fragments. */
1278
+ attrs: CollapsiblePanelAttrs;
1279
+ /** The gap-spacer fragment: reserves/releases the inline width. */
1280
+ spacerClassName: string;
1281
+ /** The fixed-container fragment: slides the panel off-screen. */
1282
+ containerClassName: string;
1283
+ }
1284
+ declare function useCollapsiblePanel({ side, open: openProp, defaultOpen, onOpenChange, widthClassName, spacerCollapsedClassName, containerSlideClassNames, }?: UseCollapsiblePanelOptions): UseCollapsiblePanelReturn;
1285
+
1286
+ /**
1287
+ * The semantic color token names that ColorPicker understands as "safe" values.
1288
+ * These map 1-to-1 with Tailwind utilities backed by CSS variables so they
1289
+ * remain theme-aware at runtime.
1290
+ */
1291
+ type ColorToken = "primary" | "secondary" | "destructive" | "success" | "warning" | "info" | "chart-1" | "chart-2" | "chart-3" | "chart-4" | "chart-5" | "chart-6" | "chart-7" | "chart-8" | "chart-9" | "chart-10" | "chart-11" | "chart-12";
1292
+ /** All recognised token names in display order. */
1293
+ declare const COLOR_TOKENS: ColorToken[];
1294
+ interface ColorPickerProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
1295
+ /**
1296
+ * Controlled value — a `ColorToken` name (preferred, theme-aware) or a raw
1297
+ * hex string (only when `allowCustom` is true).
1298
+ */
1299
+ value?: ColorToken | string;
1300
+ /** Uncontrolled default value. */
1301
+ defaultValue?: ColorToken | string;
1302
+ /** Called when the selected color changes. */
1303
+ onValueChange?: (value: ColorToken | string) => void;
1304
+ /**
1305
+ * Swatches to display. Defaults to all chart + status tokens.
1306
+ * Accepts any subset of `ColorToken`.
1307
+ */
1308
+ swatches?: ColorToken[];
1309
+ /**
1310
+ * When true, a free-form hex input is shown below the swatches.
1311
+ * NOTE: custom hex values are NOT theme-aware — they will not adapt when
1312
+ * the active theme changes. Prefer token values for all theme-safe UI.
1313
+ */
1314
+ allowCustom?: boolean;
1315
+ /** aria-label for the trigger button. Defaults to "Pick color". */
1316
+ "aria-label"?: string;
1317
+ }
1318
+ /**
1319
+ * ColorPicker — a token-safe swatch picker backed by a Popover.
1320
+ *
1321
+ * The default value type is a `ColorToken` (a semantic CSS variable name),
1322
+ * not a hex string. This ensures the chosen color adapts to the active theme.
1323
+ * Raw hex is available opt-in via `allowCustom` — see the prop docs.
1324
+ *
1325
+ * Swatch group uses `role="radiogroup"` with arrow-key navigation.
1326
+ */
1327
+ declare const ColorPicker: react.ForwardRefExoticComponent<ColorPickerProps & react.RefAttributes<HTMLDivElement>>;
1328
+
1329
+ interface ComboboxOption {
1330
+ label: string;
1331
+ value: string;
1332
+ }
1333
+ interface ComboboxProps {
1334
+ options: ComboboxOption[];
1335
+ value?: string;
1336
+ onValueChange?: (value: string) => void;
1337
+ placeholder?: string;
1338
+ searchPlaceholder?: string;
1339
+ /**
1340
+ * Message shown when the search yields no results. Defaults to "No
1341
+ * results." — or, when `allowCustomValue` is set, a message that also
1342
+ * signals a custom value is acceptable.
1343
+ */
1344
+ emptyText?: string;
1345
+ className?: string;
1346
+ /** Disables the trigger and prevents the popover from opening. */
1347
+ disabled?: boolean;
1348
+ /**
1349
+ * When `true`, typed text that doesn't match any option becomes a
1350
+ * submittable value: a synthetic "Use…" suggestion is shown, and pressing
1351
+ * Enter with no listed option highlighted accepts the typed text via
1352
+ * `onValueChange`. Suggestions still filter as usual. Default `false`
1353
+ * (selection-only, unchanged behavior) — #359.
1354
+ */
1355
+ allowCustomValue?: boolean;
1356
+ /** `id` applied to the trigger button. */
1357
+ id?: string;
1358
+ /**
1359
+ * The trigger's accessible name always defaults to the SELECTED VALUE (or
1360
+ * the placeholder) — that tells AT what is currently chosen, never what the
1361
+ * control is FOR. Pass `aria-label`/`aria-labelledby` to also name the
1362
+ * control's purpose (e.g. "Session switcher").
1363
+ */
1364
+ "aria-label"?: string;
1365
+ "aria-labelledby"?: string;
1366
+ /**
1367
+ * Escape hatch spread onto the trigger `Button` (after the named props
1368
+ * above, so it wins if both are set) for anything not covered by a named
1369
+ * prop — `data-*`, `name`, `data-testid`, etc. `role`/`aria-expanded` stay
1370
+ * component-owned and can't be passed here; disabling stays on the
1371
+ * top-level `disabled` prop so the popover-open guard below can't drift
1372
+ * out of sync with the trigger's actual disabled state.
1373
+ */
1374
+ triggerProps?: Omit<ComponentPropsWithoutRef<typeof Button>, "role" | "aria-expanded" | "disabled"> & {
1375
+ /** Arbitrary `data-*` attributes (test hooks, analytics, …). */
1376
+ [key: `data-${string}`]: string | number | boolean | undefined;
1377
+ };
1378
+ }
1379
+ /** Single-select combobox (Popover + Command). Controlled or uncontrolled. */
1380
+ declare const Combobox: react.ForwardRefExoticComponent<ComboboxProps & react.RefAttributes<HTMLButtonElement>>;
1381
+
1382
+ declare const dialogContentVariants: (props?: ({
1383
+ size?: "full" | "sm" | "lg" | "xl" | null | undefined;
1384
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1385
+ declare const Dialog: react.FC<DialogPrimitive.DialogProps>;
1386
+ declare const DialogTrigger: react.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
1387
+ declare const DialogPortal: react.FC<DialogPrimitive.DialogPortalProps>;
1388
+ declare const DialogClose: react.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
1389
+ declare const DialogOverlay: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1390
+ declare const DialogContent: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
1391
+ size?: "full" | "sm" | "lg" | "xl" | null | undefined;
1392
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLDivElement>>;
1393
+ declare function DialogHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
1394
+ declare function DialogFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
1395
+ declare const DialogTitle: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<HTMLHeadingElement>>;
1396
+ declare const DialogDescription: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<HTMLParagraphElement>>;
1397
+ type DialogBodyProps = HTMLAttributes<HTMLDivElement>;
1398
+ /**
1399
+ * The dialog's scroll owner (#341).
1400
+ *
1401
+ * Placing a `DialogBody` between `DialogHeader` and `DialogFooter` switches
1402
+ * `DialogContent` into its fixed-header/footer regime (see
1403
+ * `dialogContentVariants`): the header and footer stay put and ONLY this region
1404
+ * scrolls, so the primary action never scrolls out of view. Without it a dialog
1405
+ * behaves exactly as before — the anatomy is the switch, there is no `scroll`
1406
+ * prop.
1407
+ *
1408
+ * `overscroll-contain` stops the scroll chaining to the page underneath
1409
+ * (`.claude/rules/interaction-guidelines.md`, Touch & overscroll).
1410
+ *
1411
+ * **The `p-1`/`-m-1`/`scroll-p-1` trio reserves a focus-ring gutter (#425).**
1412
+ * Per CSS Overflow 3, authoring only `overflow-y-auto` still makes this a
1413
+ * two-axis scroll container (the `visible` axis computes to `auto` too), and a
1414
+ * scroll container clips at its **padding box**. With no padding of its own,
1415
+ * that padding box IS the content box, so a full-width child's border box
1416
+ * lands exactly on the clip edge — leaving 0px for a focus ring, which is
1417
+ * `box-shadow` (ink overflow: never part of the scrollable region, so it is
1418
+ * simply cut, not merely scrolled out of reach). `p-1` moves the scrollport
1419
+ * 4px outward on every side — enough for the library's widest outward paint
1420
+ * (`ring-2 ring-offset-2` = 4px) — and `-m-1` pulls the border box back by the
1421
+ * same amount so body content stays flush with `DialogHeader`/`DialogFooter`
1422
+ * instead of indenting 4px against them. `scroll-p-1` keeps a keyboard-driven
1423
+ * scroll-into-view (Tab landing on a control currently outside the scrollport)
1424
+ * from placing that control flush against the scrollport edge again.
1425
+ *
1426
+ * Two consumer-facing consequences: a larger `className` padding (e.g. `p-6`)
1427
+ * still wins through `tailwind-merge`, with the border box remaining 4px
1428
+ * outward; but **`className="p-0"` re-opens the bug** — the merge kills `p-1`
1429
+ * while `-m-1` survives — so a consumer who genuinely wants no gutter must
1430
+ * clear both sides with `className="m-0 p-0"`.
1431
+ *
1432
+ * Known, accepted residual: at `data-density="compact"`, `--spacing` is
1433
+ * `0.222rem` (`density.css:97`), so `p-1` is 3.55px against a 4px ring — a
1434
+ * 0.45px shortfall on the outermost edge of a 2px stroke. Do not "fix" this
1435
+ * with a fixed-px override; that would break the density dial's contract.
1436
+ */
1437
+ declare const DialogBody: react.ForwardRefExoticComponent<DialogBodyProps & react.RefAttributes<HTMLDivElement>>;
1438
+ interface DialogSectionProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
1439
+ /** The section heading. States what the group of fields is for. */
1440
+ title: ReactNode;
1441
+ /** One line of supporting context under the heading. */
1442
+ description?: ReactNode;
1443
+ /**
1444
+ * Semantic heading level. `DialogTitle` renders an `<h2>`, so a section is an
1445
+ * `<h3>` by default and an `<h4>` when nested a rung deeper.
1446
+ */
1447
+ level?: 3 | 4;
1448
+ /** Section-scoped actions, aligned to the inline end of the heading row. */
1449
+ actions?: ReactNode;
1450
+ }
1451
+ /**
1452
+ * A real section heading inside a dialog (#341).
1453
+ *
1454
+ * The recurring downstream defect was section labels rendering at the same size
1455
+ * as the field labels beneath them, which flattens a long form into one
1456
+ * undifferentiated list. The rungs are distinct BY TOKEN, not by eye:
1457
+ * `DialogTitle` `text-title` (1.25rem) > `DialogSection` `text-subtitle` (1rem) >
1458
+ * `Label` `text-body` (0.875rem).
1459
+ *
1460
+ * Deliberately NOT `SectionHeader` (`../section-header`): that is the page-level
1461
+ * `<h2>` row with an eyebrow, one rung too loud and one level too high inside a
1462
+ * dialog whose title already owns the `<h2>`.
1463
+ */
1464
+ declare const DialogSection: react.ForwardRefExoticComponent<DialogSectionProps & react.RefAttributes<HTMLElement>>;
1465
+
1466
+ interface UseDialogDismissGuardOptions {
1467
+ /**
1468
+ * Does the dialog currently hold unsaved changes? **App-owned** — brand-ui is
1469
+ * a presentation layer (`docs/DECISIONS.md` §D5) and cannot know what "dirty"
1470
+ * means for your form. Compute it (a `react-hook-form` `isDirty`, a deep
1471
+ * compare, a store flag) and pass it in.
1472
+ */
1473
+ dirty: boolean;
1474
+ /** Close the dialog — the app sets its own `open` state to `false`. */
1475
+ onClose: () => void;
1476
+ /**
1477
+ * Open the dialog. Only needed when a `DialogTrigger` (rather than the app)
1478
+ * opens it, because Radix routes that through the same `onOpenChange`.
1479
+ */
1480
+ onOpen?: () => void;
1481
+ }
1482
+ interface DialogDismissGuard {
1483
+ /**
1484
+ * Spread onto `<Dialog onOpenChange={…}>`. Intercepts EVERY user dismissal —
1485
+ * Escape, overlay click, the built-in close ✕ and any `DialogClose` — because
1486
+ * Radix funnels all four through `onOpenChange(false)`.
1487
+ */
1488
+ onOpenChange: (open: boolean) => void;
1489
+ /** Controlled `open` for the discard confirmation. */
1490
+ confirmOpen: boolean;
1491
+ /** Controlled `onOpenChange` for the discard confirmation. */
1492
+ onConfirmOpenChange: (open: boolean) => void;
1493
+ /** Confirm the discard: closes the confirmation AND calls `onClose()`. */
1494
+ confirmDiscard: () => void;
1495
+ }
1496
+ /**
1497
+ * Warn before a dialog with unsaved changes is dismissed (#341).
1498
+ *
1499
+ * `.claude/rules/interaction-guidelines.md` (Forms) requires warning before
1500
+ * navigating away from unsaved changes; this is that rule for dialogs, as a HOOK
1501
+ * rather than a prop because the component must not own app state — the app owns
1502
+ * `open` and decides what `dirty` means (D5).
1503
+ *
1504
+ * ## The asymmetry is structural, not a flag
1505
+ *
1506
+ * A **user dismissal** reaches Radix's `onOpenChange`, so the guard sees it and
1507
+ * can hold the dialog open. A **programmatic close** (the app setting its own
1508
+ * `open` to `false` after a successful save) never touches the guard, so it is
1509
+ * unobservable here and closes silently. That is exactly the wanted behaviour,
1510
+ * and it falls out of the wiring — there is no "skip the guard" option to get
1511
+ * wrong.
1512
+ *
1513
+ * The name is literal: it guards DISMISSALS routed through the returned
1514
+ * `onOpenChange`. It is not a navigation blocker and it cannot intercept a tab
1515
+ * close, a router navigation, or an `open` prop that the app flips itself.
1516
+ *
1517
+ * ```tsx
1518
+ * const [open, setOpen] = useState(false);
1519
+ * const guard = useDialogDismissGuard({
1520
+ * dirty,
1521
+ * onClose: () => setOpen(false),
1522
+ * onOpen: () => setOpen(true),
1523
+ * });
1524
+ *
1525
+ * <Dialog open={open} onOpenChange={guard.onOpenChange}>…</Dialog>
1526
+ * <ConfirmDialog
1527
+ * open={guard.confirmOpen}
1528
+ * onOpenChange={guard.onConfirmOpenChange}
1529
+ * onConfirm={guard.confirmDiscard}
1530
+ * tone="destructive"
1531
+ * title="Discard changes?"
1532
+ * description="Your edits to this project have not been saved."
1533
+ * confirmLabel="Discard"
1534
+ * />
1535
+ * ```
1536
+ *
1537
+ * The `ConfirmDialog` is a SIBLING of the guarded dialog, not a child of it.
1538
+ */
1539
+ declare function useDialogDismissGuard({ dirty, onClose, onOpen, }: UseDialogDismissGuardOptions): DialogDismissGuard;
1540
+
1541
+ interface CommandProps extends ComponentPropsWithoutRef<typeof Command$1> {
1542
+ /**
1543
+ * Reports the DOM `id` cmdk assigned to the currently highlighted item, so
1544
+ * an input rendered OUTSIDE this `Command` tree (a composer textarea, a
1545
+ * combobox trigger) can set `aria-activedescendant` without querying
1546
+ * `[role="option"]` positionally. Fires with `undefined` when nothing is
1547
+ * highlighted.
1548
+ *
1549
+ * cmdk owns each item's `id`/`role`/`aria-selected` and applies them AFTER
1550
+ * the consumer spread, so a consumer-supplied `id` on `CommandItem` is
1551
+ * silently dropped (`CommandItem` warns about this in development) — this
1552
+ * callback is the supported way to obtain it. See also the
1553
+ * `useCommandActiveItemId` hook for reading the same value from a
1554
+ * descendant already inside the `<Command>` tree.
1555
+ *
1556
+ * It fires for EVERY highlight change, including the item cmdk
1557
+ * auto-highlights on mount and the one it re-highlights after each filter
1558
+ * keystroke — the two states cmdk's own `state.selectedItemId` misses.
1559
+ */
1560
+ onActiveItemIdChange?: (id: string | undefined) => void;
1561
+ }
1562
+ declare const Command: react.ForwardRefExoticComponent<CommandProps & react.RefAttributes<HTMLDivElement>>;
1563
+ /**
1564
+ * The DOM `id` of the currently highlighted `CommandItem`. Must be called
1565
+ * from a component rendered inside a `<Command>` tree; returns `undefined`
1566
+ * when nothing is highlighted (or when there is no `<Command>` ancestor).
1567
+ * Reports exactly the same value as `Command`'s `onActiveItemIdChange`
1568
+ * callback, for a consumer that is already a descendant (rather than an
1569
+ * external input above the tree).
1570
+ */
1571
+ declare function useCommandActiveItemId(): string | undefined;
1572
+ declare function CommandDialog({ children, filter, ...props }: ComponentPropsWithoutRef<typeof Dialog> & {
1573
+ /** Custom cmdk ranking (e.g. strict substring instead of fuzzy). */
1574
+ filter?: ComponentPropsWithoutRef<typeof Command$1>["filter"];
1575
+ }): react.JSX.Element;
1576
+ declare const CommandInput: react.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<react.DetailedHTMLProps<react.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof react.InputHTMLAttributes<HTMLInputElement>> & {
1577
+ ref?: React.Ref<HTMLInputElement>;
1578
+ } & {
1579
+ asChild?: boolean;
1580
+ }, "key" | "asChild" | keyof react.InputHTMLAttributes<HTMLInputElement>>, "type" | "onChange" | "value"> & {
1581
+ value?: string;
1582
+ onValueChange?: (search: string) => void;
1583
+ } & react.RefAttributes<HTMLInputElement>, "ref"> & react.RefAttributes<HTMLInputElement>>;
1584
+ declare const CommandList: react.ForwardRefExoticComponent<Omit<{
1585
+ children?: React.ReactNode;
1586
+ } & Pick<Pick<react.DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & {
1587
+ ref?: React.Ref<HTMLDivElement>;
1588
+ } & {
1589
+ asChild?: boolean;
1590
+ }, "key" | keyof HTMLAttributes<HTMLDivElement> | "asChild"> & {
1591
+ label?: string;
1592
+ } & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1593
+ declare const CommandEmpty: react.ForwardRefExoticComponent<Omit<{
1594
+ children?: React.ReactNode;
1595
+ } & Pick<Pick<react.DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & {
1596
+ ref?: React.Ref<HTMLDivElement>;
1597
+ } & {
1598
+ asChild?: boolean;
1599
+ }, "key" | keyof HTMLAttributes<HTMLDivElement> | "asChild"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1600
+ declare const CommandGroup: react.ForwardRefExoticComponent<Omit<{
1601
+ children?: React.ReactNode;
1602
+ } & Omit<Pick<Pick<react.DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & {
1603
+ ref?: React.Ref<HTMLDivElement>;
1604
+ } & {
1605
+ asChild?: boolean;
1606
+ }, "key" | keyof HTMLAttributes<HTMLDivElement> | "asChild">, "value" | "heading"> & {
1607
+ heading?: React.ReactNode;
1608
+ value?: string;
1609
+ forceMount?: boolean;
1610
+ } & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1611
+ declare const CommandSeparator: react.ForwardRefExoticComponent<Omit<Pick<Pick<react.DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & {
1612
+ ref?: React.Ref<HTMLDivElement>;
1613
+ } & {
1614
+ asChild?: boolean;
1615
+ }, "key" | keyof HTMLAttributes<HTMLDivElement> | "asChild"> & {
1616
+ alwaysRender?: boolean;
1617
+ } & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1618
+ declare const CommandItem: react.ForwardRefExoticComponent<Omit<{
1619
+ children?: React.ReactNode;
1620
+ } & Omit<Pick<Pick<react.DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & {
1621
+ ref?: React.Ref<HTMLDivElement>;
1622
+ } & {
1623
+ asChild?: boolean;
1624
+ }, "key" | keyof HTMLAttributes<HTMLDivElement> | "asChild">, "onSelect" | "value" | "disabled"> & {
1625
+ disabled?: boolean;
1626
+ onSelect?: (value: string) => void;
1627
+ value?: string;
1628
+ keywords?: string[];
1629
+ forceMount?: boolean;
1630
+ } & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1631
+ declare function CommandShortcut({ className, ...props }: HTMLAttributes<HTMLSpanElement>): react.JSX.Element;
1632
+
1633
+ interface ConfirmDialogProps {
1634
+ /** Controlled open state — the app owns it. */
1635
+ open: boolean;
1636
+ /** Fires on cancel, Escape, and any other Radix dismissal. */
1637
+ onOpenChange: (open: boolean) => void;
1638
+ /** What is about to happen, as a question or a statement. */
1639
+ title: ReactNode;
1640
+ /**
1641
+ * The consequence, spelled out. **Required**: `AlertDialogContent` is
1642
+ * inaccessible to screen-reader users without a description (Radix warns), and
1643
+ * a confirmation whose only text is its title cannot state what is at stake.
1644
+ */
1645
+ description: ReactNode;
1646
+ /**
1647
+ * The confirm action's label. States the CONSEQUENCE ("Delete skill"), never
1648
+ * "OK" — a label that names the outcome is the last chance to catch a mistake.
1649
+ * Defaults to a generic "Confirm", which you should almost always replace.
1650
+ */
1651
+ confirmLabel?: ReactNode;
1652
+ /** The safe action's label. Defaults to "Cancel". */
1653
+ cancelLabel?: ReactNode;
1654
+ /** Runs when the confirm action is activated. */
1655
+ onConfirm: () => void;
1656
+ /** Runs when the safe action is activated (in addition to `onOpenChange`). */
1657
+ onCancel?: () => void;
1658
+ /** Visual tone of the CONFIRM action only. The dialog chrome never changes. */
1659
+ tone?: "default" | "destructive";
1660
+ /**
1661
+ * The confirm request is in flight: the action swaps its label for a spinner
1662
+ * and reports `aria-busy`. It deliberately stays ENABLED
1663
+ * (`.claude/rules/interaction-guidelines.md`, Forms — a submit is never
1664
+ * pre-disabled); repeat activations are ignored while it is set.
1665
+ */
1666
+ loading?: boolean;
1667
+ /** Extra body content between the description and the actions. */
1668
+ children?: ReactNode;
1669
+ className?: string;
1670
+ }
1671
+ /**
1672
+ * A destructive/irreversible confirmation (#341).
1673
+ *
1674
+ * Built on `AlertDialog`, not `Dialog`, and that is the entire point of it
1675
+ * existing as a named component rather than a recipe: `AlertDialogContent`
1676
+ * prevents its own open-autofocus and focuses the mounted `AlertDialogCancel`
1677
+ * instead, so **initial focus lands on the safe action** — but only if a Cancel
1678
+ * is actually mounted, which a hand-rolled confirmation routinely forgets (and a
1679
+ * plain `Dialog` cannot do at all). `ConfirmDialog` always renders one, so the
1680
+ * wrong choice is unrepresentable. It also inherits `AlertDialog`'s refusal to
1681
+ * dismiss on an outside click.
1682
+ *
1683
+ * Cancel is FIRST in the DOM so assistive tech reads the safe action first;
1684
+ * `AlertDialogFooter`'s `flex-col-reverse sm:flex-row sm:justify-end` still
1685
+ * paints the confirm action bottom-right on every breakpoint.
1686
+ *
1687
+ * **Confirming does not close the dialog** — `onConfirm` fires and the app sets
1688
+ * `open={false}` when it is ready (immediately for a synchronous action, after
1689
+ * the request for an async one, which is what makes `loading` coherent).
1690
+ * Cancelling closes through `onOpenChange(false)` as usual.
1691
+ *
1692
+ * ```tsx
1693
+ * <ConfirmDialog
1694
+ * open={open}
1695
+ * onOpenChange={setOpen}
1696
+ * tone="destructive"
1697
+ * title={`Delete ${skill.name}?`}
1698
+ * description={`Removing it also deletes its ${skill.runs} saved runs. This cannot be undone.`}
1699
+ * confirmLabel={`Delete ${skill.name}`}
1700
+ * onConfirm={() => { deleteSkill(); setOpen(false); }}
1701
+ * />
1702
+ * ```
1703
+ */
1704
+ declare function ConfirmDialog({ open, onOpenChange, title, description, confirmLabel, cancelLabel, onConfirm, onCancel, tone, loading, children, className, }: ConfirmDialogProps): react.JSX.Element;
1705
+
1706
+ declare const ContextMenu: react.FC<ContextMenuPrimitive.ContextMenuProps>;
1707
+ declare const ContextMenuTrigger: react.ForwardRefExoticComponent<ContextMenuPrimitive.ContextMenuTriggerProps & react.RefAttributes<HTMLSpanElement>>;
1708
+ declare const ContextMenuGroup: react.ForwardRefExoticComponent<ContextMenuPrimitive.ContextMenuGroupProps & react.RefAttributes<HTMLDivElement>>;
1709
+ declare const ContextMenuSub: react.FC<ContextMenuPrimitive.ContextMenuSubProps>;
1710
+ declare const ContextMenuRadioGroup: react.ForwardRefExoticComponent<ContextMenuPrimitive.ContextMenuRadioGroupProps & react.RefAttributes<HTMLDivElement>>;
1711
+ declare const ContextMenuSubTrigger: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSubTriggerProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
1712
+ inset?: boolean;
1713
+ } & react.RefAttributes<HTMLDivElement>>;
1714
+ declare const ContextMenuSubContent: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSubContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1715
+ declare const ContextMenuContent: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1716
+ declare const ContextMenuItem: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
1717
+ inset?: boolean;
1718
+ } & react.RefAttributes<HTMLDivElement>>;
1719
+ declare const ContextMenuCheckboxItem: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuCheckboxItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1720
+ declare const ContextMenuRadioItem: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuRadioItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1721
+ declare const ContextMenuLabel: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuLabelProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
1722
+ inset?: boolean;
1723
+ } & react.RefAttributes<HTMLDivElement>>;
1724
+ declare const ContextMenuSeparator: react.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1725
+ declare function ContextMenuShortcut({ className, ...props }: HTMLAttributes<HTMLSpanElement>): react.JSX.Element;
1726
+
1727
+ interface CopyableValueProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "value" | "children"> {
1728
+ /**
1729
+ * The EXACT text written to the clipboard — the unrounded, un-abbreviated
1730
+ * value. Not locale-formatted by this component: a copied number is usually
1731
+ * on its way into a spreadsheet or a query.
1732
+ */
1733
+ value: string;
1734
+ /** What the reader sees. Defaults to `value`. */
1735
+ children?: ReactNode;
1736
+ /**
1737
+ * Overrides the screen-reader hint appended to the visible text. The
1738
+ * accessible name is always `<visible text> + <hint>`, which keeps WCAG 2.5.3
1739
+ * (Label in Name) satisfied — voice-control users can say what they read.
1740
+ */
1741
+ hint?: string;
1742
+ /** ms the "Copied" confirmation stays. Default: 1500. */
1743
+ resetAfterMs?: number;
1744
+ }
1745
+ /**
1746
+ * A value that copies its exact form on click.
1747
+ *
1748
+ * ```tsx
1749
+ * <CopyableValue value="50012102.632741">50M</CopyableValue>
1750
+ * ```
1751
+ */
1752
+ declare const CopyableValue: react.ForwardRefExoticComponent<CopyableValueProps & react.RefAttributes<HTMLButtonElement>>;
1753
+
1754
+ interface DatePickerProps {
1755
+ value?: Date;
1756
+ onValueChange?: (date?: Date) => void;
1757
+ placeholder?: string;
1758
+ className?: string;
1759
+ }
1760
+ /** Single-date picker (Popover + Calendar). Controlled or uncontrolled. */
1761
+ declare function DatePicker({ value, onValueChange, placeholder, className, }: DatePickerProps): react.JSX.Element;
1762
+
1763
+ interface DateRangePreset {
1764
+ label: string;
1765
+ getRange: () => DateRange;
1766
+ }
1767
+ interface DateRangePickerProps {
1768
+ value?: DateRange;
1769
+ defaultValue?: DateRange;
1770
+ onValueChange?: (range?: DateRange) => void;
1771
+ presets?: DateRangePreset[];
1772
+ numberOfMonths?: number;
1773
+ placeholder?: string;
1774
+ className?: string;
1775
+ }
1776
+ /**
1777
+ * Date range picker (Popover + Calendar in range mode).
1778
+ * Supports optional preset quick-picks, controlled or uncontrolled.
1779
+ */
1780
+ declare const DateRangePicker: react.ForwardRefExoticComponent<DateRangePickerProps & react.RefAttributes<HTMLButtonElement>>;
1781
+
1782
+ declare const descriptionsVariants: (props?: ({
1783
+ columns?: 1 | 2 | 3 | null | undefined;
1784
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1785
+ type DescriptionsLayout = "horizontal" | "vertical";
1786
+ interface DescriptionsProps extends HTMLAttributes<HTMLDListElement>, VariantProps<typeof descriptionsVariants> {
1787
+ /**
1788
+ * Number of columns at the widest breakpoint. Collapses to a single column
1789
+ * on small screens. Default 1.
1790
+ */
1791
+ columns?: 1 | 2 | 3;
1792
+ /**
1793
+ * `horizontal` places the label beside the value; `vertical` stacks the
1794
+ * label above the value. Default `horizontal`.
1795
+ */
1796
+ layout?: DescriptionsLayout;
1797
+ }
1798
+ /**
1799
+ * Descriptions — a responsive definition list of label↔value pairs.
1800
+ *
1801
+ * Renders a native `<dl>`; compose with `DescriptionsItem` (`<dt>`/`<dd>`).
1802
+ * `columns` controls the grid; `layout` controls label placement per item.
1803
+ */
1804
+ declare const Descriptions: react.ForwardRefExoticComponent<DescriptionsProps & react.RefAttributes<HTMLDListElement>>;
1805
+ interface DescriptionsItemProps extends HTMLAttributes<HTMLDivElement> {
1806
+ /** The term / label for this entry. */
1807
+ label: React.ReactNode;
1808
+ /**
1809
+ * When the value is numeric, set this so the value uses `tabular-nums`
1810
+ * for aligned digits.
1811
+ */
1812
+ numeric?: boolean;
1813
+ }
1814
+ /**
1815
+ * DescriptionsItem — one label↔value pair (`<dt>` + `<dd>`) inside `Descriptions`.
1816
+ */
1817
+ declare const DescriptionsItem: react.ForwardRefExoticComponent<DescriptionsItemProps & react.RefAttributes<HTMLDivElement>>;
1818
+
1819
+ declare function Drawer({ shouldScaleBackground, ...props }: ComponentProps<typeof Drawer$1.Root>): react.JSX.Element;
1820
+ declare const DrawerTrigger: react.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
1821
+ declare const DrawerPortal: typeof vaul.Portal;
1822
+ declare const DrawerClose: react.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
1823
+ declare const DrawerContent: react.ForwardRefExoticComponent<Omit<Omit<DialogPrimitive.DialogContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1824
+ declare function DrawerHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
1825
+ declare function DrawerFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
1826
+ declare const DrawerTitle: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<HTMLHeadingElement>>;
1827
+ declare const DrawerDescription: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<HTMLParagraphElement>>;
1828
+
1829
+ declare const DropdownMenu: react.FC<DropdownMenuPrimitive.DropdownMenuProps>;
1830
+ declare const DropdownMenuTrigger: react.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & react.RefAttributes<HTMLButtonElement>>;
1831
+ declare const DropdownMenuGroup: react.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & react.RefAttributes<HTMLDivElement>>;
1832
+ declare const DropdownMenuPortal: react.FC<DropdownMenuPrimitive.DropdownMenuPortalProps>;
1833
+ declare const DropdownMenuSub: react.FC<DropdownMenuPrimitive.DropdownMenuSubProps>;
1834
+ declare const DropdownMenuRadioGroup: react.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuRadioGroupProps & react.RefAttributes<HTMLDivElement>>;
1835
+ declare const DropdownMenuSubTrigger: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubTriggerProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
1836
+ inset?: boolean;
1837
+ } & react.RefAttributes<HTMLDivElement>>;
1838
+ declare const DropdownMenuSubContent: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1839
+ declare const DropdownMenuRadioItem: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuRadioItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1840
+ declare const DropdownMenuCheckboxItem: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuCheckboxItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1841
+ declare const DropdownMenuContent: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1842
+ declare const DropdownMenuItem: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
1843
+ inset?: boolean;
1844
+ } & react.RefAttributes<HTMLDivElement>>;
1845
+ declare const DropdownMenuLabel: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuLabelProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1846
+ declare const DropdownMenuSeparator: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1847
+ declare function DropdownMenuShortcut({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>): react.JSX.Element;
1848
+
1849
+ interface EmptyStateProps {
1850
+ title: ReactNode;
1851
+ description?: ReactNode;
1852
+ /** Optional icon/illustration shown above the title. */
1853
+ icon?: ReactNode;
1854
+ /** Primary/secondary actions. */
1855
+ actions?: ReactNode;
1856
+ className?: string;
1857
+ }
1858
+ /** @deprecated Use `<StatePanel kind="empty" />` instead. */
1859
+ declare function EmptyState({ title, description, icon, actions, className }: EmptyStateProps): react.JSX.Element;
1860
+
1861
+ interface ErrorStateProps {
1862
+ title?: ReactNode;
1863
+ description?: ReactNode;
1864
+ /** Optional retry / support actions. */
1865
+ actions?: ReactNode;
1866
+ className?: string;
1867
+ }
1868
+ /** @deprecated Use `<StatePanel kind="error" />` instead. */
1869
+ declare function ErrorState({ title, description, actions, className }: ErrorStateProps): react.JSX.Element;
1870
+
1871
+ /**
1872
+ * ExpandDialog — the one "make this bigger" modal: enlarged content on the
1873
+ * inline-start, its context on the inline-end.
1874
+ *
1875
+ * The shape was invented inside `@elabs-ai/components-charts`'
1876
+ * `ChartFrame` (chart left, data summary right) and then hand-rolled a second
1877
+ * and third time — a chat lightbox, an in-place CSS breakout in a consuming
1878
+ * app — because it was trapped in a package the other surfaces cannot import.
1879
+ * It lives here so every "expand" affordance in the system opens the SAME
1880
+ * two-pane surface: a chart, a table, an image, a document.
1881
+ *
1882
+ * It is a LAYOUT, not a viewer. What goes in each pane is the caller's
1883
+ * business; this component owns the dialog anatomy, the pane geometry, the
1884
+ * scroll ownership and the region labelling.
1885
+ */
1886
+ /**
1887
+ * The panes grid.
1888
+ *
1889
+ * `detailPlacement` picks the axis; `stackBelow` re-runs the same decision at a
1890
+ * breakpoint, because a 2.5fr/1fr split on a 375px viewport leaves the detail
1891
+ * pane about 107px wide — technically present, practically unreadable. The 2×4
1892
+ * compound matrix mirrors `cardDetailVariants` (`card.tsx`) so the two
1893
+ * detail-panel surfaces in this package resolve their tracks the same way.
1894
+ *
1895
+ * Track sizes arrive as CSS custom properties (`--expand-dialog-view-size` /
1896
+ * `--expand-dialog-detail-size`) rather than arbitrary-value classes, because a
1897
+ * runtime string cannot be a Tailwind class — the same technique `Card` uses
1898
+ * for `--card-detail-size`. The one pair of properties drives whichever axis is
1899
+ * active: columns when the detail is beside, rows when it is below.
1900
+ */
1901
+ declare const expandDialogPanesVariants: (props?: ({
1902
+ detailPlacement?: "bottom" | "side" | null | undefined;
1903
+ stackBelow?: "md" | "never" | "sm" | "lg" | null | undefined;
1904
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1905
+ interface ExpandDialogPanesProps extends Omit<HTMLAttributes<HTMLDivElement>, "children">, VariantProps<typeof expandDialogPanesVariants> {
1906
+ /** The enlarged content — the reason the dialog opened. */
1907
+ children: ReactNode;
1908
+ /**
1909
+ * Context for what is in the view pane. Omit for a single-pane dialog: the
1910
+ * grid then renders one full-width track and no region wrapper at all.
1911
+ */
1912
+ detail?: ReactNode;
1913
+ /** Accessible name for the detail region. @default `t("ui.expandDialog.detail")` */
1914
+ detailLabel?: string;
1915
+ /** View track size (any CSS length). @default `"minmax(0, 2.5fr)"` */
1916
+ viewSize?: string;
1917
+ /** Detail track size (any CSS length). @default `"minmax(0, 1fr)"` */
1918
+ detailSize?: string;
1919
+ /** Class on the view pane. */
1920
+ viewClassName?: string;
1921
+ /** Class on the detail pane. */
1922
+ detailClassName?: string;
1923
+ /** Tab index for the view pane. Pass `-1` when it owns focusable content. */
1924
+ viewTabIndex?: number;
1925
+ /** Tab index for the detail pane. Pass `-1` when it owns focusable content. */
1926
+ detailTabIndex?: number;
1927
+ }
1928
+ /**
1929
+ * The two-pane body. Usable on its own for a headerless surface (an image
1930
+ * lightbox), or via `ExpandDialog`, which supplies the dialog around it.
1931
+ */
1932
+ declare const ExpandDialogPanes: react.ForwardRefExoticComponent<ExpandDialogPanesProps & react.RefAttributes<HTMLDivElement>>;
1933
+ interface ExpandDialogHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
1934
+ /** Names the dialog. Rendered as the `<h2>` Radix labels the dialog by. */
1935
+ title: ReactNode;
1936
+ /** One line of supporting context under the title. */
1937
+ description?: ReactNode;
1938
+ /** Controls aligned to the inline end of the title row. */
1939
+ actions?: ReactNode;
1940
+ }
1941
+ /**
1942
+ * The dialog's title row.
1943
+ *
1944
+ * `pe-12` is load-bearing: Radix positions the close button absolutely in the
1945
+ * top inline-end corner, so without the padding a long title runs underneath
1946
+ * it.
1947
+ */
1948
+ declare function ExpandDialogHeader({ actions, className, description, title, ...props }: ExpandDialogHeaderProps): react.JSX.Element;
1949
+ type ExpandDialogContentProps = ComponentPropsWithoutRef<typeof DialogContent>;
1950
+ /**
1951
+ * The full-bleed content box every expand surface uses.
1952
+ *
1953
+ * `size="full"` plus a `DialogBody` child puts `DialogContent` into its
1954
+ * fixed-header regime (a 3-row grid, header pinned, body owning the scroll) —
1955
+ * the anatomy IS the switch, so nothing here hand-rolls a flex column.
1956
+ */
1957
+ declare const ExpandDialogContent: react.ForwardRefExoticComponent<Omit<Omit<DialogPrimitive.DialogContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
1958
+ size?: "full" | "sm" | "lg" | "xl" | null | undefined;
1959
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
1960
+ interface ExpandDialogProps extends Omit<ExpandDialogContentProps, "title" | "children">, Pick<ExpandDialogHeaderProps, "title" | "description" | "actions">, Pick<ExpandDialogPanesProps, "children" | "detail" | "detailClassName" | "detailLabel" | "detailPlacement" | "detailSize" | "detailTabIndex" | "stackBelow" | "viewClassName" | "viewSize" | "viewTabIndex"> {
1961
+ /** Class on the panes grid. */
1962
+ panesClassName?: string;
1963
+ /** Class on the recessed field the panes sit in. */
1964
+ fieldClassName?: string;
1965
+ }
1966
+ /**
1967
+ * The batteries-included composition: content box → header → scroll body →
1968
+ * panes. Place it inside a `Dialog` you control:
1969
+ *
1970
+ * ```tsx
1971
+ * <Dialog open={open} onOpenChange={setOpen}>
1972
+ * <ExpandDialog title={chart.title} detail={<Summary />}>
1973
+ * <Chart />
1974
+ * </ExpandDialog>
1975
+ * </Dialog>
1976
+ * ```
1977
+ *
1978
+ * `Dialog`/`DialogTrigger` are deliberately NOT re-exported under an
1979
+ * `ExpandDialog*` name — they would be zero-behaviour aliases, and open state
1980
+ * is the consumer's already.
1981
+ */
1982
+ declare const ExpandDialog: react.ForwardRefExoticComponent<ExpandDialogProps & react.RefAttributes<HTMLDivElement>>;
1983
+
1984
+ interface FieldRowProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
1985
+ /** Field label — rendered as a real `<label>`, click-to-focus associated with the control. */
1986
+ label: ReactNode;
1987
+ /** Optional help/description text, always visible (not gated by an error). */
1988
+ description?: ReactNode;
1989
+ /**
1990
+ * Validation error text. When present: sets `aria-invalid` on the control,
1991
+ * is appended to `aria-describedby`, and is announced via `role="alert"`.
1992
+ */
1993
+ error?: ReactNode;
1994
+ /**
1995
+ * The single field control (`Input`, `Textarea`, `Select`, …). Receives
1996
+ * `id`/`aria-describedby`/`aria-invalid` via a Radix `Slot` — must be a
1997
+ * single element that forwards those props to a real form control.
1998
+ */
1999
+ children: ReactElement;
2000
+ }
2001
+ /**
2002
+ * Label/description/error/`aria-describedby` wiring for a field OUTSIDE a
2003
+ * `react-hook-form` tree — the same anatomy as `FormItem`/`FormLabel`/
2004
+ * `FormControl`/`FormDescription`/`FormMessage` (`../form`), but driven by
2005
+ * plain props (`label`/`description`/`error`) instead of RHF field state, so
2006
+ * a single `useState`-controlled field doesn't need a full `<Form>` +
2007
+ * `<FormField>` + `Controller` just to get correct label/error association.
2008
+ *
2009
+ * Reach for `Form`/`FormField`/… instead when the field already lives inside
2010
+ * a `react-hook-form` `<FormProvider>` — this component does not replace that
2011
+ * family, it covers the gap outside it (#354).
2012
+ */
2013
+ declare const FieldRow: react.ForwardRefExoticComponent<FieldRowProps & react.RefAttributes<HTMLDivElement>>;
2014
+
2015
+ type FileUploadStatus = "pending" | "uploading" | "success" | "error";
2016
+ interface UploadFile {
2017
+ /** Unique identifier for this file in the list. */
2018
+ id: string;
2019
+ /** The underlying File object. */
2020
+ file: File;
2021
+ /** Upload progress 0–100. */
2022
+ progress?: number;
2023
+ /** Upload lifecycle status. */
2024
+ status?: FileUploadStatus;
2025
+ /** Error message shown when status is "error". */
2026
+ errorMessage?: string;
2027
+ }
2028
+ interface FileUploadContextValue {
2029
+ files: UploadFile[];
2030
+ addFiles: (incoming: File[]) => void;
2031
+ removeFile: (id: string) => void;
2032
+ isDragging: boolean;
2033
+ /** Programmatically open the native file picker. */
2034
+ openPicker: () => void;
2035
+ accept?: string;
2036
+ multiple?: boolean;
2037
+ maxSize?: number;
2038
+ maxFiles?: number;
2039
+ disabled?: boolean;
2040
+ inputId: string;
2041
+ }
2042
+ declare function useFileUpload(): FileUploadContextValue;
2043
+ interface FileUploadProps extends HTMLAttributes<HTMLDivElement> {
2044
+ /** Controlled file list. */
2045
+ files?: UploadFile[];
2046
+ /** Called when files are added or removed. */
2047
+ onFilesChange?: (files: UploadFile[]) => void;
2048
+ /** Accepted MIME types / extensions (forwarded to <input accept>). */
2049
+ accept?: string;
2050
+ /** Allow multiple files at once. */
2051
+ multiple?: boolean;
2052
+ /** Maximum individual file size in bytes. */
2053
+ maxSize?: number;
2054
+ /** Maximum number of files in the list at once. */
2055
+ maxFiles?: number;
2056
+ /** Disable all interactions. */
2057
+ disabled?: boolean;
2058
+ children?: ReactNode;
2059
+ }
2060
+ /**
2061
+ * FileUpload — compound-component root (Provider).
2062
+ *
2063
+ * Holds the selected-file list + drag state and exposes
2064
+ * `{ files, addFiles, removeFile, isDragging }` via context.
2065
+ * **Presentational** — the app drives per-item `progress` + `status` on
2066
+ * `<FileUploadItem>`. No upload/network logic lives here.
2067
+ *
2068
+ * Controlled via `files`/`onFilesChange`; uncontrolled by default.
2069
+ */
2070
+ declare const FileUpload: react.ForwardRefExoticComponent<FileUploadProps & react.RefAttributes<HTMLDivElement>>;
2071
+ interface FileUploadDropzoneProps extends HTMLAttributes<HTMLElement> {
2072
+ /** Label for the visually-hidden file picker link (for SR users). */
2073
+ browseLabel?: string;
2074
+ }
2075
+ /**
2076
+ * FileUploadDropzone — the drag-and-drop target.
2077
+ *
2078
+ * Uses a `<label>` wrapping the hidden `<input>` so the ENTIRE zone is ONE hit
2079
+ * target — no `<div onClick>`. Keyboard users get the Browse button as a
2080
+ * complementary path.
2081
+ */
2082
+ declare const FileUploadDropzone: react.ForwardRefExoticComponent<FileUploadDropzoneProps & react.RefAttributes<HTMLElement>>;
2083
+ type FileUploadListProps = HTMLAttributes<HTMLUListElement>;
2084
+ /**
2085
+ * FileUploadList — the `role="status"` region that lists accepted files.
2086
+ * Reads from context; children are `<FileUploadItem>` elements.
2087
+ */
2088
+ declare const FileUploadList: react.ForwardRefExoticComponent<FileUploadListProps & react.RefAttributes<HTMLUListElement>>;
2089
+ interface FileUploadItemProps extends HTMLAttributes<HTMLLIElement> {
2090
+ /** The UploadFile entry to display. */
2091
+ uploadFile: UploadFile;
2092
+ /** Upload progress 0–100. Shown only during "uploading" status. */
2093
+ progress?: number;
2094
+ /** Current status of the upload. */
2095
+ status?: FileUploadStatus;
2096
+ /** Error message (displayed when status="error"). */
2097
+ errorMessage?: string;
2098
+ }
2099
+ /**
2100
+ * FileUploadItem — a single row in the file list.
2101
+ *
2102
+ * The app controls `progress` and `status` to drive the upload lifecycle.
2103
+ * Per-file errors use `role="alert"`.
2104
+ */
2105
+ declare const FileUploadItem: react.ForwardRefExoticComponent<FileUploadItemProps & react.RefAttributes<HTMLLIElement>>;
2106
+
2107
+ declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>({ children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, }: react_hook_form.FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
2108
+ declare function FormField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>(props: ControllerProps<TFieldValues, TName>): react.JSX.Element;
2109
+ declare function useFormField(): {
2110
+ invalid: boolean;
2111
+ isDirty: boolean;
2112
+ isTouched: boolean;
2113
+ isValidating: boolean;
2114
+ error?: react_hook_form.FieldError;
2115
+ id: string;
2116
+ name: string;
2117
+ formItemId: string;
2118
+ formDescriptionId: string;
2119
+ formMessageId: string;
2120
+ };
2121
+ declare const FormItem: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
2122
+ declare const FormLabel: react.ForwardRefExoticComponent<Omit<Omit<_radix_ui_react_label.LabelProps & react.RefAttributes<HTMLLabelElement>, "ref"> & react.RefAttributes<HTMLLabelElement>, "ref"> & react.RefAttributes<HTMLLabelElement>>;
2123
+ declare const FormControl: react.ForwardRefExoticComponent<Omit<_radix_ui_react_slot.SlotProps & react.RefAttributes<HTMLElement>, "ref"> & react.RefAttributes<HTMLElement>>;
2124
+ declare const FormDescription: react.ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & react.RefAttributes<HTMLParagraphElement>>;
2125
+ declare const FormMessage: react.ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & react.RefAttributes<HTMLParagraphElement>>;
2126
+
2127
+ declare const HoverCard: react.FC<HoverCardPrimitive.HoverCardProps>;
2128
+ declare const HoverCardTrigger: react.ForwardRefExoticComponent<HoverCardPrimitive.HoverCardTriggerProps & react.RefAttributes<HTMLAnchorElement>>;
2129
+ declare const HoverCardContent: react.ForwardRefExoticComponent<Omit<HoverCardPrimitive.HoverCardContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2130
+
2131
+ /** The icon-only size axis (a deliberate subset of `buttonVariants`' `size`). */
2132
+ type IconButtonSize = "icon" | "icon-sm" | "icon-lg";
2133
+ interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "title" | "children" | "aria-label" | "aria-describedby">, Pick<VariantProps<typeof buttonVariants>, "variant"> {
2134
+ /**
2135
+ * Accessible name AND tooltip text — a single source of truth, so the two
2136
+ * can never drift out of sync (the failure this component exists to close:
2137
+ * `aria-label` and a tooltip's children set independently, most call sites
2138
+ * only setting one).
2139
+ */
2140
+ label: string;
2141
+ /** The glyph (typically a `lucide-react` element). */
2142
+ icon: ReactNode;
2143
+ /** Icon-only size axis. Default `"icon"`. */
2144
+ size?: IconButtonSize;
2145
+ /**
2146
+ * Shown appended to the tooltip text, and — independently — exposed via
2147
+ * `aria-describedby` through an `sr-only` node that is present whenever this
2148
+ * prop is (i.e. it does NOT depend on the tooltip being open, and it is not
2149
+ * rendered at all when there is no reason — so it can never be read as stray
2150
+ * text), so assistive tech gets the reason even while the button is disabled
2151
+ * (a disabled
2152
+ * `<button>` still exposes its ARIA attributes; it just isn't
2153
+ * focusable/hoverable itself, which is why the tooltip trigger wraps a
2154
+ * focusable `<span>` instead — see the render below).
2155
+ */
2156
+ disabledReason?: string;
2157
+ /** Tooltip placement. Default `"top"`. */
2158
+ side?: ComponentProps<typeof TooltipContent>["side"];
2159
+ }
2160
+ /**
2161
+ * A single affordance for an icon-only control: `label` becomes both the
2162
+ * `aria-label` and the tooltip text, so they cannot diverge. Composes
2163
+ * `Button` + `Tooltip` — it does not reimplement either.
2164
+ *
2165
+ * Deliberately has **no `asChild`**: accepting one would dissolve the button
2166
+ * into a Radix `Slot` and break the tooltip-trigger wrapper below. A
2167
+ * link-styled icon button should compose `Button asChild` + `Tooltip`
2168
+ * directly instead.
2169
+ */
2170
+ declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<HTMLButtonElement>>;
2171
+
2172
+ type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement>;
2173
+ declare const Textarea: react.ForwardRefExoticComponent<TextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
2174
+
2175
+ declare const inputGroupVariants: (props?: ({
2176
+ variant?: "outline" | "surface" | "card" | null | undefined;
2177
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
2178
+ type InputGroupProps = ComponentProps<"div"> & VariantProps<typeof inputGroupVariants>;
2179
+ declare const InputGroup: react.ForwardRefExoticComponent<Omit<InputGroupProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
2180
+ declare const inputGroupAddonVariants: (props?: ({
2181
+ align?: "inline-end" | "inline-start" | "block-end" | "block-start" | null | undefined;
2182
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
2183
+ declare const InputGroupAddon: react.ForwardRefExoticComponent<Omit<react.ClassAttributes<HTMLDivElement> & react.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
2184
+ align?: "inline-end" | "inline-start" | "block-end" | "block-start" | null | undefined;
2185
+ } & class_variance_authority_types.ClassProp) | undefined) => string>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2186
+ declare const InputGroupButton: react.ForwardRefExoticComponent<Omit<Omit<ButtonProps & react.RefAttributes<HTMLButtonElement>, "size"> & {
2187
+ size?: "xs" | "sm" | "icon-xs" | "icon-sm";
2188
+ }, "ref"> & react.RefAttributes<HTMLButtonElement>>;
2189
+ declare const InputGroupText: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & react.RefAttributes<HTMLSpanElement>>;
2190
+ declare const InputGroupInput: react.ForwardRefExoticComponent<Omit<InputProps & react.RefAttributes<HTMLInputElement>, "ref"> & react.RefAttributes<HTMLInputElement>>;
2191
+ declare const InputGroupTextarea: react.ForwardRefExoticComponent<Omit<TextareaProps & react.RefAttributes<HTMLTextAreaElement>, "ref"> & react.RefAttributes<HTMLTextAreaElement>>;
2192
+
2193
+ declare const InputOTP: react.ForwardRefExoticComponent<ComponentPropsWithoutRef<react.ForwardRefExoticComponent<input_otp.OTPInputProps & react.RefAttributes<HTMLInputElement>>> & react.RefAttributes<HTMLInputElement>>;
2194
+ declare const InputOTPGroup: react.ForwardRefExoticComponent<react.HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
2195
+ declare const InputOTPSlot: react.ForwardRefExoticComponent<react.HTMLAttributes<HTMLDivElement> & {
2196
+ index: number;
2197
+ } & react.RefAttributes<HTMLDivElement>>;
2198
+ declare const InputOTPSeparator: react.ForwardRefExoticComponent<react.HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
2199
+
2200
+ /** Keyboard key hint, e.g. <Kbd>⌘K</Kbd>. */
2201
+ declare const Kbd: react.ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & react.RefAttributes<HTMLElement>>;
2202
+
2203
+ interface KeyValueRow {
2204
+ key: string;
2205
+ value: string;
2206
+ /**
2207
+ * Marks this row's value as sensitive: it renders masked (`type="password"`)
2208
+ * with a reveal toggle, and is never surfaced in plain text via any
2209
+ * `title`/`aria-label`/`aria-valuetext`. Defaults to false (a plain,
2210
+ * unmasked key/value pair) — the consumer opts a row in explicitly.
2211
+ */
2212
+ secret?: boolean;
2213
+ }
2214
+ interface KeyValueEditorProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
2215
+ /**
2216
+ * Controlled, ORDERED rows. An ordered `{ key, value, secret? }[]` is used
2217
+ * instead of `Record<string,string>` because a plain record can't
2218
+ * represent an in-progress duplicate key or preserve row order while the
2219
+ * user is mid-edit — both happen constantly while typing an env-var map.
2220
+ */
2221
+ value?: KeyValueRow[];
2222
+ /** Uncontrolled initial rows. */
2223
+ defaultValue?: KeyValueRow[];
2224
+ /** Called when the rows change (add, remove, or edit). */
2225
+ onValueChange?: (rows: KeyValueRow[]) => void;
2226
+ /** Placeholder for each row's key field. */
2227
+ keyPlaceholder?: string;
2228
+ /** Placeholder for each row's value field. */
2229
+ valuePlaceholder?: string;
2230
+ /** Label for the "add row" control. */
2231
+ addLabel?: ReactNode;
2232
+ /** Disables the whole editor. */
2233
+ disabled?: boolean;
2234
+ }
2235
+ /**
2236
+ * KeyValueEditor — key/value rows with per-row secret masking.
2237
+ *
2238
+ * Composes the existing `Input` + `Button` (icon vocabulary matches
2239
+ * `packages/ai/src/environment-variables.tsx`'s `Eye`/`EyeOff` reveal icons
2240
+ * for conceptual consistency, though this component lives in
2241
+ * `@elabs-ai/components-ui` — an EDITABLE settings-form primitive
2242
+ * is app UI, not the read-only agent tool-output display that
2243
+ * `EnvironmentVariables` is).
2244
+ *
2245
+ * A masked row uses the native `type="password"` input (the correct
2246
+ * primitive for an EDITABLE masked field — unlike a read-only display, the
2247
+ * value must stay typable, and native masking is what keeps it that way
2248
+ * without hand-rolling bullet substitution). The reveal toggle's
2249
+ * `aria-label` never contains the secret text itself, and no `title`
2250
+ * attribute is ever set from row content.
2251
+ *
2252
+ * Controlled via `value`/`onValueChange`; uncontrolled via `defaultValue`.
2253
+ */
2254
+ declare const KeyValueEditor: react.ForwardRefExoticComponent<KeyValueEditorProps & react.RefAttributes<HTMLDivElement>>;
2255
+
2256
+ declare const Label: react.ForwardRefExoticComponent<Omit<_radix_ui_react_label.LabelProps & react.RefAttributes<HTMLLabelElement>, "ref"> & react.RefAttributes<HTMLLabelElement>>;
2257
+
2258
+ interface LinkPreviewCardProps extends HTMLAttributes<HTMLDivElement> {
2259
+ /** Page title — the primary text, 1–2 lines. */
2260
+ title?: string;
2261
+ /** Short description / Open-Graph description. Omit for title+domain only. */
2262
+ description?: string;
2263
+ /**
2264
+ * Absolute URL of the thumbnail image (consumer-provided; the library never
2265
+ * fetches). Decorative — `alt` is always `""`. Omit to hide the thumbnail
2266
+ * area cleanly (no broken-image placeholder).
2267
+ */
2268
+ image?: string;
2269
+ /**
2270
+ * Domain label shown with the globe icon, e.g. `"github.com"`. Wrapped in
2271
+ * `translate="no"` so browsers never auto-translate identifiers.
2272
+ */
2273
+ domain?: string;
2274
+ /**
2275
+ * When set, the entire card becomes a keyboard-focusable link (stretched-link
2276
+ * pattern). The visible focus ring is placed on the card via `focus-within`.
2277
+ * Prefer a full absolute URL so the `<a>` is meaningful.
2278
+ */
2279
+ href?: string;
2280
+ /**
2281
+ * Render skeleton placeholders in lieu of real content. Sets `aria-busy="true"`
2282
+ * on the card root so assistive technology knows the content is pending.
2283
+ */
2284
+ loading?: boolean;
2285
+ }
2286
+ /**
2287
+ * A rich, presentational link-preview card (unfurled URL / bookmark block).
2288
+ * Renders favicon/domain, title, description, and an optional thumbnail from
2289
+ * **consumer-provided** metadata — the library never fetches.
2290
+ *
2291
+ * States: `loading` (skeleton), loaded (full), no-image, no-description
2292
+ * (title + domain only), and empty/error (degrades to a plain placeholder).
2293
+ *
2294
+ * Pass `href` to make the whole card a keyboard-focusable stretched link.
2295
+ * Use `loading` for the skeleton state; set `aria-busy` is applied automatically.
2296
+ */
2297
+ declare const LinkPreviewCard: react.ForwardRefExoticComponent<LinkPreviewCardProps & react.RefAttributes<HTMLDivElement>>;
2298
+ /**
2299
+ * Convenience alias for `LinkPreviewCard`. Identical component — use whichever
2300
+ * name reads more naturally at the call site.
2301
+ *
2302
+ * `LinkPreviewCard` is the canonical export; `LinkPreview` is the alias.
2303
+ */
2304
+ declare const LinkPreview: react.ForwardRefExoticComponent<LinkPreviewCardProps & react.RefAttributes<HTMLDivElement>>;
2305
+
2306
+ interface ListEditorProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
2307
+ /** Controlled list of strings. */
2308
+ value?: string[];
2309
+ /** Uncontrolled initial list of strings. */
2310
+ defaultValue?: string[];
2311
+ /** Called when the list changes (add, remove, edit, or reorder). */
2312
+ onValueChange?: (value: string[]) => void;
2313
+ /**
2314
+ * Whether rows can be reordered via move-up/move-down buttons. Default
2315
+ * true. Reordering is keyboard-operable (real buttons), never drag-only.
2316
+ */
2317
+ reorderable?: boolean;
2318
+ /** Placeholder shown in each row's text field. */
2319
+ placeholder?: string;
2320
+ /** Maximum number of rows allowed. */
2321
+ max?: number;
2322
+ /** Whether the editor is disabled. */
2323
+ disabled?: boolean;
2324
+ /** Label for the "add item" control. */
2325
+ addLabel?: ReactNode;
2326
+ }
2327
+ /**
2328
+ * ListEditor — one `Input` per row over a `string[]`, with add / remove /
2329
+ * keyboard-operable reorder (move-up/move-down buttons, not drag-and-drop —
2330
+ * no drag library exists in the monorepo and none should be added for this).
2331
+ *
2332
+ * Controlled via `value`/`onValueChange`; uncontrolled via `defaultValue`.
2333
+ */
2334
+ declare const ListEditor: react.ForwardRefExoticComponent<ListEditorProps & react.RefAttributes<HTMLDivElement>>;
2335
+
2336
+ /** A flat map of string keys to their translated values. */
2337
+ type Messages = Record<string, string>;
2338
+ interface LocaleContextValue {
2339
+ /** BCP-47 locale tag, e.g. "en-US", "ar-EG", "de-DE". */
2340
+ locale: string;
2341
+ /** Layout direction for the locale region. */
2342
+ dir: "ltr" | "rtl";
2343
+ /**
2344
+ * Translate a key.
2345
+ * Falls back to: consumer messages → English default → the key itself.
2346
+ * Supports simple `{name}`-style variable interpolation.
2347
+ */
2348
+ t: (key: string, vars?: Record<string, string | number>) => string;
2349
+ /** Format a number using the active locale. Memoized per locale+opts hash. */
2350
+ formatNumber: (n: number, opts?: Intl.NumberFormatOptions) => string;
2351
+ /** Format a date using the active locale. Memoized per locale+opts hash. */
2352
+ formatDate: (d: Date | number, opts?: Intl.DateTimeFormatOptions) => string;
2353
+ }
2354
+ interface LocaleProviderProps {
2355
+ /**
2356
+ * BCP-47 locale tag. Defaults to "en-US".
2357
+ * Used by `t`, `formatNumber`, and `formatDate`.
2358
+ */
2359
+ locale?: string;
2360
+ /**
2361
+ * Layout direction for the subtree.
2362
+ * Defaults to "ltr". Set "rtl" for Arabic, Hebrew, Farsi, etc.
2363
+ */
2364
+ dir?: "ltr" | "rtl";
2365
+ /**
2366
+ * Additional/overriding message strings merged on top of the shipped English
2367
+ * defaults. Only the keys you provide are overridden; the rest fall through
2368
+ * to the English bundle.
2369
+ */
2370
+ messages?: Messages;
2371
+ children: ReactNode;
2372
+ }
2373
+ /**
2374
+ * `LocaleProvider` supplies locale, layout direction, component microcopy, and
2375
+ * Intl formatting helpers to the component subtree.
2376
+ *
2377
+ * - Wrap your app (or a regional subtree) with it to localise brand-ui components.
2378
+ * - Components call `useLocale()` unconditionally; without a provider they
2379
+ * degrade gracefully to "en-US" / "ltr" / English defaults.
2380
+ * - Portalled Radix content (Dialog, Sheet, Popover, DropdownMenu) still honors
2381
+ * `dir` because the subtree is wrapped in Radix's `DirectionProvider`, which
2382
+ * every Radix primitive reads via context regardless of DOM position (ADR-0014).
2383
+ * The `<div dir={dir}>` continues to carry direction for non-Radix content.
2384
+ */
2385
+ declare function LocaleProvider({ locale, dir, messages, children, }: LocaleProviderProps): react.JSX.Element;
2386
+ /**
2387
+ * Read the active locale, direction, `t`, `formatNumber`, and `formatDate`.
2388
+ *
2389
+ * Provider-optional: without a `<LocaleProvider>` this returns the en-US
2390
+ * defaults so components can call it unconditionally and remain usable in
2391
+ * unwrapped contexts.
2392
+ */
2393
+ declare function useLocale(): LocaleContextValue;
2394
+
2395
+ /**
2396
+ * Shipped English (en-US) default microcopy bundle.
2397
+ *
2398
+ * Keys are intentionally terse, semantic, and framework-agnostic so they
2399
+ * translate cleanly into any target locale. Keep this list small and real —
2400
+ * only add a key here when a component actually needs it.
2401
+ */
2402
+ declare const DEFAULT_MESSAGES: Record<string, string>;
2403
+
2404
+ interface LoadingStateProps {
2405
+ /** Accessible status label. Defaults to "Loading…". */
2406
+ label?: ReactNode;
2407
+ /** Visual size of the spinner. */
2408
+ size?: "sm" | "md" | "lg";
2409
+ className?: string;
2410
+ }
2411
+ /** @deprecated Use `<StatePanel kind="loading" />` instead. */
2412
+ declare function LoadingState({ label, size, className }: LoadingStateProps): react.JSX.Element;
2413
+
2414
+ /** A half-open `[start, end)` character range within the text. */
2415
+ type MatchRange = readonly [number, number];
2416
+ interface MatchHighlightProps extends HTMLAttributes<HTMLSpanElement> {
2417
+ /** The full string to render. */
2418
+ text: string;
2419
+ /**
2420
+ * One or more needles to highlight. Case-insensitive by default. Ignored when
2421
+ * `ranges` is supplied.
2422
+ */
2423
+ query?: string | string[];
2424
+ /**
2425
+ * Precomputed match ranges (e.g. from a fuzzy matcher / MiniSearch). Wins over
2426
+ * `query` when supplied. Overlapping and adjacent ranges are merged.
2427
+ */
2428
+ ranges?: readonly MatchRange[];
2429
+ /** Match `query` case-sensitively. @default false */
2430
+ caseSensitive?: boolean;
2431
+ /**
2432
+ * Which mark is the CURRENT one, 0-based among the resolved (merged, sorted)
2433
+ * ranges. `-1` or omitted means none is.
2434
+ *
2435
+ * "One of twelve" and "the one you are on" are different meanings, so the
2436
+ * current mark gets its own token pair rather than an opacity tweak — and,
2437
+ * because colour is never the only channel (WCAG 1.4.1), an outline and
2438
+ * `aria-current="true"` as well. It also carries `data-active`, which is how
2439
+ * a caller finds it to scroll it into view:
2440
+ * `root.querySelector('[data-slot="match-highlight-mark"][data-active]')`.
2441
+ */
2442
+ activeIndex?: number;
2443
+ }
2444
+ /**
2445
+ * Find every occurrence of each needle in `text` and return their `[start, end)`
2446
+ * ranges. Uses a per-needle global regex so indices land on the ORIGINAL string
2447
+ * (unicode-safe — no `toLowerCase()` length drift), handling multiple needles and
2448
+ * case folding. Empty needles are ignored.
2449
+ */
2450
+ declare function queryToRanges(text: string, query: string | string[], caseSensitive?: boolean): MatchRange[];
2451
+ /**
2452
+ * Clamp ranges to `[0, len)`, drop empty/invalid ones, sort, and merge
2453
+ * overlapping AND adjacent ranges (so `[0,2]` + `[2,4]` → a single `[0,4]`).
2454
+ */
2455
+ declare function normalizeRanges(ranges: readonly MatchRange[], len: number): MatchRange[];
2456
+ /**
2457
+ * Render `text` with the query matches wrapped in real `<mark>` elements. Purely
2458
+ * presentational: pass `query` to let it compute ranges (case-insensitive by
2459
+ * default), or `ranges` from your own fuzzy engine. Marks use the semantic
2460
+ * `--highlight` token pair (AA-legible ink in every theme). Screen readers read
2461
+ * the full string naturally.
2462
+ */
2463
+ declare const MatchHighlight: react.ForwardRefExoticComponent<MatchHighlightProps & react.RefAttributes<HTMLSpanElement>>;
2464
+
2465
+ declare const Popover: react.FC<PopoverPrimitive.PopoverProps>;
2466
+ declare const PopoverTrigger: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
2467
+ declare const PopoverAnchor: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & react.RefAttributes<HTMLDivElement>>;
2468
+ declare const PopoverContent: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2469
+
2470
+ /**
2471
+ * The pure offset algebra behind `MentionInput`.
2472
+ *
2473
+ * Chip atomicity in a real `<textarea>` is **selection arithmetic over a token
2474
+ * map**, not DOM nodes: the field holds ordinary text, and this module keeps a
2475
+ * parallel list of `{ id, label, start }` records honest as that text is edited,
2476
+ * pasted over and deleted. Nothing here touches React or the DOM, so every
2477
+ * acceptance criterion about backspace atomicity, caret skipping and the
2478
+ * `{ text, mentionedIds }` payload reduces to a unit test on these functions.
2479
+ */
2480
+ /** One selectable roster entry. */
2481
+ interface MentionOption {
2482
+ /** Stable id — this is what `serializeMentions` emits. */
2483
+ id: string;
2484
+ /** Inserted verbatim after the trigger character. */
2485
+ label: string;
2486
+ /** Optional secondary line shown under the label. */
2487
+ description?: string;
2488
+ /** Optional leading glyph (avatar, icon). */
2489
+ icon?: ReactNode;
2490
+ /** Extra match terms, so "ada" can find "Ada Lovelace". */
2491
+ keywords?: string[];
2492
+ /** Rendered but not selectable. */
2493
+ disabled?: boolean;
2494
+ }
2495
+ /** A resolved mention inside `MentionValue.text`. */
2496
+ interface Mention {
2497
+ /** The option id this run refers to. */
2498
+ id: string;
2499
+ /** The label WITHOUT the trigger character. */
2500
+ label: string;
2501
+ /** Offset of the trigger character in `text`. */
2502
+ start: number;
2503
+ }
2504
+ /** The component's value: plain text plus the mentions it contains. */
2505
+ interface MentionValue {
2506
+ text: string;
2507
+ mentions: Mention[];
2508
+ }
2509
+ /** The result of inserting an option: the new value and where the caret goes. */
2510
+ interface InsertMentionResult {
2511
+ value: MentionValue;
2512
+ /** Offset immediately after the inserted token's trailing space. */
2513
+ caret: number;
2514
+ }
2515
+ /** Exclusive end offset of a mention's `trigger + label` run. */
2516
+ declare function mentionEnd(mention: Mention, trigger?: string): number;
2517
+ /**
2518
+ * The mention whose half-open range `[start, end)` contains `index`, if any.
2519
+ *
2520
+ * Half-open on purpose: the offset one past the token is *outside* it, so a
2521
+ * caret sitting immediately after `@Ada Lovelace` is "next to" the mention
2522
+ * rather than "in" it. Backspace therefore asks about `caret - 1` and Delete
2523
+ * about `caret`, and both get an unambiguous answer.
2524
+ */
2525
+ declare function mentionAt(value: MentionValue, index: number, trigger?: string): Mention | undefined;
2526
+ /**
2527
+ * Re-derive the mention list after the text changed underneath it.
2528
+ *
2529
+ * The edit is treated as ONE contiguous replacement — which is what a
2530
+ * keystroke, a paste, a cut and a native undo all are. The common prefix and
2531
+ * common suffix bracket it; a mention entirely before the edit keeps its
2532
+ * offset, one entirely after it shifts by the length delta, and one the edit
2533
+ * reaches into is **dropped** (its text no longer spells the person's name, so
2534
+ * the id would be a lie).
2535
+ *
2536
+ * Every survivor is then **re-validated** against the new text: the run at its
2537
+ * offset must still read exactly `trigger + label`. That second pass is what
2538
+ * makes a multi-mention paste safe — the arithmetic alone can be fooled by a
2539
+ * replacement whose prefix/suffix boundaries land ambiguously, but a run that
2540
+ * no longer spells the token can never survive the check.
2541
+ */
2542
+ declare function remapMentions(prev: MentionValue, nextText: string, trigger?: string): Mention[];
2543
+ /**
2544
+ * Replace the in-progress `trigger + query` run with `trigger + label + " "`.
2545
+ *
2546
+ * `queryStart` is the offset of the trigger character; `caret` is where the
2547
+ * query ends. The trailing space is deliberate: it terminates the query so the
2548
+ * popup closes, and it gives the next word somewhere to start.
2549
+ */
2550
+ declare function insertMention(value: MentionValue, option: MentionOption, trigger: string, queryStart: number, caret: number): InsertMentionResult;
2551
+ /**
2552
+ * The serialization contract a consumer gets out: the raw text plus the option
2553
+ * ids it references, **deduped** and in **document order** (two mentions of the
2554
+ * same person yield one id).
2555
+ */
2556
+ declare function serializeMentions(value: MentionValue): {
2557
+ text: string;
2558
+ mentionedIds: string[];
2559
+ };
2560
+ /**
2561
+ * Case-insensitive substring match over `label` and `keywords`. An empty query
2562
+ * matches everything, so the full roster shows the moment the trigger is typed.
2563
+ */
2564
+ declare function defaultMentionFilter(option: MentionOption, query: string): boolean;
2565
+
2566
+ interface MentionInputContextValue {
2567
+ state: {
2568
+ value: MentionValue;
2569
+ /** The in-progress query WITHOUT the trigger char; `null` when closed. */
2570
+ query: string | null;
2571
+ open: boolean;
2572
+ /** Index into `filtered`; `-1` when nothing is highlighted. */
2573
+ activeIndex: number;
2574
+ /** DOM id of the highlighted option; `undefined` when nothing is. */
2575
+ activeId?: string;
2576
+ filtered: MentionOption[];
2577
+ };
2578
+ actions: {
2579
+ insert: (option: MentionOption) => void;
2580
+ close: () => void;
2581
+ setActiveIndex: (index: number) => void;
2582
+ };
2583
+ meta: {
2584
+ trigger: string;
2585
+ listId: string;
2586
+ /**
2587
+ * The id `MentionInputTextarea` puts on its element. Advisory only — with
2588
+ * `asChild`, Radix `Slot` lets a consumer-supplied `id` on the child win
2589
+ * (child props are merged OVER slot props), so the component itself never
2590
+ * resolves the field through this id; it holds a real ref.
2591
+ */
2592
+ textareaId: string;
2593
+ optionId: (index: number) => string;
2594
+ };
2595
+ }
2596
+ /** Read the surrounding `MentionInput`'s state, actions and ids. */
2597
+ declare function useMentionInput(): MentionInputContextValue;
2598
+ interface MentionInputProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
2599
+ /** The roster the popup offers. */
2600
+ options: MentionOption[];
2601
+ /** Controlled value. */
2602
+ value?: MentionValue;
2603
+ /** Uncontrolled initial value. */
2604
+ defaultValue?: MentionValue;
2605
+ /** Called with the whole value whenever text or mentions change. */
2606
+ onValueChange?: (value: MentionValue) => void;
2607
+ /** Trigger character. Default `"@"`. */
2608
+ trigger?: string;
2609
+ /**
2610
+ * Which options survive the current query. Defaults to
2611
+ * `defaultMentionFilter`; pass `() => true` when the roster is fetched
2612
+ * app-side from `onQueryChange`.
2613
+ */
2614
+ filter?: (option: MentionOption, query: string) => boolean;
2615
+ /** The query changed. `null` means the popup closed. */
2616
+ onQueryChange?: (query: string | null) => void;
2617
+ /** Controlled popup state. */
2618
+ open?: boolean;
2619
+ /** Called when the popup wants to open or close. */
2620
+ onOpenChange?: (open: boolean) => void;
2621
+ children: ReactNode;
2622
+ }
2623
+ /**
2624
+ * MentionInput — an `@`-mention text field built on a real `<textarea>`.
2625
+ *
2626
+ * The field stays a native textarea (so IME, paste, undo, spellcheck, mobile
2627
+ * keyboards and `FormData` all keep working) and mentions are tracked as
2628
+ * offsets beside it. The suggestion popup is this component's own listbox
2629
+ * driven by `aria-activedescendant`, so **focus never leaves the textarea** —
2630
+ * a popup that took focus would take the caret with it.
2631
+ */
2632
+ declare const MentionInput: react.ForwardRefExoticComponent<MentionInputProps & react.RefAttributes<HTMLDivElement>>;
2633
+ interface MentionInputTextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "value" | "defaultValue"> {
2634
+ /**
2635
+ * Render the consumer's own textarea-rendering component instead of a
2636
+ * `Textarea` — e.g. `PromptInputTextarea`. The child must ultimately render a
2637
+ * real `<textarea>`; everything this component needs is spread onto it.
2638
+ */
2639
+ asChild?: boolean;
2640
+ }
2641
+ /**
2642
+ * The field itself — a real `<textarea>` carrying the combobox semantics.
2643
+ *
2644
+ * The mention interception is bound as **`onKeyDownCapture`**, not `onKeyDown`.
2645
+ * Under `asChild`, Radix `Slot` merges CHILD handlers over slot handlers and
2646
+ * runs the child's **first**. So when the child binds `onKeyDown` directly on
2647
+ * the host element, a bubble-phase handler here would fire *after* it — the
2648
+ * child's Enter→submit would win and the popup would never see the key. React
2649
+ * dispatches an element's capture pass before its bubble pass and shares one
2650
+ * `SyntheticEvent` between them, so `preventDefault()` here is already visible
2651
+ * as `event.defaultPrevented` when the child's handler runs.
2652
+ *
2653
+ * **Scope of the hazard, stated precisely** (an earlier version of this comment
2654
+ * overclaimed): it applies to a child that binds `onKeyDown` on a *host
2655
+ * element*. It does NOT apply to `PromptInputTextarea`, which is a *component*
2656
+ * that destructures `onKeyDown` out of its own props, calls it first and bails
2657
+ * on `defaultPrevented` (`packages/ai/src/prompt-input.tsx`) — that composition
2658
+ * works with either binding. The capture binding is what makes the raw-host
2659
+ * case correct too, and that is the case the locking test exercises: see
2660
+ * "T8 Slot handler-order contract" in `mention-input.test.tsx`, which fails if
2661
+ * this is ever moved to `onKeyDown`.
2662
+ */
2663
+ declare const MentionInputTextarea: react.ForwardRefExoticComponent<MentionInputTextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
2664
+ type MentionInputContentProps = React.ComponentPropsWithoutRef<typeof PopoverContent>;
2665
+ /** The floating panel. Never takes focus — the caret has to stay in the field. */
2666
+ declare const MentionInputContent: react.ForwardRefExoticComponent<Omit<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2667
+ interface MentionInputListProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
2668
+ /**
2669
+ * Either static nodes, or a render function called once per filtered option.
2670
+ * The function form is the one to reach for — the parent has to hand each
2671
+ * option back, which is exactly what `children`-as-a-function is for.
2672
+ */
2673
+ children?: ReactNode | ((option: MentionOption, index: number) => ReactNode);
2674
+ }
2675
+ /** The listbox. Owns the accessible name and the option mapping. */
2676
+ declare const MentionInputList: react.ForwardRefExoticComponent<MentionInputListProps & react.RefAttributes<HTMLDivElement>>;
2677
+ interface MentionInputItemProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
2678
+ option: MentionOption;
2679
+ children?: ReactNode;
2680
+ }
2681
+ /**
2682
+ * One option row.
2683
+ *
2684
+ * The row derives its own index from the provider's `filtered` list rather than
2685
+ * accepting one, so its `id` and `aria-selected` can never disagree with the
2686
+ * `aria-activedescendant` the field is publishing.
2687
+ */
2688
+ declare const MentionInputItem: react.ForwardRefExoticComponent<MentionInputItemProps & react.RefAttributes<HTMLDivElement>>;
2689
+ type MentionInputEmptyProps = HTMLAttributes<HTMLDivElement>;
2690
+ /**
2691
+ * The "nothing matches" line. A **sibling** of the listbox, never a child —
2692
+ * a `role="listbox"` may only own `option` and `group` children.
2693
+ */
2694
+ declare const MentionInputEmpty: react.ForwardRefExoticComponent<MentionInputEmptyProps & react.RefAttributes<HTMLDivElement>>;
2695
+
2696
+ declare const Menubar: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2697
+ declare const MenubarTrigger: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
2698
+ declare const MenubarContent: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2699
+ declare const MenubarItem: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
2700
+ inset?: boolean;
2701
+ } & react.RefAttributes<HTMLDivElement>>;
2702
+ declare const MenubarSubTrigger: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarSubTriggerProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
2703
+ inset?: boolean;
2704
+ } & react.RefAttributes<HTMLDivElement>>;
2705
+ declare const MenubarSubContent: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarSubContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2706
+ declare const MenubarCheckboxItem: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarCheckboxItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2707
+ declare const MenubarRadioItem: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarRadioItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2708
+ declare const MenubarSeparator: react.ForwardRefExoticComponent<Omit<MenubarPrimitive.MenubarSeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2709
+ declare function MenubarShortcut({ className, ...props }: HTMLAttributes<HTMLSpanElement>): react.JSX.Element;
2710
+
2711
+ /**
2712
+ * `ModelPicker`'s two state decisions, kept OUT of the component on purpose.
2713
+ *
2714
+ * Both were inline ternaries in the consuming app this component came from, and
2715
+ * both survived every mutation thrown at them — because no test could reach an
2716
+ * expression buried in JSX. As exported pure functions they are directly
2717
+ * testable, which is the whole reason they live in their own module.
2718
+ */
2719
+ /** What the picker knows about the list it was handed. */
2720
+ type ModelPickerStatus = "idle" | "loading" | "ready" | "stale" | "error" | "empty";
2721
+ /** Which of the four mutually-exclusive bodies the popover renders. */
2722
+ type ModelPickerBody = "loading" | "list" | "error" | "empty";
2723
+ /**
2724
+ * Pick the body.
2725
+ *
2726
+ * **A non-empty list always wins.** A failed refresh over usable stale data is an
2727
+ * inline strip above a working list (see `showsInlineError`), never a takeover —
2728
+ * collapsing "stale list + error" into "error panel" throws away a list the user
2729
+ * could still have picked from.
2730
+ */
2731
+ declare function modelPickerBody(status: ModelPickerStatus, itemCount: number): ModelPickerBody;
2732
+ /**
2733
+ * Whether to show the error line ABOVE a list that still works — i.e. the
2734
+ * refresh failed but there is stale data worth keeping on screen.
2735
+ */
2736
+ declare function showsInlineError(status: ModelPickerStatus, itemCount: number): boolean;
2737
+ /** One selectable row. */
2738
+ interface ModelPickerItem {
2739
+ id: string;
2740
+ label: string;
2741
+ /** Muted second line. */
2742
+ description?: string;
2743
+ /**
2744
+ * Extra strings cmdk should MATCH on without displaying — ids, a space or
2745
+ * workspace name. This is what lets a search for "northwind" find a target
2746
+ * whose visible label never says it.
2747
+ */
2748
+ keywords?: string[];
2749
+ /**
2750
+ * Leading glyph. A ReactNode, never a URL: a renderer with no remote origins
2751
+ * cannot fetch a logo, so the caller supplies a bundled node.
2752
+ */
2753
+ icon?: React.ReactNode;
2754
+ /**
2755
+ * Trailing muted badges ("not provisioned", "no modes").
2756
+ *
2757
+ * Deliberately a caller-supplied ARRAY rather than derived from flags. A
2758
+ * three-valued flag where absent means "undecided" renders as "not enabled"
2759
+ * the moment a component computes the badge from `!flag` — which mislabels
2760
+ * every row on a deployment that simply never probed. Keeping this a list the
2761
+ * caller builds means the library cannot get that wrong on their behalf.
2762
+ */
2763
+ meta?: string[];
2764
+ /** Disable this row without removing it. */
2765
+ disabled?: boolean;
2766
+ }
2767
+ /** A titled group of rows. */
2768
+ interface ModelPickerGroup {
2769
+ key: string;
2770
+ /**
2771
+ * Rendered verbatim as the group heading. The CALLER derives it (`Apps ·
2772
+ * northwind`, `Assistants · personal`) — the library never invents grouping or
2773
+ * heading text from the data.
2774
+ */
2775
+ label: string;
2776
+ items: ModelPickerItem[];
2777
+ }
2778
+ /** Total rows across all groups. */
2779
+ declare function countItems(groups: readonly ModelPickerGroup[]): number;
2780
+
2781
+ interface ModelPickerProps extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> {
2782
+ /** Grouped rows. Grouping and heading text are the caller's, never derived. */
2783
+ groups: readonly ModelPickerGroup[];
2784
+ /** The currently pinned row's id. */
2785
+ value?: string;
2786
+ /** Fires with the chosen row; the popover closes first. */
2787
+ onSelect?: (item: ModelPickerItem) => void;
2788
+ /** Drives the four bodies — see `modelPickerBody`. Default `"ready"`. */
2789
+ status?: ModelPickerStatus;
2790
+ /** Trigger text — usually the pinned row's label. */
2791
+ triggerLabel: ReactNode;
2792
+ /** Retry action for the error strip and the empty panel. Omit to hide it. */
2793
+ onRetry?: () => void;
2794
+ /** Search field placeholder. */
2795
+ searchPlaceholder?: string;
2796
+ disabled?: boolean;
2797
+ /** Extra classes for the popover panel (default width `w-96`). */
2798
+ contentClassName?: string;
2799
+ /** Accessible name for the trigger — what the control is FOR, not what is chosen. */
2800
+ "aria-label"?: string;
2801
+ /**
2802
+ * Controlled popover open state. Omit for the uncontrolled default (internal
2803
+ * `useState(false)`, unchanged). `isControlled = open !== undefined` and the
2804
+ * mode never flips mid-life — see `component-api.md` "Controlled/uncontrolled".
2805
+ */
2806
+ open?: boolean;
2807
+ /** Fires whenever the popover would open/close — a trigger click, or a row select. */
2808
+ onOpenChange?: (open: boolean) => void;
2809
+ }
2810
+ /**
2811
+ * A compact pill that opens a grouped, searchable target list anchored under
2812
+ * itself — sized to sit in a composer footer.
2813
+ *
2814
+ * The inline sibling of `@elabs-ai/components-ai`'s `ModelSelector`,
2815
+ * which is the same `Command` internals in a modal `Dialog`. Reach for that one
2816
+ * for a full command palette; reach for this one for an in-place picker.
2817
+ *
2818
+ * **`Command` lives inside a `Popover`, never a `DropdownMenu`, and that is not
2819
+ * a stylistic choice.** `DropdownMenuContent` owns roving tabindex and its own
2820
+ * typeahead, both of which fight a real `<input>` in its subtree: arrow keys move
2821
+ * the menu's focus instead of cmdk's highlight, and keystrokes are swallowed
2822
+ * before they reach `CommandInput`. `Popover` contributes positioning and
2823
+ * dismissal and claims no keyboard, which is why every combobox is built on it.
2824
+ * Do not "simplify" this back.
2825
+ */
2826
+ declare const ModelPicker: react.ForwardRefExoticComponent<ModelPickerProps & react.RefAttributes<HTMLDivElement>>;
2827
+
2828
+ /**
2829
+ * compact-number.ts — the same "shown short, copied exact" number rule the
2830
+ * charts package applies to axis ticks and tooltips, available to `ui` surfaces
2831
+ * that display a figure (today: `MetricCard`).
2832
+ *
2833
+ * DELIBERATE TWIN of `packages/charts/src/charts/value-format.ts`. Dependencies
2834
+ * flow one way — `tokens → ui → charts` — so `ui` cannot import the charts
2835
+ * module, and a chart-domain union does not belong in the `ui` public API just
2836
+ * to be shared. The duplication is ~20 lines and the two must stay in step:
2837
+ * **change one, change the other**, and keep {@link COMPACT_THRESHOLD} equal in
2838
+ * both. `metric-card.test.tsx` and `value-format.test.ts` pin the same cases on
2839
+ * each side so a drift shows up as a failing test rather than as two surfaces
2840
+ * disagreeing about what `1500` looks like.
2841
+ */
2842
+ /** How a numeric value is rendered. Mirrors the charts `ChartValueFormat`. */
2843
+ type NumberFormatKind = "number" | "compact" | "currency" | "percent";
2844
+
2845
+ declare const metricValueVariants: (props?: ({
2846
+ emphasis?: "default" | "headline" | null | undefined;
2847
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
2848
+ type MetricCardEmphasis = NonNullable<VariantProps<typeof metricValueVariants>["emphasis"]>;
2849
+ /**
2850
+ * How a NUMERIC `value` is rendered. A function takes over completely.
2851
+ *
2852
+ * `"compact"` is the default because a KPI tile is a small box and
2853
+ * `50012102.632741` does not fit in one — the exact figure stays one click
2854
+ * away via `CopyableValue`. Anything that is not a `number` (a string, an
2855
+ * element) is passed through untouched, so every existing call site is
2856
+ * unaffected.
2857
+ */
2858
+ type MetricCardValueFormat = NumberFormatKind | ((value: number) => ReactNode);
2859
+ interface MetricCardProps extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof metricValueVariants> {
2860
+ label: ReactNode;
2861
+ value: ReactNode;
2862
+ /**
2863
+ * How to render a NUMERIC `value`. Default: `"compact"`. Ignored for every
2864
+ * other `ReactNode` — a string you already formatted is rendered verbatim.
2865
+ */
2866
+ valueFormat?: MetricCardValueFormat;
2867
+ /** ISO 4217 code for `valueFormat: "currency"`. Default: `"USD"`. */
2868
+ currency?: string;
2869
+ /**
2870
+ * Offer the exact figure on click when a numeric `value` was shortened.
2871
+ * Default: `true`. Turning it off leaves a compacted number with no way back
2872
+ * to its digits, so only do that when the tile is decorative.
2873
+ */
2874
+ copyExactValue?: boolean;
2875
+ /** Secondary line under the value — sublabel / context. */
2876
+ description?: ReactNode;
2877
+ /** Signed change, e.g. "+12.4%". Direction colors it. */
2878
+ delta?: string;
2879
+ deltaDirection?: "up" | "down" | "neutral";
2880
+ /** Whether "up" is good (green) — flip for metrics where down is good. */
2881
+ positiveIsGood?: boolean;
2882
+ icon?: ReactNode;
2883
+ /** Optional inline visual (e.g. a sparkline) shown under the value/description. */
2884
+ visual?: ReactNode;
2885
+ /**
2886
+ * Optional grounding footer (research 11 §B.5 KPI-3) — connects a cited
2887
+ * figure to its source (e.g. an `EvidenceChip` from `@elabs-ai/components-ai`). Rendered
2888
+ * subdued (`text-meta text-muted-foreground`) under the tile body.
2889
+ */
2890
+ evidence?: ReactNode;
2891
+ /**
2892
+ * Loading vs ready — renders a layout-shaped skeleton (matching the real
2893
+ * box height) instead of the value/label/delta text. Default: `false`.
2894
+ */
2895
+ loading?: boolean;
2896
+ /**
2897
+ * Whether this tile announces its own `loading` state via a live region.
2898
+ * Set to `false` when several tiles are composed inside a container that
2899
+ * already announces once for the whole region (e.g. a loading
2900
+ * `MetricGrid`) — see loading-states.md §a11y ("one live region per
2901
+ * region, not per box"). Default: `true`.
2902
+ */
2903
+ announceLoading?: boolean;
2904
+ }
2905
+ /** Compact KPI tile for dashboards. */
2906
+ declare const MetricCard: react.ForwardRefExoticComponent<MetricCardProps & react.RefAttributes<HTMLDivElement>>;
2907
+
2908
+ type NavMainSubItem = {
2909
+ title: string;
2910
+ link: string;
2911
+ icon?: react__default.ReactNode;
2912
+ };
2913
+ type NavMainRoute = {
2914
+ id: string;
2915
+ title: string;
2916
+ icon?: react__default.ReactNode;
2917
+ link: string;
2918
+ subs?: NavMainSubItem[];
2919
+ };
2920
+ interface NavMainProps {
2921
+ routes: NavMainRoute[];
2922
+ className?: string;
2923
+ }
2924
+ /**
2925
+ * Collapsible primary navigation list for sidebars.
2926
+ *
2927
+ * - Routes with `subs` render as an expandable group (one open at a time).
2928
+ * - Routes without `subs` render as a simple link button.
2929
+ * - Collapses to icon-only when the enclosing `Sidebar` is in `"collapsed"` state.
2930
+ *
2931
+ * @example
2932
+ * ```tsx
2933
+ * <NavMain routes={[
2934
+ * { id: "home", title: "Home", icon: <Home />, link: "#" },
2935
+ * { id: "settings", title: "Settings", icon: <Settings />, link: "#",
2936
+ * subs: [{ title: "General", link: "#" }] },
2937
+ * ]} />
2938
+ * ```
2939
+ */
2940
+ declare function NavMain({ routes, className }: NavMainProps): react__default.JSX.Element;
2941
+
2942
+ interface NavNotification {
2943
+ id: string;
2944
+ /** Two-letter fallback initials for the avatar. */
2945
+ fallback: string;
2946
+ text: string;
2947
+ time: string;
2948
+ }
2949
+ interface NavNotificationsProps {
2950
+ notifications: NavNotification[];
2951
+ /** Label for the "view all" footer item. @default "View all notifications" */
2952
+ viewAllLabel?: string;
2953
+ }
2954
+ /**
2955
+ * Sidebar notifications dropdown button. Shared primitive from sidebar-02 (issue #99).
2956
+ * Renders a bell-icon ghost button that opens a dropdown listing recent notifications.
2957
+ */
2958
+ declare function NavNotifications({ notifications, viewAllLabel, }: NavNotificationsProps): react.JSX.Element;
2959
+
2960
+ interface NavUserUser {
2961
+ name: string;
2962
+ email: string;
2963
+ /** URL for the user's avatar image. */
2964
+ avatar?: string;
2965
+ }
2966
+ interface NavUserProps {
2967
+ user: NavUserUser;
2968
+ }
2969
+ /**
2970
+ * Sidebar account / user menu. Shared primitive from sidebar-04 (issue #99).
2971
+ * Renders a trigger showing name + email + avatar; the dropdown exposes
2972
+ * account, billing, notifications and log-out actions.
2973
+ *
2974
+ * Wire your own action handlers by composing custom `DropdownMenuItem` children
2975
+ * if you need more than the default actions — or extend via className.
2976
+ */
2977
+ declare function NavUser({ user }: NavUserProps): react.JSX.Element;
2978
+
2979
+ declare const NavigationMenu: react.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuProps & react.RefAttributes<HTMLElement>, "ref"> & react.RefAttributes<HTMLElement>>;
2980
+ declare const NavigationMenuList: react.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuListProps & react.RefAttributes<HTMLUListElement>, "ref"> & react.RefAttributes<HTMLUListElement>>;
2981
+ declare const NavigationMenuItem: react.ForwardRefExoticComponent<NavigationMenuPrimitive.NavigationMenuItemProps & react.RefAttributes<HTMLLIElement>>;
2982
+ declare const navigationMenuTriggerStyle: (props?: class_variance_authority_types.ClassProp | undefined) => string;
2983
+ declare const NavigationMenuTrigger: react.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
2984
+ declare const NavigationMenuContent: react.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2985
+ declare const NavigationMenuLink: react.ForwardRefExoticComponent<NavigationMenuPrimitive.NavigationMenuLinkProps & react.RefAttributes<HTMLAnchorElement>>;
2986
+ declare const NavigationMenuViewport: react.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuViewportProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
2987
+
2988
+ interface PageShellProps {
2989
+ children: ReactNode;
2990
+ /** Optional header row (often a <SectionHeader />, or a <ViewToolbar> — see headerVariant). */
2991
+ header?: ReactNode;
2992
+ /**
2993
+ * "default" (unset) — `header` renders inline, scrolls with the body.
2994
+ * Byte-identical to today.
2995
+ *
2996
+ * "toolbar" — for a `<ViewToolbar>` header (`@elabs-ai/components-ui`,
2997
+ * `Docs/View Toolbar Contract`): wraps `header` in a `sticky top-0` container
2998
+ * with an opaque/blurred fill and a bottom hairline, so it stays pinned while
2999
+ * the body scrolls beneath it. PLACES whatever node `header` is — it does not
3000
+ * reimplement ViewToolbar's own info/left-cluster/actions grammar, and it does
3001
+ * NOT cap the row's height (a `<ViewToolbar>` wraps at narrow widths; see
3002
+ * `Docs/View Toolbar Contract` R7).
3003
+ */
3004
+ headerVariant?: "default" | "toolbar";
3005
+ /** Constrain content width. Defaults to "xl". */
3006
+ width?: "md" | "lg" | "xl" | "full";
3007
+ className?: string;
3008
+ contentClassName?: string;
3009
+ }
3010
+ /** Page-level content container with consistent padding and max width. */
3011
+ declare function PageShell({ children, header, headerVariant, width, className, contentClassName, }: PageShellProps): react.JSX.Element;
3012
+
3013
+ declare function Pagination({ className, ...props }: ComponentProps<"nav">): react.JSX.Element;
3014
+ declare const PaginationContent: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & react.RefAttributes<HTMLUListElement>>;
3015
+ declare const PaginationItem: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & react.RefAttributes<HTMLLIElement>>;
3016
+ type PaginationLinkProps = {
3017
+ isActive?: boolean;
3018
+ } & ComponentProps<"a">;
3019
+ declare function PaginationLink({ className, isActive, ...props }: PaginationLinkProps): react.JSX.Element;
3020
+ declare function PaginationPrevious({ className, ...props }: ComponentProps<"a">): react.JSX.Element;
3021
+ declare function PaginationNext({ className, ...props }: ComponentProps<"a">): react.JSX.Element;
3022
+ declare function PaginationEllipsis({ className, ...props }: ComponentProps<"span">): react.JSX.Element;
3023
+
3024
+ /**
3025
+ * Tone vocabulary reused from `StatusBadge`/`Alert` (success/warning/destructive
3026
+ * on semantic tokens, #358) rather than reinvented. `default` keeps the fill
3027
+ * byte-identical (`bg-primary`) when `variant` is unset.
3028
+ */
3029
+ declare const progressIndicatorVariants: (props?: ({
3030
+ variant?: "default" | "success" | "warning" | "destructive" | null | undefined;
3031
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3032
+ interface ProgressProps extends ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>, VariantProps<typeof progressIndicatorVariants> {
3033
+ }
3034
+ /**
3035
+ * Color must not be the only signal a guardrail tripped: set `aria-valuetext`
3036
+ * (e.g. `"Exceeded — 120 of 100"`) alongside a non-`default` `variant` — it
3037
+ * passes straight through to the underlying `role="progressbar"` element via
3038
+ * `...props` (Radix's `ProgressPrimitive.Root` already supports it).
3039
+ */
3040
+ declare const Progress: react.ForwardRefExoticComponent<ProgressProps & react.RefAttributes<HTMLDivElement>>;
3041
+
3042
+ declare const RadioGroup: react.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3043
+ declare const RadioGroupItem: react.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupItemProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
3044
+
3045
+ declare const ratingVariants: (props?: ({
3046
+ size?: "md" | "sm" | "lg" | null | undefined;
3047
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3048
+ interface RatingProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue">, VariantProps<typeof ratingVariants> {
3049
+ /** Controlled value (0..max). */
3050
+ value?: number;
3051
+ /** Uncontrolled default value (0..max). Default 0. */
3052
+ defaultValue?: number;
3053
+ /** Called when the rating changes. */
3054
+ onValueChange?: (value: number) => void;
3055
+ /** Number of stars. Default 5. */
3056
+ max?: number;
3057
+ /** Allow half-star values (0.5 increments). Default false. */
3058
+ allowHalf?: boolean;
3059
+ /** Render as a non-interactive display of the value. */
3060
+ readOnly?: boolean;
3061
+ /** Disable interaction (interactive variant only). */
3062
+ disabled?: boolean;
3063
+ /** Accessible name for the rating group. Default "Rating". */
3064
+ "aria-label"?: string;
3065
+ }
3066
+ /**
3067
+ * Rating — a star rating control.
3068
+ *
3069
+ * Controlled via `value`/`onValueChange`; uncontrolled via `defaultValue`.
3070
+ * Interactive mode is a `radiogroup` (keyboard ←/→ adjust by `allowHalf ? 0.5 : 1`,
3071
+ * Home clears, End sets max). `readOnly` renders a non-interactive `role="img"`
3072
+ * summary. Half-star clicks land on the left/right half of a star when `allowHalf`.
3073
+ */
3074
+ declare const Rating: react.ForwardRefExoticComponent<RatingProps & react.RefAttributes<HTMLDivElement>>;
3075
+
3076
+ declare function ResizablePanelGroup({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>): react.JSX.Element;
3077
+ declare const ResizablePanel: react.ForwardRefExoticComponent<Omit<react.HTMLAttributes<HTMLAnchorElement | HTMLElement | HTMLDivElement | HTMLObjectElement | HTMLTitleElement | HTMLBodyElement | HTMLMetaElement | HTMLParagraphElement | HTMLSelectElement | HTMLLinkElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBRElement | HTMLButtonElement | HTMLCanvasElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLInputElement | HTMLLabelElement | HTMLLegendElement | HTMLLIElement | HTMLMapElement | HTMLMeterElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPreElement | HTMLProgressElement | HTMLScriptElement | HTMLSlotElement | HTMLSourceElement | HTMLSpanElement | HTMLStyleElement | HTMLTableElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement | HTMLTableCaptionElement | HTMLMenuElement | HTMLPictureElement>, "id" | "onResize"> & {
3078
+ className?: string | undefined;
3079
+ collapsedSize?: number | undefined;
3080
+ collapsible?: boolean | undefined;
3081
+ defaultSize?: number | undefined;
3082
+ id?: string | undefined;
3083
+ maxSize?: number | undefined;
3084
+ minSize?: number | undefined;
3085
+ onCollapse?: ResizablePrimitive.PanelOnCollapse | undefined;
3086
+ onExpand?: ResizablePrimitive.PanelOnExpand | undefined;
3087
+ onResize?: ResizablePrimitive.PanelOnResize | undefined;
3088
+ order?: number | undefined;
3089
+ style?: object | undefined;
3090
+ tagName?: keyof HTMLElementTagNameMap | undefined;
3091
+ } & {
3092
+ children?: react.ReactNode;
3093
+ } & react.RefAttributes<ResizablePrimitive.ImperativePanelHandle>>;
3094
+ declare function ResizableHandle({ withHandle, className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
3095
+ withHandle?: boolean;
3096
+ }): react.JSX.Element;
3097
+
3098
+ /**
3099
+ * Entrance-animation classes (tw-animate-css), gated by the motion system: the
3100
+ * `duration-*` utility feeds `--tw-duration` (= the gated `--t-*`), so the
3101
+ * reveal slows to ~0 when motion is reduced/off. `fill-mode-both` holds the
3102
+ * start state through any stagger delay so items don't flash in early.
3103
+ */
3104
+ declare const revealVariants: (props?: ({
3105
+ appear?: "left" | "right" | "zoom" | "up" | "down" | "fade" | null | undefined;
3106
+ speed?: "base" | "fast" | "slow" | null | undefined;
3107
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3108
+ interface RevealProps extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof revealVariants> {
3109
+ /** Animation delay in ms (RevealGroup sets this per child to stagger). */
3110
+ delayMs?: number;
3111
+ }
3112
+ /**
3113
+ * Animates its content in on mount (fade + directional slide/zoom). Gated by the
3114
+ * motion system — no animation when motion is reduced/off. For a list/grid, use
3115
+ * {@link RevealGroup} to stagger children.
3116
+ */
3117
+ declare const Reveal: react.ForwardRefExoticComponent<RevealProps & react.RefAttributes<HTMLDivElement>>;
3118
+ interface RevealGroupProps extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof revealVariants> {
3119
+ /** Delay added per successive child, in ms. */
3120
+ staggerMs?: number;
3121
+ }
3122
+ /**
3123
+ * Staggers an entrance across direct children. Clones each child to add the
3124
+ * reveal classes + an incremental `animation-delay` — no wrapper elements, so it
3125
+ * is safe inside flex/grid layouts. Remount it (e.g. via a changing `key`) to
3126
+ * replay. Gated by the motion system.
3127
+ */
3128
+ declare const RevealGroup: react.ForwardRefExoticComponent<RevealGroupProps & react.RefAttributes<HTMLDivElement>>;
3129
+
3130
+ declare const ScrollArea: react.ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3131
+ declare const ScrollBar: react.ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaScrollbarProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3132
+
3133
+ interface SectionHeaderProps {
3134
+ title: ReactNode;
3135
+ description?: ReactNode;
3136
+ /** Right-aligned actions (buttons, menus). */
3137
+ actions?: ReactNode;
3138
+ /** Optional element rendered above the title (eyebrow / breadcrumbs). */
3139
+ eyebrow?: ReactNode;
3140
+ className?: string;
3141
+ }
3142
+ /** A consistent page/section heading row with optional actions. */
3143
+ declare function SectionHeader({ title, description, actions, eyebrow, className, }: SectionHeaderProps): react.JSX.Element;
3144
+
3145
+ interface SegmentedFieldOption {
3146
+ /** The option's value, reported to `onValueChange`. */
3147
+ value: string;
3148
+ /** Visible content for the segment. */
3149
+ label: ReactNode;
3150
+ /** Disables just this segment. */
3151
+ disabled?: boolean;
3152
+ }
3153
+ interface SegmentedFieldProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
3154
+ /** Visible label describing the field. */
3155
+ label: ReactNode;
3156
+ /**
3157
+ * Segment options. Omit and render `ToggleGroupItem` children directly for
3158
+ * the compound-component escape hatch (component-api.md) when a plain
3159
+ * `{ value, label }` shape isn't expressive enough.
3160
+ */
3161
+ options?: SegmentedFieldOption[];
3162
+ /** Controlled selected value. */
3163
+ value?: string;
3164
+ /** Uncontrolled initial selected value. */
3165
+ defaultValue?: string;
3166
+ /**
3167
+ * Called when the selected value changes. Never called with `""` —
3168
+ * re-clicking the active segment (Radix `ToggleGroup`'s `type="single"`
3169
+ * empty-emission on re-click) is swallowed as a no-op instead of clearing
3170
+ * the field.
3171
+ */
3172
+ onValueChange?: (value: string) => void;
3173
+ /** Size applied to every segment. Defaults to "sm", matching the compact segmented look. */
3174
+ size?: "default" | "sm" | "lg";
3175
+ /** Disables every segment. */
3176
+ disabled?: boolean;
3177
+ /** `ToggleGroupItem` children — the compound escape hatch (used instead of `options`). */
3178
+ children?: ReactNode;
3179
+ }
3180
+ /**
3181
+ * SegmentedField — a labelled segmented control with STICKY selection.
3182
+ *
3183
+ * Composes the existing `Label` + `ToggleGroup`/`ToggleGroupItem`
3184
+ * (`variant="segmented"`) — no new visual style. The whole reason this
3185
+ * component exists: Radix's `ToggleGroup` in `type="single"` mode emits `""`
3186
+ * when the already-active segment is re-clicked, silently clearing a field
3187
+ * that must always hold exactly one value. `SegmentedField` swallows that
3188
+ * emission so re-clicking the active segment is a true no-op.
3189
+ *
3190
+ * Per the WAI-ARIA radiogroup pattern (each segment renders `role="radio"`
3191
+ * for `type="single"`), ARROW-KEY navigation also SELECTS the newly focused
3192
+ * segment (selection follows focus), matching native radio-button behavior —
3193
+ * Radix's roving-tabindex only moves focus, so this component adds that
3194
+ * activation on top of it.
3195
+ *
3196
+ * Selection follows focus ONLY for arrow/Home/End keys, never for arbitrary
3197
+ * focus. A bare `onFocus` commit would make three non-navigation paths mutate
3198
+ * the field: clicking the `<Label>` (which moves focus into the group),
3199
+ * tabbing into a group with nothing selected yet, and any programmatic
3200
+ * `.focus()` a consumer performs. The keyboard intent is recorded on the
3201
+ * wrapper in the CAPTURE phase (it must land before Radix's own roving-focus
3202
+ * keydown handler runs) and is cleared by the focus it explains, by a pointer
3203
+ * press, by any non-navigation key, or by focus leaving the field — so it can
3204
+ * never leak into a later, unrelated focus.
3205
+ */
3206
+ declare const SegmentedField: react.ForwardRefExoticComponent<SegmentedFieldProps & react.RefAttributes<HTMLDivElement>>;
3207
+
3208
+ declare const Select: react.FC<SelectPrimitive.SelectProps>;
3209
+ declare const SelectGroup: react.ForwardRefExoticComponent<SelectPrimitive.SelectGroupProps & react.RefAttributes<HTMLDivElement>>;
3210
+ declare const SelectValue: react.ForwardRefExoticComponent<SelectPrimitive.SelectValueProps & react.RefAttributes<HTMLSpanElement>>;
3211
+ /**
3212
+ * `[&>span]:line-clamp-1` clips the rendered `SelectValue` — necessary so a
3213
+ * long/composed label doesn't blow out the trigger's width. To keep clipped
3214
+ * text recoverable, the trigger MEASURES its content and sets a native `title`
3215
+ * only while something is genuinely cut off, so it's readable on mouse hover
3216
+ * with zero extra code.
3217
+ *
3218
+ * The measurement is not cosmetic: an unconditional `title` becomes the
3219
+ * button's accessible name, which would paper over a real "this combobox has
3220
+ * no name" a11y failure with the field's own VALUE — a value is not a name.
3221
+ * Label the trigger properly (`aria-label`/`aria-labelledby`) regardless.
3222
+ *
3223
+ * `title` also never reaches keyboard users — for that, wrap the trigger in
3224
+ * `Tooltip`/`TooltipTrigger asChild`/`TooltipContent` and pass
3225
+ * `autoTitle={false}` (see the `LongComposedLabel` story), which Radix opens
3226
+ * on keyboard focus too.
3227
+ */
3228
+ declare const SelectTrigger: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & {
3229
+ size?: "sm" | "default";
3230
+ /**
3231
+ * Auto-set a native `title` from the trigger's rendered text — but ONLY
3232
+ * while that text is actually clipped (default `true`).
3233
+ *
3234
+ * Set `false` when the trigger is a `TooltipTrigger`: the native tooltip and
3235
+ * the Radix one would otherwise both appear on hover. A caller-supplied
3236
+ * `title` also disables it (an explicit `title` is never overridden).
3237
+ */
3238
+ autoTitle?: boolean;
3239
+ } & react.RefAttributes<HTMLButtonElement>>;
3240
+ declare const SelectContent: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3241
+ declare const SelectLabel: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectLabelProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3242
+ declare const SelectItem: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3243
+ declare const SelectSeparator: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectSeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3244
+
3245
+ declare const separatorVariants: (props?: ({
3246
+ tone?: "strong" | "subtle" | null | undefined;
3247
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3248
+ type SeparatorProps = ComponentPropsWithoutRef<typeof _radix_ui_react_separator.Root> & VariantProps<typeof separatorVariants>;
3249
+ declare const Separator: react.ForwardRefExoticComponent<Omit<_radix_ui_react_separator.SeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
3250
+ tone?: "strong" | "subtle" | null | undefined;
3251
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLDivElement>>;
3252
+
3253
+ declare const Sheet: react.FC<DialogPrimitive.DialogProps>;
3254
+ declare const SheetTrigger: react.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
3255
+ declare const SheetClose: react.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
3256
+ declare const SheetPortal: react.FC<DialogPrimitive.DialogPortalProps>;
3257
+ declare const sheetVariants: (props?: ({
3258
+ side?: "bottom" | "left" | "right" | "top" | null | undefined;
3259
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3260
+ interface SheetContentProps extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants> {
3261
+ }
3262
+ declare const SheetContent: react.ForwardRefExoticComponent<SheetContentProps & react.RefAttributes<HTMLDivElement>>;
3263
+ declare function SheetHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
3264
+ declare function SheetFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
3265
+ declare const SheetTitle: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<HTMLHeadingElement>>;
3266
+ declare const SheetDescription: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<HTMLParagraphElement>>;
3267
+
3268
+ type SkeletonProps = HTMLAttributes<HTMLDivElement>;
3269
+ /** Loading placeholder. Compose with width/height utilities, e.g. `h-4 w-32`. */
3270
+ declare function Skeleton({ className, ...props }: SkeletonProps): react.JSX.Element;
3271
+
3272
+ /** Props for a single `SliderPrimitive.Thumb` — see `SliderProps["thumbProps"]`. */
3273
+ type SliderThumbProps = ComponentPropsWithoutRef<typeof SliderPrimitive.Thumb>;
3274
+ type SliderProps = ComponentPropsWithoutRef<typeof SliderPrimitive.Root> & {
3275
+ /**
3276
+ * Announced instead of the raw numeric value (e.g. `"step 3 of 12"` for a
3277
+ * replay scrubber). Forwarded to the thumb alongside `aria-label`/
3278
+ * `aria-labelledby` — see the doc comment below for why it has to land
3279
+ * there, not on the root.
3280
+ */
3281
+ "aria-valuetext"?: string;
3282
+ /**
3283
+ * Escape hatch spread onto the thumb LAST — for `data-*`/`style`/etc, or to
3284
+ * deliberately override `aria-label`/`aria-labelledby`/`aria-valuetext`
3285
+ * (an explicit key here always wins over the matching top-level prop).
3286
+ *
3287
+ * The six keys that MAKE the element a slider are ignored on purpose:
3288
+ * `role`, `aria-valuenow`, `aria-valuemin`, `aria-valuemax`,
3289
+ * `aria-orientation` and `tabIndex`. Radix derives every one of them from
3290
+ * the slider's live state and spreads consumer props AFTER its own, so
3291
+ * passing them here would silently destroy the widget (a wrong
3292
+ * `aria-valuenow` mis-announces the value; `role`/`tabIndex` make it
3293
+ * unreachable). Change the VALUE (`value`/`min`/`max`/`orientation`/
3294
+ * `disabled`) on `Slider` instead; use `aria-valuetext` to change how the
3295
+ * value is spoken.
3296
+ *
3297
+ * Radix renders one thumb per element of `value`/`defaultValue` — pass a
3298
+ * single object to apply the same props to every thumb (the historical
3299
+ * single-thumb shape, unchanged), or an ARRAY to give each thumb its own
3300
+ * props, indexed positionally against `value`/`defaultValue` (#398). A
3301
+ * missing array slot falls back to no per-thumb override for that thumb.
3302
+ */
3303
+ thumbProps?: SliderThumbProps | SliderThumbProps[];
3304
+ };
3305
+ /**
3306
+ * Range input — a single-thumb value by default, or a multi-thumb range
3307
+ * slider when `value`/`defaultValue` is an array with more than one element
3308
+ * (Radix's own range-slider shape; #398). One `Thumb` is rendered per value.
3309
+ *
3310
+ * `aria-label` / `aria-labelledby` / `aria-valuetext` are routed to the
3311
+ * THUMB(S), not the root: Radix puts `role="slider"` on the thumb, so a name
3312
+ * (or value text) on the root would never reach the widget. Pass `aria-label`
3313
+ * (or `aria-labelledby`, for a visible `<Label>`) — an unnamed slider is an
3314
+ * accessibility failure. For a range slider, pass an ARRAY to `thumbProps` so
3315
+ * each thumb gets its own name/valuetext (e.g. "Minimum price"/"Maximum
3316
+ * price") — the top-level `aria-label`/`aria-valuetext` apply identically to
3317
+ * every thumb, which is rarely what a multi-thumb slider wants.
3318
+ */
3319
+ declare const Slider: react.ForwardRefExoticComponent<Omit<SliderPrimitive.SliderProps & react.RefAttributes<HTMLSpanElement>, "ref"> & {
3320
+ /**
3321
+ * Announced instead of the raw numeric value (e.g. `"step 3 of 12"` for a
3322
+ * replay scrubber). Forwarded to the thumb alongside `aria-label`/
3323
+ * `aria-labelledby` — see the doc comment below for why it has to land
3324
+ * there, not on the root.
3325
+ */
3326
+ "aria-valuetext"?: string;
3327
+ /**
3328
+ * Escape hatch spread onto the thumb LAST — for `data-*`/`style`/etc, or to
3329
+ * deliberately override `aria-label`/`aria-labelledby`/`aria-valuetext`
3330
+ * (an explicit key here always wins over the matching top-level prop).
3331
+ *
3332
+ * The six keys that MAKE the element a slider are ignored on purpose:
3333
+ * `role`, `aria-valuenow`, `aria-valuemin`, `aria-valuemax`,
3334
+ * `aria-orientation` and `tabIndex`. Radix derives every one of them from
3335
+ * the slider's live state and spreads consumer props AFTER its own, so
3336
+ * passing them here would silently destroy the widget (a wrong
3337
+ * `aria-valuenow` mis-announces the value; `role`/`tabIndex` make it
3338
+ * unreachable). Change the VALUE (`value`/`min`/`max`/`orientation`/
3339
+ * `disabled`) on `Slider` instead; use `aria-valuetext` to change how the
3340
+ * value is spoken.
3341
+ *
3342
+ * Radix renders one thumb per element of `value`/`defaultValue` — pass a
3343
+ * single object to apply the same props to every thumb (the historical
3344
+ * single-thumb shape, unchanged), or an ARRAY to give each thumb its own
3345
+ * props, indexed positionally against `value`/`defaultValue` (#398). A
3346
+ * missing array slot falls back to no per-thumb override for that thumb.
3347
+ */
3348
+ thumbProps?: SliderThumbProps | SliderThumbProps[];
3349
+ } & react.RefAttributes<HTMLSpanElement>>;
3350
+
3351
+ interface SliderNumberProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
3352
+ /** Controlled value. Pass `null` for "use the provider default". */
3353
+ value?: number | null;
3354
+ /** Uncontrolled initial value. */
3355
+ defaultValue?: number | null;
3356
+ /** Called when the value changes — always rounded identically on the drag and type paths. */
3357
+ onValueChange?: (value: number | null) => void;
3358
+ /** Minimum allowed value. Defaults to 0. */
3359
+ min?: number;
3360
+ /** Maximum allowed value. Defaults to 100. */
3361
+ max?: number;
3362
+ /** Step increment for both the slider and the number input's arrow keys. Defaults to 1. */
3363
+ step?: number;
3364
+ /**
3365
+ * Number of decimal places to round to. Defaults to the decimal places in
3366
+ * `step` (e.g. `step={0.1}` rounds to 1 decimal). Applied identically on
3367
+ * BOTH the slider path and the number-input path so drag-then-type never
3368
+ * disagrees.
3369
+ */
3370
+ precision?: number;
3371
+ /** Label for the reset-to-provider-default control. Defaults to "Reset". */
3372
+ resetLabel?: ReactNode;
3373
+ /** Disables the whole control. */
3374
+ disabled?: boolean;
3375
+ id?: string;
3376
+ name?: string;
3377
+ "aria-label"?: string;
3378
+ "aria-labelledby"?: string;
3379
+ }
3380
+ /**
3381
+ * SliderNumber — a `Slider` and a `NumberInput` bound to one value, clamped
3382
+ * and rounded in lockstep so they can never disagree, plus an explicit
3383
+ * `null` state meaning "use the provider default" with a reset control.
3384
+ *
3385
+ * The subtle part (#372): both the slider's `onValueChange` and the number
3386
+ * input's `onValueChange` are routed through the SAME `commit` function,
3387
+ * which rounds to a fixed decimal precision before storing — so dragging to
3388
+ * a value and then typing the same value never produces two representations
3389
+ * of the same intent (e.g. floating-point drift like `0.30000000000000004`).
3390
+ */
3391
+ declare const SliderNumber: react.ForwardRefExoticComponent<SliderNumberProps & react.RefAttributes<HTMLDivElement>>;
3392
+
3393
+ type ToasterProps = React.ComponentProps<typeof Toaster$1>;
3394
+ /**
3395
+ * Toast host. Mount once near the app root. Trigger toasts with the exported
3396
+ * `toast()`. Theme follows the active brand theme (via `data-theme`), so it
3397
+ * works with or without <ThemeProvider>.
3398
+ *
3399
+ * ## Customizing toast styling
3400
+ *
3401
+ * The Toaster wrapper renders with the classes `toaster group` by default.
3402
+ * These classes are **merged** with any consumer-supplied `className`, not
3403
+ * replaced, so that built-in styling (the `.group-[.toaster]:*` selectors
3404
+ * on individual toasts) continues to work.
3405
+ *
3406
+ * To override a built-in toast class, **mirror the variant prefix** when you
3407
+ * pass `toastOptions.classNames`. Built-in toast classes are variant-scoped
3408
+ * (e.g. `group-[.toaster]:bg-card`), so a bare utility override will be
3409
+ * outspecificity'd by the built-in and appear to do nothing. Instead, use:
3410
+ *
3411
+ * ```tsx
3412
+ * <Toaster
3413
+ * toastOptions={{
3414
+ * classNames: {
3415
+ * toast: "group-[.toaster]:bg-primary", // ✓ mirrors the prefix
3416
+ * }
3417
+ * }}
3418
+ * />
3419
+ * ```
3420
+ *
3421
+ * ## Theme handling
3422
+ *
3423
+ * The Toaster's `theme` prop is automatically set from the active theme's own
3424
+ * `color-scheme` declaration, so toasts visually track the app's theme by
3425
+ * default — including a theme you authored yourself. However, you may pass
3426
+ * `theme="light"` or `theme="dark"` directly to override this derivation if needed.
3427
+ */
3428
+ declare function Toaster({ className, toastOptions, ...rest }: ToasterProps): react.JSX.Element;
3429
+
3430
+ interface SpinnerProps extends React.SVGProps<SVGSVGElement> {
3431
+ /** Accessible label; defaults to "Loading". */
3432
+ label?: string;
3433
+ }
3434
+ /** Indeterminate spinner with an accessible label. */
3435
+ declare function Spinner({ className, label, ...props }: SpinnerProps): react.JSX.Element;
3436
+
3437
+ declare const statePanelVariants: (props?: ({
3438
+ kind?: "error" | "loading" | "empty" | null | undefined;
3439
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3440
+ interface StatePanelProps extends VariantProps<typeof statePanelVariants> {
3441
+ /**
3442
+ * The visual/semantic kind of state.
3443
+ * - `"empty"` — neutral "nothing here yet" (dashed border, surface bg).
3444
+ * - `"error"` — recoverable failure (destructive border/bg, alert role).
3445
+ * - `"loading"` — in-progress (spinner, status/live-region role).
3446
+ */
3447
+ kind?: "empty" | "error" | "loading";
3448
+ /** Heading text. */
3449
+ title?: ReactNode;
3450
+ /** Supporting description below the title. */
3451
+ description?: ReactNode;
3452
+ /**
3453
+ * Icon or illustration shown above the title.
3454
+ * For `"error"` defaults to a built-in warning triangle.
3455
+ * For `"loading"` defaults to an animated spinner.
3456
+ */
3457
+ icon?: ReactNode;
3458
+ /** Accessible label for the spinner in loading state. @default "Loading…" */
3459
+ loadingLabel?: string;
3460
+ /** Spinner size (loading kind only). @default "md" */
3461
+ size?: "sm" | "md" | "lg";
3462
+ /** Primary / secondary action buttons. */
3463
+ actions?: ReactNode;
3464
+ className?: string;
3465
+ }
3466
+ /**
3467
+ * Unified state panel covering empty, error, and loading states.
3468
+ * Replaces the three separate `EmptyState` / `ErrorState` / `LoadingState` components
3469
+ * while keeping those as back-compat thin wrappers.
3470
+ */
3471
+ declare function StatePanel({ kind, title, description, icon, loadingLabel, size, actions, className, }: StatePanelProps): react.JSX.Element;
3472
+
3473
+ /** The canonical, closed 7-state status enum (research 10 §B.1). */
3474
+ declare const STATUSES: readonly ["pending", "running", "complete", "awaiting-approval", "denied", "failed", "skipped"];
3475
+ type Status = (typeof STATUSES)[number];
3476
+ /** Closed tone set for the out-of-vocabulary escape hatch (CALM treatments only). */
3477
+ declare const STATUS_TONES: readonly ["neutral", "info", "success", "warning", "destructive"];
3478
+ type StatusTone = (typeof STATUS_TONES)[number];
3479
+ /**
3480
+ * An out-of-vocabulary status. Prefer the canonical `Status` enum; reach for
3481
+ * this only when the domain genuinely has a state the 7 do not express (e.g. a
3482
+ * run engine's `stopped_guardrail`). Map it ONCE, near your domain — not per
3483
+ * call site.
3484
+ */
3485
+ interface CustomStatus {
3486
+ label: string;
3487
+ tone: StatusTone;
3488
+ /** Optional Lucide glyph. Omitted → label-only (no default glyph). */
3489
+ icon?: LucideIcon;
3490
+ }
3491
+ /** Narrows `Status | CustomStatus` — the object form is always the escape hatch. */
3492
+ declare function isCustomStatus(status: Status | CustomStatus): status is CustomStatus;
3493
+ /**
3494
+ * The canonical semantic ROLE per status — the single source of truth for
3495
+ * status colour (#392). Any other status-keyed colour map in the repo
3496
+ * (`Timeline`'s `NODE_STYLE`, or a future one) must be TESTED against this,
3497
+ * not hand-authored — a second literal copy is exactly how `NODE_STYLE`
3498
+ * drifted (`running` rendered `--primary` while this map said `--info`).
3499
+ * Do NOT interpolate `bg-${STATUS_ROLE[status]}` into a class map: Tailwind
3500
+ * scans source statically, so a template-literal class emits no CSS. Keep
3501
+ * consuming maps as literal class strings, verified against this export by a
3502
+ * test.
3503
+ */
3504
+ declare const STATUS_ROLE: {
3505
+ readonly pending: "secondary";
3506
+ readonly running: "info";
3507
+ readonly complete: "success";
3508
+ readonly "awaiting-approval": "warning";
3509
+ readonly denied: "muted";
3510
+ readonly failed: "destructive";
3511
+ readonly skipped: "secondary";
3512
+ };
3513
+ /** Default human-readable label per status (override via `children`). */
3514
+ declare const STATUS_LABELS: Record<Status, string>;
3515
+ /**
3516
+ * Lucide glyph per out-of-vocabulary TONE — the same five-tone escape hatch
3517
+ * `CustomStatus` uses (`STATUS_TONES`). A consumer that encodes a bare TONE
3518
+ * with no fuller `Status` semantics (e.g. `@elabs-ai/components-flow`'s `FlowNode.tone`,
3519
+ * #387) derives its non-colour cue from here instead of inventing a second
3520
+ * icon vocabulary — each entry reuses the SAME icon `STATUS_ICONS` already
3521
+ * pairs with that tone's one canonical status (`success`→`complete`'s
3522
+ * `CheckCircle2`, `warning`→`awaiting-approval`'s `Clock`,
3523
+ * `destructive`→`failed`'s `AlertCircle`). `neutral`/`info` have no entry:
3524
+ * nothing consumes them yet, and reaching for a glyph on every neutral/
3525
+ * default-toned element would be assistive-tech noise on the common case —
3526
+ * extend this map, don't fork a new one, the day something needs them.
3527
+ */
3528
+ declare const STATUS_TONE_ICONS: Partial<Record<StatusTone, LucideIcon>>;
3529
+ interface StatusIconProps extends Omit<LucideProps, "ref"> {
3530
+ /** The canonical execution status (closed enum). */
3531
+ status: Status;
3532
+ }
3533
+ /**
3534
+ * The icon + status-color atom `StatusBadge` itself composes — for tight rows
3535
+ * (test-result rows, timeline/rail nodes) where a full badge is too heavy.
3536
+ * Decorative by default (`aria-hidden`); the adjacent row text must carry the
3537
+ * status name for AT users.
3538
+ */
3539
+ declare const StatusIcon: react.ForwardRefExoticComponent<StatusIconProps & react.RefAttributes<SVGSVGElement>>;
3540
+ declare const statusBadgeVariants: (props?: ({
3541
+ status?: "running" | "pending" | "complete" | "awaiting-approval" | "denied" | "failed" | "skipped" | null | undefined;
3542
+ tone?: "success" | "warning" | "destructive" | "info" | "neutral" | null | undefined;
3543
+ size?: "md" | "sm" | null | undefined;
3544
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3545
+ interface StatusBadgeProps extends HTMLAttributes<HTMLSpanElement>, Omit<VariantProps<typeof statusBadgeVariants>, "status" | "tone"> {
3546
+ /** The canonical execution status, or a mapped out-of-vocabulary one (#363). */
3547
+ status: Status | CustomStatus;
3548
+ /** Render label-only (no status icon). */
3549
+ hideIcon?: boolean;
3550
+ }
3551
+ declare const StatusBadge: react.ForwardRefExoticComponent<StatusBadgeProps & react.RefAttributes<HTMLSpanElement>>;
3552
+ /** The editor/markdown `Timeline` 3-state vocabulary (`@elabs-ai/components-editor`). */
3553
+ type TimelineStatus = "done" | "active" | "pending";
3554
+ /**
3555
+ * Map the Timeline `done|active|pending` vocabulary onto the canonical
3556
+ * `Status` (research 10 §B.1 mapping b — lossless; the timeline only
3557
+ * expresses 3 of the 7 states). The AI-SDK `ToolUIPart` mapper lives in
3558
+ * `@elabs-ai/components-ai` (`statusFromToolState`, tool.tsx) so `@elabs-ai/components-ui` stays free of
3559
+ * the `ai` dependency (D6).
3560
+ */
3561
+ declare function fromTimelineStatus(status: TimelineStatus): Status;
3562
+
3563
+ /**
3564
+ * Per-pane surface tone — the ground-offset tiering axis (research 08 §H, #193).
3565
+ * `plain` keeps the ambient ground (default; non-breaking). `card` RAISES the pane as
3566
+ * a white `bg-card` + `shadow-sm` and is robust across all three themes — a card is
3567
+ * lighter than the page ground in BOTH light and dark, so it always reads as raised.
3568
+ * `muted` (`bg-surface-muted`) reads as a recessed well ONLY in light themes; in dark
3569
+ * themes `--surface-muted` is lighter than `--card`, so a `muted` pane reads as a faint
3570
+ * raised tint, not a recess (dark-mode layering only goes UP — there is no surface below
3571
+ * the page ground). For a guaranteed cross-theme raise/recess contrast, raise the focus
3572
+ * pane with `card` and leave the other `plain`.
3573
+ */
3574
+ declare const paneToneVariants: (props?: ({
3575
+ tone?: "card" | "muted" | "plain" | null | undefined;
3576
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3577
+ type SplitPanelTone = NonNullable<VariantProps<typeof paneToneVariants>["tone"]>;
3578
+ interface SplitPanelProps {
3579
+ start: ReactNode;
3580
+ end: ReactNode;
3581
+ /** Layout axis. Defaults to "horizontal" (side-by-side). */
3582
+ direction?: "horizontal" | "vertical";
3583
+ /**
3584
+ * Size of the START pane as a CSS grid track (e.g. "320px", "40%", "1fr").
3585
+ * The END pane fills the remainder. Defaults to "1fr" (equal split).
3586
+ */
3587
+ startSize?: string;
3588
+ /** Show a thin divider between panes. Defaults to true. */
3589
+ divider?: boolean;
3590
+ /** Surface tone of the START pane (ground-offset tiering). Defaults to "plain". */
3591
+ startTone?: SplitPanelTone;
3592
+ /** Surface tone of the END pane (ground-offset tiering). Defaults to "plain". */
3593
+ endTone?: SplitPanelTone;
3594
+ className?: string;
3595
+ startClassName?: string;
3596
+ endClassName?: string;
3597
+ }
3598
+ /**
3599
+ * Two-pane layout for master/detail, editor/preview and inspector workflows.
3600
+ * Static sizing by design (predictable in tests/SSR); for drag-to-resize wrap
3601
+ * with a resize hook or compose `react-resizable-panels` at the app level.
3602
+ *
3603
+ * For a master/detail surface where the detail should read as a raised card on a
3604
+ * recessed list, use `startTone="muted" endTone="card"` (ground-offset tiering).
3605
+ */
3606
+ declare function SplitPanel({ start, end, direction, startSize, divider, startTone, endTone, className, startClassName, endClassName, }: SplitPanelProps): react.JSX.Element;
3607
+
3608
+ declare const Switch: react.ForwardRefExoticComponent<Omit<SwitchPrimitive.SwitchProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
3609
+
3610
+ declare const Table: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableElement> & react.RefAttributes<HTMLTableElement>>;
3611
+ declare const TableHeader: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableSectionElement> & react.RefAttributes<HTMLTableSectionElement>>;
3612
+ declare const TableBody: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableSectionElement> & react.RefAttributes<HTMLTableSectionElement>>;
3613
+ declare const TableFooter: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableSectionElement> & react.RefAttributes<HTMLTableSectionElement>>;
3614
+ declare const TableRow: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableRowElement> & react.RefAttributes<HTMLTableRowElement>>;
3615
+ declare const TableHead: react.ForwardRefExoticComponent<ThHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
3616
+ declare const TableCell: react.ForwardRefExoticComponent<TdHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
3617
+ declare const TableCaption: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableCaptionElement> & react.RefAttributes<HTMLTableCaptionElement>>;
3618
+
3619
+ declare const Tabs: react.ForwardRefExoticComponent<TabsPrimitive.TabsProps & react.RefAttributes<HTMLDivElement>>;
3620
+ /**
3621
+ * `overflow-x-auto` + `max-w-full` turn an overflowing tab strip into a
3622
+ * scroll container instead of silently clipping it — a bare `inline-flex`
3623
+ * has no bound on this element's own width, so without `max-w-full` it would
3624
+ * just grow past its parent instead of scrolling. `justify-center-safe`
3625
+ * (not `justify-center`) is required too: plain `justify-center` strands the
3626
+ * first tab off the left edge once the set overflows; `safe` falls back to
3627
+ * start-alignment on overflow while staying visually identical when the
3628
+ * strip fits (see #344).
3629
+ */
3630
+ declare const TabsList: react.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsListProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3631
+ declare const TabsTrigger: react.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
3632
+ declare const TabsContent: react.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3633
+
3634
+ interface TagInputProps extends Omit<HTMLAttributes<HTMLDivElement>, "defaultValue" | "onChange"> {
3635
+ /** Controlled tag list. */
3636
+ value?: string[];
3637
+ /** Uncontrolled initial tag list. */
3638
+ defaultValue?: string[];
3639
+ /** Called when the tag list changes. */
3640
+ onValueChange?: (value: string[]) => void;
3641
+ /** Maximum number of tags allowed. */
3642
+ max?: number;
3643
+ /**
3644
+ * Validate a candidate tag before it is added.
3645
+ * Return `true` to accept, `false` to silently reject, or a string
3646
+ * to reject and show as an inline error message.
3647
+ */
3648
+ validate?: (tag: string) => boolean | string;
3649
+ /**
3650
+ * Characters (or strings) that trigger tag creation in addition to Enter.
3651
+ * Defaults to `[","]`.
3652
+ */
3653
+ delimiter?: string[];
3654
+ /** Allow duplicate tags (default false). */
3655
+ allowDuplicates?: boolean;
3656
+ /** Placeholder text for the entry field. */
3657
+ placeholder?: string;
3658
+ /** Whether the input is disabled. */
3659
+ disabled?: boolean;
3660
+ /** id for the underlying text input (useful for external <label>). */
3661
+ id?: string;
3662
+ /** Name forwarded to the underlying input. */
3663
+ name?: string;
3664
+ /** aria-label for the underlying text input. */
3665
+ "aria-label"?: string;
3666
+ /** aria-labelledby for the underlying text input. */
3667
+ "aria-labelledby"?: string;
3668
+ }
3669
+ /**
3670
+ * TagInput — chip-style multi-value text entry.
3671
+ *
3672
+ * Controlled via `value`/`onValueChange`; uncontrolled via `defaultValue`.
3673
+ * Enter + configurable delimiters (default `[","]`) add a tag.
3674
+ * Backspace on an empty field removes the last tag.
3675
+ * Inline validation errors render with `role="alert"`.
3676
+ */
3677
+ declare const TagInput: react.ForwardRefExoticComponent<TagInputProps & react.RefAttributes<HTMLDivElement>>;
3678
+
3679
+ type TeamSwitcherTeam = {
3680
+ name: string;
3681
+ logo: react.ElementType;
3682
+ plan: string;
3683
+ };
3684
+ interface TeamSwitcherProps {
3685
+ teams: TeamSwitcherTeam[];
3686
+ /**
3687
+ * Tailwind class for the active-team logo container background.
3688
+ * @default "bg-sidebar-accent text-sidebar-accent-foreground"
3689
+ */
3690
+ logoClassName?: string;
3691
+ className?: string;
3692
+ }
3693
+ /**
3694
+ * Sidebar team/workspace switcher. Shared primitive reconciled from sidebar-02
3695
+ * and sidebar-05 blocks (issue #99). Copy-owned blocks should import this
3696
+ * instead of maintaining local duplicates.
3697
+ */
3698
+ declare function TeamSwitcher({ teams, logoClassName, className }: TeamSwitcherProps): react.JSX.Element | null;
3699
+
3700
+ /** Whole-screen reveal effects for the animated theme switch (View Transitions API). */
3701
+ type ThemeTransitionEffect = "polygon" | "circle" | "circle-blur" | "triangle";
3702
+ /**
3703
+ * Returns a theme setter that animates the whole-screen switch via the View
3704
+ * Transitions API (the chanhdai.com "theme toggle effect", adapted to brand-ui).
3705
+ *
3706
+ * - Direction-aware: sets `data-vt="to-dark|to-light"` on `<html>` from the
3707
+ * target theme's `dark` flag, so the clip-path wipes the right way for ANY of
3708
+ * the three themes (not just light/dark).
3709
+ * - `data-vt-effect` selects the reveal shape (default "polygon").
3710
+ * - Motion-aware: under `useReducedMotion()` (OS or in-app preference) — or when
3711
+ * the browser lacks `startViewTransition` — it falls back to an instant,
3712
+ * unanimated `setTheme`.
3713
+ *
3714
+ * The visual is pure CSS on `::view-transition-*` in `@elabs-ai/components-tokens` themes.css;
3715
+ * this hook only orchestrates it.
3716
+ */
3717
+ declare function useThemeTransition(effect?: ThemeTransitionEffect): (next: ThemeName) => void;
3718
+
3719
+ type ButtonSize = "sm" | "default" | "lg";
3720
+ /** A theme choice, or "system" to follow the OS color scheme. */
3721
+ type ThemePreference = ThemeName | "system";
3722
+ interface ThemeSwitcherProps extends Omit<HTMLAttributes<HTMLButtonElement>, "onChange"> {
3723
+ /**
3724
+ * Themes to offer, as names. ≤2 → toggle; >2 → dropdown.
3725
+ *
3726
+ * Defaults to the PROVIDER's registry (ADR 0029) — so an app that registers
3727
+ * its own themes gets a working switcher with no prop at all. Pass this only
3728
+ * to offer a subset, or to fix the order; names the provider doesn't know are
3729
+ * dropped.
3730
+ */
3731
+ themes?: ThemeName[];
3732
+ /** Force presentation; "auto" (default) picks toggle vs dropdown by theme count. */
3733
+ mode?: "auto" | "toggle" | "dropdown";
3734
+ /** Offer a "System" option that follows the OS color scheme. Default true. */
3735
+ showSystem?: boolean;
3736
+ /** Whole-screen reveal effect for the animated switch. Default "polygon". */
3737
+ effect?: ThemeTransitionEffect;
3738
+ /** Control size. Default "default". */
3739
+ size?: ButtonSize;
3740
+ /**
3741
+ * Controlled preference (#366). When set, the switcher derives its "current"
3742
+ * state — including "system" — from this prop instead of its own internal,
3743
+ * `localStorage`-backed state, and reports every user pick via
3744
+ * `onPreferenceChange` instead of writing its own storage key. Pass this pair
3745
+ * when your app's actual source of truth is a different persisted preference
3746
+ * (a settings API, a different storage key, a server-synced setting). Omit
3747
+ * both for the default, uncontrolled behavior (unchanged).
3748
+ */
3749
+ preference?: ThemePreference;
3750
+ /** Called with the new preference on every user pick, when `preference` is controlled. */
3751
+ onPreferenceChange?: (preference: ThemePreference) => void;
3752
+ }
3753
+ /**
3754
+ * Adaptive theme control. With ≤2 themes it renders a light/dark/system toggle
3755
+ * (a single icon button that cycles); with >2 it auto-upgrades to a dropdown
3756
+ * over the offered themes. Every switch animates the whole screen via
3757
+ * `useThemeTransition` (respecting reduced motion). Icons follow each theme's
3758
+ * `dark` flag, so it works for any theme — including one you authored.
3759
+ *
3760
+ * Uncontrolled by default (tracks its own "system" choice via `localStorage`).
3761
+ * Pass `preference`/`onPreferenceChange` to drive it from an external store
3762
+ * instead (#366) — see the `Controlled` story.
3763
+ *
3764
+ * **It renders the PROVIDER's registry** (ADR 0029). Register your themes on
3765
+ * `<ThemeProvider themes={…}>` and this switcher offers them with no prop —
3766
+ * which is also why `allowedThemes` (#355) is honoured for free: the provider
3767
+ * has already narrowed what it exposes. The `themes` prop is now purely an
3768
+ * additional, optional narrowing on top; a name the provider does not offer is
3769
+ * dropped rather than rendered, so a disallowed or unregistered theme is never
3770
+ * reachable via a menu item, the toggle, "System", or the OS
3771
+ * `prefers-color-scheme` listener.
3772
+ *
3773
+ * The pre-ADR-0029 hard-coded `["light","dark"]` default is gone. Behaviour for
3774
+ * an app on the default provider is unchanged — that registry IS light + dark.
3775
+ */
3776
+ declare const ThemeSwitcher: react.ForwardRefExoticComponent<ThemeSwitcherProps & react.RefAttributes<HTMLButtonElement>>;
3777
+
3778
+ /**
3779
+ * A single revision entry. The APP assigns `lane` (0-based column index),
3780
+ * computes `additions`/`deletions`, and orders revisions newest-first.
3781
+ */
3782
+ interface Revision {
3783
+ /** Unique identifier — used for selection + edge references. */
3784
+ id: string;
3785
+ /** Commit message (may be long; the component truncates). */
3786
+ message: string;
3787
+ /** Display name of the commit author. */
3788
+ author?: string;
3789
+ /** Avatar image URL for the author. */
3790
+ authorAvatar?: string;
3791
+ /** When the commit was authored. Accepts Date, ISO string, or epoch ms. */
3792
+ timestamp: Date | string | number;
3793
+ /** Short commit hash (e.g. "a1b2c3d"). */
3794
+ shortSha?: string;
3795
+ /** Lines added (churn indicator). */
3796
+ additions?: number;
3797
+ /** Lines deleted (churn indicator). */
3798
+ deletions?: number;
3799
+ /**
3800
+ * Column index assigned by the app (0-based). Lane 0 = main branch (leftmost).
3801
+ * Used to position the node dot and draw the lane spine in the SVG gutter.
3802
+ */
3803
+ lane: number;
3804
+ /** Branch or tag labels rendered as chips on this revision. */
3805
+ refs?: string[];
3806
+ /**
3807
+ * Branch identity for the collapse/expand mode. Opt-in: only takes effect when
3808
+ * a matching `branches` entry is supplied to `RevisionTimeline`. When omitted
3809
+ * (or unmatched), the revision renders as a normal, never-collapsible row.
3810
+ */
3811
+ branchId?: string;
3812
+ }
3813
+ /**
3814
+ * A parent link between two revisions, for the lane graph.
3815
+ * Used to draw merge joins (curves / angled lines) in the SVG gutter.
3816
+ */
3817
+ interface RevisionEdge {
3818
+ /** Id of the child revision (newer, higher in the list). */
3819
+ from: string;
3820
+ /** Id of the parent revision (older, lower in the list). */
3821
+ to: string;
3822
+ }
3823
+ /**
3824
+ * A collapsible branch in the history. The APP supplies these (it already
3825
+ * computes lanes + edges); listing a branch here makes it collapsible. Nesting
3826
+ * via `parentBranchId` lets a parent branch's collapse also fold its descendants
3827
+ * (multi-level). Omitting a branch from this list keeps its commits permanently
3828
+ * visible (e.g. the trunk).
3829
+ */
3830
+ interface RevisionBranch {
3831
+ /** Stable id, referenced by `Revision.branchId` and other branches' `parentBranchId`. */
3832
+ id: string;
3833
+ /** Human label for the collapsed summary row. Defaults to `id`. */
3834
+ name?: string;
3835
+ /** Parent branch id — enables multi-level nesting in the collapse hierarchy. */
3836
+ parentBranchId?: string;
3837
+ }
3838
+ /** Visual density variants for the timeline. */
3839
+ declare const revisionTimelineVariants: (props?: ({
3840
+ density?: "compact" | "comfortable" | null | undefined;
3841
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3842
+ type RevisionTimelineDensity = NonNullable<VariantProps<typeof revisionTimelineVariants>["density"]>;
3843
+ /** Lane index → CSS token string (`var(--chart-1)` … `var(--chart-5)`). */
3844
+ declare function laneColor(lane: number): string;
3845
+ interface RevisionTimelineProps extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect">, VariantProps<typeof revisionTimelineVariants> {
3846
+ /** Ordered revisions, newest → oldest. */
3847
+ revisions: Revision[];
3848
+ /**
3849
+ * Parent-link edges for drawing the branch graph.
3850
+ * Each edge connects a child revision (`from`) to its parent (`to`).
3851
+ */
3852
+ edges?: RevisionEdge[];
3853
+ /**
3854
+ * How to group revisions. `"day"` inserts day headers; `"none"` renders a
3855
+ * flat list. @default "day"
3856
+ */
3857
+ groupBy?: "day" | "none";
3858
+ /** Format the day-group header label. Defaults to `Intl.DateTimeFormat` long date. */
3859
+ formatDay?: (d: Date) => string;
3860
+ /**
3861
+ * Controlled selection: the id of the currently-selected revision.
3862
+ * Omit to use uncontrolled selection (`defaultSelectedId`).
3863
+ */
3864
+ selectedId?: string;
3865
+ /** Initial selected revision id for uncontrolled usage. */
3866
+ defaultSelectedId?: string;
3867
+ /** Called when the user selects a revision row. */
3868
+ onSelect?: (id: string) => void;
3869
+ /**
3870
+ * Collapsible branch registry. **Supplying this opts in to the collapse/expand
3871
+ * mode.** Each listed branch becomes collapsible; a branch's commits fold into a
3872
+ * single summary row at its tip. `parentBranchId` nests branches so collapsing a
3873
+ * parent also folds its descendants (multi-level). A revision whose `branchId`
3874
+ * is not listed here (e.g. the trunk) stays permanently visible. Omit entirely
3875
+ * for the classic, non-collapsible timeline.
3876
+ */
3877
+ branches?: RevisionBranch[];
3878
+ /** Controlled set of collapsed branch ids. */
3879
+ collapsedBranchIds?: string[];
3880
+ /** Uncontrolled initial set of collapsed branch ids. */
3881
+ defaultCollapsedBranchIds?: string[];
3882
+ /** Called when a branch is collapsed or expanded. `collapsed` is the NEXT state. */
3883
+ onBranchToggle?: (branchId: string, collapsed: boolean) => void;
3884
+ /**
3885
+ * Trailing summary text on a collapsed branch row. Defaults to
3886
+ * `"<n> commit(s)"`; override to re-vocabulary the timeline (e.g. `"<n> steps"`
3887
+ * when modelling a process flow rather than git history).
3888
+ */
3889
+ formatBranchSummary?: (count: number, branch: RevisionBranch) => string;
3890
+ }
3891
+ /**
3892
+ * RevisionTimeline — presentational git-history timeline.
3893
+ *
3894
+ * Renders revisions in a scrollable list with:
3895
+ * - Day grouping (collapsible via `groupBy`)
3896
+ * - SVG branch-graph lanes + merge joins in the left gutter
3897
+ * - Churn indicators, ref chips, author, SHA, timestamp
3898
+ * - Accessible selection (real `<button>` elements in an `<ol>`)
3899
+ *
3900
+ * Self-contained: no required Provider ancestor. Use `selectedId` +
3901
+ * `onSelect` for controlled selection, or `defaultSelectedId` for uncontrolled.
3902
+ *
3903
+ * Pass `branches` to enable the collapse/expand mode: a branch's commits fold
3904
+ * into a single summary row at its tip (multi-level via `parentBranchId`).
3905
+ */
3906
+ declare const RevisionTimeline: react.ForwardRefExoticComponent<RevisionTimelineProps & react.RefAttributes<HTMLDivElement>>;
3907
+
3908
+ type TimelineRootProps = HTMLAttributes<HTMLOListElement>;
3909
+ /** The `<ol>` that owns the rail geometry; compose `TimelineItem`s inside. */
3910
+ declare const TimelineRoot: react.ForwardRefExoticComponent<TimelineRootProps & react.RefAttributes<HTMLOListElement>>;
3911
+ interface TimelineItemProps extends LiHTMLAttributes<HTMLLIElement> {
3912
+ /** The canonical execution status (closed 7-state enum, status-badge #189). */
3913
+ status?: Status;
3914
+ /** Right-aligned meta (e.g. a date) on the title row. */
3915
+ timestamp?: ReactNode;
3916
+ /** Secondary line under the title. */
3917
+ description?: ReactNode;
3918
+ /**
3919
+ * Rich block content under the title/description, indented with the rail —
3920
+ * the slot composing consumers (e.g. `@elabs-ai/components-ai`'s `AgentStep`, #192)
3921
+ * interleave per node. Block-level, so it must NOT ride the inline title
3922
+ * slot (`children`).
3923
+ */
3924
+ detail?: ReactNode;
3925
+ }
3926
+ /**
3927
+ * One `<li>`: status node + connector + the title row; `children` is the
3928
+ * title slot. The connector hides itself on the last item via CSS
3929
+ * (`group-last`), so streaming/compound consumers never track "is last".
3930
+ */
3931
+ declare const TimelineItem: react.ForwardRefExoticComponent<TimelineItemProps & react.RefAttributes<HTMLLIElement>>;
3932
+ /**
3933
+ * One step of the array-API `Timeline` (the editor's original item shape —
3934
+ * re-exported by `@elabs-ai/components-editor` as `TimelineItem` for back-compat).
3935
+ */
3936
+ interface TimelineEntry {
3937
+ title: ReactNode;
3938
+ description?: ReactNode;
3939
+ /** The editor's 3-state vocabulary; mapped in via `fromTimelineStatus`. */
3940
+ status?: TimelineStatus;
3941
+ timestamp?: ReactNode;
3942
+ }
3943
+ interface TimelineProps extends HTMLAttributes<HTMLOListElement> {
3944
+ items: TimelineEntry[];
3945
+ }
3946
+ /** Array convenience over the compound parts (data in, list out). */
3947
+ declare const Timeline: react.ForwardRefExoticComponent<TimelineProps & react.RefAttributes<HTMLOListElement>>;
3948
+
3949
+ declare const toggleVariants: (props?: ({
3950
+ variant?: "default" | "outline" | "segmented" | null | undefined;
3951
+ size?: "default" | "sm" | "lg" | null | undefined;
3952
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3953
+ declare const Toggle: react.ForwardRefExoticComponent<Omit<TogglePrimitive.ToggleProps & react.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
3954
+ variant?: "default" | "outline" | "segmented" | null | undefined;
3955
+ size?: "default" | "sm" | "lg" | null | undefined;
3956
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLButtonElement>>;
3957
+
3958
+ type ToggleVariantProps = VariantProps<typeof toggleVariants>;
3959
+ declare const ToggleGroup: react.ForwardRefExoticComponent<(ComponentPropsWithoutRef<react.ForwardRefExoticComponent<(ToggleGroupPrimitive.ToggleGroupSingleProps | ToggleGroupPrimitive.ToggleGroupMultipleProps) & react.RefAttributes<HTMLDivElement>>> & ToggleVariantProps) & react.RefAttributes<HTMLDivElement>>;
3960
+ declare const ToggleGroupItem: react.ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & react.RefAttributes<HTMLButtonElement>, "ref"> & ToggleVariantProps & react.RefAttributes<HTMLButtonElement>>;
3961
+
3962
+ declare const toolbarVariants: (props?: ({
3963
+ orientation?: "horizontal" | "vertical" | null | undefined;
3964
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
3965
+ interface ToolbarProps extends Omit<ComponentPropsWithoutRef<typeof ToolbarPrimitive.Root>, "orientation">, VariantProps<typeof toolbarVariants> {
3966
+ /**
3967
+ * What this toolbar acts on ("Document", "Formatting"). A toolbar is one tab
3968
+ * stop with several controls inside it, so without a name a screen-reader
3969
+ * user lands on an anonymous group — hence required, not optional.
3970
+ */
3971
+ "aria-label": string;
3972
+ }
3973
+ /**
3974
+ * The row shell. Renders no surface of its own: a toolbar sits ON something
3975
+ * (a card header, a document frame) and inherits that surface, so painting a
3976
+ * background here would double the fill wherever it is placed.
3977
+ */
3978
+ declare const Toolbar: react.ForwardRefExoticComponent<ToolbarProps & react.RefAttributes<HTMLDivElement>>;
3979
+ interface ToolbarButtonProps extends ComponentPropsWithoutRef<typeof ToolbarPrimitive.Button>, Pick<VariantProps<typeof buttonVariants>, "variant" | "size"> {
3980
+ }
3981
+ /**
3982
+ * A control inside the toolbar. Styled with `buttonVariants` — the same ink,
3983
+ * heights and focus ring as every other button in the system, not a parallel
3984
+ * set. Icon-only controls take `size="icon-sm"` and MUST carry an `aria-label`;
3985
+ * wrap in a `Tooltip` when the glyph needs a name on screen too.
3986
+ */
3987
+ declare const ToolbarButton: react.ForwardRefExoticComponent<ToolbarButtonProps & react.RefAttributes<HTMLButtonElement>>;
3988
+ type ToolbarSeparatorProps = ComponentPropsWithoutRef<typeof ToolbarPrimitive.Separator>;
3989
+ /**
3990
+ * The divider between two groups of controls. It is the ONLY cue between two
3991
+ * same-fill regions of the row, so it takes the strong rung (WCAG 1.4.11,
3992
+ * ADR 0010) — `Separator`'s subtle default would be a decorative hairline here.
3993
+ */
3994
+ declare const ToolbarSeparator: react.ForwardRefExoticComponent<Omit<ToolbarPrimitive.ToolbarSeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
3995
+ type ToolbarToggleGroupProps = ComponentPropsWithoutRef<typeof ToolbarPrimitive.ToggleGroup>;
3996
+ /** A set of mutually-exclusive or multi-select toggles (a view switcher, bold/italic). */
3997
+ declare const ToolbarToggleGroup: react.ForwardRefExoticComponent<ToolbarToggleGroupProps & react.RefAttributes<HTMLDivElement>>;
3998
+ interface ToolbarToggleItemProps extends ComponentPropsWithoutRef<typeof ToolbarPrimitive.ToggleItem>, Pick<VariantProps<typeof toggleVariants>, "size"> {
3999
+ }
4000
+ /** One toggle. Shares `Toggle`'s pressed styling, so state reads the same everywhere. */
4001
+ declare const ToolbarToggleItem: react.ForwardRefExoticComponent<ToolbarToggleItemProps & react.RefAttributes<HTMLButtonElement>>;
4002
+ /**
4003
+ * An escape hatch for anything the parts above do not cover — a `Select`, an
4004
+ * input, a `DropdownMenu` trigger. `asChild` hands the roving-tabindex wiring to
4005
+ * whatever you render, so the control stays part of the arrow-key sequence
4006
+ * instead of becoming a second tab stop inside a single-tab-stop row.
4007
+ */
4008
+ declare const ToolbarSlot: react.ForwardRefExoticComponent<ToolbarPrimitive.ToolbarButtonProps & react.RefAttributes<HTMLButtonElement>>;
4009
+
4010
+ interface TopNavProps extends HTMLAttributes<HTMLElement> {
4011
+ /** Left slot (brand on mobile, breadcrumbs, title). */
4012
+ start?: ReactNode;
4013
+ /** Right slot (search, actions, account menu). */
4014
+ end?: ReactNode;
4015
+ }
4016
+ /** Application top bar. Sticky, single row, brand-neutral. */
4017
+ declare const TopNav: react.ForwardRefExoticComponent<TopNavProps & react.RefAttributes<HTMLElement>>;
4018
+
4019
+ interface TransferItem {
4020
+ value: string;
4021
+ label: ReactNode;
4022
+ disabled?: boolean;
4023
+ }
4024
+ interface TransferProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
4025
+ /** Full data set. Source = items NOT in target; target = items IN target. */
4026
+ dataSource: TransferItem[];
4027
+ /** Controlled: values in the RIGHT (target) list. */
4028
+ targetKeys?: string[];
4029
+ /** Uncontrolled initial target keys. */
4030
+ defaultTargetKeys?: string[];
4031
+ /** Called whenever the target key-set changes. */
4032
+ onChange?: (targetKeys: string[]) => void;
4033
+ /** Show per-panel search input. @default false */
4034
+ showSearch?: boolean;
4035
+ /** Panel titles. @default ["Source", "Target"] */
4036
+ titles?: [ReactNode, ReactNode];
4037
+ /** Custom row renderer. @default (item) => item.label */
4038
+ renderItem?: (item: TransferItem) => ReactNode;
4039
+ className?: string;
4040
+ }
4041
+ declare const Transfer: react.ForwardRefExoticComponent<TransferProps & react.RefAttributes<HTMLDivElement>>;
4042
+
4043
+ interface TreeNode<T = unknown> {
4044
+ id: string;
4045
+ label: ReactNode;
4046
+ children?: TreeNode<T>[];
4047
+ /**
4048
+ * Marks a node as expandable even when `children` is not yet loaded.
4049
+ * A node with `hasChildren: true` and no `children` array will show the
4050
+ * expand affordance. Calling `loadChildren` will populate its children.
4051
+ */
4052
+ hasChildren?: boolean;
4053
+ disabled?: boolean;
4054
+ icon?: ReactNode;
4055
+ /**
4056
+ * Optional trailing content rendered after the label — e.g. a size or
4057
+ * token-count badge (#369). Rendered as a SIBLING of the label and kept out
4058
+ * of the row's accessible name: a string `label` names the row via
4059
+ * `aria-label`, a `ReactNode` label names it via `aria-labelledby` pointing
4060
+ * at the label span only, so the accessory text never joins either.
4061
+ *
4062
+ * The slot is isolated from the row: click, keydown and focus are stopped at
4063
+ * the accessory, so it never selects/expands the row, never lets the tree's
4064
+ * roving-tabindex handler swallow its keys, and never has focus yanked back
4065
+ * to the row. Interactive content (a button, a link) therefore works and is
4066
+ * independently focusable in normal tab order; the row's own keyboard
4067
+ * navigation (arrow keys, Enter/Space) is unaffected while the row is focused.
4068
+ */
4069
+ accessory?: ReactNode;
4070
+ data?: T;
4071
+ }
4072
+ interface TreeProps<T = unknown> extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> {
4073
+ nodes: TreeNode<T>[];
4074
+ /** Controlled expanded ids */
4075
+ expandedIds?: string[];
4076
+ /** Uncontrolled initial expanded ids */
4077
+ defaultExpandedIds?: string[];
4078
+ onExpandedChange?: (ids: string[]) => void;
4079
+ /** "single" | "multiple" | "none" — default "single" */
4080
+ selectionMode?: "single" | "multiple" | "none";
4081
+ /** Controlled selected ids */
4082
+ selectedIds?: string[];
4083
+ /** Uncontrolled initial selected ids */
4084
+ defaultSelectedIds?: string[];
4085
+ onSelectionChange?: (ids: string[]) => void;
4086
+ /** Show checkboxes for multi-selection affordance — default false */
4087
+ checkboxes?: boolean;
4088
+ /**
4089
+ * The surface on which the tree is rendered.
4090
+ * - `"default"` (default) — renders selected rows with `bg-accent` (for use on
4091
+ * background/card surfaces).
4092
+ * - `"sidebar"` — renders selected rows with the sidebar's own active-item
4093
+ * treatment (`bg-sidebar-accent` + `text-sidebar-accent-foreground` +
4094
+ * `font-medium`), so selection reads consistently with `SidebarMenuButton`'s
4095
+ * active state on the `--sidebar` surface. (No fill is ≥3:1 on a sidebar;
4096
+ * perceivability comes from the foreground/weight shift + `aria-selected`,
4097
+ * the same multi-cue approach the Sidebar uses.)
4098
+ */
4099
+ surface?: "default" | "sidebar";
4100
+ /**
4101
+ * Enable windowed rendering for large trees (>50 visible rows).
4102
+ * When `true`, only the visible slice of the flattened tree is mounted in
4103
+ * the DOM. Requires a bounded scroll container — either via `maxHeight` or
4104
+ * by sizing the root element externally with `overflow-auto`.
4105
+ * Default: `false` (backward-compatible nested-group DOM).
4106
+ */
4107
+ virtualize?: boolean;
4108
+ /** Estimated row height in px used by the virtualizer. Default 32. */
4109
+ estimateRowHeight?: number;
4110
+ /** Number of extra rows to render beyond the visible window. Default 8. */
4111
+ overscan?: number;
4112
+ /**
4113
+ * CSS max-height for the scroll viewport when `virtualize` is true.
4114
+ * E.g. `"400px"` or `"60vh"`. When omitted the root div must be sized by
4115
+ * the caller (e.g. via `className="h-96 overflow-auto"`).
4116
+ */
4117
+ maxHeight?: number | string;
4118
+ /**
4119
+ * Scroll the node with this id into view when the value CHANGES. Reveals a
4120
+ * node selected programmatically (via `selectedIds`) that is windowed out of
4121
+ * the DOM in `virtualize` mode (or below the fold), so the tree shows "where
4122
+ * I am", not just structure. Expands the node's (loaded) ancestors and kicks
4123
+ * their lazy `loadChildren` as needed, then centers the node. Independent of
4124
+ * keyboard focus (keyboard nav's own scroll is unchanged).
4125
+ */
4126
+ scrollToId?: string;
4127
+ /**
4128
+ * When `true`, reveal the newly-selected controlled node (the id added to
4129
+ * `selectedIds`) into view — the selection-driven equivalent of `scrollToId`.
4130
+ * `scrollToId` wins when both are set.
4131
+ */
4132
+ scrollSelectionIntoView?: boolean;
4133
+ /**
4134
+ * Async function called when a node with `hasChildren: true` (and no
4135
+ * loaded `children`) is expanded for the first time. The returned nodes
4136
+ * are merged into the internal tree state and cached so re-expanding the
4137
+ * node does not re-fetch.
4138
+ */
4139
+ loadChildren?: (node: TreeNode<T>) => Promise<TreeNode<T>[]>;
4140
+ className?: string;
4141
+ }
4142
+ declare const Tree: <T = unknown>(props: TreeProps<T> & {
4143
+ ref?: React.Ref<HTMLDivElement>;
4144
+ }) => React.ReactElement | null;
4145
+
4146
+ interface UseTreeKeyboardOptions<T> {
4147
+ nodes: TreeNode<T>[];
4148
+ expandedIds: Set<string>;
4149
+ onExpandedChange: (ids: Set<string>) => void;
4150
+ selectionMode: "single" | "multiple" | "none";
4151
+ selectedIds: Set<string>;
4152
+ onSelectionChange: (ids: Set<string>) => void;
4153
+ /**
4154
+ * When `true`, the tree uses windowed rendering. Focus navigation must
4155
+ * scroll the virtualizer before focusing an unmounted row.
4156
+ */
4157
+ virtualize?: boolean;
4158
+ /**
4159
+ * Ordered list of visible node ids in the virtual flat list. Provided by
4160
+ * the Tree when `virtualize` is true so the keyboard hook can map an id to
4161
+ * a virtual index without re-flattening.
4162
+ */
4163
+ flatNodeIds?: string[];
4164
+ /**
4165
+ * Ref that the keyboard hook writes a node id into when it needs to focus a
4166
+ * row that is currently scrolled out of view. The Tree's `registerAndFlush`
4167
+ * callback reads this ref on every ref registration and focuses the element
4168
+ * once it mounts.
4169
+ */
4170
+ pendingFocusIdRef?: React.MutableRefObject<string | null>;
4171
+ /**
4172
+ * Called when the keyboard hook wants to bring an index into view before
4173
+ * focusing it. Only called in virtual mode.
4174
+ */
4175
+ scrollToVirtualIndex?: (index: number) => void;
4176
+ }
4177
+ interface UseTreeKeyboardResult {
4178
+ activeId: string | null;
4179
+ setActiveId: (id: string | null) => void;
4180
+ /** ref callback — register each tree item element keyed by node id */
4181
+ registerNodeRef: (id: string, el: HTMLElement | null) => void;
4182
+ /** onKeyDown handler to attach to the root tree div */
4183
+ onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => void;
4184
+ }
4185
+ declare function useTreeKeyboard<T>(options: UseTreeKeyboardOptions<T>): UseTreeKeyboardResult;
4186
+
4187
+ interface TreeSelectProps<T = unknown> extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "value" | "onChange"> {
4188
+ nodes: TreeNode<T>[];
4189
+ /** Controlled value — `string` in single mode, `string[]` in multiple mode. */
4190
+ value?: string | string[];
4191
+ /** Uncontrolled initial value. */
4192
+ defaultValue?: string | string[];
4193
+ onValueChange?: (value: string | string[]) => void;
4194
+ /** Allow selecting multiple nodes (checkbox tree). Default false. */
4195
+ multiple?: boolean;
4196
+ placeholder?: string;
4197
+ className?: string;
4198
+ }
4199
+ /**
4200
+ * A select whose options are a hierarchical {@link Tree}. Single or multiple
4201
+ * selection; composes `Tree` for all keyboard/SR behaviour.
4202
+ */
4203
+ declare const TreeSelect: <T = unknown>(props: TreeSelectProps<T> & {
4204
+ ref?: React.Ref<HTMLButtonElement>;
4205
+ }) => React.ReactElement | null;
4206
+
4207
+ /**
4208
+ * The role font sizes in rem — a TS mirror of the `--text-<role>` tokens
4209
+ * (packages/tokens/src/themes.css) for consumers that need the numbers at
4210
+ * runtime (e.g. @elabs-ai/components-editor's markdown-scale CSS-var seam). Edit the tokens
4211
+ * first; typography.test.tsx pins this mirror to themes.css.
4212
+ */
4213
+ declare const TEXT_ROLE_REM: {
4214
+ readonly display: 1.875;
4215
+ readonly title: 1.25;
4216
+ readonly subtitle: 1;
4217
+ readonly body: 0.875;
4218
+ readonly caption: 0.8125;
4219
+ readonly meta: 0.75;
4220
+ readonly kpi: 2;
4221
+ readonly code: 0.8125;
4222
+ };
4223
+ type TextRole = keyof typeof TEXT_ROLE_REM;
4224
+ declare const textVariants: (props?: ({
4225
+ variant?: "body" | "caption" | "meta" | "kpi" | "code" | "lead" | null | undefined;
4226
+ tone?: "default" | "primary" | "muted" | null | undefined;
4227
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
4228
+ type TextVariant = NonNullable<VariantProps<typeof textVariants>["variant"]>;
4229
+ type TextTone = NonNullable<VariantProps<typeof textVariants>["tone"]>;
4230
+ interface TextProps extends HTMLAttributes<HTMLParagraphElement>, VariantProps<typeof textVariants> {
4231
+ /** Render as a different element. Defaults to "p". */
4232
+ as?: "p" | "span" | "div";
4233
+ /** Render the child element as the text root (Radix Slot) instead. */
4234
+ asChild?: boolean;
4235
+ }
4236
+ declare const Text: react.ForwardRefExoticComponent<TextProps & react.RefAttributes<HTMLParagraphElement>>;
4237
+ type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
4238
+ declare const headingVariants: (props?: ({
4239
+ size?: "display" | "title" | "subtitle" | null | undefined;
4240
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
4241
+ type HeadingSize = NonNullable<VariantProps<typeof headingVariants>["size"]>;
4242
+ interface HeadingProps extends HTMLAttributes<HTMLHeadingElement>, VariantProps<typeof headingVariants> {
4243
+ /** Semantic heading level — drives the rendered tag AND the default size. */
4244
+ level?: HeadingLevel;
4245
+ /** Render the child element as the heading root (Radix Slot) instead. */
4246
+ asChild?: boolean;
4247
+ }
4248
+ /**
4249
+ * `level` keeps the a11y heading order; `size` overrides the visual rung
4250
+ * independently, so a visually-small `<h2>` stays an `<h2>`.
4251
+ */
4252
+ declare const Heading: react.ForwardRefExoticComponent<HeadingProps & react.RefAttributes<HTMLHeadingElement>>;
4253
+
4254
+ type ProseHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
4255
+ /**
4256
+ * Canonical reading-scale heading sizes in rem — the single source the markdown
4257
+ * WYSIWYG editor derives its CSS vars from (@elabs-ai/components-editor `markdown-scale`).
4258
+ * h2/h4/h5/h6 sit exactly on the title/subtitle/body roles; h1 (1.5rem) and
4259
+ * h3 (1.125rem) are intermediate reading rungs with no app role.
4260
+ */
4261
+ declare const PROSE_HEADING_REM: Record<ProseHeadingLevel, number>;
4262
+ /** Canonical prose heading weight (Tailwind `font-semibold`). */
4263
+ declare const PROSE_HEADING_WEIGHT = 600;
4264
+ /** Canonical prose heading letter-spacing (Tailwind `tracking-tight`). */
4265
+ declare const PROSE_HEADING_TRACKING = "-0.025em";
4266
+ interface ProseHeadingProps extends HTMLAttributes<HTMLHeadingElement> {
4267
+ level?: ProseHeadingLevel;
4268
+ }
4269
+ declare const ProseHeading: react.ForwardRefExoticComponent<ProseHeadingProps & react.RefAttributes<HTMLHeadingElement>>;
4270
+ declare const TEXT_VARIANT: {
4271
+ readonly body: "text-body leading-relaxed text-foreground";
4272
+ readonly muted: "text-body leading-relaxed text-muted-foreground";
4273
+ readonly lead: "text-subtitle font-normal leading-relaxed text-foreground";
4274
+ readonly small: "text-meta font-normal text-muted-foreground";
4275
+ };
4276
+ interface ProseTextProps extends HTMLAttributes<HTMLParagraphElement> {
4277
+ variant?: keyof typeof TEXT_VARIANT;
4278
+ /** Render as a different element (e.g. "span"). Defaults to "p". */
4279
+ as?: "p" | "span" | "div";
4280
+ }
4281
+ declare const ProseText: react.ForwardRefExoticComponent<ProseTextProps & react.RefAttributes<HTMLParagraphElement>>;
4282
+ interface ProseLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
4283
+ /** Opens in a new tab with safe rel. Auto-detected for http(s) hrefs when unset. */
4284
+ external?: boolean;
4285
+ }
4286
+ declare const ProseLink: react.ForwardRefExoticComponent<ProseLinkProps & react.RefAttributes<HTMLAnchorElement>>;
4287
+ interface ProseListProps extends OlHTMLAttributes<HTMLElement> {
4288
+ ordered?: boolean;
4289
+ }
4290
+ declare const ProseList: react.ForwardRefExoticComponent<ProseListProps & react.RefAttributes<HTMLUListElement & HTMLOListElement>>;
4291
+ declare const ProseListItem: react.ForwardRefExoticComponent<HTMLAttributes<HTMLLIElement> & react.RefAttributes<HTMLLIElement>>;
4292
+ declare const ProseBlockquote: react.ForwardRefExoticComponent<HTMLAttributes<HTMLQuoteElement> & react.RefAttributes<HTMLQuoteElement>>;
4293
+ declare const ProseInlineCode: react.ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & react.RefAttributes<HTMLElement>>;
4294
+
4295
+ interface ViewToolbarProps extends HTMLAttributes<HTMLDivElement> {
4296
+ /**
4297
+ * What this view is, as a tooltip on an ⓘ trigger at the start of the row —
4298
+ * so a view does not need an in-page `<h1>` + paragraph block just to explain
4299
+ * itself. Omit it when the surrounding page already says what the view is.
4300
+ *
4301
+ * **Pointer/keyboard only.** A Radix tooltip opens on hover and on keyboard
4302
+ * focus but deliberately NOT on tap (and Radix suppresses the focus-open when
4303
+ * focus arrived from a pointer), so on a touch device this text is
4304
+ * unreachable. Treat `info` as progressive enhancement: never put something a
4305
+ * phone user cannot do without in it. See `Docs/View Toolbar Contract`.
4306
+ */
4307
+ info?: ReactNode;
4308
+ /** Left cluster — status/context, `ViewToolbarFilters`, `ResultCount`. */
4309
+ children?: ReactNode;
4310
+ /** Right cluster — the view's actions. Stays reachable at every width. */
4311
+ actions?: ReactNode;
4312
+ }
4313
+ declare const ViewToolbar: react.ForwardRefExoticComponent<ViewToolbarProps & react.RefAttributes<HTMLDivElement>>;
4314
+ interface ViewToolbarFiltersProps extends HTMLAttributes<HTMLDivElement> {
4315
+ /**
4316
+ * Clear every active filter. Supplying it renders the "clear all" affordance
4317
+ * at the end of the chip run; omit it when a view has no bulk reset.
4318
+ */
4319
+ onClearAll?: () => void;
4320
+ }
4321
+ /**
4322
+ * The chip run. Render it ONLY when at least one filter is active — the
4323
+ * "no filters applied" state is the region's ABSENCE, not an empty box.
4324
+ *
4325
+ * Runs at chip height (24px) so the whole group reads as one control rung; the
4326
+ * `actions` cluster runs at button height. That split is the fix for the
4327
+ * control-height scatter #331 measured.
4328
+ */
4329
+ declare const ViewToolbarFilters: react.ForwardRefExoticComponent<ViewToolbarFiltersProps & react.RefAttributes<HTMLDivElement>>;
4330
+ interface FilterChipProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
4331
+ /**
4332
+ * Label-in-value text — `"Status: Failed"`, never `"Status = failed"` and
4333
+ * never a bare `"Failed"`. The caller composes the string so the chip reads
4334
+ * as a sentence fragment out of context (and in a screen reader).
4335
+ */
4336
+ label: string;
4337
+ /** Remove this filter. The WHOLE chip is the remove control — see below. */
4338
+ onRemove: () => void;
4339
+ }
4340
+ /**
4341
+ * A removable active-filter chip.
4342
+ *
4343
+ * The whole chip is a single `<button>` whose action is "remove", rather than a
4344
+ * span with a nested ✕: one tab stop instead of two, a ≥24px target (WCAG 2.5.8)
4345
+ * with no dead zone, and Enter/Space for free from the native element. Its
4346
+ * accessible name is "Remove filter: <label>", which CONTAINS the visible label
4347
+ * (WCAG 2.5.3 Label in Name).
4348
+ *
4349
+ * A chip that must EDIT a filter rather than remove it is a different control —
4350
+ * reach for `FacetFilter` (`@elabs-ai/components-data`), not a variant of this.
4351
+ */
4352
+ declare const FilterChip: react.ForwardRefExoticComponent<FilterChipProps & react.RefAttributes<HTMLButtonElement>>;
4353
+ interface ResultCountProps extends HTMLAttributes<HTMLSpanElement> {
4354
+ /** How many rows/cards the view is showing right now. */
4355
+ count: number;
4356
+ /**
4357
+ * The unfiltered total. Supplying it renders "N of M" — the honest reading
4358
+ * when a filter is active. Omit it for an unfiltered view's bare count.
4359
+ */
4360
+ total?: number;
4361
+ /**
4362
+ * No count yet. Renders a layout-shaped placeholder instead of a `0` that
4363
+ * lies while the data is in flight (see `.claude/rules/loading-states.md`).
4364
+ */
4365
+ loading?: boolean;
4366
+ /**
4367
+ * Optional trailing noun ("results", "runs", "rows") joined with a
4368
+ * non-breaking space, so the number is never announced bare.
4369
+ */
4370
+ children?: ReactNode;
4371
+ }
4372
+ declare const ResultCount: react.ForwardRefExoticComponent<ResultCountProps & react.RefAttributes<HTMLSpanElement>>;
4373
+
4374
+ interface VirtualSelectOption {
4375
+ label: string;
4376
+ value: string;
4377
+ disabled?: boolean;
4378
+ }
4379
+ interface UseVirtualListboxOptions {
4380
+ count: number;
4381
+ filtered: VirtualSelectOption[];
4382
+ /** Reserved for future use (e.g. multi-select keyboard shortcuts). */
4383
+ multiple?: boolean;
4384
+ isOpen: boolean;
4385
+ onSelect: (value: string) => void;
4386
+ virtualizer: Virtualizer<any, any> | null;
4387
+ }
4388
+ interface UseVirtualListboxReturn {
4389
+ activeIndex: number;
4390
+ setActiveIndex: (index: number) => void;
4391
+ onInputKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
4392
+ }
4393
+ /**
4394
+ * Keyboard navigation logic for the VirtualSelect listbox.
4395
+ * Encapsulates ArrowDown/Up/Home/End/Enter/Escape handling.
4396
+ * Focus stays on the search input; `aria-activedescendant` tracks the active row.
4397
+ */
4398
+ declare function useVirtualListbox({ count, filtered, isOpen, onSelect, virtualizer, }: UseVirtualListboxOptions): UseVirtualListboxReturn;
4399
+
4400
+ interface VirtualSelectProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "value" | "onChange" | "defaultValue"> {
4401
+ /** The full option list. Only visible items are rendered in the DOM. */
4402
+ options: VirtualSelectOption[];
4403
+ /** Allow selecting multiple values. Default `false`. */
4404
+ multiple?: boolean;
4405
+ /** Controlled value — `string` in single mode, `string[]` in multiple mode. */
4406
+ value?: string | string[];
4407
+ /** Uncontrolled initial value. */
4408
+ defaultValue?: string | string[];
4409
+ /** Called when the selection changes. Emits `string` (single) or `string[]` (multiple). */
4410
+ onValueChange?: (value: string | string[]) => void;
4411
+ /** Trigger placeholder when nothing is selected. Default "Select…" */
4412
+ placeholder?: string;
4413
+ /** Search-input placeholder. Default "Search…" */
4414
+ searchPlaceholder?: string;
4415
+ /** Empty-state message when no options match the query. Default "No results." */
4416
+ emptyText?: string;
4417
+ /**
4418
+ * Estimated row height used by the virtualizer (px).
4419
+ * Increase for taller rows (e.g. with descriptions). Default 32.
4420
+ */
4421
+ estimateOptionHeight?: number;
4422
+ /**
4423
+ * CSS max-height for the scrollable listbox. Default "18rem".
4424
+ */
4425
+ maxListHeight?: string;
4426
+ className?: string;
4427
+ }
4428
+ /**
4429
+ * VirtualSelect — a combobox that renders only the visible window of options
4430
+ * in the DOM, making it suitable for option lists of 10,000+ items.
4431
+ *
4432
+ * Uses `@tanstack/react-virtual` for windowed rendering and a purpose-built
4433
+ * `aria-activedescendant` keyboard model so focus stays on the search input
4434
+ * while navigating the listbox.
4435
+ */
4436
+ declare const VirtualSelect: react.ForwardRefExoticComponent<VirtualSelectProps & react.RefAttributes<HTMLButtonElement>>;
4437
+
4438
+ interface WizardStepMeta {
4439
+ /** Stable id for the step. */
4440
+ id: string;
4441
+ /** Title shown in the step indicator. */
4442
+ title: string;
4443
+ /** Optional supporting text shown under the title. */
4444
+ description?: string;
4445
+ }
4446
+ /** A step validator — return false (or a rejected/`false` promise) to block advance. */
4447
+ type WizardValidator = () => boolean | Promise<boolean>;
4448
+ declare const wizardVariants: (props?: ({
4449
+ orientation?: "horizontal" | "vertical" | null | undefined;
4450
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
4451
+ interface WizardProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange">, VariantProps<typeof wizardVariants> {
4452
+ /** The ordered step metadata used to render the indicator. */
4453
+ steps: WizardStepMeta[];
4454
+ /** Controlled active step index. */
4455
+ step?: number;
4456
+ /** Uncontrolled initial step index. Default 0. */
4457
+ defaultStep?: number;
4458
+ /** Called whenever the active step changes. */
4459
+ onStepChange?: (step: number) => void;
4460
+ children?: ReactNode;
4461
+ }
4462
+ /**
4463
+ * Wizard — a multi-step flow with a step indicator, per-step validation gating,
4464
+ * and Back/Next/Finish navigation.
4465
+ *
4466
+ * Controlled via `step`/`onStepChange`; uncontrolled via `defaultStep`. State is
4467
+ * lifted into the provider and exposed to `WizardSteps`/`WizardStep`/`WizardNav`
4468
+ * via context. `Next` runs the active step's `validate` (sync or async) before
4469
+ * advancing and stays enabled until validation runs.
4470
+ */
4471
+ declare const Wizard: react.ForwardRefExoticComponent<WizardProps & react.RefAttributes<HTMLDivElement>>;
4472
+ type WizardStepsProps = HTMLAttributes<HTMLOListElement>;
4473
+ /** WizardSteps — the ordered step indicator. Reads steps from context. */
4474
+ declare const WizardSteps: react.ForwardRefExoticComponent<WizardStepsProps & react.RefAttributes<HTMLOListElement>>;
4475
+ interface WizardStepProps extends HTMLAttributes<HTMLDivElement> {
4476
+ /** This step's index (0-based) — must match its position in `steps`. */
4477
+ step: number;
4478
+ /** Run before advancing past this step. Return false to block. */
4479
+ validate?: WizardValidator;
4480
+ }
4481
+ /**
4482
+ * WizardStep — renders its children only when it is the active step, and
4483
+ * registers its `validate` with the wizard while active. Receives focus on
4484
+ * activation for keyboard users.
4485
+ */
4486
+ declare const WizardStep: react.ForwardRefExoticComponent<WizardStepProps & react.RefAttributes<HTMLDivElement>>;
4487
+ interface WizardNavProps extends HTMLAttributes<HTMLDivElement> {
4488
+ backLabel?: string;
4489
+ nextLabel?: string;
4490
+ finishLabel?: string;
4491
+ /** Called when Finish is pressed on the last step. */
4492
+ onFinish?: () => void;
4493
+ }
4494
+ /** WizardNav — Back / Next (or Finish on the last step) controls. */
4495
+ declare const WizardNav: react.ForwardRefExoticComponent<WizardNavProps & react.RefAttributes<HTMLDivElement>>;
4496
+
4497
+ export { ATTRIBUTIONS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AdvancedGroup, type AdvancedGroupProps, Alert, AlertDescription, type AlertDescriptionProps, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, type AlertTitleProps, AppShell, type AppShellProps, AppSidebar, type AppSidebarProps, AspectRatio, type Attribution, type AttributionCategory, AttributionPanel, type AttributionPanelProps, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, BentoGrid, BentoGridItem, type BentoGridItemProps, type BentoGridItemVariants, type BentoGridProps, type BentoGridSize, BoundedNumber, type BoundedNumberProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, type ButtonProps, CATEGORY_LABEL, COLOR_TOKENS, COPY_FEEDBACK_MS, Calendar, type CalendarProps, Card, CardAction, CardContent, CardDescription, type CardDescriptionProps, CardFooter, CardHeader, type CardProps, CardTitle, type CardTitleProps, Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, type ChangeHunk, type ChangeHunkStatus, type ChangeProvenance, ChangeReview, type ChangeReviewActions, ChangeReviewHeader, type ChangeReviewHeaderProps, ChangeReviewHunk, type ChangeReviewHunkProps, ChangeReviewList, type ChangeReviewListProps, type ChangeReviewProps, ChangeReviewProvenance, type ChangeReviewProvenanceProps, ChangeReviewProvider, type ChangeReviewProviderProps, type ChangeReviewState, Checkbox, Collapsible, CollapsibleContent, type CollapsiblePanelAttrs, type CollapsiblePanelSide, type CollapsiblePanelState, CollapsibleTrigger, ColorPicker, type ColorPickerProps, type ColorToken, Combobox, type ComboboxOption, type ComboboxProps, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, type CommandProps, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, type CopyToClipboard, CopyableValue, type CopyableValueProps, type CustomStatus, DEFAULT_MESSAGES, DOCUMENT_ADDRESS_KINDS, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, type DateRangePreset, Descriptions, DescriptionsItem, type DescriptionsItemProps, type DescriptionsProps, Dialog, DialogBody, type DialogBodyProps, DialogClose, DialogContent, DialogDescription, type DialogDismissGuard, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogSection, type DialogSectionProps, DialogTitle, DialogTrigger, type DocumentAddress, type DocumentAddressKind, type DocumentRect, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, ExpandDialog, ExpandDialogContent, type ExpandDialogContentProps, ExpandDialogHeader, type ExpandDialogHeaderProps, ExpandDialogPanes, type ExpandDialogPanesProps, type ExpandDialogProps, FILE_CATEGORY_ICONS, FieldRow, type FieldRowProps, type FileCategory, type FileKind, type FileSource, FileUpload, FileUploadDropzone, type FileUploadDropzoneProps, FileUploadItem, type FileUploadItemProps, FileUploadList, type FileUploadListProps, type FileUploadProps, type FileUploadStatus, FilterChip, type FilterChipProps, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Heading, type HeadingLevel, type HeadingProps, type HeadingSize, HoverCard, HoverCardContent, HoverCardTrigger, IconButton, type IconButtonProps, type IconButtonSize, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, type InputGroupProps, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, type InsertMentionResult, Kbd, KeyValueEditor, type KeyValueEditorProps, type KeyValueRow, Label, LinkPreview, LinkPreviewCard, type LinkPreviewCardProps, ListEditor, type ListEditorProps, LoadingState, type LoadingStateProps, type LocaleContextValue, LocaleProvider, type LocaleProviderProps, MatchHighlight, type MatchHighlightProps, type MatchRange, type Mention, MentionInput, MentionInputContent, type MentionInputContentProps, type MentionInputContextValue, MentionInputEmpty, type MentionInputEmptyProps, MentionInputItem, type MentionInputItemProps, MentionInputList, type MentionInputListProps, type MentionInputProps, MentionInputTextarea, type MentionInputTextareaProps, type MentionOption, type MentionValue, Menubar, MenubarCheckboxItem, MenubarContent, MenubarItem, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, type Messages, MetricCard, type MetricCardEmphasis, type MetricCardProps, ModelPicker, type ModelPickerBody, type ModelPickerGroup, type ModelPickerItem, type ModelPickerProps, type ModelPickerStatus, NavMain, type NavMainProps, type NavMainRoute, type NavMainSubItem, type NavNotification, NavNotifications, type NavNotificationsProps, NavUser, type NavUserProps, type NavUserUser, NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, type NormalizedText, NumberInput, type NumberInputProps, PROSE_HEADING_REM, PROSE_HEADING_TRACKING, PROSE_HEADING_WEIGHT, PageShell, type PageShellProps, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, type ProgressProps, ProseBlockquote, ProseHeading, type ProseHeadingLevel, type ProseHeadingProps, ProseInlineCode, ProseLink, type ProseLinkProps, ProseList, ProseListItem, type ProseListProps, ProseText, type ProseTextProps, type QuoteAddress, RadioGroup, RadioGroupItem, type RangeAddress, Rating, type RatingProps, type RectAddress, ResizableHandle, ResizablePanel, ResizablePanelGroup, type ResolvedFileSource, ResultCount, type ResultCountProps, Reveal, RevealGroup, type RevealGroupProps, type RevealProps, type Revision, type RevisionBranch, type RevisionEdge, RevisionTimeline, type RevisionTimelineDensity, type RevisionTimelineProps, STATUSES, STATUS_LABELS, STATUS_ROLE, STATUS_TONES, STATUS_TONE_ICONS, STREAMDOWN_TRANSLATION_KEYS, ScrollArea, ScrollBar, SectionHeader, type SectionHeaderProps, SegmentedField, type SegmentedFieldOption, type SegmentedFieldProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, type SeparatorProps, Sheet, SheetClose, SheetContent, type SheetContentProps, SheetDescription, SheetFooter, SheetHeader, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, type SkeletonProps, Slider, SliderNumber, type SliderNumberProps, type SliderProps, type SliderThumbProps, Spinner, type SpinnerProps, SplitPanel, type SplitPanelProps, type SplitPanelTone, StatePanel, type StatePanelProps, type Status, StatusBadge, type StatusBadgeProps, StatusIcon, type StatusIconProps, type StatusTone, type StreamdownTranslationKey, type StreamdownTranslationMap, Switch, TEXT_ROLE_REM, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagInput, type TagInputProps, TeamSwitcher, type TeamSwitcherProps, type TeamSwitcherTeam, Text, type TextProps, type TextRole, type TextTone, type TextVariant, Textarea, type TextareaProps, type ThemePreference, ThemeSwitcher, type ThemeSwitcherProps, type ThemeTransitionEffect, Timeline, type TimelineEntry, TimelineItem, type TimelineItemProps, type TimelineProps, TimelineRoot, type TimelineRootProps, type TimelineStatus, Toaster, type ToasterProps, Toggle, ToggleGroup, ToggleGroupItem, Toolbar, ToolbarButton, type ToolbarButtonProps, type ToolbarProps, ToolbarSeparator, type ToolbarSeparatorProps, ToolbarSlot, ToolbarToggleGroup, type ToolbarToggleGroupProps, ToolbarToggleItem, type ToolbarToggleItemProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopNav, type TopNavProps, Transfer, type TransferItem, type TransferProps, Tree, type TreeNode, type TreeProps, TreeSelect, type TreeSelectProps, type UploadFile, type UseCollapsiblePanelOptions, type UseCollapsiblePanelReturn, type UseCopyToClipboardOptions, type UseDialogDismissGuardOptions, type UseTreeKeyboardOptions, type UseTreeKeyboardResult, ViewToolbar, ViewToolbarFilters, type ViewToolbarFiltersProps, type ViewToolbarProps, VirtualSelect, type VirtualSelectOption, type VirtualSelectProps, Wizard, WizardNav, type WizardNavProps, type WizardProps, WizardStep, type WizardStepMeta, type WizardStepProps, WizardSteps, type WizardStepsProps, type WizardValidator, alertVariants, badgeVariants, bentoGridItemVariants, buttonGroupVariants, buttonVariants, cardVariants, cn, countItems, defaultMentionFilter, dialogContentVariants, downloadBlob, downloadUrl, expandDialogPanesVariants, extensionOf, fileIconFor, fromTimelineStatus, headingVariants, hunkVariants, inputGroupAddonVariants, inputGroupVariants, insertMention, isCustomStatus, laneColor, mediaTypeFromName, mentionAt, mentionEnd, modelPickerBody, navigationMenuTriggerStyle, normalizeFileSource, normalizeQuoteText, normalizeQuoteTextWithOffsets, normalizeRanges, progressIndicatorVariants, queryToRanges, remapMentions, resolveFileKind, revealVariants, revisionTimelineVariants, serializeMentions, showsInlineError, sidebarMenuButtonVariants, statePanelVariants, statusBadgeVariants, textVariants, toggleVariants, toolbarVariants, useCollapsiblePanel, useCommandActiveItemId, useCopyToClipboard, useDialogDismissGuard, useFileUpload, useFormField, useIsMobile, useLocale, useMentionInput, useSidebar, useStreamdownTranslations, useThemeTransition, useTreeKeyboard, useVirtualListbox };