@heyramzi/ui 6.1.0 → 8.0.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 (332) hide show
  1. package/COMPONENTS.md +32 -40
  2. package/README.md +10 -4
  3. package/package.json +31 -29
  4. package/scripts/sync-shadcn.mjs +29 -16
  5. package/scripts/sync-transitions.mjs +11 -11
  6. package/src/ai/ai-button/AiButton.svelte +86 -0
  7. package/src/ai/ai-button/index.ts +4 -0
  8. package/src/ai/confirmation/Confirmation.svelte +8 -8
  9. package/src/ai/confirmation/confirmation-context.svelte.ts +2 -2
  10. package/src/ai/generation-progress/GenerationProgress.svelte +354 -0
  11. package/src/ai/generation-progress/index.ts +7 -0
  12. package/src/ai/index.ts +16 -24
  13. package/src/ai/prompt-input/PromptInput.svelte +19 -1
  14. package/src/ai/prompt-input/PromptInputSubmit.svelte +9 -3
  15. package/src/ai/reasoning/Reasoning.svelte +11 -8
  16. package/src/ambient.d.ts +4 -0
  17. package/src/animations/README.md +17 -17
  18. package/src/animations/index.css +3 -14
  19. package/src/animations/upstream-coverage.test.ts +1 -1
  20. package/src/components/copy/clipboard.test.ts +206 -0
  21. package/src/components/copy/clipboard.ts +49 -0
  22. package/src/components/copy/copied.svelte.ts +39 -0
  23. package/src/components/copy/copy-button.svelte +175 -0
  24. package/src/components/copy/copy-button.test.ts +110 -0
  25. package/src/components/copy/index.ts +3 -0
  26. package/src/components/data-table/data-table.test.ts +134 -0
  27. package/src/components/data-table/data-table.ts +77 -0
  28. package/src/components/data-table/index.ts +20 -0
  29. package/src/components/data-table/infinite-scroll.svelte +69 -0
  30. package/src/components/data-table/pagination.svelte +62 -0
  31. package/src/components/data-table/row-arrow.svelte +28 -0
  32. package/src/components/data-table/row-context-menu.svelte +106 -0
  33. package/src/components/data-table/row-context-menu.test.ts +18 -0
  34. package/src/components/data-table/sortable-head.svelte +56 -0
  35. package/src/components/data-table/table-skeleton.svelte +83 -0
  36. package/src/components/hold-to-confirm/hold-to-confirm.svelte +232 -0
  37. package/src/components/hold-to-confirm/index.ts +1 -0
  38. package/src/components/icon/icon.svelte +23 -0
  39. package/src/components/icon/index.ts +1 -0
  40. package/src/components/language-flag/index.ts +1 -0
  41. package/src/components/language-flag/language-flag.svelte +60 -0
  42. package/src/components/list-page/detail-empty.svelte +50 -0
  43. package/src/components/list-page/detail-header.svelte +107 -0
  44. package/src/components/list-page/detail-panel.svelte +90 -0
  45. package/src/components/list-page/detail-row.svelte +36 -0
  46. package/src/components/list-page/detail-stack.svelte +33 -0
  47. package/src/components/list-page/empty-state.svelte +91 -0
  48. package/src/components/list-page/filter-item.svelte +49 -0
  49. package/src/components/list-page/filter-popover.svelte +88 -0
  50. package/src/components/list-page/filter-section.ts +12 -0
  51. package/src/components/list-page/grouped-list.svelte +116 -0
  52. package/src/components/list-page/index.ts +28 -0
  53. package/src/components/list-page/list-page-shell.svelte +195 -0
  54. package/src/components/list-page/list-table.ts +19 -0
  55. package/src/components/list-page/master-detail.svelte +206 -0
  56. package/src/components/list-page/master-detail.test.ts +37 -0
  57. package/src/components/list-page/notice-bar.svelte +68 -0
  58. package/src/components/list-page/prev-next.svelte +104 -0
  59. package/src/components/list-page/queue-rail.ts +25 -0
  60. package/src/components/list-page/rail-body.svelte +29 -0
  61. package/src/components/list-page/rail-empty.svelte +51 -0
  62. package/src/components/list-page/rail-head.svelte +49 -0
  63. package/src/components/list-page/rail-row.svelte +163 -0
  64. package/src/components/list-page/section-host.ts +24 -0
  65. package/src/components/list-page/section-label.svelte +39 -0
  66. package/src/components/list-page/step.test.ts +21 -0
  67. package/src/components/list-page/step.ts +10 -0
  68. package/src/components/list-page/toolbar-search.svelte +63 -0
  69. package/src/components/list-page/toolbar-trigger.ts +23 -0
  70. package/src/components/list-page/types.ts +1 -0
  71. package/src/components/locale-switch/index.ts +1 -0
  72. package/src/components/locale-switch/locale-switch.svelte +59 -0
  73. package/src/components/mark/index.ts +1 -0
  74. package/src/components/mark/mark.svelte +70 -0
  75. package/src/components/open-in/index.ts +6 -0
  76. package/src/components/open-in/open-in.svelte +106 -0
  77. package/src/components/picker/index.ts +4 -0
  78. package/src/components/picker/mark-picker.svelte +84 -0
  79. package/src/components/picker/picker.svelte +143 -0
  80. package/src/components/picker/trigger.ts +42 -0
  81. package/src/components/picker/types.ts +26 -0
  82. package/src/components/segmented/animated-tabs.svelte +175 -0
  83. package/src/components/segmented/collapse.test.ts +49 -0
  84. package/src/components/segmented/collapse.ts +39 -0
  85. package/src/components/segmented/index.ts +41 -0
  86. package/src/components/segmented/section-runs.svelte +79 -0
  87. package/src/components/segmented/segment.svelte +106 -0
  88. package/src/components/segmented/segmented-filter.svelte +125 -0
  89. package/src/components/segmented/segmented-nav.svelte +82 -0
  90. package/src/components/segmented/segmented-overflow.svelte +85 -0
  91. package/src/components/segmented/segmented-track.svelte +181 -0
  92. package/src/components/segmented/segmented.test.ts +20 -0
  93. package/src/components/segmented/segmented.ts +80 -0
  94. package/src/components/star-rating-input/index.ts +9 -0
  95. package/src/components/star-rating-input/star-rating-input.svelte +256 -0
  96. package/src/components/svg/index.ts +1 -0
  97. package/src/components/svg/svg.svelte +9 -0
  98. package/src/effects/border-beam/BorderBeam.svelte +1 -1
  99. package/src/effects/image-comparison/ImageComparison.css +42 -8
  100. package/src/effects/image-comparison/ImageComparison.svelte +138 -21
  101. package/src/effects/image-comparison/compare.test.ts +17 -0
  102. package/src/effects/image-comparison/compare.ts +5 -0
  103. package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +338 -0
  104. package/src/effects/magic-card/MagicCard.css +47 -0
  105. package/src/effects/magic-card/MagicCard.svelte +57 -0
  106. package/src/effects/marquee/Marquee.css +27 -1
  107. package/src/effects/marquee/Marquee.svelte +67 -3
  108. package/src/effects/reveal/index.ts +2 -1
  109. package/src/effects/reveal/observe.test.ts +60 -0
  110. package/src/effects/reveal/observe.ts +33 -1
  111. package/src/effects/reveal/types.ts +7 -0
  112. package/src/effects/theme-toggle/ThemeToggle.css +199 -6
  113. package/src/effects/theme-toggle/ThemeToggle.svelte +51 -26
  114. package/src/gallery.test.ts +52 -0
  115. package/src/index.ts +5 -1
  116. package/src/lib/panel.ts +7 -1
  117. package/src/lib/sliding-pill.ts +68 -0
  118. package/src/lib/theme-transition.ts +41 -13
  119. package/src/lib/tone.ts +48 -0
  120. package/src/shadcn/accordion/accordion-trigger.svelte +15 -6
  121. package/src/shadcn/alert/alert.svelte +3 -1
  122. package/src/shadcn/badge/badge.svelte +8 -7
  123. package/src/shadcn/breadcrumb/breadcrumb-ellipsis.svelte +2 -2
  124. package/src/shadcn/breadcrumb/breadcrumb-separator.svelte +2 -2
  125. package/src/shadcn/calendar/calendar-month-select.svelte +2 -2
  126. package/src/shadcn/calendar/calendar-next-button.svelte +2 -2
  127. package/src/shadcn/calendar/calendar-prev-button.svelte +2 -2
  128. package/src/shadcn/calendar/calendar-year-select.svelte +2 -2
  129. package/src/shadcn/calendar/calendar.svelte +6 -0
  130. package/src/shadcn/code-block/code-block-actions.svelte +23 -0
  131. package/src/shadcn/code-block/code-block-content.svelte +55 -0
  132. package/src/shadcn/code-block/code-block-copy-button.svelte +10 -0
  133. package/src/shadcn/code-block/code-block-footer.svelte +20 -0
  134. package/src/shadcn/code-block/code-block-header.svelte +23 -0
  135. package/src/shadcn/code-block/code-block-line.svelte +71 -0
  136. package/src/shadcn/code-block/code-block-title.svelte +23 -0
  137. package/src/shadcn/code-block/code-block.svelte +47 -0
  138. package/src/shadcn/code-block/index.ts +42 -0
  139. package/src/shadcn/command/index.ts +3 -0
  140. package/src/shadcn/field/index.ts +3 -0
  141. package/src/shadcn/field/simple-field.svelte +71 -0
  142. package/src/shadcn/field/simple-field.test.ts +47 -0
  143. package/src/shadcn/hooks/highlighter.ts +132 -0
  144. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +98 -0
  145. package/src/shadcn/kbd/index.ts +10 -0
  146. package/src/shadcn/kbd/kbd-group.svelte +20 -0
  147. package/src/shadcn/kbd/kbd.svelte +23 -0
  148. package/src/shadcn/message-scroller/index.ts +28 -0
  149. package/src/shadcn/message-scroller/message-scroller-button.svelte +52 -0
  150. package/src/shadcn/message-scroller/message-scroller-content.svelte +17 -0
  151. package/src/shadcn/message-scroller/message-scroller-item.svelte +22 -0
  152. package/src/shadcn/message-scroller/message-scroller-provider.svelte +7 -0
  153. package/src/shadcn/message-scroller/message-scroller-viewport.svelte +20 -0
  154. package/src/shadcn/message-scroller/message-scroller.svelte +20 -0
  155. package/src/shadcn/radio-group/radio-group-item.svelte +3 -2
  156. package/src/shadcn/sheet/sheet-content.svelte +1 -0
  157. package/src/shadcn/sheet/sheet.css +48 -0
  158. package/src/shadcn/sonner/sonner.svelte +7 -10
  159. package/src/shadcn/tabs/tabs-list.svelte +13 -2
  160. package/src/shadcn/tabs/tabs-trigger.svelte +1 -1
  161. package/src/shadcn/toggle-group/toggle-group.svelte +10 -3
  162. package/src/shadcn/trace/index.ts +29 -0
  163. package/src/shadcn/trace/trace-collapsible-content.svelte +29 -0
  164. package/src/shadcn/trace/trace-collapsible-trigger.svelte +29 -0
  165. package/src/shadcn/trace/trace-collapsible.svelte +20 -0
  166. package/src/shadcn/trace/trace-description.svelte +20 -0
  167. package/src/shadcn/trace/trace-icon.svelte +24 -0
  168. package/src/shadcn/trace/trace-line.svelte +31 -0
  169. package/src/shadcn/trace/trace-title.svelte +20 -0
  170. package/src/shadcn/trace/trace.svelte +23 -0
  171. package/src/ai/composer/Composer.css +0 -108
  172. package/src/ai/composer/Composer.svelte +0 -111
  173. package/src/ai/composer/index.ts +0 -10
  174. package/src/ai/conversation/Conversation.svelte +0 -28
  175. package/src/ai/conversation/ConversationContent.svelte +0 -35
  176. package/src/ai/conversation/ConversationEmptyState.svelte +0 -46
  177. package/src/ai/conversation/ConversationScrollButton.svelte +0 -51
  178. package/src/ai/conversation/index.ts +0 -33
  179. package/src/ai/conversation/stick-to-bottom-context.svelte.ts +0 -131
  180. package/src/animations/accordion.css +0 -58
  181. package/src/animations/icon-swap.css +0 -43
  182. package/src/animations/notification-badge.css +0 -81
  183. package/src/animations/panel.css +0 -86
  184. package/src/animations/reasoning-stream.css +0 -49
  185. package/src/animations/skeleton-reveal.css +0 -97
  186. package/src/animations/streaming-text.css +0 -31
  187. package/src/animations/tabs-sliding.css +0 -83
  188. package/src/animations/texts-reveal.css +0 -70
  189. package/src/animations/tooltip.css +0 -72
  190. package/src/animations/view-transition-reveal.ts +0 -74
  191. package/src/charts/animated-value.css +0 -7
  192. package/src/charts/animated-value.svelte +0 -110
  193. package/src/charts/area-chart.css +0 -29
  194. package/src/charts/area-chart.svelte +0 -195
  195. package/src/charts/bar-chart.css +0 -119
  196. package/src/charts/bar-chart.svelte +0 -269
  197. package/src/charts/charts.css +0 -201
  198. package/src/charts/crosshair.svelte +0 -35
  199. package/src/charts/donut-chart.css +0 -56
  200. package/src/charts/donut-chart.svelte +0 -158
  201. package/src/charts/edge-fade.svelte +0 -43
  202. package/src/charts/edge-fade.ts +0 -16
  203. package/src/charts/figure.css +0 -100
  204. package/src/charts/figure.svelte +0 -122
  205. package/src/charts/gauge-chart.css +0 -94
  206. package/src/charts/gauge-chart.svelte +0 -303
  207. package/src/charts/hover-band.test.ts +0 -30
  208. package/src/charts/hover-band.ts +0 -21
  209. package/src/charts/hover-focus.svelte +0 -85
  210. package/src/charts/index.ts +0 -30
  211. package/src/charts/legend.css +0 -131
  212. package/src/charts/legend.svelte +0 -112
  213. package/src/charts/line-chart.css +0 -26
  214. package/src/charts/line-chart.svelte +0 -256
  215. package/src/charts/motion.ts +0 -19
  216. package/src/charts/number-chart.css +0 -168
  217. package/src/charts/number-chart.svelte +0 -177
  218. package/src/charts/primitives/chart-container.svelte +0 -57
  219. package/src/charts/primitives/chart-style.svelte +0 -36
  220. package/src/charts/primitives/chart-tooltip.svelte +0 -161
  221. package/src/charts/primitives/chart-utils.ts +0 -54
  222. package/src/charts/primitives/index.ts +0 -11
  223. package/src/charts/reveal.svelte +0 -61
  224. package/src/charts/ring-chart.css +0 -96
  225. package/src/charts/ring-chart.svelte +0 -158
  226. package/src/charts/sparkline.css +0 -45
  227. package/src/charts/sparkline.svelte +0 -140
  228. package/src/charts/stat-card.css +0 -103
  229. package/src/charts/stat-card.svelte +0 -267
  230. package/src/charts/time-series-chart.css +0 -28
  231. package/src/charts/time-series-chart.svelte +0 -179
  232. package/src/charts/trend-pill.css +0 -38
  233. package/src/charts/trend-pill.svelte +0 -48
  234. package/src/lib/hooks/is-mobile.svelte.ts +0 -11
  235. package/src/lib/utils.ts +0 -45
  236. package/src/showcase/AiSection.svelte +0 -157
  237. package/src/showcase/AnimationsSection.svelte +0 -1658
  238. package/src/showcase/ChartsSection.svelte +0 -458
  239. package/src/showcase/EffectsSection.svelte +0 -152
  240. package/src/showcase/ShadcnSection.svelte +0 -27
  241. package/src/showcase/ShowcaseImport.svelte +0 -126
  242. package/src/showcase/ShowcaseList.svelte +0 -132
  243. package/src/showcase/ShowcaseNav.svelte +0 -247
  244. package/src/showcase/ShowcaseSection.svelte +0 -112
  245. package/src/showcase/ShowcaseShell.svelte +0 -55
  246. package/src/showcase/ShowcaseStage.svelte +0 -342
  247. package/src/showcase/ShowcaseVariant.svelte +0 -109
  248. package/src/showcase/assets/image-reveal/art-1.jpg +0 -0
  249. package/src/showcase/assets/image-reveal/art-2.jpg +0 -0
  250. package/src/showcase/assets/image-reveal/art-3.jpg +0 -0
  251. package/src/showcase/check.svg +0 -1
  252. package/src/showcase/chevron-arms.svg +0 -2
  253. package/src/showcase/chevron-down.svg +0 -1
  254. package/src/showcase/copy.svg +0 -2
  255. package/src/showcase/demos/ai/confirmation.svelte +0 -59
  256. package/src/showcase/demos/ai/conversation.svelte +0 -59
  257. package/src/showcase/demos/ai/loading-state.svelte +0 -19
  258. package/src/showcase/demos/ai/prompt-input.svelte +0 -57
  259. package/src/showcase/demos/ai/reasoning.svelte +0 -19
  260. package/src/showcase/demos/ai/thinking-dots.svelte +0 -15
  261. package/src/showcase/demos/ai/voice-waveform.svelte +0 -24
  262. package/src/showcase/demos/effects/animated-beam.svelte +0 -50
  263. package/src/showcase/demos/effects/animated-group.svelte +0 -47
  264. package/src/showcase/demos/effects/border-beam-default.svelte +0 -20
  265. package/src/showcase/demos/effects/border-beam-line.svelte +0 -20
  266. package/src/showcase/demos/effects/border-beam-mono.svelte +0 -20
  267. package/src/showcase/demos/effects/border-beam-sunset.svelte +0 -20
  268. package/src/showcase/demos/effects/image-comparison.svelte +0 -25
  269. package/src/showcase/demos/effects/image-reveal.svelte +0 -49
  270. package/src/showcase/demos/effects/in-view.svelte +0 -41
  271. package/src/showcase/demos/effects/integrations-hub.svelte +0 -82
  272. package/src/showcase/demos/effects/magnetic.svelte +0 -31
  273. package/src/showcase/demos/effects/marquee.svelte +0 -33
  274. package/src/showcase/demos/effects/progressive-blur.svelte +0 -47
  275. package/src/showcase/demos/effects/spotlight.svelte +0 -40
  276. package/src/showcase/demos/effects/text-effect.svelte +0 -55
  277. package/src/showcase/demos/shadcn/accordion.svelte +0 -45
  278. package/src/showcase/demos/shadcn/alert-dialog.svelte +0 -23
  279. package/src/showcase/demos/shadcn/alert.svelte +0 -30
  280. package/src/showcase/demos/shadcn/attachment.svelte +0 -71
  281. package/src/showcase/demos/shadcn/avatar.svelte +0 -30
  282. package/src/showcase/demos/shadcn/badge.svelte +0 -26
  283. package/src/showcase/demos/shadcn/breadcrumb.svelte +0 -34
  284. package/src/showcase/demos/shadcn/bubble.svelte +0 -36
  285. package/src/showcase/demos/shadcn/button.svelte +0 -11
  286. package/src/showcase/demos/shadcn/calendar.svelte +0 -8
  287. package/src/showcase/demos/shadcn/card.svelte +0 -39
  288. package/src/showcase/demos/shadcn/checkbox.svelte +0 -39
  289. package/src/showcase/demos/shadcn/collapsible.svelte +0 -20
  290. package/src/showcase/demos/shadcn/command.svelte +0 -48
  291. package/src/showcase/demos/shadcn/context-menu.svelte +0 -54
  292. package/src/showcase/demos/shadcn/demo-harness.svelte +0 -12
  293. package/src/showcase/demos/shadcn/demos.test.ts +0 -20
  294. package/src/showcase/demos/shadcn/dialog.svelte +0 -38
  295. package/src/showcase/demos/shadcn/dropdown-menu.svelte +0 -59
  296. package/src/showcase/demos/shadcn/empty.svelte +0 -29
  297. package/src/showcase/demos/shadcn/field.svelte +0 -115
  298. package/src/showcase/demos/shadcn/hover-card.svelte +0 -32
  299. package/src/showcase/demos/shadcn/index.ts +0 -358
  300. package/src/showcase/demos/shadcn/input-otp.svelte +0 -19
  301. package/src/showcase/demos/shadcn/input.svelte +0 -5
  302. package/src/showcase/demos/shadcn/label.svelte +0 -11
  303. package/src/showcase/demos/shadcn/marker.svelte +0 -30
  304. package/src/showcase/demos/shadcn/message.svelte +0 -75
  305. package/src/showcase/demos/shadcn/popover.svelte +0 -36
  306. package/src/showcase/demos/shadcn/progress.svelte +0 -13
  307. package/src/showcase/demos/shadcn/radio-group.svelte +0 -19
  308. package/src/showcase/demos/shadcn/scroll-area.svelte +0 -18
  309. package/src/showcase/demos/shadcn/select.svelte +0 -29
  310. package/src/showcase/demos/shadcn/separator.svelte +0 -12
  311. package/src/showcase/demos/shadcn/sheet.svelte +0 -48
  312. package/src/showcase/demos/shadcn/skeleton.svelte +0 -11
  313. package/src/showcase/demos/shadcn/slider.svelte +0 -7
  314. package/src/showcase/demos/shadcn/sonner.svelte +0 -18
  315. package/src/showcase/demos/shadcn/spinner.svelte +0 -11
  316. package/src/showcase/demos/shadcn/switch.svelte +0 -9
  317. package/src/showcase/demos/shadcn/table.svelte +0 -76
  318. package/src/showcase/demos/shadcn/tabs.svelte +0 -62
  319. package/src/showcase/demos/shadcn/textarea.svelte +0 -5
  320. package/src/showcase/demos/shadcn/toggle-group.svelte +0 -18
  321. package/src/showcase/demos/shadcn/toggle.svelte +0 -14
  322. package/src/showcase/demos/shadcn/tooltip.svelte +0 -13
  323. package/src/showcase/heart.svg +0 -1
  324. package/src/showcase/index.ts +0 -38
  325. package/src/showcase/kit.test.ts +0 -72
  326. package/src/showcase/kit.ts +0 -17
  327. package/src/showcase/plus.svg +0 -1
  328. package/src/showcase/showcase-shell.css +0 -91
  329. package/src/showcase/stacked-section.css +0 -15
  330. package/src/showcase/success-check.svg +0 -1
  331. package/src/showcase/types.ts +0 -29
  332. package/src/svg-raw.d.ts +0 -7
