@vllnt/ui 0.2.1-canary.f8033e5 → 0.3.0-canary.00b20d6

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 (347) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +38 -24
  3. package/dist/components/accordion/accordion.js +2 -2
  4. package/dist/components/activity-heatmap/activity-heatmap.js +18 -20
  5. package/dist/components/activity-log/activity-log.js +11 -11
  6. package/dist/components/agent-activity/agent-activity.js +19 -13
  7. package/dist/components/ai-artifact/ai-artifact.js +39 -22
  8. package/dist/components/ai-chat-input/ai-chat-input.js +6 -4
  9. package/dist/components/ai-message-bubble/ai-message-bubble.js +3 -3
  10. package/dist/components/ai-sidebar/ai-sidebar.js +14 -22
  11. package/dist/components/ai-source-citation/ai-source-citation.js +2 -2
  12. package/dist/components/ai-tool-call-display/ai-tool-call-display.js +5 -5
  13. package/dist/components/animated-beam/animated-beam.js +158 -0
  14. package/dist/components/animated-beam/index.js +4 -0
  15. package/dist/components/animated-grid-pattern/animated-grid-pattern.js +74 -0
  16. package/dist/components/animated-grid-pattern/index.js +6 -0
  17. package/dist/components/animated-list/animated-list.js +32 -0
  18. package/dist/components/animated-list/index.js +4 -0
  19. package/dist/components/animated-tabs/animated-tabs.js +95 -0
  20. package/dist/components/animated-tabs/index.js +6 -0
  21. package/dist/components/animated-testimonials/animated-testimonials.js +91 -0
  22. package/dist/components/animated-testimonials/index.js +6 -0
  23. package/dist/components/animated-text/animated-text.js +7 -7
  24. package/dist/components/animated-tooltip/animated-tooltip.js +51 -0
  25. package/dist/components/animated-tooltip/index.js +6 -0
  26. package/dist/components/annotation/annotation.js +1 -1
  27. package/dist/components/auto-reload/auto-reload.js +42 -8
  28. package/dist/components/avatar/avatar.js +1 -1
  29. package/dist/components/avatar-group/avatar-group.js +5 -5
  30. package/dist/components/banner/banner.js +3 -3
  31. package/dist/components/bento-grid/bento-grid.js +41 -0
  32. package/dist/components/bento-grid/index.js +8 -0
  33. package/dist/components/blog-card/blog-card.js +5 -3
  34. package/dist/components/blur-reveal/blur-reveal.js +78 -0
  35. package/dist/components/blur-reveal/index.js +4 -0
  36. package/dist/components/border-beam/border-beam.js +2 -2
  37. package/dist/components/bottom-activity-strip/bottom-activity-strip.js +3 -3
  38. package/dist/components/breadcrumb/breadcrumb.js +33 -26
  39. package/dist/components/button/button.js +1 -1
  40. package/dist/components/button-group/button-group.js +35 -0
  41. package/dist/components/button-group/index.js +8 -0
  42. package/dist/components/calendar/calendar.js +6 -6
  43. package/dist/components/callout/callout.js +1 -1
  44. package/dist/components/candlestick-chart/candlestick-chart.js +13 -12
  45. package/dist/components/canvas-shell/canvas-foundation-demo.js +18 -18
  46. package/dist/components/canvas-shell/canvas-shell.js +8 -5
  47. package/dist/components/canvas-view/canvas-view.js +71 -28
  48. package/dist/components/card-flip/card-flip.js +78 -0
  49. package/dist/components/card-flip/index.js +4 -0
  50. package/dist/components/carousel/carousel.js +18 -10
  51. package/dist/components/category-filter/category-filter.js +1 -1
  52. package/dist/components/chain-of-thought/chain-of-thought.js +77 -0
  53. package/dist/components/chain-of-thought/index.js +6 -0
  54. package/dist/components/chat-dock-section/chat-dock-section.js +3 -3
  55. package/dist/components/checkbox/checkbox.js +2 -2
  56. package/dist/components/checkbox-group/checkbox-group.js +92 -0
  57. package/dist/components/checkbox-group/index.js +8 -0
  58. package/dist/components/checklist/checklist.js +38 -10
  59. package/dist/components/checklist/index.js +8 -2
  60. package/dist/components/choropleth-map/choropleth-map.js +6 -1
  61. package/dist/components/chronological-timeline/chronological-timeline.js +44 -38
  62. package/dist/components/civilization-card/civilization-card.js +19 -2
  63. package/dist/components/code-block/code-block.js +47 -29
  64. package/dist/components/code-playground/code-playground.js +20 -18
  65. package/dist/components/color-picker/color-picker.js +134 -0
  66. package/dist/components/color-picker/index.js +4 -0
  67. package/dist/components/combobox/combobox.js +49 -30
  68. package/dist/components/command/command.js +1 -1
  69. package/dist/components/comment-pin/comment-pin.js +3 -3
  70. package/dist/components/comparison/comparison.js +11 -10
  71. package/dist/components/completion-dialog/completion-dialog.js +20 -12
  72. package/dist/components/connector-edge/connector-edge.js +1 -1
  73. package/dist/components/content-intro/content-intro.js +29 -22
  74. package/dist/components/context-menu/context-menu.js +4 -4
  75. package/dist/components/contribution-graph/contribution-graph.js +120 -0
  76. package/dist/components/contribution-graph/index.js +6 -0
  77. package/dist/components/conversation-thread/conversation-thread.js +9 -9
  78. package/dist/components/cookie-consent/cookie-consent.js +1 -1
  79. package/dist/components/copy-button/copy-button.js +3 -3
  80. package/dist/components/countdown-timer/countdown-timer.js +12 -35
  81. package/dist/components/credit-badge/credit-badge.js +1 -7
  82. package/dist/components/curriculum/curriculum.js +10 -10
  83. package/dist/components/cursor/cursor.js +48 -0
  84. package/dist/components/cursor/index.js +4 -0
  85. package/dist/components/data-list/data-list.js +1 -1
  86. package/dist/components/data-table/data-table.js +10 -9
  87. package/dist/components/date-field/date-field.js +37 -0
  88. package/dist/components/date-field/index.js +4 -0
  89. package/dist/components/date-picker/date-picker.js +4 -9
  90. package/dist/components/date-range-picker/date-range-picker.js +74 -0
  91. package/dist/components/date-range-picker/index.js +6 -0
  92. package/dist/components/dialog/dialog.js +1 -1
  93. package/dist/components/dock/dock.js +102 -0
  94. package/dist/components/dock/index.js +5 -0
  95. package/dist/components/dot-pattern/dot-pattern.js +31 -0
  96. package/dist/components/dot-pattern/index.js +4 -0
  97. package/dist/components/dropdown-menu/dropdown-menu.js +3 -3
  98. package/dist/components/empty-state/empty-state.js +3 -3
  99. package/dist/components/era-comparison/era-comparison.js +40 -22
  100. package/dist/components/exercise/exercise.js +15 -7
  101. package/dist/components/expandable-cards/expandable-cards.js +56 -0
  102. package/dist/components/expandable-cards/index.js +6 -0
  103. package/dist/components/faq/faq.js +8 -4
  104. package/dist/components/field/field.js +121 -0
  105. package/dist/components/field/index.js +16 -0
  106. package/dist/components/fieldset/fieldset.js +47 -0
  107. package/dist/components/fieldset/index.js +10 -0
  108. package/dist/components/file-upload/file-upload.js +4 -9
  109. package/dist/components/filter-bar/filter-bar.js +9 -8
  110. package/dist/components/flashcard/flashcard.js +10 -4
  111. package/dist/components/floating-action-button/floating-action-button.js +1 -1
  112. package/dist/components/floating-navbar/floating-navbar.js +62 -0
  113. package/dist/components/floating-navbar/index.js +4 -0
  114. package/dist/components/floating-toolbar/floating-toolbar.js +3 -3
  115. package/dist/components/flow-diagram/flow-controls.js +9 -9
  116. package/dist/components/flow-diagram/flow-error-boundary.js +2 -2
  117. package/dist/components/flow-diagram/flow-fullscreen.js +5 -15
  118. package/dist/components/flow-diagram/use-flow-diagram.js +7 -18
  119. package/dist/components/form/form.js +1 -1
  120. package/dist/components/gantt-chart/gantt-chart.js +22 -19
  121. package/dist/components/gauge-chart/gauge-chart.js +134 -0
  122. package/dist/components/gauge-chart/index.js +4 -0
  123. package/dist/components/geography-quiz-map/geography-quiz-map.js +6 -5
  124. package/dist/components/glass-card/glass-card.js +23 -0
  125. package/dist/components/glass-card/index.js +4 -0
  126. package/dist/components/glass-panel/glass-panel.js +1 -1
  127. package/dist/components/glass-progress/glass-progress.js +35 -0
  128. package/dist/components/glass-progress/index.js +4 -0
  129. package/dist/components/globe-3d/globe-3d.js +16 -4
  130. package/dist/components/grid/grid.js +94 -0
  131. package/dist/components/grid/index.js +4 -0
  132. package/dist/components/handoff-beacon/handoff-beacon.js +1 -1
  133. package/dist/components/historic-timeline/historic-timeline.js +4 -4
  134. package/dist/components/historical-figure-card/historical-figure-card.js +4 -7
  135. package/dist/components/horizontal-scroll-row/horizontal-scroll-row.js +6 -5
  136. package/dist/components/index.js +277 -0
  137. package/dist/components/infinite-plane/infinite-plane.js +2 -2
  138. package/dist/components/inline-input/inline-input.js +1 -1
  139. package/dist/components/input-group/index.js +14 -0
  140. package/dist/components/input-group/input-group.js +65 -0
  141. package/dist/components/input-otp/input-otp.js +1 -1
  142. package/dist/components/interactive-timeline/interactive-timeline.js +27 -11
  143. package/dist/components/item/index.js +18 -0
  144. package/dist/components/item/item.js +103 -0
  145. package/dist/components/jarvis-dock/jarvis-dock.js +4 -4
  146. package/dist/components/kbd/kbd.js +18 -10
  147. package/dist/components/key-concept/key-concept.js +6 -5
  148. package/dist/components/keyboard-shortcuts-help/keyboard-shortcuts-help.js +11 -21
  149. package/dist/components/knowledge-check/knowledge-check.js +46 -21
  150. package/dist/components/lang-provider/lang-provider.js +3 -3
  151. package/dist/components/learning-objectives/learning-objectives.js +14 -13
  152. package/dist/components/link/index.js +5 -0
  153. package/dist/components/link/link.js +55 -0
  154. package/dist/components/liquid-glass/index.js +4 -0
  155. package/dist/components/liquid-glass/liquid-glass.js +37 -0
  156. package/dist/components/list-box/index.js +8 -0
  157. package/dist/components/list-box/list-box.js +127 -0
  158. package/dist/components/live-feed/live-feed.js +20 -42
  159. package/dist/components/magnetic/index.js +4 -0
  160. package/dist/components/magnetic/magnetic.js +58 -0
  161. package/dist/components/magnetic-button/index.js +4 -0
  162. package/dist/components/magnetic-button/magnetic-button.js +57 -0
  163. package/dist/components/map-2d/map-2d.js +3 -3
  164. package/dist/components/map-timeline/map-timeline.js +6 -6
  165. package/dist/components/market-treemap/market-treemap.js +5 -6
  166. package/dist/components/mdx-content/mdx-content.js +25 -11
  167. package/dist/components/menubar/menubar.js +4 -4
  168. package/dist/components/meteors/index.js +4 -0
  169. package/dist/components/meteors/meteors.js +59 -0
  170. package/dist/components/meter/index.js +5 -0
  171. package/dist/components/meter/meter.js +78 -0
  172. package/dist/components/metric-cluster/metric-cluster.js +1 -1
  173. package/dist/components/metric-gauge/metric-gauge.js +3 -3
  174. package/dist/components/model-comparison/model-comparison.js +27 -8
  175. package/dist/components/model-selector/model-selector.js +8 -8
  176. package/dist/components/multi-select/multi-select.js +7 -7
  177. package/dist/components/native-select/index.js +4 -0
  178. package/dist/components/native-select/native-select.js +25 -0
  179. package/dist/components/navbar-saas/navbar-saas.js +11 -10
  180. package/dist/components/navigation-menu/navigation-menu.js +2 -2
  181. package/dist/components/newsletter-signup/newsletter-signup.js +5 -5
  182. package/dist/components/number-input/number-input.js +2 -2
  183. package/dist/components/number-ticker/number-ticker.js +11 -4
  184. package/dist/components/object-card/object-card.js +4 -4
  185. package/dist/components/object-inspector/object-inspector.js +1 -1
  186. package/dist/components/order-book/order-book.js +2 -2
  187. package/dist/components/overview-board/overview-board.js +2 -2
  188. package/dist/components/panel/index.js +16 -0
  189. package/dist/components/panel/panel.js +81 -0
  190. package/dist/components/parallel-timeline/parallel-timeline.js +4 -4
  191. package/dist/components/particles/index.js +4 -0
  192. package/dist/components/particles/particles.js +49 -0
  193. package/dist/components/password-input/password-input.js +1 -1
  194. package/dist/components/phone-input/index.js +6 -0
  195. package/dist/components/phone-input/phone-input.js +64 -0
  196. package/dist/components/pie-chart/index.js +4 -0
  197. package/dist/components/pie-chart/pie-chart.js +132 -0
  198. package/dist/components/plan-badge/plan-badge.js +1 -7
  199. package/dist/components/policy-delivery-panel/policy-delivery-panel.js +2 -2
  200. package/dist/components/presence-stack/presence-stack.js +2 -2
  201. package/dist/components/presence-sync-indicator/presence-sync-indicator.js +1 -1
  202. package/dist/components/pricing-table/pricing-table.js +58 -21
  203. package/dist/components/pro-tip/pro-tip.js +6 -6
  204. package/dist/components/profile-section/profile-section.js +3 -2
  205. package/dist/components/progress-card/progress-card.js +6 -5
  206. package/dist/components/progress-tracker/progress-tracker.js +26 -16
  207. package/dist/components/progressive-blur/index.js +6 -0
  208. package/dist/components/progressive-blur/progressive-blur.js +44 -0
  209. package/dist/components/prompt-input/index.js +4 -0
  210. package/dist/components/prompt-input/prompt-input.js +186 -0
  211. package/dist/components/prompt-templates/prompt-templates.js +19 -27
  212. package/dist/components/qr-code/index.js +4 -0
  213. package/dist/components/qr-code/qr-code.js +51 -0
  214. package/dist/components/quiz/quiz.js +7 -6
  215. package/dist/components/radar-chart/index.js +6 -0
  216. package/dist/components/radar-chart/radar-chart.js +181 -0
  217. package/dist/components/radio-group/radio-group.js +2 -2
  218. package/dist/components/range-calendar/index.js +4 -0
  219. package/dist/components/range-calendar/range-calendar.js +35 -0
  220. package/dist/components/rating/rating.js +3 -3
  221. package/dist/components/reasoning/index.js +4 -0
  222. package/dist/components/reasoning/reasoning.js +118 -0
  223. package/dist/components/relationship-inspector/relationship-inspector.js +2 -2
  224. package/dist/components/resizable/resizable.js +1 -1
  225. package/dist/components/reveal-text/index.js +6 -0
  226. package/dist/components/reveal-text/reveal-text.js +88 -0
  227. package/dist/components/routing-assignment-panel/routing-assignment-panel.js +2 -2
  228. package/dist/components/run-timeline/run-timeline.js +2 -2
  229. package/dist/components/runtime-overview-panel/runtime-overview-panel.js +1 -1
  230. package/dist/components/sankey-chart/index.js +6 -0
  231. package/dist/components/sankey-chart/sankey-chart.js +257 -0
  232. package/dist/components/scope-selector/scope-selector.js +13 -13
  233. package/dist/components/scramble-text/index.js +4 -0
  234. package/dist/components/scramble-text/scramble-text.js +77 -0
  235. package/dist/components/scroll-progress/index.js +4 -0
  236. package/dist/components/scroll-progress/scroll-progress.js +45 -0
  237. package/dist/components/search-bar/search-bar.js +24 -2
  238. package/dist/components/search-dialog/search-dialog.js +485 -52
  239. package/dist/components/search-field/index.js +4 -0
  240. package/dist/components/search-field/search-field.js +68 -0
  241. package/dist/components/select/select.js +5 -5
  242. package/dist/components/selection-halo/selection-halo.js +1 -1
  243. package/dist/components/severity-badge/severity-badge.js +2 -2
  244. package/dist/components/share-dialog/share-dialog.js +8 -10
  245. package/dist/components/share-section/share-section.js +2 -1
  246. package/dist/components/sheet/sheet.js +1 -1
  247. package/dist/components/shimmer-button/index.js +4 -0
  248. package/dist/components/shimmer-button/shimmer-button.js +36 -0
  249. package/dist/components/shimmer-text/index.js +4 -0
  250. package/dist/components/shimmer-text/shimmer-text.js +36 -0
  251. package/dist/components/shine-border/index.js +4 -0
  252. package/dist/components/shine-border/shine-border.js +34 -0
  253. package/dist/components/shiny-button/index.js +4 -0
  254. package/dist/components/shiny-button/shiny-button.js +35 -0
  255. package/dist/components/sidebar/sidebar.js +31 -26
  256. package/dist/components/sidebar-toggle/sidebar-toggle.js +5 -3
  257. package/dist/components/slider/slider.js +1 -1
  258. package/dist/components/slideshow/slideshow.js +358 -281
  259. package/dist/components/social-fab/social-fab.js +12 -11
  260. package/dist/components/sparkles/index.js +4 -0
  261. package/dist/components/sparkles/sparkles.js +47 -0
  262. package/dist/components/sparkline-grid/sparkline-grid.js +6 -6
  263. package/dist/components/spinner/spinner.js +4 -4
  264. package/dist/components/spinner/unicode-spinner.js +4 -2
  265. package/dist/components/spinning-text/index.js +4 -0
  266. package/dist/components/spinning-text/spinning-text.js +60 -0
  267. package/dist/components/spotlight-card/index.js +4 -0
  268. package/dist/components/spotlight-card/spotlight-card.js +48 -0
  269. package/dist/components/stat-card/stat-card.js +5 -5
  270. package/dist/components/state-badge-overlay/state-badge-overlay.js +1 -1
  271. package/dist/components/static-code/index.js +4 -0
  272. package/dist/components/static-code/static-code-copy.js +24 -0
  273. package/dist/components/static-code/static-code.js +41 -0
  274. package/dist/components/status-board/status-board.js +15 -8
  275. package/dist/components/status-indicator/status-indicator.js +3 -3
  276. package/dist/components/step-by-step/step-by-step.js +10 -8
  277. package/dist/components/step-navigation/step-navigation.js +2 -2
  278. package/dist/components/stepper/stepper.js +3 -3
  279. package/dist/components/sticky-metric/sticky-metric.js +1 -1
  280. package/dist/components/subscription-card/subscription-card.js +1 -1
  281. package/dist/components/switch/switch.js +1 -1
  282. package/dist/components/table-of-contents/table-of-contents.js +5 -2
  283. package/dist/components/table-of-contents-panel/table-of-contents-panel.js +15 -24
  284. package/dist/components/tabs/tabs.js +26 -8
  285. package/dist/components/tag-group/index.js +8 -0
  286. package/dist/components/tag-group/tag-group.js +124 -0
  287. package/dist/components/tags-input/tags-input.js +12 -4
  288. package/dist/components/terminal/terminal.js +68 -52
  289. package/dist/components/text-animate/index.js +6 -0
  290. package/dist/components/text-animate/text-animate.js +130 -0
  291. package/dist/components/text-field/index.js +4 -0
  292. package/dist/components/text-field/text-field.js +60 -0
  293. package/dist/components/text-reveal/index.js +4 -0
  294. package/dist/components/text-reveal/text-reveal.js +87 -0
  295. package/dist/components/text-shimmer/index.js +4 -0
  296. package/dist/components/text-shimmer/text-shimmer.js +29 -0
  297. package/dist/components/theme-preset-provider/index.js +4 -0
  298. package/dist/components/theme-preset-provider/theme-preset-provider.js +55 -0
  299. package/dist/components/theme-switcher/index.js +4 -0
  300. package/dist/components/theme-switcher/theme-switcher.js +43 -0
  301. package/dist/components/theme-toggle/theme-toggle.js +2 -2
  302. package/dist/components/thinking-block/thinking-block.js +3 -3
  303. package/dist/components/ticker-tape/ticker-tape.js +5 -8
  304. package/dist/components/tilt-card/index.js +4 -0
  305. package/dist/components/tilt-card/tilt-card.js +65 -0
  306. package/dist/components/time-field/index.js +4 -0
  307. package/dist/components/time-field/time-field.js +37 -0
  308. package/dist/components/time-picker/index.js +4 -0
  309. package/dist/components/time-picker/time-picker.js +114 -0
  310. package/dist/components/timeline/timeline.js +2 -2
  311. package/dist/components/timeline-scrubber/timeline-scrubber.js +2 -2
  312. package/dist/components/tldr-section/tldr-section.js +11 -9
  313. package/dist/components/toolbar/index.js +8 -0
  314. package/dist/components/toolbar/toolbar.js +83 -0
  315. package/dist/components/tour/tour.js +10 -4
  316. package/dist/components/transaction-list/transaction-list.js +40 -13
  317. package/dist/components/tree-view/tree-view.js +2 -2
  318. package/dist/components/tutorial-card/tutorial-card.js +2 -2
  319. package/dist/components/tutorial-complete/tutorial-complete.js +18 -16
  320. package/dist/components/tutorial-filters/tutorial-filters.js +2 -2
  321. package/dist/components/tutorial-intro-content/tutorial-intro-content.js +5 -5
  322. package/dist/components/tutorial-mdx/tutorial-mdx.js +20 -20
  323. package/dist/components/typewriter/index.js +4 -0
  324. package/dist/components/typewriter/typewriter.js +66 -0
  325. package/dist/components/typography/index.js +26 -0
  326. package/dist/components/typography/typography.js +150 -0
  327. package/dist/components/usage-breakdown/usage-breakdown.js +11 -7
  328. package/dist/components/video-embed/video-embed.js +2 -2
  329. package/dist/components/viewport-bookmarks/viewport-bookmarks.js +6 -4
  330. package/dist/components/wallet-card/wallet-card.js +1 -1
  331. package/dist/components/watchlist/watchlist.js +8 -10
  332. package/dist/components/world-breadcrumbs/world-breadcrumbs.js +2 -2
  333. package/dist/components/world-clock-bar/world-clock-bar.js +33 -37
  334. package/dist/components/zoom-hud/zoom-hud.js +1 -1
  335. package/dist/index.d.ts +2280 -130
  336. package/dist/index.js +34 -1
  337. package/dist/lib/format.js +14 -0
  338. package/dist/lib/theme-presets.js +32 -0
  339. package/dist/lib/use-body-scroll-lock.js +30 -0
  340. package/dist/lib/use-escape-key.js +24 -0
  341. package/dist/lib/use-live-date.js +26 -0
  342. package/dist/lib/use-theme-preset.js +95 -0
  343. package/dist/tailwind-preset.js +19 -19
  344. package/package.json +11 -8
  345. package/styles.css +95 -38
  346. package/themes/default.css +39 -39
  347. package/themes/presets.css +547 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,45 @@ All notable changes to `@vllnt/ui` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [Unreleased]
