@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,156 @@
1
+ "use client";
2
+
3
+ import { ActionBarMorePrimitive, useAui, useAuiState } from "@assistant-ui/react";
4
+ import { ChevronRightIcon } from "lucide-react";
5
+ import { DropdownMenu } from "radix-ui";
6
+ import { useCallback, useMemo, useRef, useState, type ReactElement, type ReactNode } from "react";
7
+
8
+ import { exportMessage } from "../../../replay/chat-export-run";
9
+ import { messageAnchor } from "../../../replay/snapshot";
10
+ import {
11
+ CHAT_EXPORT_FORMATS,
12
+ chatExportLabel,
13
+ chatExportStrings,
14
+ type ChatExportFormat,
15
+ type ChatExportStrings,
16
+ } from "../transcript";
17
+ import { useChatPrivateMode } from "./chat-private-mode";
18
+ import { useEmbedChatPrefsOptional } from "./embed-chat-prefs";
19
+
20
+ /** Export strings in the session language (`/language`), else English. */
21
+ export function useChatExportStrings(): ChatExportStrings {
22
+ const prefs = useEmbedChatPrefsOptional();
23
+ const locale = prefs?.prefs.language;
24
+ return useMemo(() => chatExportStrings(locale), [locale]);
25
+ }
26
+
27
+ export type MessageExportMenuProps = {
28
+ /** The "…" button. It must forward its ref (TooltipIconButton does). */
29
+ trigger: ReactElement;
30
+ /** Drawn before "Export" in the menu. */
31
+ icon?: ReactNode;
32
+ /** Drawn before each format row. */
33
+ formatIcon?: (format: ChatExportFormat) => ReactNode;
34
+ contentClassName: string;
35
+ /** The side panel. Defaults to `contentClassName`. */
36
+ subContentClassName?: string;
37
+ itemClassName: string;
38
+ side?: "top" | "bottom" | "left" | "right";
39
+ align?: "start" | "center" | "end";
40
+ sideOffset?: number;
41
+ };
42
+
43
+ /**
44
+ * The message "…" menu: `Export ▸` with `Markdown (.md)` and `HTML (.html)`
45
+ * in a side panel. Both export this assistant message only.
46
+ *
47
+ * assistant-ui's more-menu has no submenu, so the menu is radix's own
48
+ * DropdownMenu. `ActionBarMorePrimitive.Root` still wraps it, controlled by
49
+ * the same open state, so the action bar stays visible while the menu is
50
+ * open. The export runs after the menu has closed: the HTML snapshot reads
51
+ * the page, and an open menu hides the thread from it.
52
+ *
53
+ * A private session (`ChatPrivateModeProvider`) renders nothing, on every
54
+ * skin: the export would put the typed text in a file.
55
+ */
56
+ export function MessageExportMenu(props: MessageExportMenuProps) {
57
+ const privateMode = useChatPrivateMode();
58
+ if (privateMode) return null;
59
+ return <MessageExportMenuOpen {...props} />;
60
+ }
61
+
62
+ function MessageExportMenuOpen({
63
+ trigger,
64
+ icon,
65
+ formatIcon,
66
+ contentClassName,
67
+ subContentClassName,
68
+ itemClassName,
69
+ side = "bottom",
70
+ align = "start",
71
+ sideOffset = 6,
72
+ }: MessageExportMenuProps) {
73
+ const aui = useAui();
74
+ const messageId = useAuiState((s) => s.message.id);
75
+ const strings = useChatExportStrings();
76
+ const [open, setOpen] = useState(false);
77
+ const triggerRef = useRef<HTMLButtonElement>(null);
78
+ const pending = useRef<ChatExportFormat | null>(null);
79
+
80
+ const run = useCallback(
81
+ (format: ChatExportFormat) => {
82
+ // Resolve the message element now: an older answer's action bar can
83
+ // unmount once the menu closes, taking the trigger with it.
84
+ const trigger = messageAnchor(triggerRef.current, messageId) ?? triggerRef.current;
85
+ const message = aui.message().getState();
86
+ const messages = aui.thread().getState().messages;
87
+ requestAnimationFrame(() => {
88
+ void exportMessage({ format, message, messageId, messages, trigger });
89
+ });
90
+ },
91
+ [aui, messageId],
92
+ );
93
+
94
+ const onOpenChange = useCallback(
95
+ (next: boolean) => {
96
+ setOpen(next);
97
+ if (next) return;
98
+ const format = pending.current;
99
+ pending.current = null;
100
+ if (format) run(format);
101
+ },
102
+ [run],
103
+ );
104
+
105
+ return (
106
+ <ActionBarMorePrimitive.Root open={open} onOpenChange={onOpenChange}>
107
+ <DropdownMenu.Root open={open} onOpenChange={onOpenChange}>
108
+ <DropdownMenu.Trigger asChild ref={triggerRef}>
109
+ {trigger}
110
+ </DropdownMenu.Trigger>
111
+ <DropdownMenu.Portal>
112
+ <DropdownMenu.Content
113
+ side={side}
114
+ align={align}
115
+ sideOffset={sideOffset}
116
+ data-slot="message-more-menu"
117
+ className={contentClassName}
118
+ >
119
+ <DropdownMenu.Sub>
120
+ <DropdownMenu.SubTrigger
121
+ data-slot="message-export-trigger"
122
+ className={itemClassName}
123
+ >
124
+ {icon}
125
+ <span className="flex-1">{strings.export}</span>
126
+ <ChevronRightIcon aria-hidden className="size-3.5 opacity-70 rtl:rotate-180" />
127
+ </DropdownMenu.SubTrigger>
128
+ <DropdownMenu.Portal>
129
+ <DropdownMenu.SubContent
130
+ sideOffset={4}
131
+ alignOffset={-4}
132
+ data-slot="message-export-formats"
133
+ className={subContentClassName ?? contentClassName}
134
+ >
135
+ {CHAT_EXPORT_FORMATS.map((format) => (
136
+ <DropdownMenu.Item
137
+ key={format}
138
+ data-export-format={format}
139
+ className={itemClassName}
140
+ onSelect={() => {
141
+ pending.current = format;
142
+ }}
143
+ >
144
+ {formatIcon?.(format)}
145
+ {chatExportLabel(format, strings)}
146
+ </DropdownMenu.Item>
147
+ ))}
148
+ </DropdownMenu.SubContent>
149
+ </DropdownMenu.Portal>
150
+ </DropdownMenu.Sub>
151
+ </DropdownMenu.Content>
152
+ </DropdownMenu.Portal>
153
+ </DropdownMenu.Root>
154
+ </ActionBarMorePrimitive.Root>
155
+ );
156
+ }
@@ -0,0 +1,26 @@
1
+ "use client";
2
+
3
+ import { useEffect } from "react";
4
+ import { unstable_useTriggerPopoverScopeContextOptional } from "@assistant-ui/react";
5
+ import { committedChatPrefs, slashRowPreview, useEmbedChatPrefsOptional } from "./embed-chat-prefs";
6
+
7
+ /**
8
+ * Inside the `/` popover: while the highlighted row flips a purely visual
9
+ * setting in place (`/scrollbar`), the page shows the flipped look. Nothing
10
+ * is stored; moving off the row or closing the popover drops the preview,
11
+ * and choosing the row commits it as before.
12
+ */
13
+ export function PaletteRowPreview(): null {
14
+ const scope = unstable_useTriggerPopoverScopeContextOptional();
15
+ const api = useEmbedChatPrefsOptional();
16
+ const preview = api?.previewPrefs;
17
+ const id = scope?.open ? scope.items[scope.highlightedIndex]?.id : undefined;
18
+ const patch = id && api ? slashRowPreview(id, committedChatPrefs(api)) : null;
19
+ const key = patch ? JSON.stringify(patch) : "";
20
+ useEffect(() => {
21
+ if (!preview || !key) return;
22
+ preview(JSON.parse(key));
23
+ return () => preview(null);
24
+ }, [preview, key]);
25
+ return null;
26
+ }
@@ -0,0 +1,120 @@
1
+ "use client";
2
+
3
+ import { memo, useCallback, useRef } from "react";
4
+ import {
5
+ useScrollLock,
6
+ useAuiState,
7
+ type ReasoningMessagePartComponent,
8
+ type ReasoningGroupComponent,
9
+ } from "@assistant-ui/react";
10
+ import { MarkdownText } from "./markdown-text";
11
+ import {
12
+ ANIMATION_DURATION,
13
+ ReasoningRoot as ReasoningRootBase,
14
+ ReasoningTrigger,
15
+ ReasoningContent,
16
+ ReasoningText,
17
+ ReasoningFade,
18
+ reasoningVariants,
19
+ type ReasoningRootProps,
20
+ } from "./reasoning";
21
+
22
+ export type { ReasoningRootProps } from "./reasoning";
23
+
24
+ /** `ReasoningRoot` with the thread viewport scroll locked during disclosure animations. */
25
+ function ReasoningRoot({
26
+ ref,
27
+ onAnimationStart,
28
+ ...props
29
+ }: ReasoningRootProps) {
30
+ const collapsibleRef = useRef<HTMLDivElement | null>(null);
31
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
32
+
33
+ const handleAnimationStart = useCallback(() => {
34
+ lockScroll();
35
+ onAnimationStart?.();
36
+ }, [lockScroll, onAnimationStart]);
37
+
38
+ const composedRef = useCallback(
39
+ (node: HTMLDivElement | null) => {
40
+ collapsibleRef.current = node;
41
+ if (typeof ref === "function") {
42
+ ref(node);
43
+ } else if (ref) {
44
+ ref.current = node;
45
+ }
46
+ },
47
+ [ref],
48
+ );
49
+
50
+ return (
51
+ <ReasoningRootBase
52
+ ref={composedRef}
53
+ onAnimationStart={handleAnimationStart}
54
+ {...props}
55
+ />
56
+ );
57
+ }
58
+
59
+ const ReasoningImpl: ReasoningMessagePartComponent = () => <MarkdownText />;
60
+
61
+ const ReasoningGroupImpl: ReasoningGroupComponent = ({
62
+ children,
63
+ startIndex,
64
+ endIndex,
65
+ }) => {
66
+ const isReasoningStreaming = useAuiState((s) => {
67
+ if (s.message.status?.type !== "running") return false;
68
+ for (let index = startIndex; index <= endIndex; index++) {
69
+ if (s.message.parts[index]?.status.type === "running") return true;
70
+ }
71
+ return false;
72
+ });
73
+
74
+ return (
75
+ <ReasoningRoot streaming={isReasoningStreaming}>
76
+ <ReasoningTrigger active={isReasoningStreaming} />
77
+ <ReasoningContent aria-busy={isReasoningStreaming}>
78
+ <ReasoningText>{children}</ReasoningText>
79
+ </ReasoningContent>
80
+ </ReasoningRoot>
81
+ );
82
+ };
83
+
84
+ const Reasoning = memo(
85
+ ReasoningImpl,
86
+ ) as unknown as ReasoningMessagePartComponent & {
87
+ Root: typeof ReasoningRoot;
88
+ Trigger: typeof ReasoningTrigger;
89
+ Content: typeof ReasoningContent;
90
+ Text: typeof ReasoningText;
91
+ Fade: typeof ReasoningFade;
92
+ };
93
+
94
+ Reasoning.displayName = "Reasoning";
95
+ Reasoning.Root = ReasoningRoot;
96
+ Reasoning.Trigger = ReasoningTrigger;
97
+ Reasoning.Content = ReasoningContent;
98
+ Reasoning.Text = ReasoningText;
99
+ Reasoning.Fade = ReasoningFade;
100
+
101
+ /**
102
+ * @deprecated This wrapper targets the legacy `components.ReasoningGroup`
103
+ * prop on `<MessagePrimitive.Parts>`. Use `<MessagePrimitive.GroupedParts>`
104
+ * with a `groupBy` returning `"group-reasoning"` and compose `ReasoningRoot`
105
+ * / `ReasoningTrigger` / `ReasoningContent` / `ReasoningText` directly.
106
+ * See `thread.aui.tsx` for an example.
107
+ */
108
+ const ReasoningGroup = memo(ReasoningGroupImpl);
109
+ ReasoningGroup.displayName = "ReasoningGroup";
110
+
111
+ export {
112
+ Reasoning,
113
+ ReasoningGroup,
114
+ ReasoningRoot,
115
+ ReasoningTrigger,
116
+ ReasoningContent,
117
+ ReasoningText,
118
+ ReasoningFade,
119
+ reasoningVariants,
120
+ };
@@ -0,0 +1,335 @@
1
+ "use client";
2
+
3
+ import {
4
+ createContext,
5
+ useCallback,
6
+ useContext,
7
+ useEffect,
8
+ useLayoutEffect,
9
+ useRef,
10
+ useState,
11
+ } from "react";
12
+ import { cva, type VariantProps } from "class-variance-authority";
13
+ import { DisclosureChevron } from "../disclosure-chevron";
14
+ import { DotMatrix } from "../DotMatrix";
15
+ import {
16
+ Collapsible,
17
+ CollapsibleContent,
18
+ CollapsibleTrigger,
19
+ } from "./ui/collapsible";
20
+ import { cn } from "../../../lib/utils";
21
+ import { useExportKeepMounted } from "../../../replay/export-mount";
22
+ import { OverlayScrollbar } from "../overlay-scrollbar";
23
+ import { useTraceT } from "../trace-i18n";
24
+ import { stockRadius, useStockShape } from "./stock-shape";
25
+
26
+ export const ANIMATION_DURATION = 200;
27
+
28
+ const ReasoningPreviewContext = createContext(false);
29
+
30
+ const reasoningVariants = cva("aui-reasoning-root mb-4 w-full", {
31
+ variants: {
32
+ variant: {
33
+ outline: "border px-3 py-2",
34
+ ghost: "",
35
+ muted: "bg-surface-2/50 px-3 py-2",
36
+ },
37
+ },
38
+ defaultVariants: {
39
+ variant: "outline",
40
+ },
41
+ });
42
+
43
+ export type ReasoningRootProps = Omit<
44
+ React.ComponentProps<typeof Collapsible>,
45
+ "open" | "onOpenChange"
46
+ > &
47
+ VariantProps<typeof reasoningVariants> & {
48
+ open?: boolean;
49
+ onOpenChange?: (open: boolean) => void;
50
+ defaultOpen?: boolean;
51
+ /**
52
+ * Whether the reasoning is currently streaming. While `true` the
53
+ * disclosure is held open with a bottom-pinned live preview; when
54
+ * streaming ends it returns to `defaultOpen`, and the first manual
55
+ * toggle takes over the open/close state permanently. The live preview
56
+ * keeps following the newest tokens while the disclosure is open during
57
+ * streaming, even after a manual toggle, and pauses while the reader is
58
+ * scrolled up.
59
+ */
60
+ streaming?: boolean;
61
+ /** Called right before the disclosure animates, on toggle and on streaming transitions. */
62
+ onAnimationStart?: () => void;
63
+ };
64
+
65
+ function ReasoningRoot({
66
+ className,
67
+ variant,
68
+ open: controlledOpen,
69
+ onOpenChange: controlledOnOpenChange,
70
+ defaultOpen = false,
71
+ streaming,
72
+ onAnimationStart,
73
+ children,
74
+ ...props
75
+ }: ReasoningRootProps) {
76
+ const stock = useStockShape();
77
+ const initialOpenRef = useRef(defaultOpen);
78
+ const [userOpen, setUserOpen] = useState<boolean | null>(null);
79
+
80
+ const isControlled = controlledOpen !== undefined;
81
+ const isOpen = isControlled
82
+ ? controlledOpen
83
+ : (userOpen ?? (streaming || initialOpenRef.current));
84
+ const isPreview = streaming === true && isOpen;
85
+
86
+ const prevStreamingRef = useRef(streaming);
87
+ useLayoutEffect(() => {
88
+ if (prevStreamingRef.current === streaming) return;
89
+ prevStreamingRef.current = streaming;
90
+ // A streaming transition only animates the panel when the resting state
91
+ // is collapsed; with `defaultOpen` the disclosure stays open across it.
92
+ if (!isControlled && userOpen === null && !initialOpenRef.current) {
93
+ onAnimationStart?.();
94
+ }
95
+ }, [streaming, isControlled, userOpen, onAnimationStart]);
96
+
97
+ const handleOpenChange = useCallback(
98
+ (open: boolean) => {
99
+ onAnimationStart?.();
100
+ if (!isControlled) {
101
+ setUserOpen(open);
102
+ }
103
+ controlledOnOpenChange?.(open);
104
+ },
105
+ [onAnimationStart, isControlled, controlledOnOpenChange],
106
+ );
107
+
108
+ return (
109
+ <Collapsible
110
+ data-slot="reasoning-root"
111
+ data-variant={variant}
112
+ open={isOpen}
113
+ onOpenChange={handleOpenChange}
114
+ className={cn(
115
+ "group/reasoning-root",
116
+ // assistant-ui's outline/muted reasoning box is rounded-lg.
117
+ reasoningVariants({ variant }),
118
+ (variant ?? "outline") !== "ghost" && stockRadius(stock, "rounded-lg"),
119
+ className,
120
+ )}
121
+ style={
122
+ {
123
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
124
+ } as React.CSSProperties
125
+ }
126
+ {...props}
127
+ >
128
+ <ReasoningPreviewContext.Provider value={isPreview}>
129
+ {children}
130
+ </ReasoningPreviewContext.Provider>
131
+ </Collapsible>
132
+ );
133
+ }
134
+
135
+ function ReasoningFade({
136
+ side = "bottom",
137
+ className,
138
+ ...props
139
+ }: React.ComponentProps<"div"> & { side?: "top" | "bottom" }) {
140
+ if (side === "top") {
141
+ return (
142
+ <div
143
+ data-slot="reasoning-fade"
144
+ className={cn(
145
+ "aui-reasoning-fade pointer-events-none absolute inset-x-0 top-0 z-10 h-8",
146
+ "bg-[linear-gradient(to_bottom,var(--color-background),transparent)]",
147
+ "group-data-[variant=muted]/reasoning-root:bg-[linear-gradient(to_bottom,color-mix(in_oklab,var(--color-muted)_50%,var(--color-background)),transparent)]",
148
+ "fade-in-0 animate-in",
149
+ "animation-duration-(--animation-duration)",
150
+ className,
151
+ )}
152
+ {...props}
153
+ />
154
+ );
155
+ }
156
+
157
+ return (
158
+ <div
159
+ data-slot="reasoning-fade"
160
+ className={cn(
161
+ "aui-reasoning-fade pointer-events-none absolute inset-x-0 bottom-0 z-10 h-8",
162
+ "bg-[linear-gradient(to_top,var(--color-background),transparent)]",
163
+ "group-data-[variant=muted]/reasoning-root:bg-[linear-gradient(to_top,color-mix(in_oklab,var(--color-muted)_50%,var(--color-background)),transparent)]",
164
+ "fade-in-0 animate-in",
165
+ "animation-duration-(--animation-duration)",
166
+ className,
167
+ )}
168
+ {...props}
169
+ />
170
+ );
171
+ }
172
+
173
+ function ReasoningTrigger({
174
+ active,
175
+ duration,
176
+ className,
177
+ ...props
178
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
179
+ active?: boolean;
180
+ duration?: number;
181
+ }) {
182
+ const reasoningLabel = useTraceT().t("reasoning");
183
+ const durationText = duration ? ` (${duration}s)` : "";
184
+
185
+ return (
186
+ <CollapsibleTrigger
187
+ data-slot="reasoning-trigger"
188
+ className={cn(
189
+ "aui-reasoning-trigger group/trigger text-ink-mute hover:text-ink flex max-w-[75%] origin-left items-center gap-2 py-1.5 text-xs transition-[color,scale] active:scale-[0.98]",
190
+ className,
191
+ )}
192
+ {...props}
193
+ >
194
+ <DotMatrix
195
+ state={active ? "thinking" : "thought"}
196
+ decorative
197
+ className="aui-reasoning-trigger-icon size-4 shrink-0"
198
+ />
199
+ <span
200
+ data-slot="reasoning-trigger-label"
201
+ className={cn(
202
+ "aui-reasoning-trigger-label-wrapper inline-block leading-none tabular-nums",
203
+ )}
204
+ >
205
+ {reasoningLabel}{durationText}
206
+ </span>
207
+ <DisclosureChevron />
208
+ </CollapsibleTrigger>
209
+ );
210
+ }
211
+
212
+ function ReasoningContent({
213
+ className,
214
+ children,
215
+ ...props
216
+ }: React.ComponentProps<typeof CollapsibleContent>) {
217
+ const isPreview = useContext(ReasoningPreviewContext);
218
+ const keepMounted = useExportKeepMounted();
219
+
220
+ return (
221
+ <CollapsibleContent
222
+ keepMounted={keepMounted}
223
+ data-slot="reasoning-content"
224
+ className={cn(
225
+ "aui-reasoning-content text-ink-mute relative overflow-hidden text-sm outline-none",
226
+ "group/collapsible-content ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:animate-none",
227
+ "data-closed:animate-collapsible-up",
228
+ "data-open:animate-collapsible-down",
229
+ "data-closed:fill-mode-forwards",
230
+ "data-closed:pointer-events-none",
231
+ "[--tw-duration:var(--animation-duration)]",
232
+ className,
233
+ )}
234
+ {...props}
235
+ >
236
+ <ReasoningFade side="top" />
237
+ {children}
238
+ {isPreview ? <ReasoningFade /> : null}
239
+ </CollapsibleContent>
240
+ );
241
+ }
242
+
243
+ function ReasoningText({
244
+ className,
245
+ children,
246
+ ...props
247
+ }: React.ComponentProps<"div">) {
248
+ const isPreview = useContext(ReasoningPreviewContext);
249
+ const scrollRef = useRef<HTMLDivElement>(null);
250
+ const contentRef = useRef<HTMLDivElement>(null);
251
+
252
+ useEffect(() => {
253
+ if (!isPreview) return;
254
+ const scrollEl = scrollRef.current;
255
+ const contentEl = contentRef.current;
256
+ if (!scrollEl || !contentEl) return;
257
+
258
+ let pinned = true;
259
+ let lastScrollTop = scrollEl.scrollTop;
260
+ let lastScrollHeight = scrollEl.scrollHeight;
261
+ const isAtBottom = () =>
262
+ Math.abs(
263
+ scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight,
264
+ ) <= 1 || scrollEl.scrollHeight <= scrollEl.clientHeight;
265
+
266
+ const pin = () => {
267
+ if (!pinned) return;
268
+ scrollEl.scrollTop = scrollEl.scrollHeight;
269
+ };
270
+ // A pin's own scroll event can arrive after new content grew the scroll
271
+ // height and read as "not at bottom"; only an upward move at unchanged
272
+ // scroll height is user intent.
273
+ const onScroll = () => {
274
+ if (isAtBottom()) {
275
+ pinned = true;
276
+ } else if (
277
+ scrollEl.scrollTop < lastScrollTop &&
278
+ scrollEl.scrollHeight === lastScrollHeight
279
+ ) {
280
+ pinned = false;
281
+ }
282
+ lastScrollTop = scrollEl.scrollTop;
283
+ lastScrollHeight = scrollEl.scrollHeight;
284
+ };
285
+
286
+ pin();
287
+ scrollEl.addEventListener("scroll", onScroll);
288
+ const observer = new ResizeObserver(pin);
289
+ observer.observe(contentEl);
290
+ return () => {
291
+ scrollEl.removeEventListener("scroll", onScroll);
292
+ observer.disconnect();
293
+ };
294
+ }, [isPreview]);
295
+
296
+ return (
297
+ <div className="relative">
298
+ <div
299
+ ref={scrollRef}
300
+ data-slot="reasoning-text"
301
+ className={cn(
302
+ "aui-reasoning-text relative z-0 max-h-64 overflow-y-auto ps-6 pt-2 pb-2 leading-relaxed text-pretty",
303
+ "transform-gpu transition-[transform,opacity] ease-[cubic-bezier(0.32,0.72,0,1)]",
304
+ "motion-reduce:animate-none",
305
+ "group-data-open/collapsible-content:animate-in",
306
+ "group-data-closed/collapsible-content:animate-out",
307
+ "group-data-open/collapsible-content:fade-in-0",
308
+ "group-data-closed/collapsible-content:fade-out-0",
309
+ "group-data-open/collapsible-content:slide-in-from-top-4",
310
+ "group-data-closed/collapsible-content:slide-out-to-top-4",
311
+ "group-data-open/collapsible-content:blur-in-[2px]",
312
+ "group-data-closed/collapsible-content:blur-out-[2px]",
313
+ "group-data-open/collapsible-content:animation-duration-(--animation-duration)",
314
+ "group-data-closed/collapsible-content:animation-duration-(--animation-duration)",
315
+ className,
316
+ )}
317
+ {...props}
318
+ >
319
+ <div ref={contentRef} className="aui-reasoning-text-content space-y-4">
320
+ {children}
321
+ </div>
322
+ </div>
323
+ <OverlayScrollbar targetRef={scrollRef} width={4} className="aui-reasoning-scroll" />
324
+ </div>
325
+ );
326
+ }
327
+
328
+ export {
329
+ ReasoningRoot,
330
+ ReasoningTrigger,
331
+ ReasoningContent,
332
+ ReasoningText,
333
+ ReasoningFade,
334
+ reasoningVariants,
335
+ };