package/COMPONENTS.md CHANGED
@@ -21,19 +21,21 @@ The style layer lives in [`src/tokens.css`](./src/tokens.css) and the motion CSS
21
21
  - `calendar` — Calendar
22
22
  - `card` — Card
23
23
  - `checkbox` — Checkbox
24
+ - `code-block` — CodeBlock. Highlight with `useHighlightedCode` from `@heyramzi/ui/shadcn/hooks/use-highlighted-code.svelte` (Shiki, ANSI too)
24
25
  - `collapsible` — Collapsible
25
- - `command` — Command
26
+ - `command` — Command, computeCommandScore (the scorer, for a custom `filter`)
26
27
  - `context-menu` — ContextMenu
27
28
  - `dialog` — Dialog
28
29
  - `dropdown-menu` — CheckboxGroup, CheckboxItem, Content, Portal, DropdownMenu, DropdownMenuCheckboxGroup
29
30
  - `empty` — Empty
30
- - `field` — Field
31
+ - `field` — Field and its parts, plus SimpleField: label, hint or error and the control, with the message linked by `aria-describedby`
31
32
  - `hover-card` — HoverCard
32
33
  - `input` — Input
33
34
  - `input-otp` — InputOtp
34
35
  - `label` — Label
35
36
  - `marker` — Marker