8
+
9
+ > Target version: **`0.3.0`** — shipping as `0.3.0-canary.<sha>` on the npm `canary` tag on every merge to main. The stable `latest` release is gated on the [ROADMAP.md](../../ROADMAP.md) shipping criteria and is not yet published.
10
+
11
+ ### Added
12
+
13
+ - **Release intelligence surface** — `/changelog`, `/releases`, `/rss.xml`, and `/atom.xml` expose one changelog source through HTML, GitHub release cards, and feed readers. `/docs/changelog` redirects to `/changelog`.
14
+ - **Hooks + utility primitives** — `CopyButton` (+ `useCopyToClipboard` hook), `Banner` + `BannerAction`, `Kbd`, `EmptyState`, `DocumentSiblingNav`.
15
+ - **Pricing + identity cards** — `PricingTable` + `PricingPlan`, `HistoricalFigureCard`, `CivilizationCard` (+ `CivilizationComparison`).
16
+ - **Newsletter** — `NewsletterSignup` (state-machine driven submit flow).
17
+ - **AI compound families** — `ModelComparison` (+ `Column`, `Meta`, `Vote`), `PromptTemplates`, `AgentActivity`, `AISidebar`, `AIArtifact`.
18
+ - **Era / financial** — `EraComparison`, `TransactionList`.
19
+ - **Forms** — `Form`, `MultiSelect`, `SegmentedControl`, `TagsInput`, `AutoReload`.
20
+ - **Educational** — `KnowledgeCheck` (inline question runner).
21
+ - **Charts + timelines** — `GanttChart`, `ParallelTimeline`, `Timeline` + `TimelineItem`, `HistoricTimeline`, `InteractiveTimeline`, `ChronologicalTimeline`, `TreeView`.
22
+ - **Document + reading** — `PrimarySourceViewer` compound family.
23
+ - **Maps + geography** — `Map2D`, `ChoroplethMap`, `RouteMap`, `HeatMapOverlay`, `GeographyQuizMap`, `MapTimeline`, `StoryMap`, `Globe3D`.
24
+ - **Canvas foundation** — `CanvasShell`, `CanvasView`, `InfinitePlane`, `ViewportBookmarks`, `WorldBreadcrumbs`, `TopBar`, `LeftRail`, `RightDock`, `ZoomHud`, `MiniMapPanel`, `WorkspaceSwitcher`.
25
+ - **Canvas selection + manipulation** — `SelectionHalo`, `SnapGuides`, `FloatingToolbar`, `MultiSelectLasso`, `FollowMode`, `HandoffBeacon`.
26
+ - **Canvas spatial objects** — `ObjectCard`, `ObjectHandle`, `AnchorPort`, `ConnectorEdge`, `EdgeLabel`, `GroupHull`.
27
+ - **Canvas collaboration primitives** — `LiveCursor`, `CommentPin`, `PresenceSyncIndicator`, `PresenceStack`, `SelectionPresence`, `ThreadBubble`.
28
+ - **Inspector + dock panels** — `PropertySection`, `ObjectInspector`, `RelationshipInspector`, `RuntimeOverviewPanel`, `RoutingAssignmentPanel`, `PolicyDeliveryPanel`.
29
+ - **Runtime overlays** — `AlertPulse`, `ThresholdRing`, `StickyMetric`, `HeatOverlay`, `StateBadgeOverlay`, `MetricCluster`, `JarvisDock`, `ContextLens`.
30
+ - **Time navigation** — `TimelineScrubber`, `PlaybackGhost`, `BottomActivityStrip`, `RunTimeline`.
31
+ - Total component count: **225** (up from 140).
32
+
33
+ - **OKLCH theming system** — color tokens migrated to the OKLCH color space, with 13 runtime theme presets (`default`, `matrix`, `dracula`, `synthwave`, `tron`, `cyberpunk`, `nord`, `claude`, `chatgpt`, `gemini`, `dusk`, `cyberlime`, `aura`). New public theme exports from `@vllnt/ui`: `THEME_PRESETS`, `DEFAULT_THEME_PRESET`, `CUSTOM_THEME_NAME`, `isThemePresetName`, the `ThemePreset` and `ThemePresetName` types, plus the `useThemePreset` hook (with `UseThemePresetResult`), `setThemePreset`, and `setCustomTheme` for runtime preset switching and user-supplied custom themes.
34
+
35
+ - **A11y heading-level override** — every title-bearing component (`ProfileSection`, `FAQ`, `Slideshow`, `WorldClockBar`, `TableOfContentsPanel`, `TableOfContents`, `KeyboardShortcutsHelp`, `Watchlist`, `OrderBook`, `HorizontalScrollRow`, `MarketTreemap`, `ActivityHeatmap`, `Glossary`, `StatusBoard`, `CodePlayground`, `Comparison`, `Quiz`, `Exercise`, `ShareSection`, `CompletionDialog`, `Checklist`, `LearningObjectives`, `CandlestickChart`, `StepByStep`) accepts an `as` prop (`"h1"`–`"h6"`); multi-title components (`ContentIntro`, `TutorialComplete`) expose `titleAs` + `tocLabelAs` / `sectionLabelAs`. Defaults preserve existing heading tags. `HeadingTag` is re-exported from `@vllnt/ui`.
36
+
37
+ ### Changed
38
+
39
+ - Registry installs use a **hybrid CLI strategy** — leaf component source is inlined, sibling registry items resolve via `@vllnt/ui` to keep installs minimal and dedupe shared primitives.
40
+
41
+ ### Notes
42
+
43
+ - `ROADMAP.md` added at repo root tracking 50 open issues across 8 phases gating the `0.3.0` cut.
44
+ - `0.3.0` requires the codebase-health gate (`react-doctor` CI + 0 errors), the agent-first surface (`/llms.txt`, `/mcp`, sitemap, JSON-LD), and the rebuilt landing page before shipping.
45
+
7
46
  ## [0.2.1] - 2026-04-21
