@digithings-ai/ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/README.md +48 -2
  2. package/package.json +143 -4
  3. package/src/components/NavShell.tsx +776 -0
  4. package/src/components/SocialRow.tsx +87 -0
  5. package/src/components/Spinner.tsx +27 -0
  6. package/src/components/StackLogo.tsx +40 -0
  7. package/src/components/Terminal.tsx +110 -0
  8. package/src/components/TerminalManifest.tsx +212 -0
  9. package/src/components/ThemeProvider.tsx +271 -0
  10. package/src/components/account/AuthCard.tsx +309 -0
  11. package/src/components/assistant-ui/elements/mermaid-diagram.aui.tsx +63 -0
  12. package/src/components/assistant-ui/elements/mermaid-diagram.tsx +340 -0
  13. package/src/components/brand/BrandWordmark.tsx +32 -0
  14. package/src/components/changelog/ReleaseRail.tsx +81 -0
  15. package/src/components/changelog/index.ts +1 -0
  16. package/src/components/chat/ChatCodeBlock.tsx +67 -0
  17. package/src/components/chat/ChatMarkdown.tsx +66 -0
  18. package/src/components/chat/ChatMarkdownSource.tsx +203 -0
  19. package/src/components/chat/ChatMermaidBlock.tsx +202 -0
  20. package/src/components/chat/ChatMessage.tsx +77 -0
  21. package/src/components/chat/ChatPlayback.tsx +422 -0
  22. package/src/components/chat/ChatStreamCursor.tsx +25 -0
  23. package/src/components/chat/ChatThinking.tsx +113 -0
  24. package/src/components/chat/ChatToolCall.tsx +190 -0
  25. package/src/components/chat/ChatTranscript.tsx +60 -0
  26. package/src/components/chat/ChatWidgetFrame.tsx +107 -0
  27. package/src/components/chat/DigichatBootLoader.tsx +683 -0
  28. package/src/components/chat/DigichatLauncher.tsx +361 -0
  29. package/src/components/chat/DigichatThread.tsx +118 -0
  30. package/src/components/chat/DigichatThreadList.tsx +54 -0
  31. package/src/components/chat/DigichatWordmark.tsx +24 -0
  32. package/src/components/chat/DotMatrix.tsx +650 -0
  33. package/src/components/chat/boot-lab.tsx +766 -0
  34. package/src/components/chat/boot-signal.ts +144 -0
  35. package/src/components/chat/chat-surfaces.ts +52 -0
  36. package/src/components/chat/connection-status.ts +40 -0
  37. package/src/components/chat/digichat-wordmark.ts +355 -0
  38. package/src/components/chat/disclosure-chevron.tsx +49 -0
  39. package/src/components/chat/followable-href.ts +9 -0
  40. package/src/components/chat/gallery-thread/action-icons.tsx +25 -0
  41. package/src/components/chat/gallery-thread/attachment.aui.tsx +262 -0
  42. package/src/components/chat/gallery-thread/block-caret.tsx +439 -0
  43. package/src/components/chat/gallery-thread/cn.ts +1 -0
  44. package/src/components/chat/gallery-thread/composer-keyboard.ts +106 -0
  45. package/src/components/chat/gallery-thread/composer-trigger-popover.aui.tsx +235 -0
  46. package/src/components/chat/gallery-thread/css.d.ts +6 -0
  47. package/src/components/chat/gallery-thread/file.tsx +238 -0
  48. package/src/components/chat/gallery-thread/follow-up-suggestions.aui.tsx +92 -0
  49. package/src/components/chat/gallery-thread/format-json-dump.ts +112 -0
  50. package/src/components/chat/gallery-thread/hooks/use-attachment-src.ts +46 -0
  51. package/src/components/chat/gallery-thread/hooks/use-copy-to-clipboard.ts +9 -0
  52. package/src/components/chat/gallery-thread/image.tsx +519 -0
  53. package/src/components/chat/gallery-thread/markdown-text.tsx +278 -0
  54. package/src/components/chat/gallery-thread/message-error.aui.tsx +105 -0
  55. package/src/components/chat/gallery-thread/message-timing.aui.tsx +143 -0
  56. package/src/components/chat/gallery-thread/private-work-step.tsx +188 -0
  57. package/src/components/chat/gallery-thread/reasoning.tsx +332 -0
  58. package/src/components/chat/gallery-thread/scroll-mode.ts +174 -0
  59. package/src/components/chat/gallery-thread/source.tsx +76 -0
  60. package/src/components/chat/gallery-thread/thread.aui.tsx +1619 -0
  61. package/src/components/chat/gallery-thread/tooltip-icon-button.tsx +53 -0
  62. package/src/components/chat/gallery-thread/typed-welcome-copy.tsx +18 -0
  63. package/src/components/chat/gallery-thread/ui/tooltip.tsx +22 -0
  64. package/src/components/chat/gallery-thread/work-chain-summary.tsx +48 -0
  65. package/src/components/chat/gallery-thread/work-chain.tsx +110 -0
  66. package/src/components/chat/gallery-thread/work-status.ts +66 -0
  67. package/src/components/chat/overlay-scrollbar.tsx +86 -0
  68. package/src/components/chat/sanitize-mermaid-svg.ts +38 -0
  69. package/src/components/chat/skins/SOURCE.md +36 -0
  70. package/src/components/chat/skins/base/attachment.aui.tsx +287 -0
  71. package/src/components/chat/skins/base/aui-default/README.md +45 -0
  72. package/src/components/chat/skins/base/aui-default/collapsible-root.tsx +19 -0
  73. package/src/components/chat/skins/base/aui-default/collapsible.tsx +21 -0
  74. package/src/components/chat/skins/base/aui-default/reasoning.aui.tsx +120 -0
  75. package/src/components/chat/skins/base/aui-default/reasoning.tsx +331 -0
  76. package/src/components/chat/skins/base/aui-default/surfaces.ts +7 -0
  77. package/src/components/chat/skins/base/aui-default/tool-fallback.aui.tsx +772 -0
  78. package/src/components/chat/skins/base/aui-default/tool-group.aui.tsx +241 -0
  79. package/src/components/chat/skins/base/docs-model-options.ts +6 -0
  80. package/src/components/chat/skins/base/elements/assistant-trace.aui.tsx +169 -0
  81. package/src/components/chat/skins/base/elements/composer-trigger-popover.aui.tsx +271 -0
  82. package/src/components/chat/skins/base/elements/directive-text.aui.tsx +29 -0
  83. package/src/components/chat/skins/base/elements/directive-text.tsx +76 -0
  84. package/src/components/chat/skins/base/elements/message-timing.aui.tsx +104 -0
  85. package/src/components/chat/skins/base/elements/model-selector.aui.tsx +140 -0
  86. package/src/components/chat/skins/base/elements/model-selector.tsx +720 -0
  87. package/src/components/chat/skins/base/elements/quote.aui.tsx +290 -0
  88. package/src/components/chat/skins/base/elements/work-chain.tsx +100 -0
  89. package/src/components/chat/skins/base/markdown-text.tsx +294 -0
  90. package/src/components/chat/skins/base/model.ts +1 -0
  91. package/src/components/chat/skins/base/thread.tsx +1050 -0
  92. package/src/components/chat/skins/base/tooltip-icon-button.tsx +56 -0
  93. package/src/components/chat/skins/base/ui/avatar.tsx +115 -0
  94. package/src/components/chat/skins/base/ui/badge.tsx +51 -0
  95. package/src/components/chat/skins/base/ui/button.tsx +67 -0
  96. package/src/components/chat/skins/base/ui/command.tsx +185 -0
  97. package/src/components/chat/skins/base/ui/dialog.tsx +168 -0
  98. package/src/components/chat/skins/base/ui/dot-matrix.tsx +267 -0
  99. package/src/components/chat/skins/base/ui/popover.tsx +97 -0
  100. package/src/components/chat/skins/base/ui/skeleton.tsx +20 -0
  101. package/src/components/chat/skins/base/ui/textarea.tsx +24 -0
  102. package/src/components/chat/skins/base/ui/tooltip.tsx +73 -0
  103. package/src/components/chat/skins/base-assistant-ui/config-provider.tsx +90 -0
  104. package/src/components/chat/skins/base-assistant-ui/defaults.ts +419 -0
  105. package/src/components/chat/skins/base-assistant-ui/index.tsx +44 -0
  106. package/src/components/chat/skins/chatgpt.tsx +448 -0
  107. package/src/components/chat/skins/claude.tsx +380 -0
  108. package/src/components/chat/skins/digichat-composer-toolbar.tsx +151 -0
  109. package/src/components/chat/skins/digichat-context-meter-shares.ts +158 -0
  110. package/src/components/chat/skins/digichat-context-meter.tsx +243 -0
  111. package/src/components/chat/skins/digichat-meter-tone.ts +26 -0
  112. package/src/components/chat/skins/digichat-usage-meter.tsx +103 -0
  113. package/src/components/chat/skins/digichat.tsx +144 -0
  114. package/src/components/chat/skins/expo-react-native.tsx +29 -0
  115. package/src/components/chat/skins/gemini.tsx +322 -0
  116. package/src/components/chat/skins/grok-icon.tsx +34 -0
  117. package/src/components/chat/skins/grok.tsx +369 -0
  118. package/src/components/chat/skins/index.ts +46 -0
  119. package/src/components/chat/skins/perplexity.tsx +462 -0
  120. package/src/components/chat/skins/product-page-assistant/assistant-modal.tsx +73 -0
  121. package/src/components/chat/skins/product-page-assistant/index.tsx +19 -0
  122. package/src/components/chat/skins/product-page-assistant/product-dashboard.tsx +164 -0
  123. package/src/components/chat/skins/react-ink.tsx +97 -0
  124. package/src/components/chat/skins/thread-skin-host-contract.ts +102 -0
  125. package/src/components/chat/skins/thread-skin-view.tsx +156 -0
  126. package/src/components/chat/skins/thread-skins.ts +143 -0
  127. package/src/components/chat/skins/tooltip-icon-button.tsx +35 -0
  128. package/src/components/chat/skins/ui/dropdown-menu.tsx +272 -0
  129. package/src/components/chat/skins/webpage-assistant/assistant-config.ts +238 -0
  130. package/src/components/chat/skins/webpage-assistant/assistant-modal.tsx +78 -0
  131. package/src/components/chat/skins/webpage-assistant/config-provider.tsx +132 -0
  132. package/src/components/chat/skins/webpage-assistant/docs-app.tsx +106 -0
  133. package/src/components/chat/skins/webpage-assistant/docs-article.tsx +109 -0
  134. package/src/components/chat/skins/webpage-assistant/docs-assistant.tsx +73 -0
  135. package/src/components/chat/skins/webpage-assistant/docs-nav.tsx +81 -0
  136. package/src/components/chat/skins/webpage-assistant/host-ui.ts +79 -0
  137. package/src/components/chat/skins/webpage-assistant/index.tsx +12 -0
  138. package/src/components/chat/skins/webpage-assistant/markdown-page.tsx +11 -0
  139. package/src/components/chat/skins/webpage-assistant/pages.ts +9 -0
  140. package/src/components/chat/skins/webpage-assistant/types.ts +178 -0
  141. package/src/components/chat/skins/webpage-assistant/use-mobile.ts +19 -0
  142. package/src/components/chat/stock/SOURCE.md +90 -0
  143. package/src/components/chat/stock/artifacts-panel.tsx +305 -0
  144. package/src/components/chat/stock/attachment.aui.tsx +280 -0
  145. package/src/components/chat/stock/chat-notice.tsx +143 -0
  146. package/src/components/chat/stock/chat-private-mode.tsx +64 -0
  147. package/src/components/chat/stock/deploy-ui-context.tsx +89 -0
  148. package/src/components/chat/stock/embed-chat-prefs.tsx +471 -0
  149. package/src/components/chat/stock/file.tsx +265 -0
  150. package/src/components/chat/stock/follow-up-suggestions.aui.tsx +83 -0
  151. package/src/components/chat/stock/image.tsx +531 -0
  152. package/src/components/chat/stock/index.ts +129 -0
  153. package/src/components/chat/stock/json-view.tsx +140 -0
  154. package/src/components/chat/stock/markdown-text.tsx +319 -0
  155. package/src/components/chat/stock/message-error.aui.tsx +96 -0
  156. package/src/components/chat/stock/message-export-menu.tsx +156 -0
  157. package/src/components/chat/stock/palette-row-preview.tsx +26 -0
  158. package/src/components/chat/stock/reasoning.aui.tsx +120 -0
  159. package/src/components/chat/stock/reasoning.tsx +335 -0
  160. package/src/components/chat/stock/skin-chrome.tsx +81 -0
  161. package/src/components/chat/stock/skin-credit.tsx +63 -0
  162. package/src/components/chat/stock/skin-palette-bridge.tsx +235 -0
  163. package/src/components/chat/stock/skin-palette-context.ts +16 -0
  164. package/src/components/chat/stock/skin-runtime.tsx +52 -0
  165. package/src/components/chat/stock/skin-slash-palette.tsx +393 -0
  166. package/src/components/chat/stock/skin-types.ts +217 -0
  167. package/src/components/chat/stock/stock-chat-prefs-host.tsx +501 -0
  168. package/src/components/chat/stock/stock-send-gate.tsx +94 -0
  169. package/src/components/chat/stock/stock-shape.tsx +39 -0
  170. package/src/components/chat/stock/thread.aui.tsx +645 -0
  171. package/src/components/chat/stock/tool-display.ts +6 -0
  172. package/src/components/chat/stock/tool-fallback.aui.tsx +866 -0
  173. package/src/components/chat/stock/tool-group.aui.tsx +244 -0
  174. package/src/components/chat/stock/tool-surface.ts +120 -0
  175. package/src/components/chat/stock/tooltip-icon-button.tsx +49 -0
  176. package/src/components/chat/stock/ui/avatar.tsx +108 -0
  177. package/src/components/chat/stock/ui/button.tsx +81 -0
  178. package/src/components/chat/stock/ui/collapsible.tsx +21 -0
  179. package/src/components/chat/stock/ui/dialog.tsx +163 -0
  180. package/src/components/chat/stock/ui/skeleton.tsx +13 -0
  181. package/src/components/chat/stock/ui/textarea.tsx +20 -0
  182. package/src/components/chat/stock/ui/tooltip.tsx +68 -0
  183. package/src/components/chat/stock/use-attachment-src.ts +42 -0
  184. package/src/components/chat/stock/use-copy-to-clipboard.ts +29 -0
  185. package/src/components/chat/strip-model-boilerplate.ts +42 -0
  186. package/src/components/chat/suggestion-cycle.tsx +230 -0
  187. package/src/components/chat/suggestion-scroll-row.tsx +81 -0
  188. package/src/components/chat/trace-grouping/chain-group-by.ts +44 -0
  189. package/src/components/chat/trace-grouping/chain-state.ts +141 -0
  190. package/src/components/chat/trace-grouping/index.ts +32 -0
  191. package/src/components/chat/trace-grouping/tool-row.ts +74 -0
  192. package/src/components/chat/trace-grouping/use-deploy-work-disclosure.ts +35 -0
  193. package/src/components/chat/trace-grouping/use-work-chain.ts +103 -0
  194. package/src/components/chat/trace-i18n/core.ts +48 -0
  195. package/src/components/chat/trace-i18n/index.tsx +23 -0
  196. package/src/components/chat/trace-i18n/locales/en.ts +24 -0
  197. package/src/components/chat/trace-i18n/locales/fr.ts +28 -0
  198. package/src/components/chat/trace-i18n/types.ts +35 -0
  199. package/src/components/chat/trace-spacing.ts +249 -0
  200. package/src/components/chat/transcript/activity-view.ts +375 -0
  201. package/src/components/chat/transcript/chat-export.ts +133 -0
  202. package/src/components/chat/transcript/index.ts +10 -0
  203. package/src/components/chat/transcript/save-file.ts +209 -0
  204. package/src/components/chat/transcript/transcript-markdown.ts +428 -0
  205. package/src/components/chat/transcript/types.ts +81 -0
  206. package/src/components/chat/turn-outcome.ts +52 -0
  207. package/src/components/chat/use-warmup-phase.ts +18 -0
  208. package/src/components/chat/work-status-lead.tsx +49 -0
  209. package/src/components/chrome.tsx +264 -0
  210. package/src/components/command-palette/CommandPalette.tsx +404 -0
  211. package/src/components/command-palette/index.ts +6 -0
  212. package/src/components/contact/ContactMailto.tsx +112 -0
  213. package/src/components/contact/index.ts +5 -0
  214. package/src/components/conviction/ConvictionMeter.tsx +40 -0
  215. package/src/components/conviction/SignedConvictionBadge.tsx +26 -0
  216. package/src/components/conviction/index.ts +7 -0
  217. package/src/components/data-layout/BentoGrid.tsx +52 -0
  218. package/src/components/data-layout/CardRail.tsx +150 -0
  219. package/src/components/data-layout/DotMatrixStat.tsx +65 -0
  220. package/src/components/data-layout/FeatureCell.tsx +80 -0
  221. package/src/components/data-layout/MediaFrame.tsx +125 -0
  222. package/src/components/data-layout/ModuleGrid.tsx +735 -0
  223. package/src/components/data-layout/Odometer.tsx +149 -0
  224. package/src/components/data-layout/ProductFrame.tsx +79 -0
  225. package/src/components/data-layout/TestimonialWall.tsx +139 -0
  226. package/src/components/data-layout/index.ts +19 -0
  227. package/src/components/data-layout/treemap.ts +368 -0
  228. package/src/components/deck/DeckStack.tsx +243 -0
  229. package/src/components/desk/DataTable.tsx +373 -0
  230. package/src/components/desk/KpiGrid.tsx +80 -0
  231. package/src/components/desk/Sparkline.tsx +63 -0
  232. package/src/components/desk/StateBlock.tsx +132 -0
  233. package/src/components/desk/index.ts +18 -0
  234. package/src/components/diagrams/ArchitectureDiagram.tsx +350 -0
  235. package/src/components/diagrams/ArchitectureTour.tsx +912 -0
  236. package/src/components/diagrams/TerminalSchematic.tsx +192 -0
  237. package/src/components/diagrams/architecture-svg.tsx +384 -0
  238. package/src/components/diagrams/index.ts +30 -0
  239. package/src/components/diagrams/mermaid-theme.ts +115 -0
  240. package/src/components/diagrams/tour-camera.ts +171 -0
  241. package/src/components/docs/CodeTabs.tsx +90 -0
  242. package/src/components/docs/CopyCommand.tsx +151 -0
  243. package/src/components/docs/DocsLayout.tsx +197 -0
  244. package/src/components/docs/DocsSearch.tsx +97 -0
  245. package/src/components/docs/Endpoint.tsx +135 -0
  246. package/src/components/document/DocumentFrame.tsx +43 -0
  247. package/src/components/document/GlyphList.tsx +51 -0
  248. package/src/components/document/PageTitle.tsx +44 -0
  249. package/src/components/document/Prose.tsx +38 -0
  250. package/src/components/document/Section.tsx +55 -0
  251. package/src/components/document/index.ts +13 -0
  252. package/src/components/effects-chrome/AnnouncementBar.tsx +88 -0
  253. package/src/components/effects-chrome/HorizontalScrollTrack.tsx +461 -0
  254. package/src/components/effects-chrome/Pipeline.tsx +226 -0
  255. package/src/components/effects-chrome/RotatingPrompts.tsx +116 -0
  256. package/src/components/effects-chrome/StackingPanels.tsx +101 -0
  257. package/src/components/effects-chrome/TabStrip.tsx +232 -0
  258. package/src/components/effects-chrome/ToastStack.tsx +201 -0
  259. package/src/components/effects-chrome/horizontal-track-core.ts +70 -0
  260. package/src/components/effects-chrome/index.ts +35 -0
  261. package/src/components/emblems.tsx +188 -0
  262. package/src/components/faviconTheme.ts +23 -0
  263. package/src/components/figure/Figure.tsx +38 -0
  264. package/src/components/figure/index.ts +2 -0
  265. package/src/components/finance-charts/DrawdownPlot.tsx +76 -0
  266. package/src/components/finance-charts/EquityCurve.tsx +71 -0
  267. package/src/components/finance-charts/PriceChart.tsx +119 -0
  268. package/src/components/finance-charts/chart-host.tsx +236 -0
  269. package/src/components/finance-charts/chart-scale.ts +93 -0
  270. package/src/components/finance-charts/demo-data.ts +88 -0
  271. package/src/components/finance-charts/index.ts +46 -0
  272. package/src/components/finance-charts/lw-chart.tsx +292 -0
  273. package/src/components/finance-composites/MarketBar.tsx +243 -0
  274. package/src/components/finance-composites/OrderBook.tsx +133 -0
  275. package/src/components/finance-composites/PerformanceDashboard.tsx +185 -0
  276. package/src/components/finance-composites/SortableTable.tsx +144 -0
  277. package/src/components/finance-composites/StockTicker.tsx +65 -0
  278. package/src/components/finance-composites/SyncedTearsheet.tsx +226 -0
  279. package/src/components/finance-composites/index.ts +28 -0
  280. package/src/components/finance-tearsheet/KpiStrip.tsx +49 -0
  281. package/src/components/finance-tearsheet/LiveBadge.tsx +29 -0
  282. package/src/components/finance-tearsheet/ReturnsMatrix.tsx +321 -0
  283. package/src/components/finance-tearsheet/StrategyTearsheet.tsx +99 -0
  284. package/src/components/finance-tearsheet/TearsheetCard.tsx +54 -0
  285. package/src/components/finance-tearsheet/TradeLogTable.tsx +73 -0
  286. package/src/components/finance-tearsheet/charts.tsx +2624 -0
  287. package/src/components/finance-tearsheet/demo-data.ts +177 -0
  288. package/src/components/finance-tearsheet/format.ts +41 -0
  289. package/src/components/finance-tearsheet/index.ts +120 -0
  290. package/src/components/finance-tearsheet/print.ts +52 -0
  291. package/src/components/finance-tearsheet/risk-bands.ts +48 -0
  292. package/src/components/finance-tearsheet/stats.ts +35 -0
  293. package/src/components/finance-tearsheet/strategy-sheet-model.ts +238 -0
  294. package/src/components/finance-tearsheet/types.ts +58 -0
  295. package/src/components/footer/FooterCells.tsx +109 -0
  296. package/src/components/footer/index.ts +6 -0
  297. package/src/components/graph.tsx +158 -0
  298. package/src/components/icons.tsx +98 -0
  299. package/src/components/landing/PixelWordmark.tsx +36 -0
  300. package/src/components/logos.ts +39 -0
  301. package/src/components/marquee/Marquee.tsx +204 -0
  302. package/src/components/metrics/PerfMetrics.tsx +68 -0
  303. package/src/components/metrics/StatCounter.tsx +104 -0
  304. package/src/components/page-geometry.tsx +177 -0
  305. package/src/components/pricing/Pricing.tsx +174 -0
  306. package/src/components/pricing/PricingMatrix.tsx +219 -0
  307. package/src/components/prose/index.ts +2 -0
  308. package/src/components/prose/prose.tsx +86 -0
  309. package/src/components/repo-activity/RepoActivity.tsx +599 -0
  310. package/src/components/repo-activity/RepoHeatmap.tsx +225 -0
  311. package/src/components/repo-activity/demo.ts +201 -0
  312. package/src/components/repo-activity/fetch.ts +211 -0
  313. package/src/components/repo-activity/heatmap.ts +123 -0
  314. package/src/components/repo-activity/index.ts +28 -0
  315. package/src/components/repo-activity/types.ts +99 -0
  316. package/src/components/stages/NumberedStages.tsx +116 -0
  317. package/src/components/symbols/marks.tsx +116 -0
  318. package/src/components/symbols/terminal-lockup.tsx +136 -0
  319. package/src/components/symbols/terminal-marks.tsx +226 -0
  320. package/src/components/terminal/ChatResponseLoader.tsx +67 -0
  321. package/src/components/terminal/ContainerBootLoader.tsx +82 -0
  322. package/src/components/terminal/TerminalStepCaret.tsx +202 -0
  323. package/src/components/themeInit.ts +24 -0
  324. package/src/components/typography/MotionReveal.tsx +108 -0
  325. package/src/components/typography/TypewriterReveal.tsx +101 -0
  326. package/src/components/typography/WordReveal.tsx +143 -0
  327. package/src/data/modules.ts +378 -0
  328. package/src/data/subsystems.ts +101 -0
  329. package/src/index.ts +587 -0
  330. package/src/lib/base-path.ts +60 -0
  331. package/src/lib/cx.ts +25 -0
  332. package/src/lib/gloomberb.ts +69 -0
  333. package/src/lib/record.ts +19 -0
  334. package/src/lib/stub-payload.ts +183 -0
  335. package/src/lib/useBodyScrollLock.ts +44 -0
  336. package/src/lib/utils.ts +6 -0
  337. package/src/motion/primitives.tsx +105 -0
  338. package/src/motion/scroll-glide.ts +62 -0
  339. package/src/motion/scrolly-core.ts +38 -0
  340. package/src/motion/scrolly.tsx +95 -0
  341. package/src/navigation/HashScrollManager.tsx +167 -0
  342. package/src/navigation/hashScroll.ts +78 -0
  343. package/src/replay/browser.ts +280 -0
  344. package/src/replay/chat-export-run.ts +121 -0
  345. package/src/replay/export-format.ts +25 -0
  346. package/src/replay/export-mount.ts +32 -0
  347. package/src/replay/filename.ts +54 -0
  348. package/src/replay/index.ts +21 -0
  349. package/src/replay/redact-dom.ts +178 -0
  350. package/src/replay/redact.ts +113 -0
  351. package/src/replay/snapshot.ts +659 -0
  352. package/src/styles/account-auth.css +339 -0
  353. package/src/styles/brand-wordmark.css +11 -0
  354. package/src/styles/card-rail.css +120 -0
  355. package/src/styles/chat-aui.css +1143 -0
  356. package/src/styles/chat-core.css +469 -0
  357. package/src/styles/chat-digichat.css +2531 -0
  358. package/src/styles/chat-math.css +70 -0
  359. package/src/styles/chat-skin-palette.css +138 -0
  360. package/src/styles/chat-stock-menu.css +37 -0
  361. package/src/styles/chat-widgets.css +190 -0
  362. package/src/styles/command-palette.css +372 -0
  363. package/src/styles/controls-core.css +2261 -0
  364. package/src/styles/controls-overlay.css +603 -0
  365. package/src/styles/data-layout.css +288 -0
  366. package/src/styles/deck.css +141 -0
  367. package/src/styles/diagrams.css +1860 -0
  368. package/src/styles/digichat-app-theme.css +250 -0
  369. package/src/styles/digichat-boot-loader.css +487 -0
  370. package/src/styles/digichat-launcher.css +377 -0
  371. package/src/styles/docs.css +165 -0
  372. package/src/styles/effects-chrome.css +888 -0
  373. package/src/styles/finance-composites.css +214 -0
  374. package/src/styles/finance-tearsheet-overlay.css +90 -0
  375. package/src/styles/finance-tearsheet.css +945 -0
  376. package/src/styles/marquee.css +168 -0
  377. package/src/styles/metrics.css +82 -0
  378. package/src/styles/nav-shell.css +551 -0
  379. package/src/styles/pricing.css +79 -0
  380. package/src/styles/repo-activity.css +575 -0
  381. package/src/styles/stages.css +69 -0
  382. package/src/styles/terminal-loaders.css +122 -0
  383. package/src/styles/terminal-manifest.css +228 -0
  384. package/src/styles/web-theme.css +1007 -0
  385. package/src/styles/word-reveal.css +204 -0
  386. package/src/theme/apply-theme.ts +214 -0
  387. package/src/theme/index.ts +27 -0
  388. package/src/theme/palette-registry.ts +855 -0
  389. package/src/theme/tui-prefs.ts +64 -0
  390. package/src/ui/alert.tsx +78 -0
  391. package/src/ui/avatar.tsx +104 -0
  392. package/src/ui/badge.tsx +75 -0
  393. package/src/ui/breadcrumb.tsx +61 -0
  394. package/src/ui/button.tsx +67 -0
  395. package/src/ui/card.tsx +139 -0
  396. package/src/ui/checkbox.tsx +27 -0
  397. package/src/ui/collapsible.tsx +32 -0
  398. package/src/ui/date-pager.tsx +325 -0
  399. package/src/ui/dialog.tsx +157 -0
  400. package/src/ui/dropdown-menu.tsx +267 -0
  401. package/src/ui/empty-state.tsx +165 -0
  402. package/src/ui/field.tsx +104 -0
  403. package/src/ui/form.tsx +36 -0
  404. package/src/ui/icon-button.tsx +36 -0
  405. package/src/ui/index.ts +34 -0
  406. package/src/ui/input.tsx +33 -0
  407. package/src/ui/kbd.tsx +30 -0
  408. package/src/ui/label.tsx +32 -0
  409. package/src/ui/pager.tsx +119 -0
  410. package/src/ui/pagination.tsx +126 -0
  411. package/src/ui/radio-group.tsx +51 -0
  412. package/src/ui/search-bar.tsx +85 -0
  413. package/src/ui/segmented-control.tsx +76 -0
  414. package/src/ui/select.tsx +257 -0
  415. package/src/ui/separator.tsx +24 -0
  416. package/src/ui/sheet.tsx +141 -0
  417. package/src/ui/skeleton.tsx +76 -0
  418. package/src/ui/slider.tsx +76 -0
  419. package/src/ui/switch.tsx +31 -0
  420. package/src/ui/table.tsx +179 -0
  421. package/src/ui/tabs.tsx +89 -0
  422. package/src/ui/tags-input.tsx +168 -0
  423. package/src/ui/textarea.tsx +17 -0
  424. package/src/ui/tooltip.tsx +71 -0