36
37
  - `message` — Message
38
+ - `message-scroller` — MessageScroller, the chat transcript scroller: follows a streamed reply, anchors each turn, keeps place on prepend
37
39
  - `popover` — Popover
38
40
  - `progress` — Progress
39
41
  - `radio-group` — RadioGroup
@@ -53,56 +55,68 @@ The style layer lives in [`src/tokens.css`](./src/tokens.css) and the motion CSS
53
55
  - `toggle` — toggleVariants, ToggleSize, ToggleVariant, ToggleVariants
54
56
  - `toggle-group` — ToggleGroup
55
57
  - `tooltip` — Tooltip
58
+ - `trace` — Trace, an agent's steps: reasoning, tool calls and sources as status rows that can expand
59
+
60
+ ## Components (`src/components`)
61
+
62
+ Generic pieces built on the primitives, imported from `@heyramzi/ui/components/<name>`.
63
+
64
+ - `copy` — CopyButton, copyText, copyRichText, htmlToPlainText, Copied
65
+ - `data-table` — SortableHead, Pagination, InfiniteScroll, RowContextMenu, TableSkeleton, and the sort, page and filter helpers
66
+ - `hold-to-confirm` — HoldToConfirm, press and hold to confirm
67
+ - `icon` — Icon, a Phosphor component at a size
68
+ - `language-flag` — LanguageFlag
69
+ - `list-page` — ListPageShell, MasterDetail, GroupedList, RailRow and the rest of the master-detail page kit, NoticeBar, EmptyState, FilterPopover, setSectionHost
70
+ - `locale-switch` — LocaleSwitch, a language switch on SegmentedFilter
71
+ - `mark` — Mark, a logo or photo glyph with an initial fallback
72
+ - `open-in` — OpenIn, a link out to a tool that takes the tool's name, label and mark as a prop
73
+ - `picker` — Picker, MarkPicker, pickerTriggerClass, a command palette at popover scale
74
+ - `segmented` — AnimatedTabs (pill or underline), SegmentedFilter, SegmentedNav, SectionRuns, one bordered track with a sliding pill, a badge note and an overflow menu
75
+ - `star-rating-input` — StarRatingInput
76
+ - `svg` — Svg, an SVG file imported with `?raw`
56
77
 
