@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,267 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Menu as MenuPrimitive } from "@base-ui/react/menu"
5
+ import { cn } from "../lib/utils"
6
+ import { ChevronRightIcon, CheckIcon } from "lucide-react"
7
+
8
+ function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
9
+ return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />
10
+ }
11
+
12
+ function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
13
+ return <MenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
14
+ }
15
+
16
+ function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
17
+ return <MenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />
18
+ }
19
+
20
+ function DropdownMenuContent({
21
+ align = "start",
22
+ alignOffset = 0,
23
+ side = "bottom",
24
+ sideOffset = 4,
25
+ className,
26
+ ...props
27
+ }: MenuPrimitive.Popup.Props &
28
+ Pick<
29
+ MenuPrimitive.Positioner.Props,
30
+ "align" | "alignOffset" | "side" | "sideOffset"
31
+ >) {
32
+ return (
33
+ <MenuPrimitive.Portal>
34
+ <MenuPrimitive.Positioner
35
+ className="isolate z-50 outline-none"
36
+ align={align}
37
+ alignOffset={alignOffset}
38
+ side={side}
39
+ sideOffset={sideOffset}
40
+ >
41
+ <MenuPrimitive.Popup
42
+ data-slot="dropdown-menu-content"
43
+ className={cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-none bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95", className )}
44
+ {...props}
45
+ />
46
+ </MenuPrimitive.Positioner>
47
+ </MenuPrimitive.Portal>
48
+ )
49
+ }
50
+
51
+ function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {
52
+ return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
53
+ }
54
+
55
+ function DropdownMenuLabel({
56
+ className,
57
+ inset,
58
+ ...props
59
+ }: MenuPrimitive.GroupLabel.Props & {
60
+ inset?: boolean
61
+ }) {
62
+ return (
63
+ <MenuPrimitive.GroupLabel
64
+ data-slot="dropdown-menu-label"
65
+ data-inset={inset}
66
+ className={cn(
67
+ "px-2 py-2 text-xs text-muted-foreground data-inset:ps-7",
68
+ className
69
+ )}
70
+ {...props}
71
+ />
72
+ )
73
+ }
74
+
75
+ function DropdownMenuItem({
76
+ className,
77
+ inset,
78
+ variant = "default",
79
+ ...props
80
+ }: MenuPrimitive.Item.Props & {
81
+ inset?: boolean
82
+ variant?: "default" | "destructive"
83
+ }) {
84
+ return (
85
+ <MenuPrimitive.Item
86
+ data-slot="dropdown-menu-item"
87
+ data-inset={inset}
88
+ data-variant={variant}
89
+ className={cn(
90
+ "group/dropdown-menu-item relative flex cursor-pointer items-center gap-2 rounded-none px-2 py-2 text-xs outline-hidden select-none focus:bg-secondary focus:text-secondary-foreground not-data-[variant=destructive]:focus:**:text-secondary-foreground data-inset:ps-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
91
+ className
92
+ )}
93
+ {...props}
94
+ />
95
+ )
96
+ }
97
+
98
+ function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
99
+ return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />
100
+ }
101
+
102
+ function DropdownMenuSubTrigger({
103
+ className,
104
+ inset,
105
+ children,
106
+ ...props
107
+ }: MenuPrimitive.SubmenuTrigger.Props & {
108
+ inset?: boolean
109
+ }) {
110
+ return (
111
+ <MenuPrimitive.SubmenuTrigger
112
+ data-slot="dropdown-menu-sub-trigger"
113
+ data-inset={inset}
114
+ className={cn(
115
+ "flex cursor-pointer items-center gap-2 rounded-none px-2 py-2 text-xs outline-hidden select-none focus:bg-secondary focus:text-secondary-foreground not-data-[variant=destructive]:focus:**:text-secondary-foreground data-inset:ps-7 data-popup-open:bg-secondary data-popup-open:text-secondary-foreground data-open:bg-secondary data-open:text-secondary-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
116
+ className
117
+ )}
118
+ {...props}
119
+ >
120
+ {children}
121
+ <ChevronRightIcon className="ms-auto rtl:-scale-x-100" />
122
+ </MenuPrimitive.SubmenuTrigger>
123
+ )
124
+ }
125
+
126
+ function DropdownMenuSubContent({
127
+ align = "start",
128
+ alignOffset = -3,
129
+ side = "right",
130
+ sideOffset = 0,
131
+ className,
132
+ ...props
133
+ }: React.ComponentProps<typeof DropdownMenuContent>) {
134
+ return (
135
+ <DropdownMenuContent
136
+ data-slot="dropdown-menu-sub-content"
137
+ className={cn("w-auto min-w-[96px] rounded-none bg-popover text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
138
+ align={align}
139
+ alignOffset={alignOffset}
140
+ side={side}
141
+ sideOffset={sideOffset}
142
+ {...props}
143
+ />
144
+ )
145
+ }
146
+
147
+ function DropdownMenuCheckboxItem({
148
+ className,
149
+ children,
150
+ checked,
151
+ inset,
152
+ ...props
153
+ }: MenuPrimitive.CheckboxItem.Props & {
154
+ inset?: boolean
155
+ }) {
156
+ return (
157
+ <MenuPrimitive.CheckboxItem
158
+ data-slot="dropdown-menu-checkbox-item"
159
+ data-inset={inset}
160
+ className={cn(
161
+ "relative flex cursor-pointer items-center gap-2 rounded-none py-2 pe-8 ps-2 text-xs outline-hidden select-none focus:bg-secondary focus:text-secondary-foreground focus:**:text-secondary-foreground data-inset:ps-7 data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
162
+ className
163
+ )}
164
+ checked={checked}
165
+ {...props}
166
+ >
167
+ <span
168
+ className="pointer-events-none absolute end-2 flex items-center justify-center"
169
+ data-slot="dropdown-menu-checkbox-item-indicator"
170
+ >
171
+ <MenuPrimitive.CheckboxItemIndicator>
172
+ <CheckIcon
173
+ />
174
+ </MenuPrimitive.CheckboxItemIndicator>
175
+ </span>
176
+ {children}
177
+ </MenuPrimitive.CheckboxItem>
178
+ )
179
+ }
180
+
181
+ function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
182
+ return (
183
+ <MenuPrimitive.RadioGroup
184
+ data-slot="dropdown-menu-radio-group"
185
+ {...props}
186
+ />
187
+ )
188
+ }
189
+
190
+ function DropdownMenuRadioItem({
191
+ className,
192
+ children,
193
+ inset,
194
+ ...props
195
+ }: MenuPrimitive.RadioItem.Props & {
196
+ inset?: boolean
197
+ }) {
198
+ return (
199
+ <MenuPrimitive.RadioItem
200
+ data-slot="dropdown-menu-radio-item"
201
+ data-inset={inset}
202
+ className={cn(
203
+ "relative flex cursor-pointer items-center gap-2 rounded-none py-2 pe-8 ps-2 text-xs outline-hidden select-none focus:bg-secondary focus:text-secondary-foreground focus:**:text-secondary-foreground data-inset:ps-7 data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
204
+ className
205
+ )}
206
+ {...props}
207
+ >
208
+ <span
209
+ className="pointer-events-none absolute end-2 flex items-center justify-center"
210
+ data-slot="dropdown-menu-radio-item-indicator"
211
+ >
212
+ <MenuPrimitive.RadioItemIndicator>
213
+ <CheckIcon
214
+ />
215
+ </MenuPrimitive.RadioItemIndicator>
216
+ </span>
217
+ {children}
218
+ </MenuPrimitive.RadioItem>
219
+ )
220
+ }
221
+
222
+ function DropdownMenuSeparator({
223
+ className,
224
+ ...props
225
+ }: MenuPrimitive.Separator.Props) {
226
+ return (
227
+ <MenuPrimitive.Separator
228
+ data-slot="dropdown-menu-separator"
229
+ className={cn("-mx-1 h-px bg-border", className)}
230
+ {...props}
231
+ />
232
+ )
233
+ }
234
+
235
+ function DropdownMenuShortcut({
236
+ className,
237
+ ...props
238
+ }: React.ComponentProps<"span">) {
239
+ return (
240
+ <span
241
+ data-slot="dropdown-menu-shortcut"
242
+ className={cn(
243
+ "ms-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-secondary-foreground",
244
+ className
245
+ )}
246
+ {...props}
247
+ />
248
+ )
249
+ }
250
+
251
+ export {
252
+ DropdownMenu,
253
+ DropdownMenuPortal,
254
+ DropdownMenuTrigger,
255
+ DropdownMenuContent,
256
+ DropdownMenuGroup,
257
+ DropdownMenuLabel,
258
+ DropdownMenuItem,
259
+ DropdownMenuCheckboxItem,
260
+ DropdownMenuRadioGroup,
261
+ DropdownMenuRadioItem,
262
+ DropdownMenuSeparator,
263
+ DropdownMenuShortcut,
264
+ DropdownMenuSub,
265
+ DropdownMenuSubTrigger,
266
+ DropdownMenuSubContent,
267
+ }
@@ -0,0 +1,165 @@
1
+ "use client"
2
+
3
+ /**
4
+ * EmptyState — the no-results / first-run / load-error triple (#1548),
5
+ * promoted from the controls layer into the kit (#4306, batch K1). A centered
6
+ * hairline card: glyph disc, mono title, one line of guidance, and the single
7
+ * action that moves the user forward. Monochrome by default; `variant="error"`
8
+ * is the only one that spends the down/danger color (on the glyph disc).
9
+ *
10
+ * The old `.ctl-empty*` dress (styles/controls-core.css) is translated
11
+ * value-for-value into token utilities here, so the controls CSS can retire.
12
+ * The `glass` / `glass-display` dresses restyle type/spacing/slots ONLY — the
13
+ * surface class stays call-site (dashboard's `.glass-card`) so the app's
14
+ * motion-reveal hook keeps firing.
15
+ *
16
+ * #4452: `glass-display` is the full-page gate card (dashboard's DB gate) and
17
+ * must survive phone widths. It is declared `w-full` (fluid: fills its
18
+ * container up to a consumer cap, never content-sized) and its title/body
19
+ * `break-words` (a long unbreakable token breaks rather than overflowing).
20
+ * The dress is text-first, so it may never ellipsise its own message:
21
+ * `truncate` / `whitespace-nowrap` / `line-clamp` are banned here.
22
+ */
23
+
24
+ import type { HTMLAttributes, ReactNode } from "react"
25
+
26
+ import { cn } from "../lib/utils"
27
+
28
+ export type EmptyStateVariant = "no-results" | "first-run" | "error"
29
+
30
+ export type EmptyStateDress = "reference" | "glass" | "glass-display"
31
+
32
+ export type EmptyStateProps = Omit<HTMLAttributes<HTMLElement>, "title"> & {
33
+ variant?: EmptyStateVariant
34
+ /** Look cut — "reference" (default) or the dashboard glass cuts (see docblock). */
35
+ dress?: EmptyStateDress
36
+ /** Replaces the variant's default glyph inside the disc. */
37
+ icon?: ReactNode
38
+ title: ReactNode
39
+ /** One line of guidance under the title. */
40
+ body?: ReactNode
41
+ /** Short italic secondary line — explains *why* it's empty without reading as broken. */
42
+ note?: ReactNode
43
+ /** The single action that moves forward — pass a `<Button/>`. */
44
+ action?: ReactNode
45
+ }
46
+
47
+ const DEFAULT_GLYPHS: Record<EmptyStateVariant, ReactNode> = {
48
+ "no-results": (
49
+ <>
50
+ <circle cx="11" cy="11" r="7" />
51
+ <path d="M20 20l-3.5-3.5M8 11h6" strokeLinecap="round" />
52
+ </>
53
+ ),
54
+ "first-run": (
55
+ <>
56
+ <path d="M12 3v18M3 12h18" strokeLinecap="round" />
57
+ <circle cx="12" cy="12" r="9" opacity="0.35" />
58
+ </>
59
+ ),
60
+ error: (
61
+ <>
62
+ <path d="M12 3l9 16H3z" />
63
+ <path d="M12 10v4M12 17v.5" strokeLinecap="round" />
64
+ </>
65
+ ),
66
+ }
67
+
68
+ export function EmptyState({
69
+ variant = "no-results",
70
+ dress = "reference",
71
+ icon,
72
+ title,
73
+ body,
74
+ note,
75
+ action,
76
+ className,
77
+ children,
78
+ ...props
79
+ }: EmptyStateProps) {
80
+ // The dashboard glass dresses ship without a glyph disc; an explicit `icon`
81
+ // still renders one. The reference dress always wears its variant glyph.
82
+ const glyphless = dress !== "reference" && icon == null
83
+ // WCAG 4.1.3 (#2287): "error" is the one variant that can appear or replace
84
+ // prior content asynchronously — give it an assertive live role. Spread
85
+ // AFTER ...props so the derived role stays authoritative.
86
+ const live = variant === "error" ? ({ role: "alert" as const }) : {}
87
+ const glass = dress === "glass"
88
+ const glassDisplay = dress === "glass-display"
89
+ return (
90
+ <article
91
+ data-slot="empty-state"
92
+ className={cn(
93
+ "flex flex-col items-center border border-hair bg-surface/55 p-[1.8rem_1.3rem] text-center",
94
+ // glass: justify-center gap-2 p-8 (observability quiet card)
95
+ glass && "justify-center gap-2 p-8",
96
+ // glass-display: w-full justify-center gap-0 px-6 py-8 (full-page gate
97
+ // card). #4452: `w-full` states the fluid contract explicitly — the card
98
+ // fills its container up to any consumer `max-w-*`, so it can never be
99
+ // content-sized past the viewport.
100
+ glassDisplay && "w-full justify-center gap-0 px-6 py-8",
101
+ !glass && !glassDisplay && "gap-[0.55rem]",
102
+ className,
103
+ )}
104
+ {...props}
105
+ {...live}
106
+ >
107
+ {glyphless ? null : (
108
+ <span
109
+ className={cn(
110
+ "mb-[0.15rem] grid size-11 place-items-center rounded-none bg-ink/8 text-ink-mute",
111
+ variant === "error" && "bg-danger/12 text-danger",
112
+ )}
113
+ aria-hidden="true"
114
+ >
115
+ {icon ?? (
116
+ <svg
117
+ viewBox="0 0 24 24"
118
+ width="22"
119
+ height="22"
120
+ fill="none"
121
+ stroke="currentColor"
122
+ strokeWidth="1.6"
123
+ strokeLinejoin="round"
124
+ >
125
+ {DEFAULT_GLYPHS[variant]}
126
+ </svg>
127
+ )}
128
+ </span>
129
+ )}
130
+ <h3
131
+ className={cn(
132
+ "m-0 font-mono text-[0.86rem] font-normal text-ink",
133
+ glass && "font-sans text-sm leading-[1.4286] font-medium text-ink-soft",
134
+ glassDisplay && "font-display break-words text-2xl leading-[1.3333] tracking-tight font-normal text-ink",
135
+ )}
136
+ >
137
+ {title}
138
+ </h3>
139
+ {body != null ? (
140
+ <p
141
+ className={cn(
142
+ "max-w-[24ch] text-[0.8rem] leading-[1.5] text-ink-mute",
143
+ !glass && !glassDisplay && "mt-0 mb-[0.4rem]",
144
+ glass && "m-0 max-w-md text-xs leading-[1.3333]",
145
+ glassDisplay && "mt-2 mb-0 max-w-none break-words text-sm leading-[1.625]",
146
+ )}
147
+ >
148
+ {body}
149
+ </p>
150
+ ) : null}
151
+ {note != null ? (
152
+ <p
153
+ className={cn(
154
+ "m-0 max-w-[24ch] text-[0.75rem] leading-[1.3333] text-ink-mute",
155
+ glass && "mt-1 max-w-md",
156
+ )}
157
+ >
158
+ {note}
159
+ </p>
160
+ ) : null}
161
+ {action}
162
+ {children}
163
+ </article>
164
+ )
165
+ }
@@ -0,0 +1,104 @@
1
+ "use client"
2
+
3
+ /**
4
+ * Field — the label + control + hint/error wrapper (#1548), promoted from the
5
+ * controls layer into the kit (#4306, batch K1). One component meshes the
6
+ * accessible wiring callers otherwise hand-roll: a mono micro-cap label, an
7
+ * optional hint, an optional error (which replaces the hint), and
8
+ * `aria-describedby` / `aria-invalid` injected into the child control via
9
+ * clone — so the control keeps its own props and ref. The child must accept
10
+ * `id`, `aria-describedby`, and `aria-invalid` (native inputs and every shared
11
+ * input do).
12
+ *
13
+ * Error is `--danger`, never `--down` (tokens.css house rule: money colors are
14
+ * P&L-only). The `.ctl-field*` dress is translated into token utilities here,
15
+ * so the controls CSS can retire.
16
+ */
17
+
18
+ import { cloneElement, isValidElement, useId } from "react"
19
+ import type { ReactElement, ReactNode } from "react"
20
+
21
+ import { cn } from "../lib/utils"
22
+
23
+ type ControlProps = {
24
+ id?: string
25
+ "aria-describedby"?: string
26
+ "aria-invalid"?: boolean | string
27
+ }
28
+
29
+ export type FieldProps = {
30
+ label: ReactNode
31
+ hint?: ReactNode
32
+ error?: ReactNode
33
+ htmlFor?: string
34
+ required?: boolean
35
+ className?: string
36
+ children: ReactNode
37
+ }
38
+
39
+ export function Field({
40
+ label,
41
+ hint,
42
+ error,
43
+ htmlFor,
44
+ required = false,
45
+ className,
46
+ children,
47
+ }: FieldProps) {
48
+ const autoId = useId()
49
+ // Resolve the control id FIRST: a child with its own id wins, and the
50
+ // label follows it — never the synthetic id.
51
+ const childId = isValidElement<ControlProps>(children) ? children.props.id : undefined
52
+ const controlId = htmlFor ?? childId ?? `${autoId}-control`
53
+ const hintId = `${autoId}-hint`
54
+ const errorId = `${autoId}-error`
55
+ const describedBy = [
56
+ isValidElement<ControlProps>(children) ? children.props["aria-describedby"] : null,
57
+ error ? errorId : null,
58
+ hint && !error ? hintId : null,
59
+ ]
60
+ .filter(Boolean)
61
+ .join(" ")
62
+
63
+ const control = isValidElement<ControlProps>(children)
64
+ ? cloneElement(children as ReactElement<ControlProps>, {
65
+ id: childId ?? controlId,
66
+ ...(describedBy ? { "aria-describedby": describedBy } : null),
67
+ ...(error ? { "aria-invalid": true } : null),
68
+ ...(required ? { "aria-required": true } : null),
69
+ })
70
+ : children
71
+
72
+ return (
73
+ <div
74
+ data-slot="field"
75
+ data-invalid={error ? true : undefined}
76
+ className={cn("grid min-w-0 gap-[0.35rem]", className)}
77
+ >
78
+ <label
79
+ htmlFor={controlId}
80
+ className="cursor-pointer font-mono text-[0.6rem] uppercase tracking-[0.1em] text-ink-mute"
81
+ >
82
+ {label}
83
+ {required ? (
84
+ <>
85
+ <span aria-hidden="true" className="text-ink-soft">
86
+ {" *"}
87
+ </span>
88
+ <span className="sr-only"> (required)</span>
89
+ </>
90
+ ) : null}
91
+ </label>
92
+ {control}
93
+ {error ? (
94
+ <p id={errorId} className="m-0 font-mono text-[0.62rem] leading-[1.5] text-danger">
95
+ {error}
96
+ </p>
97
+ ) : hint ? (
98
+ <p id={hintId} className="m-0 font-mono text-[0.62rem] leading-[1.5] text-ink-mute">
99
+ {hint}
100
+ </p>
101
+ ) : null}
102
+ </div>
103
+ )
104
+ }
@@ -0,0 +1,36 @@
1
+ "use client"
2
+
3
+ /**
4
+ * Form — a thin presentational wrapper over the K1 `Field` and the kit inputs,
5
+ * added in #4306 batch K2. This is deliberately **not** shadcn's
6
+ * react-hook-form-bound Form: the repo carries no form-library dependency
7
+ * (`react-hook-form` is not installed), so this part owns no state, no
8
+ * validation and no submit. It supplies the `<form>` root with the canon's
9
+ * vertical rhythm, a `FormField` façade over `Field` (label + hint/error +
10
+ * accessible wiring, already meshed), and a `FormActions` footer row. Callers
11
+ * keep owning the values and the submit handler.
12
+ */
13
+ import type { ComponentProps } from "react"
14
+
15
+ import { cn } from "../lib/utils"
16
+ import { Field, type FieldProps } from "./field"
17
+
18
+ function Form({ className, ...props }: ComponentProps<"form">) {
19
+ return <form data-slot="form" className={cn("grid gap-[1rem]", className)} {...props} />
20
+ }
21
+
22
+ function FormField({ className, ...props }: FieldProps) {
23
+ return <Field className={cn("min-w-0", className)} {...props} />
24
+ }
25
+
26
+ function FormActions({ className, ...props }: ComponentProps<"div">) {
27
+ return (
28
+ <div
29
+ data-slot="form-actions"
30
+ className={cn("flex flex-wrap items-center gap-[0.6rem]", className)}
31
+ {...props}
32
+ />
33
+ )
34
+ }
35
+
36
+ export { Form, FormField, FormActions }
@@ -0,0 +1,36 @@
1
+ "use client"
2
+
3
+ /**
4
+ * IconButton — the borderless 2rem glyph button (#1548), promoted from the
5
+ * controls layer into the kit (#4306, batch K1). `aria-label` is required —
6
+ * the child is a bare svg. Ink-mute glyph, ink + ink/6 wash on hover, the
7
+ * kit's not-allowed disabled convention, and a token-backed focus ring.
8
+ * Token utilities only, so `.nb-icon` can retire.
9
+ *
10
+ * A plain `<button>` (not the Base UI Button primitive): the controls part was
11
+ * plain, and Base UI re-emits `disabled`/`aria-disabled` in its own attribute
12
+ * order — a real dashboard specimen asserts on that order, and the plain
13
+ * element keeps the rendered markup byte-for-byte compatible.
14
+ */
15
+
16
+ import type { ComponentPropsWithoutRef } from "react"
17
+
18
+ import { cn } from "../lib/utils"
19
+
20
+ export type IconButtonProps = ComponentPropsWithoutRef<"button"> & {
21
+ "aria-label": string
22
+ }
23
+
24
+ export function IconButton({ className, ...props }: IconButtonProps) {
25
+ return (
26
+ <button
27
+ type="button"
28
+ data-slot="icon-button"
29
+ className={cn(
30
+ "inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-none border-0 bg-transparent text-ink-mute transition-colors outline-none hover:bg-ink/6 hover:text-ink focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:shrink-0",
31
+ className,
32
+ )}
33
+ {...props}
34
+ />
35
+ )
36
+ }
@@ -0,0 +1,34 @@
1
+ export * from "./alert";
2
+ export * from "./avatar";
3
+ export * from "./badge";
4
+ export * from "./breadcrumb";
5
+ export * from "./button";
6
+ export * from "./card";
7
+ export * from "./checkbox";
8
+ export * from "./collapsible";
9
+ export * from "./date-pager";
10
+ export * from "./dialog";
11
+ export * from "./dropdown-menu";
12
+ export * from "./empty-state";
13
+ export * from "./field";
14
+ export * from "./form";
15
+ export * from "./icon-button";
16
+ export * from "./input";
17
+ export * from "./kbd";
18
+ export * from "./label";
19
+ export * from "./pagination";
20
+ export * from "./pager";
21
+ export * from "./radio-group";
22
+ export * from "./search-bar";
23
+ export * from "./segmented-control";
24
+ export * from "./select";
25
+ export * from "./skeleton";
26
+ export * from "./slider";
27
+ export * from "./separator";
28
+ export * from "./sheet";
29
+ export * from "./switch";
30
+ export * from "./table";
31
+ export * from "./tabs";
32
+ export * from "./tags-input";
33
+ export * from "./textarea";
34
+ export * from "./tooltip";
@@ -0,0 +1,33 @@
1
+ import * as React from "react"
2
+ import { Input as InputPrimitive } from "@base-ui/react/input"
3
+ import { cn } from "../lib/utils"
4
+
5
+ export type InputDress = "default" | "chat";
6
+
7
+ function Input({
8
+ className,
9
+ type,
10
+ dress = "default",
11
+ ...props
12
+ }: React.ComponentProps<"input"> & { dress?: InputDress }) {
13
+ // dress="chat" emits the digichat chat-dress class (styles/controls-core.css)
14
+ // instead of the kit utilities, keeping digichat's rendered look exact.
15
+ const classes =
16
+ dress === "chat"
17
+ ? cn("ctl-input-chat", className)
18
+ : cn(
19
+ "h-8 w-full min-w-0 rounded-none border border-input bg-transparent px-2.5 py-1 text-xs transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-xs file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 md:text-xs dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
20
+ className
21
+ );
22
+
23
+ return (
24
+ <InputPrimitive
25
+ type={type}
26
+ data-slot="input"
27
+ className={classes}
28
+ {...props}
29
+ />
30
+ )
31
+ }
32
+
33
+ export { Input }