@@ -0,0 +1,241 @@
1
+ "use client";
2
+
3
+ import {
4
+ memo,
5
+ useCallback,
6
+ useRef,
7
+ useState,
8
+ type FC,
9
+ type PropsWithChildren,
10
+ } from "react";
11
+ import { ChevronDownIcon, LoaderIcon } from "lucide-react";
12
+ import { cva, type VariantProps } from "class-variance-authority";
13
+ import { useScrollLock } from "@assistant-ui/react";
14
+ import {
15
+ Collapsible,
16
+ CollapsibleContent,
17
+ CollapsibleTrigger,
18
+ } from "./collapsible";
19
+ import { cn } from "../../../../../lib/utils";
20
+ import { useTraceT } from "../../../trace-i18n";
21
+
22
+ const ANIMATION_DURATION = 200;
23
+
24
+ const toolGroupVariants = cva("aui-tool-group-root group/tool-group w-full", {
25
+ variants: {
26
+ variant: {
27
+ outline: "rounded-lg border py-3",
28
+ ghost: "",
29
+ muted: "border-muted-foreground/30 bg-muted/30 rounded-lg border py-3",
30
+ },
31
+ },
32
+ defaultVariants: { variant: "outline" },
33
+ });
34
+
35
+ export type ToolGroupRootProps = Omit<
36
+ React.ComponentProps<typeof Collapsible>,
37
+ "open" | "onOpenChange"
38
+ > &
39
+ VariantProps<typeof toolGroupVariants> & {
40
+ open?: boolean;
41
+ onOpenChange?: (open: boolean) => void;
42
+ defaultOpen?: boolean;
43
+ /** Open while this group is still streaming, auto-close on completion. */
44
+ streamingOpen?: boolean;
45
+ };
46
+
47
+ function ToolGroupRoot({
48
+ className,
49
+ variant,
50
+ open: controlledOpen,
51
+ onOpenChange: controlledOnOpenChange,
52
+ defaultOpen = false,
53
+ streamingOpen = false,
54
+ children,
55
+ ...props
56
+ }: ToolGroupRootProps) {
57
+ const collapsibleRef = useRef<HTMLDivElement>(null);
58
+ const [initialOpen] = useState(defaultOpen);
59
+ const [userOpen, setUserOpen] = useState<boolean | null>(null);
60
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
61
+
62
+ const isControlled = controlledOpen !== undefined;
63
+ // The first manual toggle wins; until then the group follows the stream.
64
+ const isOpen = isControlled
65
+ ? controlledOpen
66
+ : (userOpen ?? (streamingOpen || initialOpen));
67
+
68
+ const handleOpenChange = useCallback(
69
+ (open: boolean) => {
70
+ lockScroll();
71
+ if (!isControlled) {
72
+ setUserOpen(open);
73
+ }
74
+ controlledOnOpenChange?.(open);
75
+ },
76
+ [lockScroll, isControlled, controlledOnOpenChange],
77
+ );
78
+
79
+ return (
80
+ <Collapsible
81
+ ref={collapsibleRef}
82
+ data-slot="tool-group-root"
83
+ data-variant={variant ?? "outline"}
84
+ open={isOpen}
85
+ onOpenChange={handleOpenChange}
86
+ className={cn(
87
+ toolGroupVariants({ variant }),
88
+ "group/tool-group-root",
89
+ className,
90
+ )}
91
+ style={
92
+ {
93
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
94
+ } as React.CSSProperties
95
+ }
96
+ {...props}
97
+ >
98
+ {children}
99
+ </Collapsible>
100
+ );
101
+ }
102
+
103
+ function ToolGroupTrigger({
104
+ count,
105
+ active = false,
106
+ className,
107
+ ...props
108
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
109
+ count: number;
110
+ active?: boolean;
111
+ }) {
112
+ const label = useTraceT().plural("toolCalls", count);
113
+
114
+ return (
115
+ <CollapsibleTrigger
116
+ data-slot="tool-group-trigger"
117
+ className={cn(
118
+ "aui-tool-group-trigger group/trigger flex origin-left items-center gap-2 text-sm transition-[color,scale] active:scale-[0.98]",
119
+ "group-data-[variant=ghost]/tool-group-root:text-muted-foreground group-data-[variant=ghost]/tool-group-root:hover:text-foreground group-data-[variant=ghost]/tool-group-root:py-1.5",
120
+ "group-data-[variant=outline]/tool-group-root:w-full group-data-[variant=outline]/tool-group-root:px-4",
121
+ "group-data-[variant=muted]/tool-group-root:w-full group-data-[variant=muted]/tool-group-root:px-4",
122
+ className,
123
+ )}
124
+ // Folded while the tools run, the trigger is the one control that
125
+ // knows about them, so it carries the busy state.
126
+ aria-busy={active || undefined}
127
+ {...props}
128
+ >
129
+ {active && (
130
+ <LoaderIcon
131
+ data-slot="tool-group-trigger-loader"
132
+ className="aui-tool-group-trigger-loader size-3 shrink-0 animate-spin [animation-duration:0.6s]"
133
+ />
134
+ )}
135
+ <span
136
+ data-slot="tool-group-trigger-label"
137
+ className={cn(
138
+ "aui-tool-group-trigger-label-wrapper inline-block text-start text-xs leading-none font-medium",
139
+ "group-data-[variant=ghost]/tool-group-root:font-normal",
140
+ "group-data-[variant=outline]/tool-group-root:grow",
141
+ "group-data-[variant=muted]/tool-group-root:grow",
142
+ active && "shimmer motion-reduce:animate-none",
143
+ )}
144
+ >
145
+ {label}
146
+ </span>
147
+ <ChevronDownIcon
148
+ data-slot="tool-group-trigger-chevron"
149
+ className={cn(
150
+ "aui-tool-group-trigger-chevron size-3 shrink-0",
151
+ "transition-transform duration-(--animation-duration) ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none",
152
+ "-rotate-90",
153
+ "group-data-open/trigger:rotate-0",
154
+ "group-data-panel-open/trigger:rotate-0",
155
+ )}
156
+ />
157
+ </CollapsibleTrigger>
158
+ );
159
+ }
160
+
161
+ function ToolGroupContent({
162
+ className,
163
+ children,
164
+ ...props
165
+ }: React.ComponentProps<typeof CollapsibleContent>) {
166
+ return (
167
+ <CollapsibleContent
168
+ data-slot="tool-group-content"
169
+ className={cn(
170
+ "aui-tool-group-content relative overflow-hidden text-sm outline-none",
171
+ "group/collapsible-content ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:animate-none",
172
+ "data-closed:animate-collapsible-up",
173
+ "data-open:animate-collapsible-down",
174
+ "data-closed:fill-mode-forwards",
175
+ "data-closed:pointer-events-none",
176
+ "[--tw-duration:var(--animation-duration)]",
177
+ className,
178
+ )}
179
+ {...props}
180
+ >
181
+ <div
182
+ className={cn(
183
+ "mt-2 flex flex-col gap-2",
184
+ "group-data-[variant=ghost]/tool-group-root:mt-1 group-data-[variant=ghost]/tool-group-root:gap-1",
185
+ "group-data-[variant=outline]/tool-group-root:mt-3 group-data-[variant=outline]/tool-group-root:border-t group-data-[variant=outline]/tool-group-root:px-4 group-data-[variant=outline]/tool-group-root:pt-3",
186
+ "group-data-[variant=muted]/tool-group-root:mt-3 group-data-[variant=muted]/tool-group-root:border-t group-data-[variant=muted]/tool-group-root:px-4 group-data-[variant=muted]/tool-group-root:pt-3",
187
+ "[&>*]:animate-in [&>*]:fade-in-0 [&>*]:blur-in-[2px] [&>*]:slide-in-from-top-1 [&>*]:animation-duration-(--animation-duration) [&>*]:ease-[cubic-bezier(0.32,0.72,0,1)]",
188
+ "[&>*]:motion-reduce:animate-none",
189
+ "[&>*:nth-child(2)]:[animation-delay:40ms]",
190
+ "[&>*:nth-child(3)]:[animation-delay:80ms]",
191
+ "[&>*:nth-child(4)]:[animation-delay:120ms]",
192
+ "[&>*:nth-child(n+5)]:[animation-delay:160ms]",
193
+ )}
194
+ >
195
+ {children}
196
+ </div>
197
+ </CollapsibleContent>
198
+ );
199
+ }
200
+
201
+ type ToolGroupComponent = FC<
202
+ PropsWithChildren<{ startIndex: number; endIndex: number }>
203
+ > & {
204
+ Root: typeof ToolGroupRoot;
205
+ Trigger: typeof ToolGroupTrigger;
206
+ Content: typeof ToolGroupContent;
207
+ };
208
+
209
+ const ToolGroupImpl: FC<
210
+ PropsWithChildren<{ startIndex: number; endIndex: number }>
211
+ > = ({ children, startIndex, endIndex }) => {
212
+ const toolCount = endIndex - startIndex + 1;
213
+
214
+ return (
215
+ <ToolGroupRoot>
216
+ <ToolGroupTrigger count={toolCount} />
217
+ <ToolGroupContent>{children}</ToolGroupContent>
218
+ </ToolGroupRoot>
219
+ );
220
+ };
221
+
222
+ /**
223
+ * @deprecated This wrapper targets the legacy `components.ToolGroup` prop
224
+ * on `<MessagePrimitive.Parts>`. Use `<MessagePrimitive.GroupedParts>` with
225
+ * a `groupBy` returning `"group-tool"` and compose `ToolGroupRoot` /
226
+ * `ToolGroupTrigger` / `ToolGroupContent` directly. See `thread.tsx`.
227
+ */
228
+ const ToolGroup = memo(ToolGroupImpl) as unknown as ToolGroupComponent;
229
+
230
+ ToolGroup.displayName = "ToolGroup";
231
+ ToolGroup.Root = ToolGroupRoot;
232
+ ToolGroup.Trigger = ToolGroupTrigger;
233
+ ToolGroup.Content = ToolGroupContent;
234
+
235
+ export {
236
+ ToolGroup,
237
+ ToolGroupRoot,
238
+ ToolGroupTrigger,
239
+ ToolGroupContent,
240
+ toolGroupVariants,
241
+ };
@@ -0,0 +1,6 @@
1
+ export function docsModelOptions() {
2
+ return [
3
+ { id: "gpt-5.6-luna", name: "GPT-5.6 Luna" },
4
+ { id: "gpt-5.6-terra", name: "GPT-5.6 Terra" },
5
+ ];
6
+ }
@@ -0,0 +1,169 @@
1
+ "use client";
2
+
3
+ import type { ComponentType, FC, PropsWithChildren, ReactNode } from "react";
4
+ import {
5
+ MessagePrimitive,
6
+ useAuiState,
7
+ type ToolCallMessagePartComponent,
8
+ } from "@assistant-ui/react";
9
+ import {
10
+ Reasoning,
11
+ ReasoningContent,
12
+ ReasoningRoot,
13
+ ReasoningText,
14
+ ReasoningTrigger,
15
+ } from "../aui-default/reasoning.aui";
16
+ import { ToolFallback } from "../aui-default/tool-fallback.aui";
17
+ import {
18
+ ToolGroupContent,
19
+ ToolGroupRoot,
20
+ ToolGroupTrigger,
21
+ } from "../aui-default/tool-group.aui";
22
+ import { WorkChain } from "./work-chain";
23
+ import {
24
+ chainFollowedByText,
25
+ chainGroupBy,
26
+ chainHoldsWork,
27
+ chainToolCount,
28
+ reasoningGroupDisclosure,
29
+ toolGroupDisclosure,
30
+ useDeployWorkDisclosure,
31
+ } from "../../../trace-grouping";
32
+ import { useViewDisclosure } from "../../../stock/deploy-ui-context";
33
+
34
+ export type AssistantTraceGroupPart = MessagePrimitive.GroupedParts.GroupPart;
35
+
36
+ type GroupedPartsRender = Parameters<
37
+ NonNullable<MessagePrimitive.GroupedParts.Props["children"]>
38
+ >[0];
39
+
40
+ /** A part the trace does not own (text, file, image, indicator, data, source). */
41
+ export type AssistantTracePartProps = {
42
+ part: GroupedPartsRender["part"];
43
+ children: ReactNode;
44
+ };
45
+
46
+ export type AssistantTraceProps = {
47
+ /**
48
+ * Renders the parts that are not the trace (text, file, image, indicator,
49
+ * data, source). Return `null` to drop a part.
50
+ */
51
+ renderPart: (props: AssistantTracePartProps) => ReactNode;
52
+ /** Replaces assistant-ui's tool card for calls with no registered tool UI. */
53
+ ToolFallback?: ToolCallMessagePartComponent | undefined;
54
+ /** Replaces the `N tool calls` group. */
55
+ ToolGroup?:
56
+ | ComponentType<PropsWithChildren<{ group: AssistantTraceGroupPart }>>
57
+ | undefined;
58
+ /** Replaces the reasoning box. */
59
+ ReasoningGroup?:
60
+ | ComponentType<PropsWithChildren<{ group: AssistantTraceGroupPart }>>
61
+ | undefined;
62
+ };
63
+
64
+ /**
65
+ * The assistant message trace the base skin draws: one work chain over the
66
+ * reasoning and tool calls (folded it reads "Used 3 tools"), a reasoning box
67
+ * and an `N tool calls` group inside it, and assistant-ui's own tool card for
68
+ * each call. The grouping and fold rules are the shared trace rules
69
+ * (`../../../trace-grouping`, the digichat skin's); the look is assistant-ui's
70
+ * defaults (`../aui-default`). Shared by the base skin and the stock thread so
71
+ * both trace the same way; each skin keeps its own text, file and indicator
72
+ * rendering through `renderPart`.
73
+ */
74
+ export const AssistantTrace: FC<AssistantTraceProps> = ({
75
+ renderPart,
76
+ ToolFallback: ToolFallbackComponent = ToolFallback,
77
+ ToolGroup,
78
+ ReasoningGroup,
79
+ }) => {
80
+ const disclosure = useViewDisclosure();
81
+ const { reasoningMode, toolCallsMode, disclosure: work } = useDeployWorkDisclosure();
82
+ // The whole turn, not just the group: the tools answer faster than the
83
+ // chain can fold, and a group that closes between two of them flickers.
84
+ const turnRunning = useAuiState((s) => s.thread.isRunning);
85
+ const messageParts = useAuiState((s) => s.message.parts);
86
+
87
+ return (
88
+ <MessagePrimitive.GroupedParts groupBy={chainGroupBy}>
89
+ {({ part, children }) => {
90
+ switch (part.type) {
91
+ case "group-chainOfThought":
92
+ // A chain of only status or source parts is not work: no
93
+ // header, the loading row covers that phase. The parts still
94
+ // render bare so a backend notice does not vanish.
95
+ if (!chainHoldsWork(messageParts, part.indices)) return <>{children}</>;
96
+ // One header for the whole chain: the reasoning and the tool
97
+ // calls collapse together.
98
+ return (
99
+ <div data-slot="aui_chain-of-thought">
100
+ <WorkChain
101
+ key={disclosure.key}
102
+ indices={part.indices}
103
+ openAtRest={work.openAtRest}
104
+ foldOnAnswer={work.foldOnAnswer}
105
+ followedByText={chainFollowedByText(messageParts, part.indices)}
106
+ >
107
+ {children}
108
+ </WorkChain>
109
+ </div>
110
+ );
111
+ case "group-tool": {
112
+ if (toolCallsMode === "off") return null;
113
+ // The group can hold the source and status parts between two
114
+ // tool runs; the count is the tool calls only.
115
+ const toolCount = chainToolCount(messageParts, part.indices);
116
+ if (toolCount === 0) return <div data-slot="aui_chain-tools">{children}</div>;
117
+ if (ToolGroup) return <ToolGroup group={part}>{children}</ToolGroup>;
118
+ const running = part.status.type === "running";
119
+ const group = toolGroupDisclosure(work, toolCallsMode, running || turnRunning);
120
+ return (
121
+ <ToolGroupRoot
122
+ key={disclosure.key}
123
+ variant="ghost"
124
+ defaultOpen={group.defaultOpen}
125
+ streamingOpen={group.streamingOpen}
126
+ {...(group.locked ? { open: true, onOpenChange: () => {} } : {})}
127
+ >
128
+ <ToolGroupTrigger count={toolCount} active={running} disabled={group.locked} />
129
+ <ToolGroupContent>{children}</ToolGroupContent>
130
+ </ToolGroupRoot>
131
+ );
132
+ }
133
+ case "group-reasoning": {
134
+ if (reasoningMode === "off") return null;
135
+ if (ReasoningGroup) return <ReasoningGroup group={part}>{children}</ReasoningGroup>;
136
+ const running = part.status.type === "running";
137
+ const box = reasoningGroupDisclosure(work, reasoningMode, running || turnRunning);
138
+ return (
139
+ <ReasoningRoot
140
+ key={disclosure.key}
141
+ variant="ghost"
142
+ className="mb-0"
143
+ streaming={box.streamingOpen}
144
+ defaultOpen={box.defaultOpen}
145
+ {...(box.locked ? { open: true, onOpenChange: () => {} } : {})}
146
+ >
147
+ {/* The reasoning is a sub-step with its own disclosure
148
+ inside the chain, streaming while it runs. */}
149
+ <ReasoningTrigger active={running} disabled={box.locked} />
150
+ <ReasoningContent aria-busy={running}>
151
+ <ReasoningText>{children}</ReasoningText>
152
+ </ReasoningContent>
153
+ </ReasoningRoot>
154
+ );
155
+ }
156
+ case "reasoning":
157
+ if (reasoningMode === "off") return null;
158
+ return <Reasoning {...part} />;
159
+ case "tool-call":
160
+ if (toolCallsMode === "off") return null;
161
+ // assistant-ui's ToolFallback owns the approval controls too.
162
+ return part.toolUI ?? <ToolFallbackComponent key={disclosure.key} {...part} />;
163
+ default:
164
+ return renderPart({ part, children });
165
+ }
166
+ }}
167
+ </MessagePrimitive.GroupedParts>
168
+ );
169
+ };
@@ -0,0 +1,271 @@
1
+ "use client";
2
+
3
+ import { memo, useRef, type ComponentPropsWithoutRef, type FC } from "react";
4
+ import {
5
+ ComposerPrimitive,
6
+ unstable_defaultDirectiveFormatter,
7
+ unstable_useTriggerPopoverScopeContext,
8
+ type Unstable_DirectiveFormatter,
9
+ type Unstable_TriggerItem,
10
+ } from "@assistant-ui/react";
11
+ import { ChevronLeftIcon, ChevronRightIcon, SparklesIcon } from "lucide-react";
12
+ import { cn } from "../../../../../lib/utils";
13
+ import { PaletteRowPreview } from "../../../stock/palette-row-preview";
14
+
15
+ type IconComponent = FC<{ className?: string }>;
16
+
17
+ type DirectiveBehaviorProps = {
18
+ /** Formatter used to serialize the selected item into composer text. */
19
+ formatter?: Unstable_DirectiveFormatter | undefined;
20
+ /** Called after the directive text has been inserted into the composer. */
21
+ onInserted?: ((item: Unstable_TriggerItem) => void) | undefined;
22
+ };
23
+
24
+ type ActionBehaviorProps = {
25
+ /** Formatter used to serialize the audit-trail chip (when `removeOnExecute` is false). */
26
+ formatter?: Unstable_DirectiveFormatter | undefined;
27
+ /** Invoked with the selected item at the moment of selection. */
28
+ onExecute: (item: Unstable_TriggerItem) => void;
29
+ /** If `true`, strip the trigger text from the composer after executing. @default false */
30
+ removeOnExecute?: boolean | undefined;
31
+ };
32
+
33
+ type ComposerTriggerPopoverBaseProps = Omit<
34
+ ComponentPropsWithoutRef<typeof ComposerPrimitive.Unstable_TriggerPopover>,
35
+ "children"
36
+ > & {
37
+ /**
38
+ * Maps icon keys to components. Items look up via `item.metadata?.icon`
39
+ * (string); categories look up via their `id`.
40
+ */
41
+ iconMap?: Record<string, IconComponent>;
42
+ /** Fallback icon when no entry in `iconMap` matches. */
43
+ fallbackIcon?: IconComponent;
44
+ /** Label shown on the back button. @default "Back" */
45
+ backLabel?: string;
46
+ /** Label shown when no categories are available. @default "No items available" */
47
+ emptyCategoriesLabel?: string;
48
+ /** Label shown when no items match. @default "No matching items" */
49
+ emptyItemsLabel?: string;
50
+ /** Label shown while an async adapter is resolving items. @default "Loading…" */
51
+ loadingLabel?: string;
52
+ };
53
+
54
+ type ComposerTriggerPopoverProps = ComposerTriggerPopoverBaseProps &
55
+ (
56
+ | {
57
+ /** Insert-directive behavior. */
58
+ directive: DirectiveBehaviorProps;
59
+ action?: never;
60
+ }
61
+ | {
62
+ /** Action behavior. */
63
+ action: ActionBehaviorProps;
64
+ directive?: never;
65
+ }
66
+ );
67
+
68
+ function resolveIcon(
69
+ iconKey: string | undefined,
70
+ iconMap: Record<string, IconComponent> | undefined,
71
+ fallback: IconComponent,
72
+ ): IconComponent {
73
+ if (iconKey && iconMap?.[iconKey]) return iconMap[iconKey]!;
74
+ return fallback;
75
+ }
76
+
77
+ type CategoriesProps = {
78
+ iconMap: Record<string, IconComponent> | undefined;
79
+ fallbackIcon: IconComponent;
80
+ emptyLabel: string;
81
+ };
82
+
83
+ const Categories: FC<CategoriesProps> = ({
84
+ iconMap,
85
+ fallbackIcon,
86
+ emptyLabel,
87
+ }) => (
88
+ <ComposerPrimitive.Unstable_TriggerPopoverCategories>
89
+ {(categories) => (
90
+ <div
91
+ data-slot="composer-trigger-popover-categories"
92
+ className="flex flex-col py-1"
93
+ >
94
+ {categories.map((cat) => {
95
+ const Icon = resolveIcon(cat.id, iconMap, fallbackIcon);
96
+ return (
97
+ <ComposerPrimitive.Unstable_TriggerPopoverCategoryItem
98
+ key={cat.id}
99
+ categoryId={cat.id}
100
+ className="hover:bg-muted focus:bg-muted data-[highlighted]:bg-muted focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset data-[highlighted]:ring-2 data-[highlighted]:ring-ring data-[highlighted]:ring-inset flex cursor-pointer items-center justify-between gap-2 px-3 py-2 text-sm transition-colors outline-none"
101
+ >
102
+ <span className="flex items-center gap-2">
103
+ <Icon className="text-muted-foreground size-4" />
104
+ {cat.label}
105
+ </span>
106
+ <ChevronRightIcon className="text-muted-foreground size-4" />
107
+ </ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
108
+ );
109
+ })}
110
+ {categories.length === 0 && (
111
+ <div className="text-muted-foreground px-3 py-2 text-sm">
112
+ {emptyLabel}
113
+ </div>
114
+ )}
115
+ </div>
116
+ )}
117
+ </ComposerPrimitive.Unstable_TriggerPopoverCategories>
118
+ );
119
+
120
+ type ItemsProps = {
121
+ iconMap: Record<string, IconComponent> | undefined;
122
+ fallbackIcon: IconComponent;
123
+ backLabel: string;
124
+ emptyLabel: string;
125
+ loadingLabel: string;
126
+ };
127
+
128
+ const Items: FC<ItemsProps> = ({
129
+ iconMap,
130
+ fallbackIcon,
131
+ backLabel,
132
+ emptyLabel,
133
+ loadingLabel,
134
+ }) => {
135
+ const { isLoading } = unstable_useTriggerPopoverScopeContext();
136
+ return (
137
+ <ComposerPrimitive.Unstable_TriggerPopoverItems>
138
+ {(items) => (
139
+ <div
140
+ data-slot="composer-trigger-popover-items"
141
+ className="flex flex-col"
142
+ >
143
+ <ComposerPrimitive.Unstable_TriggerPopoverBack className="text-muted-foreground hover:bg-muted flex cursor-pointer items-center gap-1.5 border-b px-3 py-2 text-xs tracking-wide uppercase transition-colors">
144
+ <ChevronLeftIcon className="size-3.5" />
145
+ {backLabel}
146
+ </ComposerPrimitive.Unstable_TriggerPopoverBack>
147
+
148
+ <div className="py-1">
149
+ {items.map((item, index) => {
150
+ const iconKey =
151
+ typeof item.metadata?.icon === "string"
152
+ ? item.metadata.icon
153
+ : undefined;
154
+ const Icon = resolveIcon(iconKey, iconMap, fallbackIcon);
155
+ const value =
156
+ typeof item.metadata?.value === "string" ? item.metadata.value : "";
157
+ const detailId = item.description ? `slash-desc-${item.id}` : undefined;
158
+ return (
159
+ <ComposerPrimitive.Unstable_TriggerPopoverItem
160
+ key={item.id}
161
+ item={item}
162
+ index={index}
163
+ aria-describedby={detailId}
164
+ className="group hover:bg-muted focus:bg-muted data-[highlighted]:bg-muted focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset data-[highlighted]:ring-2 data-[highlighted]:ring-ring data-[highlighted]:ring-inset flex w-full cursor-pointer flex-col items-stretch gap-0.5 px-3 py-2 text-start transition-colors outline-none"
165
+ >
166
+ <span className="flex w-full items-center gap-2 text-sm font-medium">
167
+ <Icon className="text-primary size-3.5" />
168
+ <span className="min-w-0 flex-1">{item.label}</span>
169
+ {value ? (
170
+ <span
171
+ data-slot="palette-value"
172
+ className="text-muted-foreground ml-auto min-w-0 truncate text-end text-xs font-normal"
173
+ >
174
+ {value}
175
+ </span>
176
+ ) : null}
177
+ </span>
178
+ {item.description ? (
179
+ <span
180
+ id={detailId}
181
+ data-slot="palette-detail"
182
+ className="text-muted-foreground ms-5.5 hidden truncate text-xs leading-tight group-data-[highlighted]:block"
183
+ >
184
+ {item.description}
185
+ </span>
186
+ ) : null}
187
+ </ComposerPrimitive.Unstable_TriggerPopoverItem>
188
+ );
189
+ })}
190
+ {items.length === 0 && (
191
+ <div className="text-muted-foreground px-3 py-2 text-sm">
192
+ {isLoading ? loadingLabel : emptyLabel}
193
+ </div>
194
+ )}
195
+ </div>
196
+ </div>
197
+ )}
198
+ </ComposerPrimitive.Unstable_TriggerPopoverItems>
199
+ );
200
+ };
201
+
202
+ /**
203
+ * Pre-built popover UI for a trigger-driven picker (mentions, slash commands, etc).
204
+ * Pass exactly one of `directive` (inserts a chip) or `action` (fires a handler).
205
+ */
206
+ const ComposerTriggerPopoverImpl: FC<ComposerTriggerPopoverProps> = ({
207
+ iconMap,
208
+ fallbackIcon = SparklesIcon,
209
+ backLabel = "Back",
210
+ emptyCategoriesLabel = "No items available",
211
+ emptyItemsLabel = "No matching items",
212
+ loadingLabel = "Loading…",
213
+ className,
214
+ directive,
215
+ action,
216
+ ...props
217
+ }) => {
218
+ const warnedRef = useRef(false);
219
+ if (
220
+ process.env.NODE_ENV !== "production" &&
221
+ !warnedRef.current &&
222
+ Boolean(directive) === Boolean(action)
223
+ ) {
224
+ warnedRef.current = true;
225
+ console.warn(
226
+ "[assistant-ui] ComposerTriggerPopover requires exactly one of `directive` or `action` props.",
227
+ );
228
+ }
229
+
230
+ return (
231
+ <ComposerPrimitive.Unstable_TriggerPopover
232
+ data-slot="composer-trigger-popover"
233
+ className={cn(
234
+ "aui-composer-trigger-popover bg-popover text-popover-foreground absolute start-0 bottom-full z-50 mb-2 w-64 overflow-hidden rounded-xl border",
235
+ className,
236
+ )}
237
+ {...props}
238
+ >
239
+ {directive ? (
240
+ <ComposerPrimitive.Unstable_TriggerPopover.Directive
241
+ formatter={directive.formatter ?? unstable_defaultDirectiveFormatter}
242
+ onInserted={directive.onInserted}
243
+ />
244
+ ) : action ? (
245
+ <ComposerPrimitive.Unstable_TriggerPopover.Action
246
+ formatter={action.formatter ?? unstable_defaultDirectiveFormatter}
247
+ onExecute={action.onExecute}
248
+ removeOnExecute={action.removeOnExecute}
249
+ />
250
+ ) : null}
251
+ <PaletteRowPreview />
252
+ <Categories
253
+ iconMap={iconMap}
254
+ fallbackIcon={fallbackIcon}
255
+ emptyLabel={emptyCategoriesLabel}
256
+ />
257
+ <Items
258
+ iconMap={iconMap}
259
+ fallbackIcon={fallbackIcon}
260
+ backLabel={backLabel}
261
+ emptyLabel={emptyItemsLabel}
262
+ loadingLabel={loadingLabel}
263
+ />
264
+ </ComposerPrimitive.Unstable_TriggerPopover>
265
+ );
266
+ };
267
+ ComposerTriggerPopoverImpl.displayName = "ComposerTriggerPopover";
268
+
269
+ export const ComposerTriggerPopover = memo(
270
+ ComposerTriggerPopoverImpl,
271
+ ) as FC<ComposerTriggerPopoverProps>;