57
78
  ## Effects (`src/effects`)
58
79
 
80
+ - `interactive-hover-button` — InteractiveHoverButton, a dot that grows into the fill
81
+
59
82
  - `animated-beam` — AnimatedBeam, AnimatedBeamProps, AnchorPosition
60
83
  - `border-beam` — BorderBeam
61
- - `image-comparison` — ImageComparison
84
+ - `image-comparison` — ImageComparison, a before/after wipe with a bindable position, side badges and a hint sweep
62
85
  - `image-reveal` — ImageReveal, ImageRevealProps, ImageRevealHandle
63
86
  - `magnetic` — magnetic
87
+ - `magic-card` — MagicCard. Props: `glow`, `radius`, `class`, `contentClass`; the glow colour is `--magic-card-glow` set on `class`.
64
88
  - `marquee` — Marquee
65
89
  - `progressive-blur` — ProgressiveBlur
66
90
  - `reveal` — InView, AnimatedGroup, TextEffect, observeInView, RevealPreset, RevealPer
67
91
  - `shader-gradient` — ShaderGradient, ShaderGradientProps, ShaderGradientUniforms
68
92
  - `spotlight` — Spotlight
69
- - `theme-toggle` — ThemeToggle, revealTheme. Props: `isDark`, `mode` (`light`, `dark`, `system`; swaps in the Monitor icon), `onToggle`, `variant` (`outline`, `ghost`, `inverted`; `inverted` boolean is an alias), `size`, `label`, `title`, `skipTransition`, `class`. `revealTheme(event, apply, { skip, duration })` is the circular wipe on its own: `import { revealTheme } from "@heyramzi/ui"` (the `./lib/*` subpath points at `.js` and the source is `.ts`).
93
+ - `theme-toggle` — ThemeToggle, revealTheme. Props: `isDark`, `mode` (`light`, `dark`, `system`; swaps in the Monitor icon), `onToggle`, `variant` (`outline`, `ghost`, `inverted`, `slide`; `inverted` boolean is an alias; `slide` is a pill with a moving thumb, coloured by `--theme-toggle-thumb-light`, `--theme-toggle-thumb-dark`, `--theme-toggle-track`, `--theme-toggle-glow` and friends set on `class`), `size`, `label`, `title`, `skipTransition`, `class`. `revealTheme(event, apply, { skip, duration, easing })` is the circular wipe on its own: `import { revealTheme } from "@heyramzi/ui"` (the `./lib/*` subpath points at `.js` and the source is `.ts`).
70
94
 
