@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,185 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ /**
4
+ * PerformanceDashboard — the book-level surface promoted from the design
5
+ * reference (finance/performance-dashboard): a value/return headline row, a
6
+ * strip of aggregate ratios, and an allocation-by-strategy breakdown. Sits
7
+ * above the single-strategy tearsheet metrics (<PerfMetrics/>): this is the
8
+ * whole book. P&L reads wear the money colors (`tone`); ratios stay ink; the
9
+ * allocation bars take the module accent. Server component — no state, no
10
+ * effects.
11
+ *
12
+ * `children` is the composite slot: an optional chart section rendered
13
+ * between the headline row and the ratio strip (intended for the
14
+ * finance-charts family — <EquityCurve/>, <SyncedTearsheet/> — passed in by
15
+ * the page, never imported here). Give the slot content a definite height;
16
+ * the dashboard only contributes the hairline divider.
17
+ *
18
+ * The hairline grammar between headline cells and ratio cells is
19
+ * sibling-index CSS (styles/finance-composites.css, pdash-*) keyed off the
20
+ * strip's `data-cols` — Tailwind can't express nth-child, so it stays CSS.
21
+ * Below 720px the headline stacks and the ratio strip collapses to 3-up.
22
+ *
23
+ * Wiring (in the consuming app):
24
+ * globals.css @import "@digithings-ai/ui/styles/finance-composites.css";
25
+ * @source "<path-to>/packages/ui/src/components/finance-composites";
26
+ */
27
+ export type DashboardHeadline = {
28
+ /** Mono micro-caps label — "portfolio value", "total return" … */
29
+ label: string;
30
+ /** Big tabular read — "$1.284M", "+28.4%" … */
31
+ value: string;
32
+ /** Money semantics on the value: only P&L reads take a tone. */
33
+ tone?: "up" | "down";
34
+ /** Small line under the value — "+$5.47K · +0.43% today", "since inception · 2y" … */
35
+ note?: string;
36
+ /** Money semantics on the note; untoned notes read muted ink. */
37
+ noteTone?: "up" | "down";
38
+ };
39
+
40
+ export type DashboardRatio = {
41
+ /** Mono micro-caps label — "sharpe", "max drawdown" … */
42
+ label: string;
43
+ /** Preformatted read — "2.31", "−18.4%" … */
44
+ value: string;
45
+ /** Money semantics: drawdown-class reads take "down"; ratios stay ink. */
46
+ tone?: "up" | "down";
47
+ };
48
+
49
+ export type DashboardAllocation = {
50
+ /** Strategy / sleeve name — "trend_xsec" … */
51
+ name: string;
52
+ /** Share of the book, 0–100; drives the accent bar width. */
53
+ pct: number;
54
+ };
55
+
56
+ export type PerformanceDashboardProps = {
57
+ /** Headline cells; designed for two (value + return), 1.4fr/1fr split. */
58
+ headlines: DashboardHeadline[];
59
+ ratios?: DashboardRatio[];
60
+ /** Desktop ratio cells per row (collapses to 3-up below 720px). */
61
+ ratioColumns?: 3 | 4 | 5 | 6;
62
+ allocations?: DashboardAllocation[];
63
+ /** Mono micro-caps heading over the allocation bars. */
64
+ allocationsLabel?: string;
65
+ /** Optional chart slot rendered after the headline row (see docblock). */
66
+ children?: ReactNode;
67
+ /** Extra classes on the dashboard shell (margins — the call site's business). */
68
+ className?: string;
69
+ };
70
+
71
+ const HEAD_COLS: Record<number, string> = {
72
+ 1: "grid-cols-1",
73
+ 2: "grid-cols-[1.4fr_1fr]",
74
+ 3: "grid-cols-3",
75
+ 4: "grid-cols-4",
76
+ };
77
+
78
+ const RATIO_COLS: Record<3 | 4 | 5 | 6, string> = {
79
+ 3: "grid-cols-3",
80
+ 4: "grid-cols-4",
81
+ 5: "grid-cols-5",
82
+ 6: "grid-cols-6",
83
+ };
84
+
85
+ export function PerformanceDashboard({
86
+ headlines,
87
+ ratios,
88
+ ratioColumns = 6,
89
+ allocations,
90
+ allocationsLabel = "allocation by strategy",
91
+ children,
92
+ className,
93
+ }: PerformanceDashboardProps) {
94
+ return (
95
+ <div
96
+ className={`overflow-hidden rounded-none border border-hair bg-surface${
97
+ className ? ` ${className}` : ""
98
+ }`}
99
+ >
100
+ <div className={`grid ${HEAD_COLS[headlines.length] ?? "grid-cols-2"} max-[720px]:grid-cols-1`}>
101
+ {headlines.map((h) => (
102
+ <div
103
+ key={h.label}
104
+ className="pdash-head flex flex-col gap-[0.3rem] px-[1.4rem] pb-[1.2rem] pt-[1.4rem]"
105
+ >
106
+ <span className="font-mono text-[0.58rem] uppercase tracking-[0.1em] text-ink-mute">
107
+ {h.label}
108
+ </span>
109
+ <span
110
+ className={`font-mono text-[clamp(1.6rem,4vw,2.2rem)] [font-variant-numeric:tabular-nums] ${
111
+ h.tone === "up" ? "text-up" : h.tone === "down" ? "text-down" : "text-ink"
112
+ }`}
113
+ >
114
+ {h.value}
115
+ </span>
116
+ {h.note ? (
117
+ <span
118
+ className={`font-mono ${
119
+ h.noteTone === "up"
120
+ ? "text-[0.72rem] text-up"
121
+ : h.noteTone === "down"
122
+ ? "text-[0.72rem] text-down"
123
+ : "text-[0.66rem] text-ink-mute"
124
+ }`}
125
+ >
126
+ {h.note}
127
+ </span>
128
+ ) : null}
129
+ </div>
130
+ ))}
131
+ </div>
132
+
133
+ {children ? <div className="border-t border-hair">{children}</div> : null}
134
+
135
+ {ratios && ratios.length > 0 ? (
136
+ <div
137
+ data-cols={ratioColumns}
138
+ className={`pdash-ratios grid ${RATIO_COLS[ratioColumns]} border-t border-hair max-[720px]:grid-cols-3`}
139
+ >
140
+ {ratios.map((r) => (
141
+ <div key={r.label} className="pdash-ratio flex flex-col gap-[0.3rem] px-4 py-[0.9rem]">
142
+ <span className="font-mono text-[0.52rem] uppercase tracking-[0.08em] text-ink-mute">
143
+ {r.label}
144
+ </span>
145
+ <span
146
+ className={`font-mono text-[0.98rem] [font-variant-numeric:tabular-nums] ${
147
+ r.tone === "up" ? "text-up" : r.tone === "down" ? "text-down" : "text-ink"
148
+ }`}
149
+ >
150
+ {r.value}
151
+ </span>
152
+ </div>
153
+ ))}
154
+ </div>
155
+ ) : null}
156
+
157
+ {allocations && allocations.length > 0 ? (
158
+ <div className="border-t border-hair px-[1.4rem] pb-[1.4rem] pt-[1.2rem]">
159
+ <p className="mx-0 mb-[0.8rem] mt-0 font-mono text-[0.58rem] uppercase tracking-[0.1em] text-ink-mute">
160
+ {allocationsLabel}
161
+ </p>
162
+ {allocations.map((a) => (
163
+ <div
164
+ key={a.name}
165
+ className="grid grid-cols-[6rem_1fr_3rem] items-center gap-[0.9rem] py-[0.35rem] font-mono text-[0.78rem] text-ink-soft"
166
+ >
167
+ <span className="min-w-0 truncate text-ink" title={a.name}>
168
+ {a.name}
169
+ </span>
170
+ <span className="h-2 overflow-hidden rounded-none bg-ink/[0.08]">
171
+ <span
172
+ className="block h-full rounded-none bg-accent"
173
+ style={{ width: `${a.pct}%` }}
174
+ />
175
+ </span>
176
+ <span className="text-end text-ink-soft [font-variant-numeric:tabular-nums]">
177
+ {a.pct}%
178
+ </span>
179
+ </div>
180
+ ))}
181
+ </div>
182
+ ) : null}
183
+ </div>
184
+ );
185
+ }
@@ -0,0 +1,144 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+
5
+ /**
6
+ * SortableTable — the reorderable leaderboard promoted from the design
7
+ * reference (data/sortable-table): click (or keyboard-activate — real
8
+ * <button>s in the headers) a column to sort, click again to flip. The active
9
+ * column shows a caret and reports `aria-sort` on its <th>; numeric columns
10
+ * sort numerically and right-align, text sorts lexically. Column `tone`
11
+ * wears the money colors (--up / --down) — returns up, drawdowns down —
12
+ * and everything else stays ink.
13
+ *
14
+ * The table grammar (srt-*) lives in styles/finance-composites.css: header
15
+ * hover/active state, caret accent, hairline row rules, td money colors —
16
+ * descendant/state selectors that stay CSS per migrate-vs-leave. Rows render
17
+ * fully server-side markup-wise; without JS you get the table in its default
18
+ * order.
19
+ *
20
+ * Wiring (in the consuming app):
21
+ * globals.css @import "@digithings-ai/ui/styles/finance-composites.css";
22
+ * @source "<path-to>/packages/ui/src/components/finance-composites";
23
+ */
24
+ export type SortableColumn<Row> = {
25
+ /** Row field this column reads (and sorts by). */
26
+ key: keyof Row & string;
27
+ /** Mono micro-caps header label. */
28
+ label: string;
29
+ /** Numeric columns right-align and default to descending on first sort. */
30
+ numeric?: boolean;
31
+ /** Preformats the cell read; defaults to String(value). */
32
+ format?: (value: Row[keyof Row & string], row: Row) => string;
33
+ /** Money semantics for the whole column: returns "up", drawdowns "down". */
34
+ tone?: "up" | "down";
35
+ /** Identifier column emphasis — the read stays ink instead of ink-soft. */
36
+ emphasis?: boolean;
37
+ };
38
+
39
+ export type SortableTableProps<Row> = {
40
+ rows: Row[];
41
+ columns: SortableColumn<Row>[];
42
+ /** Stable React key per row — e.g. `(r) => r.strat`. */
43
+ rowKey: (row: Row) => string;
44
+ /** Initial sort; defaults to the first column in its natural direction. */
45
+ defaultSort?: { key: keyof Row & string; dir?: "asc" | "desc" };
46
+ /** Extra classes on the scroll shell (margins — the call site's business). */
47
+ className?: string;
48
+ };
49
+
50
+ export function SortableTable<Row>({
51
+ rows,
52
+ columns,
53
+ rowKey,
54
+ defaultSort,
55
+ className,
56
+ }: SortableTableProps<Row>) {
57
+ const naturalDir = (key: keyof Row & string): "asc" | "desc" =>
58
+ columns.find((c) => c.key === key)?.numeric ? "desc" : "asc";
59
+
60
+ const initialKey = defaultSort?.key ?? columns[0]?.key;
61
+ const [sortKey, setSortKey] = useState<keyof Row & string>(initialKey);
62
+ const [dir, setDir] = useState<"asc" | "desc">(
63
+ defaultSort?.dir ?? (initialKey ? naturalDir(initialKey) : "asc"),
64
+ );
65
+
66
+ const sorted = [...rows].sort((a, b) => {
67
+ const av = a[sortKey];
68
+ const bv = b[sortKey];
69
+ const cmp =
70
+ typeof av === "number" && typeof bv === "number"
71
+ ? av - bv
72
+ : String(av).localeCompare(String(bv));
73
+ return dir === "asc" ? cmp : -cmp;
74
+ });
75
+
76
+ const onSort = (key: keyof Row & string) => {
77
+ if (key === sortKey) {
78
+ setDir((d) => (d === "asc" ? "desc" : "asc"));
79
+ } else {
80
+ setSortKey(key);
81
+ setDir(naturalDir(key));
82
+ }
83
+ };
84
+
85
+ return (
86
+ <div
87
+ // tabIndex + role/aria-label: this is a horizontally-scrolling region on
88
+ // narrow viewports (no wrap point in the table itself) — without a tab
89
+ // stop, a keyboard-only user (no touch, no scrollbar drag) has no way
90
+ // to focus it and arrow-key-scroll the columns that overflow.
91
+ tabIndex={0}
92
+ role="region"
93
+ aria-label="Table, scrollable horizontally"
94
+ className={`overflow-x-auto rounded-none border border-hair bg-surface${
95
+ className ? ` ${className}` : ""
96
+ }`}
97
+ >
98
+ <table className="srt-table">
99
+ <thead>
100
+ <tr>
101
+ {columns.map((c) => {
102
+ const active = c.key === sortKey;
103
+ return (
104
+ <th
105
+ key={c.key}
106
+ scope="col"
107
+ className={c.numeric ? "srt-r" : "srt-l"}
108
+ aria-sort={active ? (dir === "asc" ? "ascending" : "descending") : "none"}
109
+ >
110
+ <button
111
+ type="button"
112
+ className={`srt-head${active ? " is-active" : ""}`}
113
+ onClick={() => onSort(c.key)}
114
+ >
115
+ {c.label}
116
+ <span className="srt-caret" aria-hidden="true">
117
+ {active ? (dir === "asc" ? "▲" : "▼") : "↕"}
118
+ </span>
119
+ </button>
120
+ </th>
121
+ );
122
+ })}
123
+ </tr>
124
+ </thead>
125
+ <tbody>
126
+ {sorted.map((row) => (
127
+ <tr key={rowKey(row)}>
128
+ {columns.map((c) => (
129
+ <td
130
+ key={c.key}
131
+ className={`${c.numeric ? "srt-r" : "srt-l"}${c.tone ? ` ${c.tone}` : ""}${
132
+ c.emphasis ? " srt-sym" : ""
133
+ }`}
134
+ >
135
+ {c.format ? c.format(row[c.key], row) : String(row[c.key])}
136
+ </td>
137
+ ))}
138
+ </tr>
139
+ ))}
140
+ </tbody>
141
+ </table>
142
+ </div>
143
+ );
144
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * StockTicker — the scrolling market strip promoted from the design reference
3
+ * (finance/ticker-tape): one mono row of symbol · last · change looping
4
+ * seamlessly (content duplicated once, track translated exactly -50%) behind
5
+ * edge-fade masks, pause-on-hover/focus-within/tap (the container is
6
+ * tabbable so touch users can tap-to-focus and keyboard users can tab to it —
7
+ * :focus-within mirrors the :hover rule, no JS state needed). This is the one
8
+ * marquee that legitimately wears the money colors — a price change IS the
9
+ * up/down semantic — while the module accent stays out of it entirely. Pure
10
+ * CSS animation (styles/finance-composites.css), so a plain server component;
11
+ * the tape is fully readable with no JS and prefers-reduced-motion holds it
12
+ * still.
13
+ *
14
+ * Wiring (in the consuming app):
15
+ * globals.css @import "@digithings-ai/ui/styles/finance-composites.css";
16
+ * @source "<path-to>/packages/ui/src/components/finance-composites";
17
+ */
18
+ export type TickerItem = {
19
+ /** Instrument symbol — "BTC-PERP", "SPY", "US10Y" … */
20
+ symbol: string;
21
+ /** Preformatted last price — "63,410", "4.281%" … */
22
+ last: string;
23
+ /** Preformatted change magnitude — "1.24%" (direction carried by `up`). */
24
+ change: string;
25
+ /** Direction of the change: true wears --up, false wears --down. */
26
+ up: boolean;
27
+ };
28
+
29
+ export type StockTickerProps = {
30
+ /** The ticks on the tape — duplicated internally for the seamless loop. */
31
+ items: TickerItem[];
32
+ /** Extra classes on the tape shell (margins, widths — the call site's business). */
33
+ className?: string;
34
+ };
35
+
36
+ export function StockTicker({ items, className }: StockTickerProps) {
37
+ return (
38
+ <div
39
+ className={`tk${className ? ` ${className}` : ""}`}
40
+ tabIndex={0}
41
+ aria-label="Price ticker, tab or tap to pause"
42
+ >
43
+ <div className="tk-track">
44
+ {[...items, ...items].map((t, i) => (
45
+ <span
46
+ className="inline-flex items-baseline gap-2 whitespace-nowrap border-e border-hair px-[1.3rem] py-[0.7rem] font-mono text-[0.82rem] [font-variant-numeric:tabular-nums]"
47
+ key={`${t.symbol}-${i}`}
48
+ aria-hidden={i >= items.length || undefined}
49
+ >
50
+ <span className="tracking-[0.02em] text-ink">{t.symbol}</span>
51
+ <span className="text-ink-soft">{t.last}</span>
52
+ <span
53
+ className={`inline-flex items-center gap-[0.28rem] text-[0.76rem] ${
54
+ t.up ? "text-up" : "text-down"
55
+ }`}
56
+ >
57
+ <span aria-hidden="true">{t.up ? "▲" : "▼"}</span>
58
+ {t.change}
59
+ </span>
60
+ </span>
61
+ ))}
62
+ </div>
63
+ </div>
64
+ );
65
+ }
@@ -0,0 +1,226 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef } from "react";
4
+ import {
5
+ AreaSeries,
6
+ BaselineSeries,
7
+ ColorType,
8
+ createChart,
9
+ CrosshairMode,
10
+ type AreaData,
11
+ type BaselineData,
12
+ type IChartApi,
13
+ type Time,
14
+ } from "lightweight-charts";
15
+
16
+ /**
17
+ * SyncedTearsheet — the multi-pane tearsheet chart promoted from the design
18
+ * reference (finance/synced-tearsheet): ONE Lightweight Charts instance, two
19
+ * panes sharing a single time axis — cumulative equity on top, the underwater
20
+ * drawdown below. Because both live in one chart, the x-axis, crosshair and
21
+ * zoom are synced natively (no cross-chart plumbing). Equity wears the module
22
+ * accent (identity); drawdown wears --down (it only ever reads negative) —
23
+ * per the charting house rules, every color is read from a design token at
24
+ * runtime and a MutationObserver on data-theme re-themes live.
25
+ *
26
+ * This IS the multi-series primitive: add a pane per series rather than
27
+ * stacking separate charts. The finance-charts family's single-series
28
+ * specimens (price-chart / equity-curve / drawdown-plot) are siblings, not
29
+ * children — composites embed this component directly. Give the host a
30
+ * definite height (the reference wraps it in `.pc-frame--tall`); autoSize
31
+ * fills it. Canvas-only, so nothing to read without JS — decorative by
32
+ * default (aria-hidden) unless you pass `ariaLabel`.
33
+ *
34
+ * Wiring (in the consuming app):
35
+ * package: lightweight-charts ^5.2.0
36
+ * globals.css @source "<path-to>/packages/ui/src/components/finance-composites";
37
+ * (no family CSS needed — the chart paints from tokens on canvas)
38
+ */
39
+ export type TearsheetPoint = {
40
+ /** ISO date, yyyy-mm-dd — Lightweight Charts business-day time. */
41
+ time: string;
42
+ value: number;
43
+ };
44
+
45
+ export type SyncedTearsheetProps = {
46
+ /** Cumulative equity series (pane 0, module accent). */
47
+ equity: TearsheetPoint[];
48
+ /**
49
+ * Underwater drawdown series (pane 1, --down), in percent (≤ 0). Derived
50
+ * from `equity`'s running peak (one decimal) when omitted.
51
+ */
52
+ drawdown?: TearsheetPoint[];
53
+ /** Height share of the equity pane relative to the drawdown pane's 1. */
54
+ equityStretch?: number;
55
+ /** Describes the chart to AT; omitted = decorative (aria-hidden). */
56
+ ariaLabel?: string;
57
+ /** Extra classes on the host (defaults fill the parent: h-full w-full). */
58
+ className?: string;
59
+ /**
60
+ * Let page scroll/wheel/touch-drag pass through instead of panning or
61
+ * zooming the chart. Off by default — this component rides real dashboard
62
+ * dashboard surfaces (e.g. a workspace's drawdown view) where pan/zoom on
63
+ * the chart is an intended interaction. Turn it on only for a display
64
+ * specimen embedded in scrolling prose (see synced-tearsheet-reference.tsx)
65
+ * where nobody is meant to interact with the chart itself.
66
+ */
67
+ pageScrollThrough?: boolean;
68
+ };
69
+
70
+ function deriveDrawdown(equity: TearsheetPoint[]): TearsheetPoint[] {
71
+ let peak = -Infinity;
72
+ return equity.map((p) => {
73
+ peak = Math.max(peak, p.value);
74
+ return { time: p.time, value: Math.round((p.value / peak - 1) * 1000) / 10 };
75
+ });
76
+ }
77
+
78
+ export function SyncedTearsheet({
79
+ equity,
80
+ drawdown,
81
+ equityStretch = 2.4,
82
+ ariaLabel,
83
+ className,
84
+ pageScrollThrough = false,
85
+ }: SyncedTearsheetProps) {
86
+ const hostRef = useRef<HTMLDivElement | null>(null);
87
+
88
+ useEffect(() => {
89
+ const host = hostRef.current;
90
+ if (!host || equity.length === 0) return;
91
+ const cssVar = (name: string, fb: string) =>
92
+ getComputedStyle(host).getPropertyValue(name).trim() || fb;
93
+ const toRgba = (col: string, a: number) => {
94
+ const m = col.match(/[\d.]+/g);
95
+ if (col.startsWith("#") || !m || m.length < 3) return col;
96
+ return `rgba(${m[0]},${m[1]},${m[2]},${a})`;
97
+ };
98
+
99
+ const palette = () => ({
100
+ inkMute: cssVar("--ink-mute", "#7D8389"),
101
+ hair: cssVar("--hair", "rgba(255,255,255,0.09)"),
102
+ accent: cssVar("--accent", "#3dd6c4"),
103
+ down: cssVar("--down", "#E5533E"),
104
+ mono: cssVar("--font-mono", "monospace"),
105
+ });
106
+ let p = palette();
107
+
108
+ const chart: IChartApi = createChart(host, {
109
+ autoSize: true,
110
+ layout: {
111
+ background: { type: ColorType.Solid, color: "transparent" },
112
+ textColor: p.inkMute,
113
+ fontFamily: p.mono,
114
+ fontSize: 11,
115
+ attributionLogo: false,
116
+ },
117
+ grid: { vertLines: { color: p.hair }, horzLines: { color: p.hair } },
118
+ rightPriceScale: { borderColor: p.hair },
119
+ timeScale: { borderColor: p.hair, timeVisible: false },
120
+ crosshair: {
121
+ mode: CrosshairMode.Normal,
122
+ vertLine: { color: p.inkMute, labelBackgroundColor: p.accent },
123
+ horzLine: { color: p.inkMute, labelBackgroundColor: p.accent },
124
+ },
125
+ ...(pageScrollThrough
126
+ ? {
127
+ handleScroll: {
128
+ mouseWheel: false,
129
+ pressedMouseMove: false,
130
+ horzTouchDrag: false,
131
+ vertTouchDrag: false,
132
+ },
133
+ handleScale: { axisPressedMouseMove: false, mouseWheel: false, pinch: false },
134
+ }
135
+ : {}),
136
+ });
137
+
138
+ // pane 0 — cumulative equity (identity accent)
139
+ const equitySeries = chart.addSeries(
140
+ AreaSeries,
141
+ {
142
+ lineColor: p.accent,
143
+ topColor: toRgba(p.accent, 0.28),
144
+ bottomColor: toRgba(p.accent, 0.02),
145
+ lineWidth: 2,
146
+ priceLineVisible: false,
147
+ },
148
+ 0,
149
+ );
150
+ equitySeries.setData(
151
+ equity.map((pt): AreaData => ({ time: pt.time as Time, value: pt.value })),
152
+ );
153
+
154
+ // pane 1 — underwater drawdown (money --down)
155
+ const drawdownSeries = chart.addSeries(
156
+ BaselineSeries,
157
+ {
158
+ baseValue: { type: "price", price: 0 },
159
+ topLineColor: "transparent",
160
+ topFillColor1: "transparent",
161
+ topFillColor2: "transparent",
162
+ bottomLineColor: p.down,
163
+ bottomFillColor1: toRgba(p.down, 0.05),
164
+ bottomFillColor2: toRgba(p.down, 0.32),
165
+ lineWidth: 2,
166
+ priceLineVisible: false,
167
+ // this pane is always the underwater drawdown series (percent, ≤ 0) —
168
+ // format the axis accordingly rather than leaving it bare numbers.
169
+ priceFormat: { type: "custom", formatter: (v: number) => `${v.toFixed(1)}%`, minMove: 0.1 },
170
+ },
171
+ 1,
172
+ );
173
+ drawdownSeries.setData(
174
+ (drawdown ?? deriveDrawdown(equity)).map(
175
+ (pt): BaselineData => ({ time: pt.time as Time, value: pt.value }),
176
+ ),
177
+ );
178
+
179
+ // give the equity pane the lion's share of the height
180
+ const panes = chart.panes();
181
+ panes[0]?.setStretchFactor(equityStretch);
182
+ panes[1]?.setStretchFactor(1);
183
+
184
+ chart.timeScale().fitContent();
185
+
186
+ const retheme = () => {
187
+ p = palette();
188
+ chart.applyOptions({
189
+ layout: { textColor: p.inkMute },
190
+ grid: { vertLines: { color: p.hair }, horzLines: { color: p.hair } },
191
+ rightPriceScale: { borderColor: p.hair },
192
+ timeScale: { borderColor: p.hair },
193
+ });
194
+ equitySeries.applyOptions({
195
+ lineColor: p.accent,
196
+ topColor: toRgba(p.accent, 0.28),
197
+ bottomColor: toRgba(p.accent, 0.02),
198
+ });
199
+ drawdownSeries.applyOptions({
200
+ bottomLineColor: p.down,
201
+ bottomFillColor1: toRgba(p.down, 0.05),
202
+ bottomFillColor2: toRgba(p.down, 0.32),
203
+ });
204
+ };
205
+ const themeObs = new MutationObserver(retheme);
206
+ themeObs.observe(document.documentElement, {
207
+ attributes: true,
208
+ attributeFilter: ["data-theme"],
209
+ });
210
+
211
+ return () => {
212
+ themeObs.disconnect();
213
+ chart.remove();
214
+ };
215
+ }, [equity, drawdown, equityStretch, pageScrollThrough]);
216
+
217
+ return (
218
+ <div
219
+ className={className ?? "h-full w-full"}
220
+ ref={hostRef}
221
+ role={ariaLabel ? "img" : undefined}
222
+ aria-label={ariaLabel}
223
+ aria-hidden={ariaLabel ? undefined : "true"}
224
+ />
225
+ );
226
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Finance-composites family barrel (#1450) — the composite finance surfaces
3
+ * promoted from the reference finance/data pages: ticker tape, order book,
4
+ * sortable leaderboard, book-level performance dashboard, and the synced
5
+ * two-pane tearsheet chart. Structural CSS: styles/finance-composites.css.
6
+ * Re-exported from the package barrel (src/index.ts) by the F1 wire-up.
7
+ */
8
+ export { StockTicker, type TickerItem, type StockTickerProps } from "./StockTicker";
9
+ export {
10
+ MarketBar,
11
+ type MarketBarProps,
12
+ type MarketBarCell,
13
+ type MarketBarStatus,
14
+ } from "./MarketBar";
15
+ export { OrderBook, type OrderBookLevel, type OrderBookProps } from "./OrderBook";
16
+ export { SortableTable, type SortableColumn, type SortableTableProps } from "./SortableTable";
17
+ export {
18
+ PerformanceDashboard,
19
+ type DashboardHeadline,
20
+ type DashboardRatio,
21
+ type DashboardAllocation,
22
+ type PerformanceDashboardProps,
23
+ } from "./PerformanceDashboard";
24
+ export {
25
+ SyncedTearsheet,
26
+ type TearsheetPoint,
27
+ type SyncedTearsheetProps,
28
+ } from "./SyncedTearsheet";