@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,650 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState, type ComponentProps, type CSSProperties } from "react";
4
+
5
+ /**
6
+ * 5×5 snap-on/off cube matrix. Motion states are agent actions; static
7
+ * states are status and chrome glyphs. Unlit cells are omitted — only lit
8
+ * cubes paint. No opacity ease — cubes are on or off.
9
+ */
10
+
11
+ const GRID = 5;
12
+ const CENTER = (GRID - 1) / 2;
13
+ const CELL_COUNT = GRID * GRID;
14
+ const STEP_MS = 120;
15
+
16
+ const idx = (row: number, col: number) => row * GRID + col;
17
+
18
+ const chebyshev = (i: number) => {
19
+ const row = Math.floor(i / GRID);
20
+ const col = i % GRID;
21
+ return Math.max(Math.abs(row - CENTER), Math.abs(col - CENTER));
22
+ };
23
+
24
+ const cellsAt = (distance: number) => {
25
+ const lit: number[] = [];
26
+ for (let i = 0; i < CELL_COUNT; i += 1) {
27
+ if (chebyshev(i) === distance) lit.push(i);
28
+ }
29
+ return lit;
30
+ };
31
+
32
+ const cellsAtMost = (distance: number) => {
33
+ const lit: number[] = [];
34
+ for (let i = 0; i < CELL_COUNT; i += 1) {
35
+ if (chebyshev(i) <= distance) lit.push(i);
36
+ }
37
+ return lit;
38
+ };
39
+
40
+ const rowCells = (row: number) => {
41
+ const lit: number[] = [];
42
+ for (let col = 0; col < GRID; col += 1) lit.push(idx(row, col));
43
+ return lit;
44
+ };
45
+
46
+ const colCells = (col: number) => {
47
+ const lit: number[] = [];
48
+ for (let row = 0; row < GRID; row += 1) lit.push(idx(row, col));
49
+ return lit;
50
+ };
51
+
52
+ /** Clockwise rim, starting top-left. */
53
+ const PERIMETER = [
54
+ idx(0, 0),
55
+ idx(0, 1),
56
+ idx(0, 2),
57
+ idx(0, 3),
58
+ idx(0, 4),
59
+ idx(1, 4),
60
+ idx(2, 4),
61
+ idx(3, 4),
62
+ idx(4, 4),
63
+ idx(4, 3),
64
+ idx(4, 2),
65
+ idx(4, 1),
66
+ idx(4, 0),
67
+ idx(3, 0),
68
+ idx(2, 0),
69
+ idx(1, 0),
70
+ ];
71
+
72
+ const unionRows = (...rows: number[]) => rows.flatMap(rowCells);
73
+
74
+ const glyph = (dots: readonly (readonly [number, number])[]) =>
75
+ dots.map(([row, col]) => idx(row, col));
76
+
77
+ const CHECK = glyph([
78
+ [1, 4],
79
+ [2, 3],
80
+ [3, 0],
81
+ [3, 2],
82
+ [4, 1],
83
+ ]);
84
+ const CROSS = glyph([
85
+ [0, 0],
86
+ [0, 4],
87
+ [1, 1],
88
+ [1, 3],
89
+ [2, 2],
90
+ [3, 1],
91
+ [3, 3],
92
+ [4, 0],
93
+ [4, 4],
94
+ ]);
95
+ const BANG = glyph([
96
+ [0, 2],
97
+ [1, 2],
98
+ [2, 2],
99
+ [4, 2],
100
+ ]);
101
+ const CORNERS = [idx(0, 0), idx(0, 4), idx(4, 0), idx(4, 4)];
102
+ /** Lit plus of cubes — attach / add. */
103
+ const PLUS = glyph([
104
+ [0, 2],
105
+ [1, 2],
106
+ [2, 0],
107
+ [2, 1],
108
+ [2, 2],
109
+ [2, 3],
110
+ [2, 4],
111
+ [3, 2],
112
+ [4, 2],
113
+ ]);
114
+ /** Inverse plus — 2×2 in each corner; empty mid row/col is the plus. */
115
+ const NEW_CHAT = glyph([
116
+ [0, 0],
117
+ [0, 1],
118
+ [0, 3],
119
+ [0, 4],
120
+ [1, 0],
121
+ [1, 1],
122
+ [1, 3],
123
+ [1, 4],
124
+ [3, 0],
125
+ [3, 1],
126
+ [3, 3],
127
+ [3, 4],
128
+ [4, 0],
129
+ [4, 1],
130
+ [4, 3],
131
+ [4, 4],
132
+ ]);
133
+ /** Small centered `^` — status `up` only. */
134
+ const ARROW_UP = glyph([
135
+ [1, 2],
136
+ [2, 1],
137
+ [2, 3],
138
+ ]);
139
+ /** Small centered `v` — status `down` only. */
140
+ const ARROW_DOWN = glyph([
141
+ [2, 1],
142
+ [2, 3],
143
+ [3, 2],
144
+ ]);
145
+ /** Small `>` centered so a 90° rotate around the grid becomes `down`. */
146
+ const ARROW_RIGHT = glyph([
147
+ [1, 2],
148
+ [2, 3],
149
+ [3, 2],
150
+ ]);
151
+ /** Small `<` — exact mirror of the user `>`. */
152
+ const ARROW_LEFT = glyph([
153
+ [1, 3],
154
+ [2, 2],
155
+ [3, 3],
156
+ ]);
157
+ /** Download: down arrow into a 5-wide tray. */
158
+ const TRAY_DOWNLOAD = glyph([
159
+ [0, 2],
160
+ [1, 2],
161
+ [2, 1],
162
+ [2, 2],
163
+ [2, 3],
164
+ [3, 2],
165
+ [4, 0],
166
+ [4, 1],
167
+ [4, 2],
168
+ [4, 3],
169
+ [4, 4],
170
+ ]);
171
+ /** Export: up arrow out of the same bottom tray. */
172
+ const TRAY_EXPORT = glyph([
173
+ [0, 2],
174
+ [1, 1],
175
+ [1, 2],
176
+ [1, 3],
177
+ [2, 2],
178
+ [3, 2],
179
+ [4, 0],
180
+ [4, 1],
181
+ [4, 2],
182
+ [4, 3],
183
+ [4, 4],
184
+ ]);
185
+ /** Double `v` — scroll to bottom, not download and not `down`. */
186
+ const SCROLL_CHEVRONS = glyph([
187
+ [1, 1],
188
+ [1, 3],
189
+ [2, 2],
190
+ [3, 1],
191
+ [3, 3],
192
+ [4, 2],
193
+ ]);
194
+ /** Centered 3×3 stop block. */
195
+ const STOP_SQUARE = glyph([
196
+ [1, 1],
197
+ [1, 2],
198
+ [1, 3],
199
+ [2, 1],
200
+ [2, 2],
201
+ [2, 3],
202
+ [3, 1],
203
+ [3, 2],
204
+ [3, 3],
205
+ ]);
206
+ /** Corner brackets — system, not a stop square. */
207
+ const SYSTEM_BRACKETS = glyph([
208
+ [0, 0],
209
+ [0, 1],
210
+ [0, 3],
211
+ [0, 4],
212
+ [1, 0],
213
+ [1, 4],
214
+ [3, 0],
215
+ [3, 4],
216
+ [4, 0],
217
+ [4, 1],
218
+ [4, 3],
219
+ [4, 4],
220
+ ]);
221
+ /** Compact open `>` — two cubes per arm including the tip. */
222
+ const USER_CHEVRON = glyph([
223
+ [1, 1],
224
+ [2, 2],
225
+ [3, 1],
226
+ ]);
227
+ /** Compact filled `▸` — two cubes per side. */
228
+ const ASSISTANT_CHEVRON = glyph([
229
+ [1, 0],
230
+ [1, 1],
231
+ [2, 0],
232
+ [2, 1],
233
+ [2, 2],
234
+ [3, 0],
235
+ [3, 1],
236
+ ]);
237
+ /** Four cubes in a diamond — example prompts. */
238
+ const EXAMPLE_DIAMOND = glyph([
239
+ [1, 2],
240
+ [2, 1],
241
+ [2, 3],
242
+ [3, 2],
243
+ ]);
244
+ /**
245
+ * Like / dislike: 2×2 thumb on the *left* of an outlined fist.
246
+ * A centered thumb reads as a chimney; left-aligned is the usual like icon.
247
+ *
248
+ * ■ ■ · · · ■ ■ ■ ■ ■
249
+ * ■ ■ · · · ■ · · · ■
250
+ * ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
251
+ * ■ · · · ■ ■ ■ · · ·
252
+ * ■ ■ ■ ■ ■ ■ ■ · · ·
253
+ */
254
+ const THUMB_UP = glyph([
255
+ [0, 0],
256
+ [0, 1],
257
+ [1, 0],
258
+ [1, 1],
259
+ [2, 0],
260
+ [2, 1],
261
+ [2, 2],
262
+ [2, 3],
263
+ [2, 4],
264
+ [3, 0],
265
+ [3, 4],
266
+ [4, 0],
267
+ [4, 1],
268
+ [4, 2],
269
+ [4, 3],
270
+ [4, 4],
271
+ ]);
272
+ const THUMB_DOWN = glyph([
273
+ [0, 0],
274
+ [0, 1],
275
+ [0, 2],
276
+ [0, 3],
277
+ [0, 4],
278
+ [1, 0],
279
+ [1, 4],
280
+ [2, 0],
281
+ [2, 1],
282
+ [2, 2],
283
+ [2, 3],
284
+ [2, 4],
285
+ [3, 0],
286
+ [3, 1],
287
+ [4, 0],
288
+ [4, 1],
289
+ ]);
290
+
291
+ const hold = (distances: number[]) => distances.map((d) => cellsAt(d));
292
+ const fill = (distances: number[]) => distances.map((d) => cellsAtMost(d));
293
+ /** Consecutive cells on a ring — a thick spinning arc, not one cube. */
294
+ const trail = (ring: readonly number[], length: number) =>
295
+ ring.map((_, start) =>
296
+ Array.from({ length }, (_, i) => ring[(start + i) % ring.length]),
297
+ );
298
+
299
+ const PATTERNS = {
300
+ idle: [CORNERS],
301
+ /** Outer rim sweep — a moving C, as dense as thinking's outer ring. */
302
+ loading: trail(PERIMETER, 9),
303
+ /** Hollow ring in, hold center, ring out. */
304
+ thinking: hold([2, 2, 1, 1, 0, 0, 1, 1, 2, 2]),
305
+ /**
306
+ * Press: two bars close on the middle, hold the work, then open.
307
+ * Not another spinner — tool execution is a stamp, not a wait.
308
+ */
309
+ tool: [
310
+ unionRows(0, 4),
311
+ unionRows(0, 4),
312
+ unionRows(1, 3),
313
+ unionRows(1, 3),
314
+ unionRows(1, 2, 3),
315
+ unionRows(1, 2, 3),
316
+ unionRows(1, 3),
317
+ unionRows(1, 3),
318
+ ],
319
+ /**
320
+ * Pixel braces `{ }` — the mark on a tool-call group. One static frame on
321
+ * the same 5×5 cube grid as the reasoning bulb (`thought`). The middle row
322
+ * is the outward point of each brace; the rows around it tuck in, so the
323
+ * pair still reads at the 12px row. Not a filled grid, and not the corner
324
+ * brackets used for system asides.
325
+ *
326
+ * · ■ · ■ ·
327
+ * · ■ · ■ ·
328
+ * ■ · · · ■
329
+ * · ■ · ■ ·
330
+ * · ■ · ■ ·
331
+ */
332
+ tools: [
333
+ glyph([
334
+ [0, 1],
335
+ [0, 3],
336
+ [1, 1],
337
+ [1, 3],
338
+ [2, 0],
339
+ [2, 4],
340
+ [3, 1],
341
+ [3, 3],
342
+ [4, 1],
343
+ [4, 3],
344
+ ]),
345
+ ],
346
+ /** Scanline down the rows. */
347
+ executing: [0, 1, 2, 3, 4].map(rowCells),
348
+ /** Scanline across the columns (web search). */
349
+ searching: [0, 1, 2, 3, 4].map(colCells),
350
+ /** Filled square shrinks to the center, then grows back. */
351
+ compacting: fill([2, 2, 1, 1, 0, 0, 1, 1, 2, 2]),
352
+ warning: [BANG],
353
+ error: [CROSS],
354
+ success: [CHECK],
355
+ /**
356
+ * Light bulb — reasoning done. Not a check (that's tools) and not a ring
357
+ * (that's thinking in motion).
358
+ *
359
+ * · ■ ■ ■ ·
360
+ * ■ ■ ■ ■ ■
361
+ * ■ ■ ■ ■ ■
362
+ * · · ■ · ·
363
+ * · ■ ■ ■ ·
364
+ */
365
+ thought: [
366
+ glyph([
367
+ [0, 1],
368
+ [0, 2],
369
+ [0, 3],
370
+ [1, 0],
371
+ [1, 1],
372
+ [1, 2],
373
+ [1, 3],
374
+ [1, 4],
375
+ [2, 0],
376
+ [2, 1],
377
+ [2, 2],
378
+ [2, 3],
379
+ [2, 4],
380
+ [3, 2],
381
+ [4, 1],
382
+ [4, 2],
383
+ [4, 3],
384
+ ]),
385
+ ],
386
+ /** Two overlapping page squares. */
387
+ copy: [
388
+ glyph([
389
+ [0, 2],
390
+ [0, 3],
391
+ [0, 4],
392
+ [1, 2],
393
+ [1, 4],
394
+ [2, 0],
395
+ [2, 1],
396
+ [2, 2],
397
+ [2, 3],
398
+ [2, 4],
399
+ [3, 0],
400
+ [3, 2],
401
+ [4, 0],
402
+ [4, 1],
403
+ [4, 2],
404
+ ]),
405
+ ],
406
+ /** I-beam / text caret. */
407
+ edit: [
408
+ glyph([
409
+ [0, 0],
410
+ [0, 1],
411
+ [0, 2],
412
+ [0, 3],
413
+ [0, 4],
414
+ [1, 2],
415
+ [2, 2],
416
+ [3, 2],
417
+ [4, 0],
418
+ [4, 1],
419
+ [4, 2],
420
+ [4, 3],
421
+ [4, 4],
422
+ ]),
423
+ ],
424
+ /** Lit plus of cubes — composer attach only. */
425
+ attach: [PLUS],
426
+ /** Enter/send: top-right bend, right stem, bar, left `<` arrowhead. */
427
+ send: [
428
+ glyph([
429
+ [0, 2],
430
+ [0, 3],
431
+ [0, 4],
432
+ [1, 4],
433
+ [2, 1],
434
+ [2, 4],
435
+ [3, 0],
436
+ [3, 1],
437
+ [3, 2],
438
+ [3, 3],
439
+ [3, 4],
440
+ [4, 1],
441
+ ]),
442
+ ],
443
+ /** Three cubes on the mid row. */
444
+ more: [glyph([[2, 0], [2, 2], [2, 4]])],
445
+ /** Cycle: down the right with a head; up the left with a head. */
446
+ refresh: [
447
+ glyph([
448
+ [0, 1],
449
+ [0, 2],
450
+ [0, 3],
451
+ [0, 4],
452
+ [1, 0],
453
+ [1, 4],
454
+ [2, 0],
455
+ [2, 1],
456
+ [2, 3],
457
+ [2, 4],
458
+ [3, 0],
459
+ [3, 4],
460
+ [4, 0],
461
+ [4, 1],
462
+ [4, 2],
463
+ [4, 3],
464
+ ]),
465
+ ],
466
+ /** Up arrow out of a bottom tray. */
467
+ export: [TRAY_EXPORT],
468
+ /** Down arrow into a bottom tray. */
469
+ download: [TRAY_DOWNLOAD],
470
+ /** Centered 3×3 block — a stop, not a single cell. */
471
+ stop: [STOP_SQUARE],
472
+ /** Clear × without the error center fill. */
473
+ remove: [
474
+ glyph([
475
+ [0, 0],
476
+ [0, 4],
477
+ [1, 1],
478
+ [1, 3],
479
+ [3, 1],
480
+ [3, 3],
481
+ [4, 0],
482
+ [4, 4],
483
+ ]),
484
+ ],
485
+ /** Double chevron down — scroll to bottom. */
486
+ scroll: [SCROLL_CHEVRONS],
487
+ /** Tiny centered `^`. */
488
+ up: [ARROW_UP],
489
+ /** Tiny centered `v`. */
490
+ down: [ARROW_DOWN],
491
+ /** Small `<` — mirror of `next` / `user`. */
492
+ prev: [ARROW_LEFT],
493
+ /** Small `>` — same size as the user arrow. */
494
+ next: [USER_CHEVRON],
495
+ /** Mic. */
496
+ dictate: [
497
+ glyph([
498
+ [0, 1],
499
+ [0, 2],
500
+ [0, 3],
501
+ [1, 1],
502
+ [1, 3],
503
+ [2, 1],
504
+ [2, 2],
505
+ [2, 3],
506
+ [3, 2],
507
+ [4, 0],
508
+ [4, 1],
509
+ [4, 2],
510
+ [4, 3],
511
+ [4, 4],
512
+ ]),
513
+ ],
514
+ /** Inverse plus — 2×2 corners; new chat, not attach. */
515
+ newChat: [NEW_CHAT],
516
+ /** Thumb pad + fist. */
517
+ thumbsUp: [THUMB_UP],
518
+ /** Vertical mirror of thumbsUp. */
519
+ thumbsDown: [THUMB_DOWN],
520
+ /** Disclosure `>` — rotate 90° in a square to point down. Not the fat V. */
521
+ expand: [ARROW_RIGHT],
522
+ /** User role — compact open `>`. */
523
+ user: [USER_CHEVRON],
524
+ /** Assistant role — compact filled `▸`. */
525
+ assistant: [ASSISTANT_CHEVRON],
526
+ /** Example prompt — outline diamond. */
527
+ example: [EXAMPLE_DIAMOND],
528
+ /** System aside — corner brackets. */
529
+ system: [SYSTEM_BRACKETS],
530
+ } as const;
531
+
532
+ export type DotMatrixState = keyof typeof PATTERNS;
533
+
534
+ const dotMatrixStates = Object.keys(PATTERNS) as readonly DotMatrixState[];
535
+
536
+ // `role` and `aria-label` are the component's own: a caller cannot set a
537
+ // name the component would not announce, and cannot put a name on a glyph
538
+ // the component renders as decorative.
539
+ type DotMatrixBaseProps = Omit<ComponentProps<"span">, "children" | "role" | "aria-label"> & {
540
+ state?: DotMatrixState;
541
+ };
542
+
543
+ /**
544
+ * A dot matrix is either a named glyph or a decorative one, never both.
545
+ *
546
+ * - Named (no `decorative`): the glyph carries `label` as its accessible name
547
+ * and is the only thing in its control that names it. Use it when the glyph
548
+ * is the whole content of a control.
549
+ * - Decorative (`decorative`): the glyph is hidden from assistive technology
550
+ * and carries no name. Use it when the control already has visible text, so
551
+ * the text is the name and the glyph is not read out a second time.
552
+ *
553
+ * The type refuses a label on a decorative glyph: a name that is never
554
+ * announced is a name that will be read as a bug.
555
+ */
556
+ export type DotMatrixProps =
557
+ | (DotMatrixBaseProps & { decorative?: false; label?: string })
558
+ | (DotMatrixBaseProps & { decorative: true; label?: never });
559
+
560
+ function cx(...parts: Array<string | false | null | undefined>): string {
561
+ return parts.filter(Boolean).join(" ");
562
+ }
563
+
564
+ /** The cube svg fills its box. A bare svg otherwise paints at its 300px default. */
565
+ const gridStyle: CSSProperties = {
566
+ display: "block",
567
+ width: "100%",
568
+ height: "100%",
569
+ maxWidth: "100%",
570
+ maxHeight: "100%",
571
+ };
572
+
573
+ function DotMatrix({
574
+ className,
575
+ state = "loading",
576
+ label,
577
+ decorative = false,
578
+ style,
579
+ ...props
580
+ }: DotMatrixProps) {
581
+ const frames = PATTERNS[state];
582
+ const [frame, setFrame] = useState(0);
583
+
584
+ useEffect(() => {
585
+ setFrame(0);
586
+ if (frames.length <= 1) return;
587
+ const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
588
+ if (mq.matches) return;
589
+ const id = window.setInterval(() => {
590
+ setFrame((current) => (current + 1) % frames.length);
591
+ }, STEP_MS);
592
+ return () => window.clearInterval(id);
593
+ }, [frames]);
594
+
595
+ const lit = new Set(frames[frame] ?? frames[0]);
596
+ const name = label ?? state;
597
+
598
+ return (
599
+ <span
600
+ {...props}
601
+ data-slot="dot-matrix"
602
+ data-state={state}
603
+ // One name, one home: a named glyph is named by its aria-label (the
604
+ // role makes its children presentational, so there is no second copy of
605
+ // the label in the tree), a decorative glyph has no name at all.
606
+ {...(decorative
607
+ ? { "aria-hidden": true }
608
+ : { role: "img", "aria-label": name })}
609
+ className={cx("inline-block size-4 shrink-0", className)}
610
+ style={{ position: "relative", ...style }}
611
+ >
612
+ <svg
613
+ data-slot="dot-matrix-grid"
614
+ aria-hidden
615
+ viewBox="0 0 20 20"
616
+ width="100%"
617
+ height="100%"
618
+ fill="currentColor"
619
+ className="size-full"
620
+ style={gridStyle}
621
+ >
622
+ {Array.from({ length: CELL_COUNT }, (_, i) => {
623
+ if (!lit.has(i)) return null;
624
+ const row = Math.floor(i / GRID);
625
+ const col = i % GRID;
626
+ return (
627
+ <rect
628
+ key={i}
629
+ data-slot="dot-matrix-dot"
630
+ data-on="true"
631
+ x={0.85 + col * 4}
632
+ y={0.85 + row * 4}
633
+ width={2.3}
634
+ height={2.3}
635
+ fill="currentColor"
636
+ shapeRendering="crispEdges"
637
+ />
638
+ );
639
+ })}
640
+ </svg>
641
+ </span>
642
+ );
643
+ }
644
+
645
+ export function litCellsFor(state: DotMatrixState, frame = 0): readonly number[] {
646
+ const frames = PATTERNS[state];
647
+ return frames[frame] ?? frames[0];
648
+ }
649
+
650
+ export { DotMatrix, dotMatrixStates, PATTERNS };