8
47
 
9
48
  ### Fixed
package/README.md CHANGED
@@ -44,7 +44,7 @@ export default {
44
44
  ```
45
45
 
46
46
  The preset configures:
47
- - **Colors**: `primary`, `secondary`, `muted`, `accent`, `destructive`, `background`, `foreground`, `card`, `popover`, `border`, `input`, `ring` — all as `hsl(var(--name))` for theming
47
+ - **Colors**: `primary`, `secondary`, `muted`, `accent`, `destructive`, `background`, `foreground`, `card`, `popover`, `border`, `input`, `ring` — all as `oklch(var(--name) / <alpha-value>)` for theming
48
48
  - **Border radius**: `lg`, `md`, `sm` via `--radius` CSS variable
49
49
  - **Animations**: `accordion-down`, `accordion-up`, `shimmer`
50
50
  - **Font**: `mono` family via `--font-mono` variable
@@ -83,45 +83,59 @@ export function Example() {
83
83
  | `@vllnt/ui/tailwind-preset` | Tailwind CSS preset config |
84
84
  | `@vllnt/ui/styles.css` | Full styles (Tailwind base + theme variables + utilities) |
85
85
  | `@vllnt/ui/themes/default.css` | Theme CSS variables only (no Tailwind base) |
86
+ | `@vllnt/ui/themes/presets.css` | Built-in color presets (applied via `data-theme`) |
86
87
 
87
88
  ## Theming
88
89
 
89
- All colors use HSL CSS variables. Override them after importing styles:
90
+ All colors are **OKLCH channel** CSS variables (`L C H`), consumed as
91
+ `oklch(var(--name) / <alpha-value>)`. Override them after importing styles:
90
92
 
91
93
  ```css
92
94
  /* Light theme */
93
95
  :root {
94
- --background: 0 0% 100%;
95
- --foreground: 0 0% 3.9%;
96
- --primary: 222.2 47.4% 11.2%;
97
- --primary-foreground: 210 40% 98%;
98
- --secondary: 210 40% 96.1%;
99
- --secondary-foreground: 222.2 47.4% 11.2%;
100
- --muted: 210 40% 96.1%;
101
- --muted-foreground: 215.4 16.3% 46.9%;
102
- --accent: 210 40% 96.1%;
103
- --accent-foreground: 222.2 47.4% 11.2%;
104
- --destructive: 0 84.2% 60.2%;
105
- --destructive-foreground: 0 0% 98%;
106
- --border: 214.3 31.8% 91.4%;
107
- --input: 214.3 31.8% 91.4%;
108
- --ring: 222.2 84% 4.9%;
96
+ --background: 1 0 0;
97
+ --foreground: 0.1445 0 0;
98
+ --primary: 0.2044 0 0;
99
+ --primary-foreground: 0.9848 0 0;
100
+ --secondary: 0.9703 0 0;
101
+ --secondary-foreground: 0.2044 0 0;
102
+ --muted: 0.9703 0 0;
103
+ --muted-foreground: 0.5555 0 0;
104
+ --accent: 0.9703 0 0;
105
+ --accent-foreground: 0.2044 0 0;
106
+ --destructive: 0.6368 0.2078 25.326;
107
+ --destructive-foreground: 0.9848 0 0;
108
+ --border: 0.9219 0 0;
109
+ --input: 0.9219 0 0;
110
+ --ring: 0.1445 0 0;
109
111
  --radius: 0.5rem;
110
- --card: 0 0% 100%;
111
- --card-foreground: 0 0% 3.9%;
112
- --popover: 0 0% 100%;
113
- --popover-foreground: 0 0% 3.9%;
112
+ --card: 1 0 0;
113
+ --card-foreground: 0.1445 0 0;
114
+ --popover: 1 0 0;
115
+ --popover-foreground: 0.1445 0 0;
114
116
  }
115
117
 
116
118
  /* Dark theme (applied via class="dark" on html/body) */
117
119
  .dark {
118
- --background: 0 0% 3.9%;
119
- --foreground: 0 0% 98%;
120
+ --background: 0 0 0;
121
+ --foreground: 0.9848 0 0;
120
122
  /* ... override other variables */
121
123
  }
122
124
  ```
123
125
 
124
- Use `@vllnt/ui/themes/default.css` instead of `@vllnt/ui/styles.css` if you only want the variables without Tailwind base layer styles.
126
+ Use `@vllnt/ui/themes/default.css` instead of `@vllnt/ui/styles.css` if you only
127
+ want the variables without the Tailwind base layer.
128
+
129
+ ### Runtime presets & the theme editor
130
+
131
+ Import `@vllnt/ui/themes/presets.css` and switch between built-in color presets
132
+ at runtime with `<ThemeSwitcher />` (or `setThemePreset` / `useThemePreset`),
133
+ which set `data-theme` on the document root. Render `<ThemePresetProvider />`
134
+ once near the root to restore the saved preset before paint.
135
+
136
+ To design and export your own theme, use the visual editor at
137
+ [`/themes`](https://ui.vllnt.ai/themes) — it exports a CSS block, a
138
+ `npx shadcn add` command, or design tokens.
125
139
 
126
140
  ## Component Patterns
127
141
 
@@ -104,7 +104,7 @@ function AccordionTrigger({
104
104
  "span",
105
105
  {
106
106
  className: cn(
107
- "h-4 w-4 flex-shrink-0 transition-transform duration-200",
107
+ "size-4 flex-shrink-0 transition-transform duration-200",
108
108
  isOpen && "rotate-180"
109
109
  ),
110
110
  children: icon
@@ -113,7 +113,7 @@ function AccordionTrigger({
113
113
  "svg",
114
114
  {
115
115
  className: cn(
116
- "h-4 w-4 flex-shrink-0 transition-transform duration-200",
116
+ "size-4 flex-shrink-0 transition-transform duration-200",
117
117
  isOpen && "rotate-180"
118
118
  ),
119
119
  fill: "none",
@@ -1,5 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
+ import { normalizeDate } from "../../lib/format";
3
4
  import { cn } from "../../lib/utils";
4
5
  const WEEKDAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
5
6
  const VISIBLE_DAY_LABELS = /* @__PURE__ */ new Set(["Mon", "Wed", "Fri"]);
@@ -10,12 +11,6 @@ const LEVEL_CLASS_NAMES = [
10
11
  "bg-emerald-500/65",
11
12
  "bg-emerald-500"
12
13
  ];
13
- function normalizeDate(input) {
14
- if (input instanceof Date) {
15
- return new Date(input.getTime());
16
- }
17
- return new Date(input);
18
- }
19
14
  function toUtcDate(date) {
20
15
  return new Date(
21
16
  Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())
@@ -72,19 +67,21 @@ function getGridData(data, endDate, weeks) {
72
67
  });
73
68
  });
74
69
  }
70
+ const MONTH_LABEL_FORMATTER = new Intl.DateTimeFormat("en-US", {
71
+ month: "short",
72
+ timeZone: "UTC"
73
+ });
74
+ const TOOLTIP_DATE_FORMATTER = new Intl.DateTimeFormat("en-US", {
75
+ day: "numeric",
76
+ month: "short",
77
+ timeZone: "UTC",
78
+ year: "numeric"
79
+ });
75
80
  function formatMonthLabel(date) {
76
- return new Intl.DateTimeFormat("en-US", {
77
- month: "short",
78
- timeZone: "UTC"
79
- }).format(date);
81
+ return MONTH_LABEL_FORMATTER.format(date);
80
82
  }
81
83
  function formatTooltip(date, count) {
82
- const formattedDate = new Intl.DateTimeFormat("en-US", {
83
- day: "numeric",
84
- month: "short",
85
- timeZone: "UTC",
86
- year: "numeric"
87
- }).format(date);
84
+ const formattedDate = TOOLTIP_DATE_FORMATTER.format(date);
88
85
  return `${count} activity ${count === 1 ? "event" : "events"} on ${formattedDate}`;
89
86
  }
90
87
  function HeatmapGrid({
@@ -127,15 +124,15 @@ function HeatmapGrid({
127
124
  ),
128
125
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2 text-xs text-muted-foreground", children: [
129
126
  /* @__PURE__ */ jsx("span", { children: "Less" }),
130
- LEVEL_CLASS_NAMES.map((className, index) => /* @__PURE__ */ jsx(
127
+ LEVEL_CLASS_NAMES.map((className) => /* @__PURE__ */ jsx(
131
128
  "span",
132
129
  {
133
130
  className: cn(
134
- "h-3 w-3 rounded-[3px] border border-border/40",
131
+ "size-3 rounded-[3px] border border-border/40",
135
132
  className
136
133
  )
137
134
  },
138
- `legend-${index}`
135
+ `legend-${className}`
139
136
  )),
140
137
  /* @__PURE__ */ jsx("span", { children: "More" })
141
138
  ] })
@@ -143,6 +140,7 @@ function HeatmapGrid({
143
140
  }
144
141
  const ActivityHeatmap = React.forwardRef(
145
142
  ({
143
+ as: Heading = "h2",
146
144
  className,
147
145
  data,
148
146
  description,
@@ -155,7 +153,7 @@ const ActivityHeatmap = React.forwardRef(
155
153
  const gridData = getGridData(data, normalizedEndDate, weeks);
156
154
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), ref, ...props, children: [
157
155
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
158
- /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold tracking-tight", children: title }),
156
+ /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold tracking-tight", children: title }),
159
157
  description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null
160
158
  ] }),
161
159
  /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-lg border bg-card p-4 shadow-sm", children: /* @__PURE__ */ jsx(HeatmapGrid, { gridData, weeks }) })
@@ -3,18 +3,18 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { forwardRef, useMemo, useState } from "react";
4
4
  import { ArrowRight, ChevronLeft, ChevronRight } from "lucide-react";
5
5
  import { cn } from "../../lib/utils";
6
- import { Avatar, AvatarFallback } from "../avatar";
7
- import { Badge } from "../badge";
8
- import { Button } from "../button";
6
+ import { Avatar, AvatarFallback } from "../avatar/avatar";
7
+ import { Badge } from "../badge/badge";
8
+ import { Button } from "../button/button";
9
9
  import {
10
10
  Card,
11
11
  CardContent,
12
12
  CardDescription,
13
13
  CardHeader,
14
14
  CardTitle
15
- } from "../card";
16
- import { ScrollArea } from "../scroll-area";
17
- import { Separator } from "../separator";
15
+ } from "../card/card";
16
+ import { ScrollArea } from "../scroll-area/scroll-area";
17
+ import { Separator } from "../separator/separator";
18
18
  const toneConfig = {
19
19
  danger: {
20
20
  badgeClassName: "border-destructive/20 bg-destructive/10 text-destructive dark:text-destructive",
@@ -82,7 +82,7 @@ function PaginationControls({
82
82
  size: "sm",
83
83
  variant: "outline",
84
84
  children: [
85
- /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" }),
85
+ /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" }),
86
86
  "Previous"
87
87
  ]
88
88
  }
@@ -111,7 +111,7 @@ function PaginationControls({
111
111
  variant: "outline",
112
112
  children: [
113
113
  "Next",
114
- /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
114
+ /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
115
115
  ]
116
116
  }
117
117
  )
@@ -132,18 +132,18 @@ function ActivityRow({ item }) {
132
132
  {
133
133
  "aria-hidden": "true",
134
134
  className: cn(
135
- "absolute left-4 top-3 h-3 w-3 rounded-full ring-4 ring-background",
135
+ "absolute left-4 top-3 size-3 rounded-full ring-4 ring-background",
136
136
  palette.markerClassName
137
137
  )
138
138
  }
139
139
  ),
140
140
  /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-background/70 p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between", children: [
141
141
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-3", children: [
142
- /* @__PURE__ */ jsx(Avatar, { className: "h-9 w-9 border bg-muted", children: /* @__PURE__ */ jsx(AvatarFallback, { children: getInitials(item.actor) }) }),
142
+ /* @__PURE__ */ jsx(Avatar, { className: "size-9 border bg-muted", children: /* @__PURE__ */ jsx(AvatarFallback, { children: getInitials(item.actor) }) }),
143
143
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
144
144
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
145
145
  /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: item.actor }),
146
- /* @__PURE__ */ jsx(ArrowRight, { className: "h-3.5 w-3.5 text-muted-foreground" }),
146
+ /* @__PURE__ */ jsx(ArrowRight, { className: "size-3.5 text-muted-foreground" }),
147
147
  /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: item.action }),
148
148
  item.target ? /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium text-foreground", children: item.target }) : null
149
149
  ] }),
@@ -46,11 +46,11 @@ const STATUS_CLASSES = {
46
46
  }
47
47
  };
48
48
  const DEFAULT_STATUS_ICON = {
49
- completed: /* @__PURE__ */ jsx(CheckCircle2, { "aria-hidden": "true", className: "h-4 w-4" }),
50
- error: /* @__PURE__ */ jsx(AlertTriangle, { "aria-hidden": "true", className: "h-4 w-4" }),
51
- pending: /* @__PURE__ */ jsx(Circle, { "aria-hidden": "true", className: "h-4 w-4" }),
52
- running: /* @__PURE__ */ jsx(Loader2, { "aria-hidden": "true", className: "h-4 w-4 animate-spin" }),
53
- skipped: /* @__PURE__ */ jsx(MinusCircle, { "aria-hidden": "true", className: "h-4 w-4" })
49
+ completed: /* @__PURE__ */ jsx(CheckCircle2, { "aria-hidden": "true", className: "size-4" }),
50
+ error: /* @__PURE__ */ jsx(AlertTriangle, { "aria-hidden": "true", className: "size-4" }),
51
+ pending: /* @__PURE__ */ jsx(Circle, { "aria-hidden": "true", className: "size-4" }),
52
+ running: /* @__PURE__ */ jsx(Loader2, { "aria-hidden": "true", className: "size-4 animate-spin" }),
53
+ skipped: /* @__PURE__ */ jsx(MinusCircle, { "aria-hidden": "true", className: "size-4" })
54
54
  };
55
55
  const StepContext = createContext({ status: "pending" });
56
56
  const DEFAULT_LABELS = {
@@ -59,6 +59,7 @@ const DEFAULT_LABELS = {
59
59
  elapsed: "Elapsed",
60
60
  expand: "Show details"
61
61
  };
62
+ const AgentActivityLabelsContext = createContext(DEFAULT_LABELS);
62
63
  const ACTIVITY_LIVE_REGION_ROLE = {
63
64
  completed: "status",
64
65
  error: "status",
@@ -75,8 +76,11 @@ const AgentActivity = forwardRef(
75
76
  status = "idle",
76
77
  ...rest
77
78
  } = props;
78
- const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
79
- return /* @__PURE__ */ jsxs(
79
+ const resolvedLabels = useMemo(
80
+ () => ({ ...DEFAULT_LABELS, ...labels }),
81
+ [labels]
82
+ );
83
+ return /* @__PURE__ */ jsx(AgentActivityLabelsContext.Provider, { value: resolvedLabels, children: /* @__PURE__ */ jsxs(
80
84
  "section",
81
85
  {
82
86
  "aria-live": status === "running" ? "polite" : "off",
@@ -103,7 +107,7 @@ const AgentActivity = forwardRef(
103
107
  /* @__PURE__ */ jsx("ol", { className: "flex flex-col gap-2", children })
104
108
  ]
105
109
  }
106
- );
110
+ ) });
107
111
  }
108
112
  );
109
113
  AgentActivity.displayName = "AgentActivity";
@@ -148,7 +152,7 @@ function StepRow({
148
152
  {
149
153
  "aria-hidden": "true",
150
154
  className: cn(
151
- "mt-0.5 inline-flex h-5 w-5 shrink-0 items-center justify-center",
155
+ "mt-0.5 inline-flex size-5 shrink-0 items-center justify-center",
152
156
  iconClass
153
157
  ),
154
158
  children: icon
@@ -161,7 +165,7 @@ function StepRow({
161
165
  "aria-controls": detailsId,
162
166
  "aria-expanded": open,
163
167
  "aria-label": open ? labels.collapse : labels.expand,
164
- className: "ml-auto inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-foreground/10 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
168
+ className: "ml-auto inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-foreground/10 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
165
169
  onClick: onToggle,
166
170
  type: "button",
167
171
  children: /* @__PURE__ */ jsx(
@@ -169,7 +173,7 @@ function StepRow({
169
173
  {
170
174
  "aria-hidden": "true",
171
175
  className: cn(
172
- "h-4 w-4 transition-transform",
176
+ "size-4 transition-transform",
173
177
  open ? "rotate-180" : "rotate-0"
174
178
  )
175
179
  }
@@ -193,6 +197,7 @@ const AgentStep = forwardRef(
193
197
  const hasDetails = split.body.length > 0;
194
198
  const [open, setOpen] = useState(defaultOpen);
195
199
  const detailsId = useId();
200
+ const labels = useContext(AgentActivityLabelsContext);
196
201
  const handleToggle = useCallback(() => {
197
202
  setOpen((value) => !value);
198
203
  }, []);
@@ -222,15 +227,16 @@ const AgentStep = forwardRef(
222
227
  header: split.header,
223
228
  icon: resolvedIcon,
224
229
  iconClass: palette.iconClass,
225
- labels: DEFAULT_LABELS,
230
+ labels,
226
231
  onToggle: handleToggle,
227
232
  open
228
233
  }
229
234
  ),
230
- hasDetails && open ? /* @__PURE__ */ jsx(
235
+ hasDetails ? /* @__PURE__ */ jsx(
231
236
  "div",
232
237
  {
233
238
  className: "border-t border-border/60 px-3 py-2 text-xs",
239
+ hidden: !open,
234
240
  id: detailsId,
235
241
  children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 pl-8", children: split.body })
236
242
  }
@@ -5,7 +5,9 @@ import {
5
5
  forwardRef,
6
6
  useCallback,
7
7
  useContext,
8
+ useEffect,
8
9
  useMemo,
10
+ useRef,
9
11
  useState
10
12
  } from "react";
11
13
  import {
@@ -121,6 +123,24 @@ function ArtifactHeader({
121
123
  subtitle ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: subtitle }) : null
122
124
  ] });
123
125
  }
126
+ function useCopiedFlag() {
127
+ const [copied, setCopied] = useState(false);
128
+ const timerRef = useRef(void 0);
129
+ useEffect(
130
+ () => () => {
131
+ clearTimeout(timerRef.current);
132
+ },
133
+ []
134
+ );
135
+ const flagCopied = useCallback(() => {
136
+ setCopied(true);
137
+ clearTimeout(timerRef.current);
138
+ timerRef.current = setTimeout(() => {
139
+ setCopied(false);
140
+ }, COPIED_TIMEOUT_MS);
141
+ }, []);
142
+ return { copied, flagCopied };
143
+ }
124
144
  function useArtifactController(options) {
125
145
  const {
126
146
  defaultFullscreen,
@@ -133,7 +153,7 @@ function useArtifactController(options) {
133
153
  value
134
154
  } = options;
135
155
  const [fullscreen, setFullscreen] = useState(defaultFullscreen);
136
- const [copied, setCopied] = useState(false);
156
+ const { copied, flagCopied } = useCopiedFlag();
137
157
  const resolvedFilename = useMemo(
138
158
  () => buildFilename({ filename, language, title, type }),
139
159
  [filename, language, title, type]
@@ -141,12 +161,9 @@ function useArtifactController(options) {
141
161
  const copy = useCallback(async () => {
142
162
  const ok = await writeToClipboard(value);
143
163
  if (!ok) return false;
144
- setCopied(true);
145
- setTimeout(() => {
146
- setCopied(false);
147
- }, COPIED_TIMEOUT_MS);
164
+ flagCopied();
148
165
  return true;
149
- }, [value]);
166
+ }, [flagCopied, value]);
150
167
  const download = useCallback(() => {
151
168
  downloadValueAsFile(value, resolvedFilename);
152
169
  }, [resolvedFilename, value]);
@@ -259,7 +276,7 @@ const AIArtifactToolbar = forwardRef(({ className, ...rest }, ref) => /* @__PURE
259
276
  AIArtifactToolbar.displayName = "AIArtifactToolbar";
260
277
  const AIArtifactCopyButton = forwardRef(({ className, onClick, ...rest }, ref) => {
261
278
  const { copied, copy, labels } = useAIArtifact();
262
- const handleClick = useCallback(
279
+ const handleCopyArtifact = useCallback(
263
280
  (event) => {
264
281
  onClick?.(event);
265
282
  if (event.defaultPrevented) return;
@@ -271,21 +288,21 @@ const AIArtifactCopyButton = forwardRef(({ className, onClick, ...rest }, ref) =
271
288
  Button,
272
289
  {
273
290
  "aria-label": copied ? labels.copied : labels.copy,
274
- className: cn("h-8 w-8", className),
275
- onClick: handleClick,
291
+ className: cn("size-8", className),
292
+ onClick: handleCopyArtifact,
276
293
  ref,
277
294
  size: "icon",
278
295
  type: "button",
279
296
  variant: "ghost",
280
297
  ...rest,
281
- children: copied ? /* @__PURE__ */ jsx(Check, { "aria-hidden": "true", className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Copy, { "aria-hidden": "true", className: "h-4 w-4" })
298
+ children: copied ? /* @__PURE__ */ jsx(Check, { "aria-hidden": "true", className: "size-4" }) : /* @__PURE__ */ jsx(Copy, { "aria-hidden": "true", className: "size-4" })
282
299
  }
283
300
  );
284
301
  });
285
302
  AIArtifactCopyButton.displayName = "AIArtifactCopyButton";
286
303
  const AIArtifactEditButton = forwardRef(({ className, onClick, ...rest }, ref) => {
287
304
  const { hasOnEdit, labels, onEdit } = useAIArtifact();
288
- const handleClick = useCallback(
305
+ const handleEditArtifact = useCallback(
289
306
  (event) => {
290
307
  onClick?.(event);
291
308
  if (event.defaultPrevented) return;
@@ -298,21 +315,21 @@ const AIArtifactEditButton = forwardRef(({ className, onClick, ...rest }, ref) =
298
315
  Button,
299
316
  {
300
317
  "aria-label": labels.edit,
301
- className: cn("h-8 w-8", className),
302
- onClick: handleClick,
318
+ className: cn("size-8", className),
319
+ onClick: handleEditArtifact,
303
320
  ref,
304
321
  size: "icon",
305
322
  type: "button",
306
323
  variant: "ghost",
307
324
  ...rest,
308
- children: /* @__PURE__ */ jsx(Pencil, { "aria-hidden": "true", className: "h-4 w-4" })
325
+ children: /* @__PURE__ */ jsx(Pencil, { "aria-hidden": "true", className: "size-4" })
309
326
  }
310
327
  );
311
328
  });
312
329
  AIArtifactEditButton.displayName = "AIArtifactEditButton";
313
330
  const AIArtifactDownloadButton = forwardRef(({ className, onClick, ...rest }, ref) => {
314
331
  const { download, labels } = useAIArtifact();
315
- const handleClick = useCallback(
332
+ const handleDownloadArtifact = useCallback(
316
333
  (event) => {
317
334
  onClick?.(event);
318
335
  if (event.defaultPrevented) return;
@@ -324,21 +341,21 @@ const AIArtifactDownloadButton = forwardRef(({ className, onClick, ...rest }, re
324
341
  Button,
325
342
  {
326
343
  "aria-label": labels.download,
327
- className: cn("h-8 w-8", className),
328
- onClick: handleClick,
344
+ className: cn("size-8", className),
345
+ onClick: handleDownloadArtifact,
329
346
  ref,
330
347
  size: "icon",
331
348
  type: "button",
332
349
  variant: "ghost",
333
350
  ...rest,
334
- children: /* @__PURE__ */ jsx(Download, { "aria-hidden": "true", className: "h-4 w-4" })
351
+ children: /* @__PURE__ */ jsx(Download, { "aria-hidden": "true", className: "size-4" })
335
352
  }
336
353
  );
337
354
  });
338
355
  AIArtifactDownloadButton.displayName = "AIArtifactDownloadButton";
339
356
  const AIArtifactFullscreenButton = forwardRef(({ className, onClick, ...rest }, ref) => {
340
357
  const { fullscreen, labels, toggleFullscreen } = useAIArtifact();
341
- const handleClick = useCallback(
358
+ const handleToggleArtifactFullscreen = useCallback(
342
359
  (event) => {
343
360
  onClick?.(event);
344
361
  if (event.defaultPrevented) return;
@@ -351,14 +368,14 @@ const AIArtifactFullscreenButton = forwardRef(({ className, onClick, ...rest },
351
368
  {
352
369
  "aria-label": fullscreen ? labels.exitFullscreen : labels.enterFullscreen,
353
370
  "aria-pressed": fullscreen,
354
- className: cn("h-8 w-8", className),
355
- onClick: handleClick,
371
+ className: cn("size-8", className),
372
+ onClick: handleToggleArtifactFullscreen,
356
373
  ref,
357
374
  size: "icon",
358
375
  type: "button",
359
376
  variant: "ghost",
360
377
  ...rest,
361
- children: fullscreen ? /* @__PURE__ */ jsx(Minimize2, { "aria-hidden": "true", className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Maximize2, { "aria-hidden": "true", className: "h-4 w-4" })
378
+ children: fullscreen ? /* @__PURE__ */ jsx(Minimize2, { "aria-hidden": "true", className: "size-4" }) : /* @__PURE__ */ jsx(Maximize2, { "aria-hidden": "true", className: "size-4" })
362
379
  }
363
380
  );
364
381
  });
@@ -3,8 +3,8 @@ import { forwardRef } from "react";
3
3
  import { cva } from "class-variance-authority";
4
4
  import { LoaderCircle, SendHorizontal } from "lucide-react";
5
5
  import { cn } from "../../lib/utils";
6
- import { Button } from "../button";
7
- import { Textarea } from "../textarea";
6
+ import { Button } from "../button/button";
7
+ import { Textarea } from "../textarea/textarea";
8
8
  const formShellVariants = cva(
9
9
  "rounded-2xl border border-border/70 bg-background shadow-sm"
10
10
  );
@@ -36,7 +36,7 @@ function AIChatInputFooter({
36
36
  disabled: isSubmitDisabled,
37
37
  type: "submit",
38
38
  children: [
39
- isSubmitting ? /* @__PURE__ */ jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(SendHorizontal, { className: "mr-2 h-4 w-4" }),
39
+ isSubmitting ? /* @__PURE__ */ jsx(LoaderCircle, { className: "mr-2 size-4 animate-spin" }) : /* @__PURE__ */ jsx(SendHorizontal, { className: "mr-2 size-4" }),
40
40
  submitLabel
41
41
  ]
42
42
  }
@@ -48,6 +48,7 @@ const AIChatInput = forwardRef(
48
48
  className,
49
49
  disabled = false,
50
50
  helperText,
51
+ inputLabel = "Chat message",
51
52
  isSubmitting = false,
52
53
  onSubmit,
53
54
  onValueChange,
@@ -72,7 +73,8 @@ const AIChatInput = forwardRef(
72
73
  /* @__PURE__ */ jsx(
73
74
  Textarea,
74
75
  {
75
- className: "min-h-[120px] resize-none rounded-xl border-0 bg-transparent px-1 py-1 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0",
76
+ "aria-label": inputLabel,
77
+ className: "min-h-[120px] resize-none rounded-xl border-0 bg-transparent p-1 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0",
76
78
  disabled,
77
79
  onChange: (event) => {
78
80
  textareaProps?.onChange?.(event);
@@ -2,8 +2,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import { cva } from "class-variance-authority";
4
4
  import { cn } from "../../lib/utils";
5
- import { Avatar, AvatarFallback } from "../avatar";
6
- import { Badge } from "../badge";
5
+ import { Avatar, AvatarFallback } from "../avatar/avatar";
6
+ import { Badge } from "../badge/badge";
7
7
  const bubbleVariants = cva(
8
8
  "rounded-2xl border px-4 py-3 shadow-sm transition-colors",
9
9
  {
@@ -73,7 +73,7 @@ const AIMessageBubble = forwardRef(
73
73
  isUser ? "flex-row-reverse text-right" : "flex-row"
74
74
  ),
75
75
  children: [
76
- /* @__PURE__ */ jsx(Avatar, { className: "mt-0.5 h-8 w-8 border border-border/70", children: /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-muted text-[11px] font-medium uppercase text-muted-foreground", children: fallbackLabel }) }),
76
+ /* @__PURE__ */ jsx(Avatar, { className: "mt-0.5 size-8 border border-border/70", children: /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-muted text-[11px] font-medium uppercase text-muted-foreground", children: fallbackLabel }) }),
77
77
  /* @__PURE__ */ jsxs(
78
78
  "div",
79
79
  {