71
95
  ## Animations (`src/animations`)
72
96
 
73
- - `accordion` — keyframe utilities
74
97
  - `avatar-group-hover` — keyframe utilities
75
98
  - `card-tilt` — keyframe utilities
76
99
  - `digit-pop-in` — keyframe utilities
77
100
  - `dropdown` — keyframe utilities
78
- - `icon-swap` — keyframe utilities
79
101
  - `input-clear-dissolve` — keyframe utilities
80
102
  - `input-shake` — keyframe utilities
81
103
  - `learn-more-hover` — keyframe utilities
82
104
  - `like-button` — keyframe utilities
83
105
  - `modal` — keyframe utilities
84
- - `notification-badge` — keyframe utilities
85
106
  - `page-side-by-side` — keyframe utilities
86
- - `panel` — keyframe utilities
87
107
  - `plus-menu-morph` — keyframe utilities
88
- - `reasoning-stream` — keyframe utilities
89
108
  - `resize` — keyframe utilities
90
109
  - `shimmer-text` — keyframe utilities
91
- - `skeleton-reveal` — keyframe utilities
92
110
  - `spinning-counter` — keyframe utilities
93
- - `streaming-text` — keyframe utilities
94
111
  - `success-check` — keyframe utilities
95
- - `tabs-sliding` — keyframe utilities
96
112
  - `text-swap` — keyframe utilities
97
- - `texts-reveal` — keyframe utilities
98
113
  - `thinking-states` — keyframe utilities
99
- - `tooltip` — keyframe utilities
100
114
 
101
115
  ## AI and chat (`src/ai`)
102
116
 
103
- - `composer` — Composer, ComposerProps
117
+ - `ai-button` — AiButton
104
118
  - `confirmation` — Confirmation, ConfirmationTitle, ConfirmationRequest, ConfirmationAccepted, ConfirmationRejected, ConfirmationActions, ConfirmationAction
105
- - `conversation` — Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton
119
+ - `generation-progress` — GenerationProgress
106
120
  - `loading-state` — PixelLoader
107
121
  - `prompt-input` — PromptInput, PromptInputBody, PromptInputToolbar, PromptInputTextarea, PromptInputSubmit
108
122
  - `reasoning` — Reasoning, ReasoningTrigger, ReasoningContent
@@ -112,30 +126,8 @@ The style layer lives in [`src/tokens.css`](./src/tokens.css) and the motion CSS
112
126
  - `typing-dots` — TypingDots
113
127
  - `voice-waveform` — VoiceWaveform
114
128
 
115
- ## Charts (`src/charts`)
116
-
117
- - `animated-value` — AnimatedValue
118
- - `area-chart` — AreaChart
119
- - `bar-chart` — BarChart
120
- - `crosshair` — Crosshair
121
- - `donut-chart` — DonutChart
122
- - `edge-fade` — EdgeFade
123
- - `figure` — Figure
124
- - `gauge-chart` — GaugeChart
125
- - `hover-focus` — HoverFocus
126
- - `legend` — Legend
127
- - `line-chart` — LineChart
128
- - `number-chart` — NumberChart
129
- - `reveal` — Reveal
130
- - `ring-chart` — RingChart
131
- - `sparkline` — Sparkline
132
- - `stat-card` — StatCard
133
- - `time-series-chart` — TimeSeriesChart
134
- - `trend-pill` — TrendPill
135
- - `primitives` — ChartContainer, ChartTooltip, ChartStyle, ChartConfig, TooltipSeriesItem, getPayloadConfigFromPayload
136
-
137
129
  ---
138
130
 
139
- Skipped on purpose: brand assets (logos, marks, brand renderer, language flags,
140
- locale switch), kanban and status (they live in `@heyramzi/board`). The bot avatars
131
+ Skipped on purpose: brand assets (logos, marks, brand renderer), kanban, list, gantt and status (they live in `@heyramzi/tasks`), and charts
132
+ (they live in `@heyramzi/charts`). The bot avatars
141
133
  are in `src/agents`, imported from `@heyramzi/ui/agents`.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @heyramzi/ui
2
2
 
3
3
  Svelte 5 UI primitives you copy into your project and own. Components, visual
4
- effects, CSS animations, charts and a small set of chat and AI surfaces. No build step, no runtime wrapper,
4
+ effects, CSS animations and a small set of chat and AI surfaces. No build step, no runtime wrapper,
5
5
  no framework lock-in.
6
6
 
7
7
  The package is a source registry. Every component is a folder under
@@ -11,13 +11,12 @@ only a convenience.
11
11
  ## What is inside
12
12
 
13
13
  - `src/shadcn` shadcn-svelte primitives, generalized.
14
+ - `src/components` generic pieces on the primitives: segmented control, picker, copy button, data table, list page, hold to confirm and more.
14
15
  - `src/effects` animated borders, beams, marquee, spotlight, image reveal,
15
16
  image comparison, shimmer gradients and a theme toggle.
16
17
  - `src/animations` keyframe CSS for dropdowns, modals, tooltips, text swaps,
17
18
  success checks and the rest of the motion vocabulary.
18
- - `src/ai` chat and AI surfaces: conversation, composer, prompt input, response, reasoning, confirmation and loaders.
19
- - `src/charts` SVG charts: line, area, bar, donut, ring, gauge, sparkline,
20
- time series, and stat cards.
19
+ - `src/ai` chat and AI surfaces: prompt input, response, reasoning, confirmation and loaders.
21
20
  - `src/agents` bot avatars and a cast grid, imported from `@heyramzi/ui/agents`:
22
21
  `AgentAvatar` draws an eyes-only face from a name, role, shape and colour, and
23
22
  `AgentCast` lays a list of agents out as cards you can pick from.
@@ -43,6 +42,13 @@ Retheme by overriding any variable on `:root`, for example
43
42
  `--color-brand-indigo` or `--radius-lg`. Dark mode keys off a `.dark`
44
43
  class on `html`.
45
44
 
