@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,361 @@
1
+ "use client";
2
+
3
+ /**
4
+ * DigichatLauncher — the reusable corner entry point for embedded digichat.
5
+ *
6
+ * Idle is a 30px square carrying the canonical compact terminal mark. Hover or
7
+ * keyboard focus types `digichat` one character at a time without changing the
8
+ * control's height or border. Opening replaces that square in place with a chat
9
+ * panel that expands in two steps from the same corner: first sideways into a
10
+ * composer-height bar, then upward to full height. The transparent backdrop,
11
+ * header close button, and Escape key all dismiss it, reversing both steps.
12
+ *
13
+ * The launcher portals to document.body by default so a backdrop-filter or
14
+ * transformed app shell cannot trap its fixed positioning. Reference specimens
15
+ * can set `portal={false}` to contain it inside a positioned stage.
16
+ *
17
+ * Import `@digithings-ai/ui/styles/digichat-launcher.css` once in the app shell.
18
+ */
19
+ import {
20
+ useCallback,
21
+ useEffect,
22
+ useRef,
23
+ useState,
24
+ useSyncExternalStore,
25
+ type CSSProperties,
26
+ type ReactNode,
27
+ } from "react";
28
+ import { createPortal } from "react-dom";
29
+
30
+ import { TerminalMark } from "../symbols/terminal-marks";
31
+ import { DigichatWordmark } from "./DigichatWordmark";
32
+ import { DotMatrix } from "./DotMatrix";
33
+
34
+ const WORDMARK = "digichat";
35
+ const TYPE_MS = 48;
36
+ /** Must match the close animation in styles/digichat-launcher.css. */
37
+ const CLOSE_MS = 340;
38
+
39
+ const subscribeToClient = () => () => {};
40
+ const getClientSnapshot = () => true;
41
+ const getServerSnapshot = () => false;
42
+
43
+ /**
44
+ * Test a keydown against a `mod+k` / `ctrl+shift+d` style hotkey.
45
+ *
46
+ * `mod` means "ctrl or meta" so one deployment string works on both macOS and
47
+ * Windows/Linux; naming `ctrl` or `meta` explicitly pins that one. Every
48
+ * modifier not named must be absent, so `k` alone never fires on `mod+k`. A
49
+ * malformed string (empty token, e.g. `k+` or `mod++k`) matches nothing rather
50
+ * than silently degrading to the bare key.
51
+ */
52
+ export function matchesHotkey(event: KeyboardEvent, hotkey: string): boolean {
53
+ const parts = hotkey.split("+");
54
+ if (parts.some((part) => part.trim() === "")) return false;
55
+ const tokens = parts.map((token) => token.trim().toLowerCase());
56
+ if (tokens.length === 0) return false;
57
+ const key = tokens[tokens.length - 1];
58
+ const mods = new Set(tokens.slice(0, -1));
59
+ const needsCtrl = mods.has("ctrl");
60
+ const needsMeta = mods.has("meta") || mods.has("cmd");
61
+ const needsMod = mods.has("mod");
62
+ const needsAlt = mods.has("alt") || mods.has("option");
63
+ const needsShift = mods.has("shift");
64
+
65
+ if (needsCtrl && !event.ctrlKey) return false;
66
+ if (needsMeta && !event.metaKey) return false;
67
+ // `mod` is exactly one of ctrl/meta — both held is not the shortcut.
68
+ if (needsMod && event.ctrlKey === event.metaKey) return false;
69
+ if (!needsCtrl && !needsMod && event.ctrlKey) return false;
70
+ if (!needsMeta && !needsMod && event.metaKey) return false;
71
+ if (needsAlt !== event.altKey) return false;
72
+ if (needsShift !== event.shiftKey) return false;
73
+ return event.key.toLowerCase() === key;
74
+ }
75
+
76
+ export type DigichatLauncherProps = {
77
+ /** Embedded chat surface, usually the digichat iframe. */
78
+ children: ReactNode;
79
+ /** Header label inside the expanded panel. */
80
+ title?: ReactNode;
81
+ /** Accessible name for the expanded panel. */
82
+ ariaLabel?: string;
83
+ /** Render into document.body (default) or inside the current container. */
84
+ portal?: boolean;
85
+ /**
86
+ * Keyboard shortcut that opens the panel while it is closed, e.g. `mod+k`.
87
+ * See `matchesHotkey` for the accepted syntax.
88
+ */
89
+ hotkey?: string;
90
+ /** Start open for demos or controlled previews. */
91
+ defaultOpen?: boolean;
92
+ /** Called after opening or after the close animation completes. */
93
+ onOpenChange?: (open: boolean) => void;
94
+ className?: string;
95
+ /** Optional CSS custom properties such as panel dimensions or offsets. */
96
+ style?: CSSProperties;
97
+ /** Reset the in-process thread. Rendered only when a caller wires it (e.g. the gallery specimen). */
98
+ onNewChat?: () => void;
99
+ };
100
+
101
+ export function DigichatLauncher({
102
+ children,
103
+ title = "digichat",
104
+ ariaLabel = "digichat",
105
+ portal = true,
106
+ hotkey,
107
+ defaultOpen = false,
108
+ onOpenChange,
109
+ className,
110
+ style,
111
+ onNewChat,
112
+ }: DigichatLauncherProps) {
113
+ /* A portal cannot render on the server. useSyncExternalStore supplies a
114
+ hydration-safe client signal without a mount effect whose sole purpose is
115
+ a synchronous state update. */
116
+ const mounted = useSyncExternalStore(
117
+ subscribeToClient,
118
+ getClientSnapshot,
119
+ getServerSnapshot,
120
+ );
121
+ const [open, setOpen] = useState(defaultOpen);
122
+ const [closing, setClosing] = useState(false);
123
+ const [hasOpened, setHasOpened] = useState(defaultOpen);
124
+ const triggerRef = useRef<HTMLButtonElement>(null);
125
+ const closeRef = useRef<HTMLButtonElement>(null);
126
+ const typedRef = useRef<HTMLSpanElement>(null);
127
+ const typingTimerRef = useRef<number | null>(null);
128
+ const closeTimerRef = useRef<number | null>(null);
129
+ /* Focus is restored to the trigger on close for keyboard users, but a
130
+ pointer-driven close should leave a bare square rather than a typed
131
+ wordmark — `:focus-visible` is too unreliable here to decide that. */
132
+ const skipFocusTypeRef = useRef(false);
133
+ const pendingReturnRef = useRef<{ type: boolean } | null>(null);
134
+
135
+ const stopTyping = () => {
136
+ if (typingTimerRef.current !== null) {
137
+ window.clearTimeout(typingTimerRef.current);
138
+ typingTimerRef.current = null;
139
+ }
140
+ };
141
+
142
+ const resetTrigger = () => {
143
+ stopTyping();
144
+ const trigger = triggerRef.current;
145
+ if (!trigger) return;
146
+ trigger.removeAttribute("data-typing");
147
+ if (typedRef.current) typedRef.current.textContent = "d";
148
+ };
149
+
150
+ const typeWordmark = () => {
151
+ if (open || closing) return;
152
+ stopTyping();
153
+ const trigger = triggerRef.current;
154
+ const typed = typedRef.current;
155
+ if (!trigger || !typed) return;
156
+
157
+ trigger.setAttribute("data-typing", "");
158
+ typed.textContent = "d";
159
+ let length = 1;
160
+
161
+ const reveal = () => {
162
+ length += 1;
163
+ typed.textContent = WORDMARK.slice(0, length);
164
+ if (length < WORDMARK.length) {
165
+ typingTimerRef.current = window.setTimeout(reveal, TYPE_MS);
166
+ } else {
167
+ typingTimerRef.current = null;
168
+ }
169
+ };
170
+
171
+ typingTimerRef.current = window.setTimeout(reveal, TYPE_MS);
172
+ };
173
+
174
+ const openPanel = () => {
175
+ stopTyping();
176
+ setHasOpened(true);
177
+ setOpen(true);
178
+ onOpenChange?.(true);
179
+ };
180
+
181
+ const closePanel = useCallback(
182
+ (options?: { typeOnReturn?: boolean }) => {
183
+ if (!open || closing) return;
184
+ pendingReturnRef.current = { type: options?.typeOnReturn === true };
185
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
186
+ setOpen(false);
187
+ onOpenChange?.(false);
188
+ return;
189
+ }
190
+ setClosing(true);
191
+ closeTimerRef.current = window.setTimeout(() => {
192
+ setOpen(false);
193
+ setClosing(false);
194
+ onOpenChange?.(false);
195
+ }, CLOSE_MS);
196
+ },
197
+ [closing, onOpenChange, open],
198
+ );
199
+
200
+ /* Focus restoration rides the trigger's own ref callback: it is the one
201
+ moment the node is guaranteed to exist, and focusing an already-focused
202
+ node fires no event, so the typing decision is made here rather than in
203
+ the focus handler. */
204
+ const attachTrigger = (node: HTMLButtonElement | null) => {
205
+ triggerRef.current = node;
206
+ if (!node) return;
207
+ const pending = pendingReturnRef.current;
208
+ if (!pending) return;
209
+ pendingReturnRef.current = null;
210
+ skipFocusTypeRef.current = true;
211
+ node.focus();
212
+ if (pending.type) {
213
+ skipFocusTypeRef.current = false;
214
+ typeWordmark();
215
+ return;
216
+ }
217
+ /* React may dispatch the focus this call produced after the current task,
218
+ so hold the suppression until that has been delivered, then clear any
219
+ typing it started. */
220
+ window.requestAnimationFrame(() => {
221
+ skipFocusTypeRef.current = false;
222
+ resetTrigger();
223
+ });
224
+ };
225
+
226
+ useEffect(() => {
227
+ if (!open) return;
228
+ const focusFrame = window.requestAnimationFrame(() => closeRef.current?.focus());
229
+ const onKeyDown = (event: KeyboardEvent) => {
230
+ if (event.key === "Escape") closePanel({ typeOnReturn: true });
231
+ };
232
+ window.addEventListener("keydown", onKeyDown);
233
+ return () => {
234
+ window.cancelAnimationFrame(focusFrame);
235
+ window.removeEventListener("keydown", onKeyDown);
236
+ };
237
+ }, [closePanel, open]);
238
+
239
+ /* The hotkey only opens: once the panel is up, Escape and the backdrop own
240
+ dismissal, so a shortcut cannot toggle the surface out from under a user
241
+ mid-message. `openPanelRef` keeps the listener stable across renders. */
242
+ const openPanelRef = useRef(openPanel);
243
+ // eslint-disable-next-line react-hooks/refs -- useLatest for the hotkey listener
244
+ openPanelRef.current = openPanel;
245
+
246
+ useEffect(() => {
247
+ if (!hotkey || open || closing) return;
248
+ const onKeyDown = (event: KeyboardEvent) => {
249
+ if (!matchesHotkey(event, hotkey)) return;
250
+ event.preventDefault();
251
+ openPanelRef.current();
252
+ };
253
+ window.addEventListener("keydown", onKeyDown);
254
+ return () => window.removeEventListener("keydown", onKeyDown);
255
+ }, [closing, hotkey, open]);
256
+
257
+ useEffect(
258
+ () => () => {
259
+ stopTyping();
260
+ if (closeTimerRef.current !== null) {
261
+ window.clearTimeout(closeTimerRef.current);
262
+ }
263
+ },
264
+ [],
265
+ );
266
+
267
+ const retainPanel = open || closing || hasOpened;
268
+ const launcher = (
269
+ <div
270
+ className={[
271
+ "digichat-launcher",
272
+ portal ? "" : "digichat-launcher--contained",
273
+ className ?? "",
274
+ ]
275
+ .filter(Boolean)
276
+ .join(" ")}
277
+ style={style}
278
+ >
279
+ {open ? (
280
+ <button
281
+ type="button"
282
+ className="digichat-launcher__backdrop"
283
+ aria-label="Close digichat"
284
+ tabIndex={-1}
285
+ onClick={() => closePanel()}
286
+ />
287
+ ) : null}
288
+ {retainPanel ? (
289
+ <section
290
+ className={[
291
+ "digichat-launcher__panel",
292
+ closing ? "is-closing" : "",
293
+ !open && !closing ? "is-hidden" : "",
294
+ ]
295
+ .filter(Boolean)
296
+ .join(" ")}
297
+ role="dialog"
298
+ aria-label={ariaLabel}
299
+ >
300
+ <header className="digichat-launcher__header">
301
+ <span>{title === "digichat" ? <DigichatWordmark /> : title}</span>
302
+ <div className="digichat-launcher__header-actions">
303
+ {onNewChat ? (
304
+ <button
305
+ type="button"
306
+ className="digichat-launcher__new"
307
+ aria-label="New chat"
308
+ data-tooltip="New chat"
309
+ onClick={onNewChat}
310
+ >
311
+ <DotMatrix state="newChat" decorative className="size-3.5" />
312
+ </button>
313
+ ) : null}
314
+ <button
315
+ ref={closeRef}
316
+ type="button"
317
+ className="digichat-launcher__close"
318
+ aria-label="Close digichat"
319
+ onClick={() => closePanel()}
320
+ >
321
+ <DotMatrix state="remove" decorative className="size-3.5" />
322
+ </button>
323
+ </div>
324
+ </header>
325
+ <div className="digichat-launcher__body">{children}</div>
326
+ </section>
327
+ ) : null}
328
+ {!open && !closing ? (
329
+ <button
330
+ ref={attachTrigger}
331
+ type="button"
332
+ className="digichat-launcher__trigger"
333
+ aria-label="Open digichat"
334
+ aria-expanded="false"
335
+ onMouseEnter={typeWordmark}
336
+ onMouseLeave={resetTrigger}
337
+ onFocus={() => {
338
+ if (skipFocusTypeRef.current) return;
339
+ typeWordmark();
340
+ }}
341
+ onBlur={resetTrigger}
342
+ onClick={openPanel}
343
+ >
344
+ <TerminalMark
345
+ variant="compact"
346
+ size={20}
347
+ className="digichat-launcher__mark"
348
+ />
349
+ <span className="digichat-launcher__word" aria-hidden="true">
350
+ <span ref={typedRef}>d</span>
351
+ <span className="digichat-launcher__cursor" />
352
+ </span>
353
+ </button>
354
+ ) : null}
355
+ </div>
356
+ );
357
+
358
+ if (!portal) return launcher;
359
+ if (!mounted) return null;
360
+ return createPortal(launcher, document.body);
361
+ }
@@ -0,0 +1,118 @@
1
+ "use client";
2
+
3
+ /**
4
+ * First-party digichat Thread — the gallery `/chatbot` Thread module
5
+ * (`gallery-thread/thread.aui.tsx` + slots + chatbot.css), not a parallel
6
+ * ChatMarkdown / ChatThinking / ChatToolCall tree.
7
+ */
8
+ import type { FormEvent, ReactNode } from "react";
9
+
10
+ import {
11
+ Thread,
12
+ type ComposerLayout,
13
+ type GroupDisclosureMode,
14
+ type ThreadComponents,
15
+ type ThreadGroupPart,
16
+ type ThreadProps,
17
+ type ThreadSlashTrigger,
18
+ type ThreadMentionTrigger,
19
+ } from "./gallery-thread/thread.aui";
20
+ import type { WorkVisibility } from "./stock/skin-types";
21
+ import type { ScrollMode } from "./gallery-thread/scroll-mode";
22
+
23
+ export type DigichatThreadProps = {
24
+ welcome?: string;
25
+ /** Subparagraphs under the headline. Deploy `chrome.welcome.body`. */
26
+ welcomeBody?: readonly string[];
27
+ /** Welcome-state example prompts. Deploy `chrome.suggestions`. */
28
+ suggestions?: readonly string[];
29
+ placeholder?: string;
30
+ className?: string;
31
+ /** Embed send-gate / system page-context attach. Form onSubmit. */
32
+ onComposerSubmit?: (event: FormEvent<HTMLFormElement>) => void;
33
+ composerLayout?: ComposerLayout;
34
+ components?: ThreadComponents;
35
+ /** Native `/` trigger popover (`unstable_useSlashCommandAdapter`). */
36
+ slash?: ThreadSlashTrigger;
37
+ /** Native `@` mention popover for catalog tools. */
38
+ mention?: ThreadMentionTrigger;
39
+ /** Attachment names whose chips render nowhere (file part still reaches the model). */
40
+ hiddenAttachmentNames?: readonly string[];
41
+ /** Deploy `reasoning` disclosure mode. Defaults to `collapsed`. */
42
+ reasoningMode?: GroupDisclosureMode;
43
+ /** Deploy `toolCalls` disclosure mode. Defaults to `collapsed`. */
44
+ toolCallsMode?: GroupDisclosureMode;
45
+ /** How much of the agent's work the user sees: quiet | balanced | verbose. */
46
+ workVisibility?: WorkVisibility;
47
+ /** Row rendered inside the composer border, under the input. */
48
+ composerToolbar?: ReactNode;
49
+ /** `always` reserves a scrollbar gutter; `auto` shows bars only on scroll. */
50
+ scrollbars?: "always" | "auto";
51
+ /** Worked-chain rhythm. `default` is the fixed spacing. */
52
+ density?: "compact" | "default" | "airy";
53
+ /** `follow` chases the stream; `free` never moves the viewport. */
54
+ scrollMode?: ScrollMode;
55
+ /**
56
+ * Private session: the work surfaces that carry user data — reasoning text
57
+ * and tool-call JSON — do not mount at all, and the composer shows the mode
58
+ * badge. Display-only; see packages/ui/ARCHITECTURE.md.
59
+ */
60
+ privateMode?: boolean;
61
+ };
62
+
63
+ export function DigichatThread({
64
+ welcome = "What should we inspect?",
65
+ welcomeBody = [],
66
+ suggestions,
67
+ placeholder = "Ask digichat…",
68
+ className,
69
+ onComposerSubmit,
70
+ composerLayout,
71
+ components,
72
+ slash,
73
+ mention,
74
+ hiddenAttachmentNames,
75
+ reasoningMode,
76
+ toolCallsMode,
77
+ workVisibility,
78
+ composerToolbar,
79
+ scrollbars,
80
+ density = "default",
81
+ scrollMode,
82
+ privateMode,
83
+ }: DigichatThreadProps) {
84
+ return (
85
+ <Thread
86
+ welcome={welcome}
87
+ welcomeBody={welcomeBody}
88
+ suggestions={suggestions}
89
+ placeholder={placeholder}
90
+ className={className}
91
+ onComposerSubmit={onComposerSubmit}
92
+ composerLayout={composerLayout}
93
+ components={components}
94
+ slash={slash}
95
+ mention={mention}
96
+ hiddenAttachmentNames={hiddenAttachmentNames}
97
+ reasoningMode={reasoningMode}
98
+ toolCallsMode={toolCallsMode}
99
+ workVisibility={workVisibility}
100
+ composerToolbar={composerToolbar}
101
+ scrollbars={scrollbars}
102
+ density={density}
103
+ scrollMode={scrollMode}
104
+ privateMode={privateMode}
105
+ />
106
+ );
107
+ }
108
+
109
+ export {
110
+ Thread,
111
+ type ComposerLayout,
112
+ type GroupDisclosureMode,
113
+ type ThreadComponents,
114
+ type ThreadGroupPart,
115
+ type ThreadProps,
116
+ type ThreadSlashTrigger,
117
+ type ThreadMentionTrigger,
118
+ };
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ /**
4
+ * DigichatThreadList — terminal-nav conversation list (not a ChatGPT history
5
+ * rail). Wraps ThreadListPrimitive so gallery mocks and product memory
6
+ * persistence share one dress.
7
+ */
8
+ import {
9
+ ThreadListItemPrimitive,
10
+ ThreadListPrimitive,
11
+ } from "@assistant-ui/react";
12
+
13
+ import { digichatSurfaces } from "./chat-surfaces";
14
+ import { DigichatWordmark } from "./DigichatWordmark";
15
+ import { DotMatrix } from "./DotMatrix";
16
+
17
+ export type DigichatThreadListProps = {
18
+ className?: string;
19
+ /**
20
+ * Landmark the list renders as. The standalone sidebar is page-level
21
+ * complementary content (`aside`); embedded in a page section (e.g. the
22
+ * digiquant landing chat band) it is a thread navigator inside `<main>`,
23
+ * where a complementary landmark is a violation — pass `"nav"`.
24
+ */
25
+ landmark?: "aside" | "nav";
26
+ };
27
+
28
+ export function DigichatThreadList({ className, landmark = "aside" }: DigichatThreadListProps) {
29
+ const cls = [digichatSurfaces.list, className ?? ""].filter(Boolean).join(" ");
30
+ const Tag = landmark;
31
+ return (
32
+ <Tag className={cls} data-memory-thread-list aria-label="Conversations">
33
+ <div className="flex h-8 shrink-0 items-center justify-between gap-2 border-b border-term-hair px-[0.7rem]">
34
+ <span className="min-w-0 flex-1">
35
+ <DigichatWordmark />
36
+ </span>
37
+ <ThreadListPrimitive.New className={digichatSurfaces.action} aria-label="New chat">
38
+ <DotMatrix state="newChat" decorative className="size-3.5" />
39
+ </ThreadListPrimitive.New>
40
+ </div>
41
+ <ThreadListPrimitive.Root className="flex min-h-0 flex-1 flex-col overflow-y-auto py-[0.25rem]">
42
+ <ThreadListPrimitive.Items>
43
+ {() => (
44
+ <ThreadListItemPrimitive.Root className="rounded-none">
45
+ <ThreadListItemPrimitive.Trigger className={digichatSurfaces.listItem}>
46
+ <ThreadListItemPrimitive.Title fallback="new chat" />
47
+ </ThreadListItemPrimitive.Trigger>
48
+ </ThreadListItemPrimitive.Root>
49
+ )}
50
+ </ThreadListPrimitive.Items>
51
+ </ThreadListPrimitive.Root>
52
+ </Tag>
53
+ );
54
+ }
@@ -0,0 +1,24 @@
1
+ "use client";
2
+
3
+ import { DIGICHAT } from "@digithings-ai/hero-banner/definitions";
4
+ import { HeroBanner } from "@digithings-ai/hero-banner/web";
5
+
6
+ /** Square-pixel DIGICHAT mark, drawn from the shared hero-banner definition
7
+ * (`packages/hero-banner`, `DIGICHAT`: scramble 80/240/180 with a 960 hold,
8
+ * settled at 2000 ms, seed 0). Plays once per tab — the session claim lives
9
+ * inside `HeroBanner`, so header remounts keep the settled mark instead of
10
+ * replaying. `live={false}` keeps the replaced component's settled behavior
11
+ * rather than the definition's streaming LIVE pass. Reduced motion paints
12
+ * the settled mark with no scramble (inside `HeroBanner`, not in CSS). The
13
+ * fixed 140x20 box preserves the replaced SVG's intrinsic size (70x10 units
14
+ * at cell 2); the `span` keeps both callers' `<span>` nesting valid. The
15
+ * server render and a no-JS page show the settled mark: `HeroBanner`
16
+ * renders it as a CSS mask over the mark's colour, so the canvas is never an
17
+ * empty box before it paints. */
18
+ export function DigichatWordmark() {
19
+ return (
20
+ <span className="digichat-wordmark" style={{ display: "inline-block", width: 140, height: 20 }}>
21
+ <HeroBanner def={DIGICHAT} live={false} />
22
+ </span>
23
+ );
24
+ }