45
+ Rich text lives in [`@heyramzi/rich-editor`](https://github.com/heyramzi/ui/tree/main/packages/rich-editor),
46
+ so the kit doesn't pull Tiptap into every app.
47
+
48
+ Charts live in their own package now,
49
+ [`@heyramzi/charts`](https://github.com/heyramzi/ui/tree/main/packages/charts). It reads
50
+ the same tokens, so import `tokens.css` once and both work.
51
+
46
52
  React and other framework ports are out of scope. The source is Svelte 5
47
53
  runes only.
48
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyramzi/ui",
3
- "version": "6.1.0",
3
+ "version": "8.0.0",
4
4
  "description": "Svelte 5 UI primitives: effects, animations, and shared component CSS.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,7 +29,16 @@
29
29
  "default": "./src/index.ts"
30
30
  },
31
31
  "./tokens.css": "./src/tokens.css",
32
- "./lib/*": "./src/lib/*",
32
+ "./lib/*.js": {
33
+ "svelte": "./src/lib/*.ts",
34
+ "types": "./src/lib/*.ts",
35
+ "default": "./src/lib/*.ts"
36
+ },
37
+ "./lib/*": {
38
+ "svelte": "./src/lib/*.ts",
39
+ "types": "./src/lib/*.ts",
40
+ "default": "./src/lib/*.ts"
41
+ },
33
42
  "./border-beam": {
34
43
  "svelte": "./src/effects/border-beam/BorderBeam.svelte",
35
44
  "default": "./src/effects/border-beam/BorderBeam.svelte"
@@ -55,6 +64,10 @@
55
64
  "svelte": "./src/effects/spotlight/Spotlight.svelte",
56
65
  "default": "./src/effects/spotlight/Spotlight.svelte"
57
66
  },
67
+ "./effects/magic-card": {
68
+ "svelte": "./src/effects/magic-card/MagicCard.svelte",
69
+ "default": "./src/effects/magic-card/MagicCard.svelte"
70
+ },
58
71
  "./effects/marquee": {
59
72
  "svelte": "./src/effects/marquee/Marquee.svelte",
60
73
  "default": "./src/effects/marquee/Marquee.svelte"
@@ -78,6 +91,10 @@
78
91
  "svelte": "./src/effects/progressive-blur/ProgressiveBlur.svelte",
79
92
  "default": "./src/effects/progressive-blur/ProgressiveBlur.svelte"
80
93
  },
94
+ "./effects/interactive-hover-button": {
95
+ "svelte": "./src/effects/interactive-hover-button/InteractiveHoverButton.svelte",
96
+ "default": "./src/effects/interactive-hover-button/InteractiveHoverButton.svelte"
97
+ },
81
98
  "./effects/image-comparison": {
82
99
  "svelte": "./src/effects/image-comparison/ImageComparison.svelte",
83
100
  "default": "./src/effects/image-comparison/ImageComparison.svelte"
@@ -115,31 +132,21 @@
115
132
  "./animations/*": {
116
133
  "default": "./src/animations/*"
117
134
  },
118
- "./charts": {
119
- "svelte": "./src/charts/index.ts",
120
- "types": "./src/charts/index.ts",
121
- "default": "./src/charts/index.ts"
122
- },
123
- "./showcase": {
124
- "svelte": "./src/showcase/index.ts",
125
- "types": "./src/showcase/index.ts",
126
- "default": "./src/showcase/index.ts"
127
- },
128
- "./showcase/kit": {
129
- "svelte": "./src/showcase/kit.ts",
130
- "types": "./src/showcase/kit.ts",
131
- "default": "./src/showcase/kit.ts"
132
- },
133
- "./shadcn/hooks/is-mobile.svelte": {
134
- "svelte": "./src/shadcn/hooks/is-mobile.svelte.ts",
135
- "types": "./src/shadcn/hooks/is-mobile.svelte.ts",
136
- "default": "./src/shadcn/hooks/is-mobile.svelte.ts"
135
+ "./shadcn/hooks/*": {
136
+ "svelte": "./src/shadcn/hooks/*.ts",
137
+ "types": "./src/shadcn/hooks/*.ts",
138
+ "default": "./src/shadcn/hooks/*.ts"
137
139
  },
138
140
  "./shadcn/*": {
139
141
  "svelte": "./src/shadcn/*/index.ts",
140
142
  "types": "./src/shadcn/*/index.ts",
141
143
  "default": "./src/shadcn/*/index.ts"
142
144
  },
145
+ "./components/*": {
146
+ "svelte": "./src/components/*/index.ts",
147
+ "types": "./src/components/*/index.ts",
148
+ "default": "./src/components/*/index.ts"
149
+ },
143
150
  "./shadcn/utilities.css": {
144
151
  "style": "./src/shadcn/utilities.css",
145
152
  "default": "./src/shadcn/utilities.css"
@@ -163,21 +170,16 @@
163
170
  },
164
171
  "dependencies": {
165
172
  "@heyramzi/utils": "^1.3.3",
166
- "@lucide/svelte": "^1.52.0",
167
- "clsx": "^2.1.1",
168
- "d3-scale": "^4.0.2",
169
- "d3-shape": "^3.2.0",
170
- "layerchart": "^2.5.1",
173
+ "@shadcn-svelte/primitives": "^0.0.1",
171
174
  "marked": "^18.1.0",
172
175
  "phosphor-svelte": "^3.1.0",
173
- "tailwind-merge": "^3.7.0",
176
+ "shiki": "^4.5.0",
174
177
  "tailwind-variants": "^3.3.1"
175
178
  },
176
179
  "devDependencies": {
177
180
  "@internationalized/date": "^3.12.4",
178
181
  "@sveltejs/vite-plugin-svelte": "^7.3.1",
179
- "@types/d3-scale": "^4.0.9",
180
- "@types/d3-shape": "^3.2.0",
182
+ "@types/node": "^26.6.4",
181
183
  "bits-ui": "^2.19.5",
182
184
  "jsdom": "^30.1.2",
183
185
  "mode-watcher": "^1.1.0",
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- /* Sync shadcn-svelte into src/shadcn and its demos into the showcase, three-way
2
+ /* Sync shadcn-svelte into src/shadcn and its demos into the site, three-way
3
3
  * per file against `.upstream/`. The rules and why: ../docs/decisions.md. */
4
4
 
5
5
  // pnpm sync:shadcn fetch, vendor, apply, report
@@ -8,7 +8,7 @@
8
8
  import { execFileSync } from "node:child_process";
9
9
  import { existsSync, readFileSync, readdirSync } from "node:fs";
10
10
  import { fileURLToPath } from "node:url";
11
- import { basename, dirname, resolve } from "node:path";
11
+ import { basename, dirname, relative, resolve } from "node:path";
12
12
  import {
13
13
  CHECK,
14
14
  classify,
@@ -42,26 +42,30 @@ const ALIASES = [
42
42
  ["$UTILS$.js", "@heyramzi/utils"],
43
43
  ["$UI$/", "../src/shadcn"],
44
44
  ["$HOOKS$/", "../src/shadcn/hooks"],
45
+ ["$LIB$/", "../src/shadcn/hooks"],
45
46
  ];
46
47
 
47
48
  /* Upstream target path -> ours, where the two differ. Everything else lands at
48
49
  * src/shadcn/<target>. */
49
50
  const REROUTE = {
50
51
  "is-mobile/is-mobile.svelte.ts": "src/shadcn/hooks/is-mobile.svelte.ts",
52
+ "highlighter/highlighter.ts": "src/shadcn/hooks/highlighter.ts",
53
+ "use-highlighted-code/use-highlighted-code.svelte.ts":
54
+ "src/shadcn/hooks/use-highlighted-code.svelte.ts",
51
55
  };
52
56
 
53
57
  const DOCS = "https://raw.githubusercontent.com/huntabyte/shadcn-svelte/main/docs";
54
58
  const DEMO_VENDOR = `${PKG}/.upstream/shadcn-demos`;
55
- const DEMO_LOCAL = `${PKG}/src/showcase/demos/shadcn`;
59
+ const DEMO_LOCAL = `${ROOT}/site/src/lib/shadcn-demos`;
56
60
  const DEMO_MANIFEST = `${DEMO_LOCAL}/index.ts`;
57
61
 
58
62
  /* The docs site's aliases. A demo is a docs file, not a registry payload, so it
59
63
  * carries `$lib/...` rather than the registry's `$UI$`. */
60
64
  const DEMO_ALIASES = [
61
- ["$lib/registry/ui/", "../src/shadcn"],
65
+ ["$lib/registry/ui/", "@heyramzi/ui/shadcn/"],
62
66
  // A handful reach their neighbour by relative path instead of the alias.
63
- ["../ui/", "../src/shadcn"],
64
- ["$lib/registry/hooks/", "../src/shadcn/hooks"],
67
+ ["../ui/", "@heyramzi/ui/shadcn/"],
68
+ ["$lib/registry/hooks/", "@heyramzi/ui/shadcn/hooks/"],
65
69
  ["$lib/utils.js", "@heyramzi/utils"],
66
70
  // The peer here is the runes build, published under its own name.
67
71
  ["@tabler/icons-svelte/", "@tabler/icons-svelte-runes/"],
@@ -90,20 +94,29 @@ const NOT_SHIPPED = new Set([
90
94
  // `cn` ships from @heyramzi/utils in vibe-kit, so a copy here would be a stray.
91
95
  "utils",
92
96
  "questionnaire",
93
- // Every app chat runs on our ai/conversation, so a second scroller would be two answers to one job.
94
- "message-scroller",
95
97
  ]);
96
98
 
97
99
  /* No demo to take: `hooks`, `is-mobile` and `utils` are not components, and `sidebar` demos as a page block. */
98
- const NO_DEMO = new Set(["hooks", "is-mobile", "sidebar", "utils"]);
100
+ const NO_DEMO = new Set([
101
+ "hooks",
102
+ "is-mobile",
103
+ "highlighter",
104
+ "use-highlighted-code",
105
+ "sidebar",
106
+ "utils",
107
+ ]);
99
108
 
100
109
  const adapt = (text) => ALIASES.reduce((acc, [from, to]) => acc.replaceAll(from, to), text);
110
+ /* The site imports the kit the way a consumer does, so the exports map names a
111
+ * primitive without its `/index.js` and a hook without its `.js`. */
101
112
  const adaptDemo = (text) =>
102
- DEMO_ALIASES.reduce((acc, [from, to]) => acc.replaceAll(from, to), text);
113
+ DEMO_ALIASES.reduce((acc, [from, to]) => acc.replaceAll(from, to), text)
114
+ .replace(/(@heyramzi\/ui\/shadcn\/[a-z-]+)\/index\.js/g, "$1")
115
+ .replace(/(@heyramzi\/ui\/shadcn\/hooks\/[a-z-]+(?:\.svelte)?)\.js/g, "$1");
103
116
  const readIf = (path) => (existsSync(path) ? readFileSync(path, "utf8") : null);
104
117
  const route = (name, target) => `${PKG}/${REROUTE[`${name}/${target}`] ?? `src/shadcn/${target}`}`;
105
118
  /** Report a file by where it lives here, not by its upstream target. */
106
- const label = (path) => path.slice(PKG.length + 1);
119
+ const label = (path) => (path.startsWith(`${PKG}/`) ? path.slice(PKG.length + 1) : relative(ROOT, path));
107
120
 
108
121
  const pascal = (name) => name.replace(/(^|-)([a-z])/g, (_, __, c) => c.toUpperCase());
109
122
 
@@ -118,10 +131,10 @@ const meta = (doc, name) => {
118
131
  return { title: field("title") ?? pascal(name), note: field("description") ?? "" };
119
132
  };
120
133
 
121
- /** The demo's own shadcn imports, respelled as a consumer writes them. */
134
+ /** The demo's own shadcn imports, as it spells them for a consumer. */
122
135
  const publicImports = (demo) =>
123
- [...demo.matchAll(/import[^;]*?from\s+"#src\/shadcn\/([^"]+?)(?:\/index\.js)?";/g)]
124
- .map((m) => m[0].replace(/"[^"]+"/, `"@heyramzi/ui/shadcn/${m[1]}"`))
136
+ [...demo.matchAll(/import[^;]*?from\s+"@heyramzi\/ui\/shadcn\/[^"]+";/g)]
137
+ .map((m) => m[0])
125
138
  .join("\n");
126
139
 
127
140
  /* The section's list, generated: a primitive reaches the page by being synced,
@@ -136,7 +149,7 @@ async function writeManifest(demos) {
136
149
  " * own, and the sync rewrites this list. */",
137
150
  'import type { Component } from "svelte";',
138
151
  ...demos.map(
139
- (d) => `import ${pascal(d.name)}Demo from "../src/showcase/demos/shadcn/${d.name}.svelte";`,
152
+ (d) => `import ${pascal(d.name)}Demo from "./${d.name}.svelte";`,
140
153
  ),
141
154
  "",
142
155
  "export type ShadcnDemo = {",
@@ -258,7 +271,7 @@ const ours = readdirSync(LOCAL, { withFileTypes: true })
258
271
  for (const name of ours) buckets.unported.push(`${name} — in src/shadcn, not in the registry`);
259
272
 
260
273
  /* The docs site's own demo for each primitive, vendored on the same three-way
261
- * rule. Upstream writes them; the showcase renders them. */
274
+ * rule. Upstream writes them; the site renders them. */
262
275
  const demoNames = [...Object.keys(entries), ...LOCAL_ONLY]
263
276
  .filter((name) => !NO_DEMO.has(name))
264
277
  .toSorted();
@@ -46,7 +46,7 @@ const SRC = `${PKG}/src`;
46
46
  */
47
47
 
48
48
  /*
49
- * Most land in src/animations. Five do not, because a component already did the job and one behaviour gets one implementation: the last five entries name where each went instead.
49
+ * Fourteen of these name the component that owns the motion instead of a file in src/animations.
50
50
  */
51
51
 
52
52
  /*
@@ -55,31 +55,31 @@ const SRC = `${PKG}/src`;
55
55
  const PORTED = {
56
56
  "card-resize": "animations/resize.css",
57
57
  "number-pop-in": "animations/digit-pop-in.css",
58
- "notification-badge": "animations/notification-badge.css",
58
+ "notification-badge": "shadcn/badge/badge.svelte",
59
59
  "text-states-swap": "animations/text-swap.css",
60
60
  "menu-dropdown": "animations/dropdown.css",
61
61
  "modal-open-close": "animations/modal.css",
62
- "panel-reveal": "animations/panel.css",
62
+ "panel-reveal": "shadcn/sheet/sheet-content.svelte",
63
63
  "page-side-by-side": "animations/page-side-by-side.css",
64
- "icon-swap": "animations/icon-swap.css",
64
+ "icon-swap": "effects/theme-toggle/ThemeToggle.svelte",
65
65
  "success-check": "animations/success-check.css",
66
66
  "avatar-group-hover": "animations/avatar-group-hover.css",
67
67
  "error-state-shake": "animations/input-shake.css",
68
68
  "input-clear-with-dissolve": "animations/input-clear-dissolve.css",
69
- "skeleton-loader-and-reveal": "animations/skeleton-reveal.css",
70
- "texts-reveal": "animations/texts-reveal.css",
71
- "tabs-sliding": "animations/tabs-sliding.css",
69
+ "skeleton-loader-and-reveal": "shadcn/skeleton/skeleton.svelte",
70
+ "texts-reveal": "effects/reveal/TextEffect.svelte",
71
+ "tabs-sliding": "shadcn/tabs/tabs-list.svelte",
72
72
  "shimmer-text": "animations/shimmer-text.css",
73
- "tooltip-open-close": "animations/tooltip.css",
73
+ "tooltip-open-close": "shadcn/tooltip/tooltip-content.svelte",
74
74
  "3d-tilt": "animations/card-tilt.css",
75
75
  "dropdown-menu-morph": "animations/plus-menu-morph.css",
76
- accordion: "animations/accordion.css",
76
+ accordion: "shadcn/accordion/accordion-content.svelte",
77
77
  "like-button": "animations/like-button.css",
78
78
  "learn-more-hover": "animations/learn-more-hover.css",
79
79
  "spinning-counter": "animations/spinning-counter.css",
80
80
  "thinking-states": "animations/thinking-states.css",
81
- "reasoning-stream": "animations/reasoning-stream.css",
82
- "streaming-text": "animations/streaming-text.css",
81
+ "reasoning-stream": "ai/reasoning/ReasoningContent.svelte",
82
+ "streaming-text": "effects/reveal/TextEffect.svelte",
83
83
  toggle: "shadcn/switch/switch.svelte",
84
84
  "checkbox-check": "shadcn/checkbox/checkbox.svelte",
85
85
  "toast-open-close": "shadcn/sonner/sonner.svelte",
@@ -0,0 +1,86 @@
1
+ <script lang="ts" module>
2
+ import type { ButtonProps } from "../../shadcn/button/index.js";
3
+
4
+ export type AiStatus = "idle" | "processing" | "done";
5
+
6
+ export interface AiButtonProps {
7
+ status?: AiStatus;
8
+ label?: string;
9
+ processingLabel?: string;
10
+ variant?: ButtonProps["variant"];
11
+ size?: ButtonProps["size"];
12
+ disabled?: boolean;
13
+ onclick?: (e: MouseEvent) => void;
14
+ class?: string;
15
+ iconOnly?: boolean;
16
+ }
17
+ </script>
18
+
19
+ <script lang="ts">
20
+ // =========================
21
+ // IMPORTS
22
+ // =========================
23
+ import { cn } from "@heyramzi/utils";
24
+ import { Sparkle } from "phosphor-svelte";
25
+ import { Spinner } from "../../shadcn/spinner/index.js";
26
+ import { Button } from "../../shadcn/button/index.js";
27
+
28
+ // =========================
29
+ // PROPS
30
+ // =========================
31
+ let {
32
+ status = "idle",
33
+ label = "Generate",
34
+ processingLabel = "Processing...",
35
+ variant = "outline",
36
+ size = "sm",
37
+ disabled = false,
38
+ onclick,
39
+ class: className,
40
+ iconOnly = false,
41
+ }: AiButtonProps = $props();
42
+ </script>
43
+
44
+ <!-- ===========================
45
+ MARKUP
46
+ =========================== -->
47
+ {#if iconOnly}
48
+ <Button
49
+ {variant}
50
+ size="sm"
51
+ icon
52
+ disabled={disabled || status === "processing"}
53
+ onclick={onclick}
54
+ class={cn(
55
+ "relative",
56
+ status === "processing" && "pointer-events-none",
57
+ className,
58
+ )}
59
+ >
60
+ {#if status === "processing"}
61
+ <Spinner class="size-4" />
62
+ {:else}
63
+ <Sparkle class="size-4" weight="fill" />
64
+ {/if}
65
+ </Button>
66
+ {:else}
67
+ <Button
68
+ {variant}
69
+ {size}
70
+ disabled={disabled || status === "processing"}
71
+ onclick={onclick}
72
+ class={cn(
73
+ "gap-1.5",
74
+ status === "processing" && "pointer-events-none",
75
+ className,
76
+ )}
77
+ >
78
+ {#if status === "processing"}
79
+ <Spinner class="size-3.5" />
80
+ <span>{processingLabel}</span>
81
+ {:else}
82
+ <Sparkle class="size-3.5" weight="fill" />
83
+ <span>{label}</span>
84
+ {/if}
85
+ </Button>
86
+ {/if}
@@ -0,0 +1,4 @@
1
+ import AiButton from "./AiButton.svelte";
2
+ import type { AiButtonProps, AiStatus } from "./AiButton.svelte";
3
+
4
+ export { AiButton, type AiButtonProps, type AiStatus };
@@ -23,15 +23,15 @@
23
23
  ...rest
24
24
  }: ConfirmationProps = $props();
25
25
 
26
- // WHY: setContext runs once on mount but the value is referenced reactively via the proxy Svelte sets up on objects passed to setContext.
27
-
28
- // State changes rerun any $derived in child components.
29
- const ctx = $state({ kind, executing });
30
- $effect(() => {
31
- ctx.kind = kind;
32
- ctx.executing = executing;
26
+ // WHY getters: setContext runs once on mount, so the parts read the props through these and rerun their $derived when a prop changes.
27
+ setConfirmationContext({
28
+ get kind() {
29
+ return kind;
30
+ },
31
+ get executing() {
32
+ return executing;
33
+ },
33
34
  });
34
- setConfirmationContext(ctx);
35
35
  </script>
36
36
 
37
37
  {#if kind !== "idle"}
@@ -5,8 +5,8 @@ const CONFIRMATION_CONTEXT_KEY = Symbol("confirmation-context");
5
5
  export type ConfirmationState = "idle" | "requested" | "accepted" | "rejected" | "failed";
6
6
 
7
7
  export interface ConfirmationContextValue {
8
- kind: ConfirmationState;
9
- executing: boolean;
8
+ readonly kind: ConfirmationState;
9
+ readonly executing: boolean;
10
10
  }
11
11
 
12
12
  export function setConfirmationContext(value: ConfirmationContextValue) {