@webjsdev/ui 0.3.16 → 0.4.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 (358) hide show
  1. package/README.md +71 -10
  2. package/THIRD_PARTY_NOTICES.md +349 -0
  3. package/package.json +4 -2
  4. package/packages/registry/blocks/_shared/placeholder.svg +1 -0
  5. package/packages/registry/blocks/charts/chart-area-axes.ts +72 -0
  6. package/packages/registry/blocks/charts/chart-area-default.ts +64 -0
  7. package/packages/registry/blocks/charts/chart-area-gradient.ts +82 -0
  8. package/packages/registry/blocks/charts/chart-area-icons.ts +77 -0
  9. package/packages/registry/blocks/charts/chart-area-interactive.ts +204 -0
  10. package/packages/registry/blocks/charts/chart-area-legend.ts +72 -0
  11. package/packages/registry/blocks/charts/chart-area-linear.ts +64 -0
  12. package/packages/registry/blocks/charts/chart-area-stacked-expand.ts +77 -0
  13. package/packages/registry/blocks/charts/chart-area-stacked.ts +71 -0
  14. package/packages/registry/blocks/charts/chart-area-step.ts +68 -0
  15. package/packages/registry/blocks/charts/chart-bar-active.ts +93 -0
  16. package/packages/registry/blocks/charts/chart-bar-default.ts +60 -0
  17. package/packages/registry/blocks/charts/chart-bar-horizontal.ts +62 -0
  18. package/packages/registry/blocks/charts/chart-bar-interactive.ts +185 -0
  19. package/packages/registry/blocks/charts/chart-bar-label-custom.ts +78 -0
  20. package/packages/registry/blocks/charts/chart-bar-label.ts +66 -0
  21. package/packages/registry/blocks/charts/chart-bar-mixed.ts +87 -0
  22. package/packages/registry/blocks/charts/chart-bar-multiple.ts +67 -0
  23. package/packages/registry/blocks/charts/chart-bar-negative.ts +61 -0
  24. package/packages/registry/blocks/charts/chart-bar-stacked.ts +68 -0
  25. package/packages/registry/blocks/charts/chart-line-default.ts +61 -0
  26. package/packages/registry/blocks/charts/chart-line-dots-colors.ts +86 -0
  27. package/packages/registry/blocks/charts/chart-line-dots-custom.ts +75 -0
  28. package/packages/registry/blocks/charts/chart-line-dots.ts +65 -0
  29. package/packages/registry/blocks/charts/chart-line-interactive.ts +185 -0
  30. package/packages/registry/blocks/charts/chart-line-label-custom.ts +94 -0
  31. package/packages/registry/blocks/charts/chart-line-label.ts +73 -0
  32. package/packages/registry/blocks/charts/chart-line-linear.ts +61 -0
  33. package/packages/registry/blocks/charts/chart-line-multiple.ts +71 -0
  34. package/packages/registry/blocks/charts/chart-line-step.ts +61 -0
  35. package/packages/registry/blocks/charts/chart-pie-donut-active.ts +86 -0
  36. package/packages/registry/blocks/charts/chart-pie-donut-text.ts +89 -0
  37. package/packages/registry/blocks/charts/chart-pie-donut.ts +77 -0
  38. package/packages/registry/blocks/charts/chart-pie-interactive.ts +120 -0
  39. package/packages/registry/blocks/charts/chart-pie-label-custom.ts +82 -0
  40. package/packages/registry/blocks/charts/chart-pie-label-list.ts +86 -0
  41. package/packages/registry/blocks/charts/chart-pie-label.ts +77 -0
  42. package/packages/registry/blocks/charts/chart-pie-legend.ts +79 -0
  43. package/packages/registry/blocks/charts/chart-pie-separator-none.ts +77 -0
  44. package/packages/registry/blocks/charts/chart-pie-simple.ts +77 -0
  45. package/packages/registry/blocks/charts/chart-pie-stacked.ts +99 -0
  46. package/packages/registry/blocks/charts/chart-radar-default.ts +61 -0
  47. package/packages/registry/blocks/charts/chart-radar-dots.ts +61 -0
  48. package/packages/registry/blocks/charts/chart-radar-grid-circle-fill.ts +61 -0
  49. package/packages/registry/blocks/charts/chart-radar-grid-circle-no-lines.ts +61 -0
  50. package/packages/registry/blocks/charts/chart-radar-grid-circle.ts +61 -0
  51. package/packages/registry/blocks/charts/chart-radar-grid-custom.ts +61 -0
  52. package/packages/registry/blocks/charts/chart-radar-grid-fill.ts +61 -0
  53. package/packages/registry/blocks/charts/chart-radar-grid-none.ts +60 -0
  54. package/packages/registry/blocks/charts/chart-radar-icons.ts +76 -0
  55. package/packages/registry/blocks/charts/chart-radar-label-custom.ts +77 -0
  56. package/packages/registry/blocks/charts/chart-radar-legend.ts +70 -0
  57. package/packages/registry/blocks/charts/chart-radar-lines-only.ts +68 -0
  58. package/packages/registry/blocks/charts/chart-radar-multiple.ts +68 -0
  59. package/packages/registry/blocks/charts/chart-radar-radius.ts +68 -0
  60. package/packages/registry/blocks/charts/chart-radial-grid.ts +80 -0
  61. package/packages/registry/blocks/charts/chart-radial-label.ts +85 -0
  62. package/packages/registry/blocks/charts/chart-radial-shape.ts +81 -0
  63. package/packages/registry/blocks/charts/chart-radial-simple.ts +79 -0
  64. package/packages/registry/blocks/charts/chart-radial-stacked.ts +69 -0
  65. package/packages/registry/blocks/charts/chart-radial-text.ts +82 -0
  66. package/packages/registry/blocks/charts/chart-tooltip-advanced.ts +84 -0
  67. package/packages/registry/blocks/charts/chart-tooltip-default.ts +62 -0
  68. package/packages/registry/blocks/charts/chart-tooltip-formatter.ts +75 -0
  69. package/packages/registry/blocks/charts/chart-tooltip-icons.ts +68 -0
  70. package/packages/registry/blocks/charts/chart-tooltip-indicator-line.ts +62 -0
  71. package/packages/registry/blocks/charts/chart-tooltip-indicator-none.ts +62 -0
  72. package/packages/registry/blocks/charts/chart-tooltip-label-custom.ts +65 -0
  73. package/packages/registry/blocks/charts/chart-tooltip-label-formatter.ts +66 -0
  74. package/packages/registry/blocks/charts/chart-tooltip-label-none.ts +62 -0
  75. package/packages/registry/blocks/dashboard-01/components/app-sidebar.ts +108 -0
  76. package/packages/registry/blocks/dashboard-01/components/chart-area-interactive.ts +276 -0
  77. package/packages/registry/blocks/dashboard-01/components/dashboard-data.ts +89 -0
  78. package/packages/registry/blocks/dashboard-01/components/data-table.ts +637 -0
  79. package/packages/registry/blocks/dashboard-01/components/nav-documents.ts +65 -0
  80. package/packages/registry/blocks/dashboard-01/components/nav-main.ts +61 -0
  81. package/packages/registry/blocks/dashboard-01/components/nav-secondary.ts +40 -0
  82. package/packages/registry/blocks/dashboard-01/components/nav-user.ts +66 -0
  83. package/packages/registry/blocks/dashboard-01/components/section-cards.ts +59 -0
  84. package/packages/registry/blocks/dashboard-01/components/site-header.ts +52 -0
  85. package/packages/registry/blocks/dashboard-01/page.ts +39 -0
  86. package/packages/registry/blocks/login-01/components/login-form.ts +70 -0
  87. package/packages/registry/blocks/login-01/page.ts +19 -0
  88. package/packages/registry/blocks/login-02/components/login-form.ts +68 -0
  89. package/packages/registry/blocks/login-02/page.ts +36 -0
  90. package/packages/registry/blocks/login-03/components/login-form.ts +89 -0
  91. package/packages/registry/blocks/login-03/page.ts +28 -0
  92. package/packages/registry/blocks/login-04/components/login-form.ts +91 -0
  93. package/packages/registry/blocks/login-04/page.ts +20 -0
  94. package/packages/registry/blocks/login-05/components/login-form.ts +75 -0
  95. package/packages/registry/blocks/login-05/page.ts +19 -0
  96. package/packages/registry/blocks/preview/cards/activate-agent-dialog.ts +77 -0
  97. package/packages/registry/blocks/preview/cards/analytics-card.ts +64 -0
  98. package/packages/registry/blocks/preview/cards/anomaly-alert.ts +35 -0
  99. package/packages/registry/blocks/preview/cards/bar-chart-card.ts +91 -0
  100. package/packages/registry/blocks/preview/cards/book-appointment.ts +51 -0
  101. package/packages/registry/blocks/preview/cards/codespaces-card.ts +172 -0
  102. package/packages/registry/blocks/preview/cards/contributions-activity.ts +63 -0
  103. package/packages/registry/blocks/preview/cards/contributors.ts +51 -0
  104. package/packages/registry/blocks/preview/cards/environment-variables.ts +47 -0
  105. package/packages/registry/blocks/preview/cards/feedback-form.ts +61 -0
  106. package/packages/registry/blocks/preview/cards/file-upload.ts +51 -0
  107. package/packages/registry/blocks/preview/cards/github-profile.ts +66 -0
  108. package/packages/registry/blocks/preview/cards/icon-preview-grid.ts +47 -0
  109. package/packages/registry/blocks/preview/cards/invite-team.ts +78 -0
  110. package/packages/registry/blocks/preview/cards/invoice.ts +91 -0
  111. package/packages/registry/blocks/preview/cards/live-waveform.ts +330 -0
  112. package/packages/registry/blocks/preview/cards/no-team-members.ts +61 -0
  113. package/packages/registry/blocks/preview/cards/not-found.ts +46 -0
  114. package/packages/registry/blocks/preview/cards/observability-card.ts +44 -0
  115. package/packages/registry/blocks/preview/cards/pie-chart-card.ts +84 -0
  116. package/packages/registry/blocks/preview/cards/report-bug.ts +71 -0
  117. package/packages/registry/blocks/preview/cards/shipping-address.ts +79 -0
  118. package/packages/registry/blocks/preview/cards/shortcuts.ts +57 -0
  119. package/packages/registry/blocks/preview/cards/skeleton-loading.ts +37 -0
  120. package/packages/registry/blocks/preview/cards/sleep-report.ts +85 -0
  121. package/packages/registry/blocks/preview/cards/style-overview.ts +64 -0
  122. package/packages/registry/blocks/preview/cards/typography-specimen.ts +107 -0
  123. package/packages/registry/blocks/preview/cards/ui-elements.ts +164 -0
  124. package/packages/registry/blocks/preview/cards/usage-card.ts +63 -0
  125. package/packages/registry/blocks/preview/cards/visitors.ts +71 -0
  126. package/packages/registry/blocks/preview/cards/weekly-fitness-summary.ts +54 -0
  127. package/packages/registry/blocks/preview/page.ts +103 -0
  128. package/packages/registry/blocks/preview-02/cards/account-access.ts +70 -0
  129. package/packages/registry/blocks/preview-02/cards/card-overview.ts +75 -0
  130. package/packages/registry/blocks/preview-02/cards/claimable-balance.ts +54 -0
  131. package/packages/registry/blocks/preview-02/cards/contribution-history.ts +80 -0
  132. package/packages/registry/blocks/preview-02/cards/cover-art.ts +41 -0
  133. package/packages/registry/blocks/preview-02/cards/dividend-income.ts +76 -0
  134. package/packages/registry/blocks/preview-02/cards/empty-connect-bank.ts +38 -0
  135. package/packages/registry/blocks/preview-02/cards/empty-distribute-track.ts +38 -0
  136. package/packages/registry/blocks/preview-02/cards/empty-explore-catalog.ts +39 -0
  137. package/packages/registry/blocks/preview-02/cards/faq.ts +79 -0
  138. package/packages/registry/blocks/preview-02/cards/front-door.ts +40 -0
  139. package/packages/registry/blocks/preview-02/cards/index-investing.ts +31 -0
  140. package/packages/registry/blocks/preview-02/cards/kitchen-island.ts +90 -0
  141. package/packages/registry/blocks/preview-02/cards/loading-card.ts +34 -0
  142. package/packages/registry/blocks/preview-02/cards/new-milestone.ts +53 -0
  143. package/packages/registry/blocks/preview-02/cards/notification-settings.ts +126 -0
  144. package/packages/registry/blocks/preview-02/cards/payments.ts +88 -0
  145. package/packages/registry/blocks/preview-02/cards/payout-threshold.ts +92 -0
  146. package/packages/registry/blocks/preview-02/cards/power-usage.ts +84 -0
  147. package/packages/registry/blocks/preview-02/cards/preferences.ts +89 -0
  148. package/packages/registry/blocks/preview-02/cards/qr-connect.ts +54 -0
  149. package/packages/registry/blocks/preview-02/cards/receiving-method.ts +89 -0
  150. package/packages/registry/blocks/preview-02/cards/recent-transactions.ts +101 -0
  151. package/packages/registry/blocks/preview-02/cards/release-catalog.ts +73 -0
  152. package/packages/registry/blocks/preview-02/cards/roller-shades.ts +110 -0
  153. package/packages/registry/blocks/preview-02/cards/savings-progress.ts +68 -0
  154. package/packages/registry/blocks/preview-02/cards/savings-targets.ts +132 -0
  155. package/packages/registry/blocks/preview-02/cards/sidebar-nav.ts +88 -0
  156. package/packages/registry/blocks/preview-02/cards/social-links.ts +57 -0
  157. package/packages/registry/blocks/preview-02/cards/stock-performance.ts +106 -0
  158. package/packages/registry/blocks/preview-02/cards/syncing-state.ts +37 -0
  159. package/packages/registry/blocks/preview-02/cards/transfer-funds.ts +111 -0
  160. package/packages/registry/blocks/preview-02/cards/upcoming-payments.ts +69 -0
  161. package/packages/registry/blocks/preview-02/page.ts +111 -0
  162. package/packages/registry/blocks/preview-03/cards/files-chat.ts +75 -0
  163. package/packages/registry/blocks/preview-03/cards/group-chat.ts +114 -0
  164. package/packages/registry/blocks/preview-03/cards/reasoning-chat.ts +88 -0
  165. package/packages/registry/blocks/preview-03/cards/simple-chat.ts +53 -0
  166. package/packages/registry/blocks/preview-03/components/chat-card.ts +126 -0
  167. package/packages/registry/blocks/preview-03/components/chat-player.ts +174 -0
  168. package/packages/registry/blocks/preview-03/components/part-file.ts +77 -0
  169. package/packages/registry/blocks/preview-03/components/part-reasoning.ts +25 -0
  170. package/packages/registry/blocks/preview-03/components/part-source.ts +48 -0
  171. package/packages/registry/blocks/preview-03/components/part-text.ts +69 -0
  172. package/packages/registry/blocks/preview-03/components/part-tool.ts +71 -0
  173. package/packages/registry/blocks/preview-03/components/prompt-input.ts +86 -0
  174. package/packages/registry/blocks/preview-03/page.ts +39 -0
  175. package/packages/registry/blocks/sidebar-01/components/app-sidebar.ts +113 -0
  176. package/packages/registry/blocks/sidebar-01/components/search-form.ts +33 -0
  177. package/packages/registry/blocks/sidebar-01/components/version-switcher.ts +50 -0
  178. package/packages/registry/blocks/sidebar-01/page.ts +58 -0
  179. package/packages/registry/blocks/sidebar-02/components/app-sidebar.ts +131 -0
  180. package/packages/registry/blocks/sidebar-02/components/search-form.ts +33 -0
  181. package/packages/registry/blocks/sidebar-02/components/version-switcher.ts +50 -0
  182. package/packages/registry/blocks/sidebar-02/page.ts +53 -0
  183. package/packages/registry/blocks/sidebar-03/components/app-sidebar.ts +134 -0
  184. package/packages/registry/blocks/sidebar-03/page.ts +60 -0
  185. package/packages/registry/blocks/sidebar-04/components/app-sidebar.ts +136 -0
  186. package/packages/registry/blocks/sidebar-04/page.ts +58 -0
  187. package/packages/registry/blocks/sidebar-05/components/app-sidebar.ts +147 -0
  188. package/packages/registry/blocks/sidebar-05/components/search-form.ts +33 -0
  189. package/packages/registry/blocks/sidebar-05/page.ts +58 -0
  190. package/packages/registry/blocks/sidebar-06/components/app-sidebar.ts +105 -0
  191. package/packages/registry/blocks/sidebar-06/components/nav-main.ts +56 -0
  192. package/packages/registry/blocks/sidebar-06/components/sidebar-opt-in-form.ts +44 -0
  193. package/packages/registry/blocks/sidebar-06/page.ts +57 -0
  194. package/packages/registry/blocks/sidebar-07/components/app-sidebar.ts +108 -0
  195. package/packages/registry/blocks/sidebar-07/components/nav-main.ts +61 -0
  196. package/packages/registry/blocks/sidebar-07/components/nav-projects.ts +65 -0
  197. package/packages/registry/blocks/sidebar-07/components/nav-user.ts +70 -0
  198. package/packages/registry/blocks/sidebar-07/components/team-switcher.ts +66 -0
  199. package/packages/registry/blocks/sidebar-07/page.ts +59 -0
  200. package/packages/registry/blocks/sidebar-08/components/app-sidebar.ts +122 -0
  201. package/packages/registry/blocks/sidebar-08/components/nav-main.ts +68 -0
  202. package/packages/registry/blocks/sidebar-08/components/nav-projects.ts +65 -0
  203. package/packages/registry/blocks/sidebar-08/components/nav-secondary.ts +40 -0
  204. package/packages/registry/blocks/sidebar-08/components/nav-user.ts +70 -0
  205. package/packages/registry/blocks/sidebar-08/page.ts +59 -0
  206. package/packages/registry/blocks/sidebar-09/components/app-sidebar.ts +213 -0
  207. package/packages/registry/blocks/sidebar-09/components/nav-user.ts +70 -0
  208. package/packages/registry/blocks/sidebar-09/page.ts +52 -0
  209. package/packages/registry/blocks/sidebar-10/components/app-sidebar.ts +125 -0
  210. package/packages/registry/blocks/sidebar-10/components/nav-actions.ts +84 -0
  211. package/packages/registry/blocks/sidebar-10/components/nav-favorites.ts +66 -0
  212. package/packages/registry/blocks/sidebar-10/components/nav-main.ts +37 -0
  213. package/packages/registry/blocks/sidebar-10/components/nav-secondary.ts +43 -0
  214. package/packages/registry/blocks/sidebar-10/components/nav-workspaces.ts +78 -0
  215. package/packages/registry/blocks/sidebar-10/components/team-switcher.ts +63 -0
  216. package/packages/registry/blocks/sidebar-10/page.ts +46 -0
  217. package/packages/registry/blocks/sidebar-11/components/app-sidebar.ts +114 -0
  218. package/packages/registry/blocks/sidebar-11/page.ts +63 -0
  219. package/packages/registry/blocks/sidebar-12/components/app-sidebar.ts +63 -0
  220. package/packages/registry/blocks/sidebar-12/components/calendars.ts +53 -0
  221. package/packages/registry/blocks/sidebar-12/components/date-picker.ts +26 -0
  222. package/packages/registry/blocks/sidebar-12/components/nav-user.ts +70 -0
  223. package/packages/registry/blocks/sidebar-12/page.ts +43 -0
  224. package/packages/registry/blocks/sidebar-13/components/settings-dialog.ts +114 -0
  225. package/packages/registry/blocks/sidebar-13/page.ts +21 -0
  226. package/packages/registry/blocks/sidebar-14/components/app-sidebar.ts +120 -0
  227. package/packages/registry/blocks/sidebar-14/page.ts +55 -0
  228. package/packages/registry/blocks/sidebar-15/components/calendars.ts +53 -0
  229. package/packages/registry/blocks/sidebar-15/components/date-picker.ts +26 -0
  230. package/packages/registry/blocks/sidebar-15/components/nav-favorites.ts +66 -0
  231. package/packages/registry/blocks/sidebar-15/components/nav-main.ts +35 -0
  232. package/packages/registry/blocks/sidebar-15/components/nav-secondary.ts +43 -0
  233. package/packages/registry/blocks/sidebar-15/components/nav-user.ts +70 -0
  234. package/packages/registry/blocks/sidebar-15/components/nav-workspaces.ts +75 -0
  235. package/packages/registry/blocks/sidebar-15/components/sidebar-left.ts +126 -0
  236. package/packages/registry/blocks/sidebar-15/components/sidebar-right.ts +62 -0
  237. package/packages/registry/blocks/sidebar-15/components/team-switcher.ts +63 -0
  238. package/packages/registry/blocks/sidebar-15/page.ts +47 -0
  239. package/packages/registry/blocks/sidebar-16/components/app-sidebar.ts +124 -0
  240. package/packages/registry/blocks/sidebar-16/components/nav-main.ts +67 -0
  241. package/packages/registry/blocks/sidebar-16/components/nav-projects.ts +65 -0
  242. package/packages/registry/blocks/sidebar-16/components/nav-secondary.ts +40 -0
  243. package/packages/registry/blocks/sidebar-16/components/nav-user.ts +70 -0
  244. package/packages/registry/blocks/sidebar-16/components/search-form.ts +27 -0
  245. package/packages/registry/blocks/sidebar-16/components/site-header.ts +42 -0
  246. package/packages/registry/blocks/sidebar-16/page.ts +38 -0
  247. package/packages/registry/blocks/signup-01/components/signup-form.ts +78 -0
  248. package/packages/registry/blocks/signup-01/page.ts +19 -0
  249. package/packages/registry/blocks/signup-02/components/signup-form.ts +78 -0
  250. package/packages/registry/blocks/signup-02/page.ts +36 -0
  251. package/packages/registry/blocks/signup-03/components/signup-form.ts +79 -0
  252. package/packages/registry/blocks/signup-03/page.ts +28 -0
  253. package/packages/registry/blocks/signup-04/components/signup-form.ts +100 -0
  254. package/packages/registry/blocks/signup-04/page.ts +20 -0
  255. package/packages/registry/blocks/signup-05/components/signup-form.ts +75 -0
  256. package/packages/registry/blocks/signup-05/page.ts +20 -0
  257. package/packages/registry/components/accordion.ts +20 -7
  258. package/packages/registry/components/alert-dialog.ts +58 -13
  259. package/packages/registry/components/alert.ts +11 -6
  260. package/packages/registry/components/attachment.ts +119 -0
  261. package/packages/registry/components/avatar.ts +17 -8
  262. package/packages/registry/components/badge.ts +16 -9
  263. package/packages/registry/components/breadcrumb.ts +6 -6
  264. package/packages/registry/components/bubble.ts +95 -0
  265. package/packages/registry/components/button-group.ts +73 -0
  266. package/packages/registry/components/button.ts +35 -25
  267. package/packages/registry/components/calendar.ts +566 -0
  268. package/packages/registry/components/card.ts +8 -8
  269. package/packages/registry/components/carousel.ts +352 -0
  270. package/packages/registry/components/chart-element.ts +547 -0
  271. package/packages/registry/components/chart-geometry.ts +457 -0
  272. package/packages/registry/components/chart.ts +932 -0
  273. package/packages/registry/components/checkbox.ts +22 -84
  274. package/packages/registry/components/code-block.ts +191 -0
  275. package/packages/registry/components/collapsible.ts +5 -2
  276. package/packages/registry/components/combobox.ts +802 -0
  277. package/packages/registry/components/command.ts +618 -0
  278. package/packages/registry/components/context-menu.ts +302 -0
  279. package/packages/registry/components/dialog.ts +156 -45
  280. package/packages/registry/components/direction.ts +43 -0
  281. package/packages/registry/components/drawer.ts +226 -0
  282. package/packages/registry/components/dropdown-menu.ts +262 -83
  283. package/packages/registry/components/empty.ts +88 -0
  284. package/packages/registry/components/field.ts +165 -0
  285. package/packages/registry/components/floating.ts +124 -0
  286. package/packages/registry/components/hover-card.ts +19 -8
  287. package/packages/registry/components/input-group.ts +118 -0
  288. package/packages/registry/components/input-otp.ts +365 -0
  289. package/packages/registry/components/input.ts +3 -3
  290. package/packages/registry/components/item.ts +134 -0
  291. package/packages/registry/components/kbd.ts +2 -2
  292. package/packages/registry/components/label.ts +1 -1
  293. package/packages/registry/components/marker.ts +63 -0
  294. package/packages/registry/components/menubar.ts +388 -0
  295. package/packages/registry/components/message-scroller.ts +470 -0
  296. package/packages/registry/components/message.ts +69 -0
  297. package/packages/registry/components/native-select.ts +5 -5
  298. package/packages/registry/components/navigation-menu.ts +564 -0
  299. package/packages/registry/components/pagination.ts +5 -5
  300. package/packages/registry/components/popover.ts +30 -84
  301. package/packages/registry/components/progress.ts +7 -3
  302. package/packages/registry/components/questionnaire.ts +840 -0
  303. package/packages/registry/components/radio-group.ts +18 -73
  304. package/packages/registry/components/resizable.ts +330 -0
  305. package/packages/registry/components/scroll-area.ts +46 -0
  306. package/packages/registry/components/select.ts +650 -0
  307. package/packages/registry/components/separator.ts +1 -1
  308. package/packages/registry/components/sheet.ts +128 -0
  309. package/packages/registry/components/sidebar.ts +457 -0
  310. package/packages/registry/components/skeleton.ts +1 -1
  311. package/packages/registry/components/slider.ts +333 -0
  312. package/packages/registry/components/sonner.ts +74 -7
  313. package/packages/registry/components/spinner.ts +66 -0
  314. package/packages/registry/components/switch.ts +117 -9
  315. package/packages/registry/components/table.ts +11 -9
  316. package/packages/registry/components/tabs.ts +76 -25
  317. package/packages/registry/components/textarea.ts +1 -1
  318. package/packages/registry/components/toggle-group.ts +30 -11
  319. package/packages/registry/components/toggle.ts +20 -13
  320. package/packages/registry/components/tooltip.ts +68 -7
  321. package/packages/registry/components/trace.ts +75 -0
  322. package/packages/registry/lib/icons-hugeicons.ts +955 -0
  323. package/packages/registry/lib/icons-phosphor.ts +955 -0
  324. package/packages/registry/lib/icons-remixicon.ts +955 -0
  325. package/packages/registry/lib/icons-tabler.ts +955 -0
  326. package/packages/registry/lib/icons.ts +768 -0
  327. package/packages/registry/lib/utils.ts +49 -4
  328. package/packages/registry/registry.json +4092 -60
  329. package/packages/registry/styles/shadcn-tailwind.css +654 -0
  330. package/packages/registry/styles/style-luma.css +1987 -0
  331. package/packages/registry/styles/style-lyra.css +1965 -0
  332. package/packages/registry/styles/style-maia.css +1987 -0
  333. package/packages/registry/styles/style-mira.css +1992 -0
  334. package/packages/registry/styles/style-new-york.css +1597 -0
  335. package/packages/registry/styles/style-nova.css +1990 -0
  336. package/packages/registry/styles/style-rhea.css +1987 -0
  337. package/packages/registry/styles/style-sera.css +1977 -0
  338. package/packages/registry/styles/style-vega.css +1990 -0
  339. package/packages/registry/styles/supplement.json +54 -0
  340. package/packages/registry/styles/tw-animate.css +6 -0
  341. package/packages/registry/themes/base-colors.js +8 -2
  342. package/packages/registry/themes/fonts.js +120 -0
  343. package/packages/registry/themes/index.css +2 -0
  344. package/packages/registry/themes/items.js +61 -0
  345. package/packages/registry/themes/preset.js +302 -0
  346. package/packages/registry/themes/themes.js +1193 -0
  347. package/src/commands/add.js +236 -12
  348. package/src/commands/diff.js +34 -20
  349. package/src/commands/info.js +7 -0
  350. package/src/commands/init.js +125 -8
  351. package/src/commands/list.js +43 -11
  352. package/src/commands/view.js +33 -5
  353. package/src/registry/extract.js +192 -2
  354. package/src/registry/icons.js +31 -0
  355. package/src/registry/local.js +15 -1
  356. package/src/registry/schema.js +13 -0
  357. package/src/registry/style-bake.js +506 -0
  358. package/src/utils/theme.js +110 -21
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The preview block's invite card: two invites with a role each, an "Add
3
+ * another" button, and a read-only invite link with a copy button. A
4
+ * fragment helper, rendered by the server, with the kit's `<ui-select>`.
5
+ * Installed by `npx @webjsdev/ui add preview` at
6
+ * `components/preview/invite-team.ts`. Ported from shadcn/ui's preview block.
7
+ *
8
+ * The `<form>` has no `action` yet. Bind a server action from a
9
+ * `'use server'` file (`<form action=${sendInvites}>`) before you ship it.
10
+ */
11
+ import { html } from '@webjsdev/core';
12
+ import { cn } from '../../../lib/utils.ts';
13
+ import { buttonClass } from '../../../components/button.ts';
14
+ import {
15
+ cardClass,
16
+ cardContentClass,
17
+ cardDescriptionClass,
18
+ cardFooterClass,
19
+ cardHeaderClass,
20
+ cardTitleClass,
21
+ } from '../../../components/card.ts';
22
+ import { fieldClass, fieldLabelClass } from '../../../components/field.ts';
23
+ import { inputClass } from '../../../components/input.ts';
24
+ import {
25
+ inputGroupAddonClass,
26
+ inputGroupButtonClass,
27
+ inputGroupClass,
28
+ inputGroupInputClass,
29
+ } from '../../../components/input-group.ts';
30
+ import { selectTriggerClass } from '../../../components/select.ts';
31
+ import { separatorClass } from '../../../components/separator.ts';
32
+ import { CopyIcon, PlusIcon } from '../../../lib/icons.ts';
33
+
34
+ const INVITES = [
35
+ { email: 'alex@example.com', role: 'editor' },
36
+ { email: 'sam@example.com', role: 'viewer' },
37
+ ];
38
+
39
+ const ROLES: Array<[string, string]> = [['admin', 'Admin'], ['editor', 'Editor'], ['viewer', 'Viewer']];
40
+
41
+ export function inviteTeam() {
42
+ return html`
43
+ <div data-slot="card" data-size="default" class=${cardClass()}>
44
+ <div data-slot="card-header" class=${cardHeaderClass()}>
45
+ <div data-slot="card-title" class=${cardTitleClass()}>Invite Team</div>
46
+ <div data-slot="card-description" class=${cardDescriptionClass()}>Add members to your workspace</div>
47
+ </div>
48
+ <div data-slot="card-content" class=${cn(cardContentClass(), 'flex flex-col gap-4')}>
49
+ <form id="invite-team-form" class="flex flex-col gap-3">
50
+ ${INVITES.map((invite, i) => html`
51
+ <div class="flex items-center gap-2">
52
+ <input data-slot="input" type="email" name="email" value=${invite.email} aria-label=${`Invite ${i + 1} email`} class=${cn(inputClass(), 'flex-1')}>
53
+ <ui-select position="popper">
54
+ <select name="role" aria-label=${`Invite ${i + 1} role`} class=${cn(selectTriggerClass(), 'w-24')}>
55
+ ${ROLES.map(([value, text]) => html`<option value=${value} ?selected=${value === invite.role}>${text}</option>`)}
56
+ </select>
57
+ </ui-select>
58
+ </div>
59
+ `)}
60
+ </form>
61
+ <button type="button" data-slot="button" data-variant="outline" data-size="default" class=${buttonClass({ variant: 'outline' })}>${PlusIcon()}Add another</button>
62
+ <div data-slot="separator" data-orientation="horizontal" role="none" class=${separatorClass()}></div>
63
+ <div role="group" data-slot="field" data-orientation="vertical" class=${fieldClass()}>
64
+ <label data-slot="field-label" for="invite-team-link" class=${fieldLabelClass()}>Or share invite link</label>
65
+ <div data-slot="input-group" role="group" class=${inputGroupClass()}>
66
+ <input data-slot="input-group-control" id="invite-team-link" value="https://app.co/invite/x8f2k" readonly class=${inputGroupInputClass()}>
67
+ <div data-slot="input-group-addon" data-align="inline-end" role="group" class=${inputGroupAddonClass({ align: 'inline-end' })}>
68
+ <button type="button" aria-label="Copy link" data-slot="button" data-variant="ghost" data-size="icon-xs" class=${inputGroupButtonClass({ size: 'icon-xs' })}>${CopyIcon()}</button>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ <div data-slot="card-footer" class=${cardFooterClass()}>
74
+ <button type="submit" form="invite-team-form" data-slot="button" data-variant="default" data-size="default" class=${cn(buttonClass(), 'w-full')}>Send Invites</button>
75
+ </div>
76
+ </div>
77
+ `;
78
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The preview block's invoice card: the line items, subtotal, tax and total
3
+ * in a table, with download and pay buttons. A fragment helper, rendered by
4
+ * the server. Installed by `npx @webjsdev/ui add preview` at
5
+ * `components/preview/invoice.ts`. Ported from shadcn/ui's preview block.
6
+ */
7
+ import { html } from '@webjsdev/core';
8
+ import { cn } from '../../../lib/utils.ts';
9
+ import { badgeClass } from '../../../components/badge.ts';
10
+ import { buttonClass } from '../../../components/button.ts';
11
+ import {
12
+ cardActionClass,
13
+ cardClass,
14
+ cardContentClass,
15
+ cardDescriptionClass,
16
+ cardFooterClass,
17
+ cardHeaderClass,
18
+ cardTitleClass,
19
+ } from '../../../components/card.ts';
20
+ import {
21
+ tableBodyClass,
22
+ tableCellClass,
23
+ tableClass,
24
+ tableContainerClass,
25
+ tableHeadClass,
26
+ tableHeaderClass,
27
+ tableRowClass,
28
+ } from '../../../components/table.ts';
29
+
30
+ const INVOICE_ITEMS = [
31
+ { item: 'Design System License', qty: 1, unitPrice: 499 },
32
+ { item: 'Priority Support', qty: 12, unitPrice: 99 },
33
+ { item: 'Custom Components', qty: 3, unitPrice: 250 },
34
+ ];
35
+
36
+ function formatCurrency(value: number): string {
37
+ return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 2 }).format(value);
38
+ }
39
+
40
+ export function invoice() {
41
+ const subtotal = INVOICE_ITEMS.reduce((sum, row) => sum + row.qty * row.unitPrice, 0);
42
+ const totalDue = subtotal;
43
+ const total = (label: string, value: string) => html`
44
+ <tr data-slot="table-row" class=${tableRowClass()}>
45
+ <td data-slot="table-cell" colspan="3" class=${cn(tableCellClass(), 'text-right')}>${label}</td>
46
+ <td data-slot="table-cell" class=${cn(tableCellClass(), 'text-right tabular-nums')}>${value}</td>
47
+ </tr>
48
+ `;
49
+ return html`
50
+ <div data-slot="card" data-size="default" class=${cardClass()}>
51
+ <div data-slot="card-header" class=${cardHeaderClass()}>
52
+ <div data-slot="card-title" class=${cardTitleClass()}>Invoice #INV-2847</div>
53
+ <div data-slot="card-description" class=${cardDescriptionClass()}>Due March 30, 2026</div>
54
+ <div data-slot="card-action" class=${cardActionClass()}>
55
+ <span data-slot="badge" data-variant="secondary" class=${badgeClass({ variant: 'secondary' })}>Pending</span>
56
+ </div>
57
+ </div>
58
+ <div data-slot="card-content" class=${cardContentClass()}>
59
+ <div data-slot="table-container" class=${tableContainerClass()}>
60
+ <table data-slot="table" class=${tableClass()}>
61
+ <thead data-slot="table-header" class=${tableHeaderClass()}>
62
+ <tr data-slot="table-row" class=${tableRowClass()}>
63
+ <th data-slot="table-head" scope="col" class=${tableHeadClass()}>Item</th>
64
+ <th data-slot="table-head" scope="col" class=${cn(tableHeadClass(), 'text-right')}>Qty</th>
65
+ <th data-slot="table-head" scope="col" class=${cn(tableHeadClass(), 'text-right')}>Rate</th>
66
+ <th data-slot="table-head" scope="col" class=${cn(tableHeadClass(), 'text-right')}>Amount</th>
67
+ </tr>
68
+ </thead>
69
+ <tbody data-slot="table-body" class=${tableBodyClass()}>
70
+ ${INVOICE_ITEMS.map((row) => html`
71
+ <tr data-slot="table-row" class=${tableRowClass()}>
72
+ <td data-slot="table-cell" class=${tableCellClass()}>${row.item}</td>
73
+ <td data-slot="table-cell" class=${cn(tableCellClass(), 'text-right tabular-nums')}>${row.qty}</td>
74
+ <td data-slot="table-cell" class=${cn(tableCellClass(), 'text-right tabular-nums')}>${formatCurrency(row.unitPrice)}</td>
75
+ <td data-slot="table-cell" class=${cn(tableCellClass(), 'text-right tabular-nums')}>${formatCurrency(row.qty * row.unitPrice)}</td>
76
+ </tr>
77
+ `)}
78
+ ${total('Subtotal', formatCurrency(subtotal))}
79
+ ${total('Tax', '$0.00')}
80
+ ${total('Total Due', formatCurrency(totalDue))}
81
+ </tbody>
82
+ </table>
83
+ </div>
84
+ </div>
85
+ <div data-slot="card-footer" class=${cardFooterClass()}>
86
+ <button type="button" data-slot="button" data-variant="outline" data-size="sm" class=${buttonClass({ variant: 'outline', size: 'sm' })}>Download PDF</button>
87
+ <button type="button" data-slot="button" data-variant="default" data-size="sm" class=${cn(buttonClass({ size: 'sm' }), 'ml-auto')}>Pay Now</button>
88
+ </div>
89
+ </div>
90
+ `;
91
+ }
@@ -0,0 +1,330 @@
1
+ /**
2
+ * The preview block's live waveform card: an audio waveform drawn on a
3
+ * canvas, which shows a "processing" wave on load, follows the microphone
4
+ * once "Start Listening" is pressed, and switches between a mirrored static
5
+ * view and a scrolling one. Installed by `npx @webjsdev/ui add preview` at
6
+ * `components/preview/live-waveform.ts`. Ported from shadcn/ui's preview
7
+ * block (its LiveWaveform component and LiveWaveformCard).
8
+ *
9
+ * The card's header is a fragment; the waveform and its three buttons are
10
+ * the `<preview-live-waveform>` element, since they share state. The server
11
+ * renders the first frame of the processing wave as an SVG, so the card reads
12
+ * with JavaScript off; the element swaps in the canvas and animates it. With
13
+ * `prefers-reduced-motion: reduce` the wave holds still until you listen.
14
+ */
15
+ import { WebComponent, html, svg, signal } from '@webjsdev/core';
16
+ import { cn } from '../../../lib/utils.ts';
17
+ import { buttonClass } from '../../../components/button.ts';
18
+ import {
19
+ cardClass,
20
+ cardContentClass,
21
+ cardDescriptionClass,
22
+ cardFooterClass,
23
+ cardHeaderClass,
24
+ cardTitleClass,
25
+ } from '../../../components/card.ts';
26
+
27
+ const HEIGHT = 80;
28
+ const BAR_WIDTH = 3;
29
+ const BAR_GAP = 2;
30
+ const BAR_RADIUS = 1.5;
31
+ const BASE_BAR_HEIGHT = 4;
32
+ const FADE_WIDTH = 24;
33
+ const HISTORY_SIZE = 120;
34
+ const UPDATE_RATE = 30;
35
+ // The width the server draws the first frame at, about a preview card's.
36
+ const FIRST_FRAME_WIDTH = 330;
37
+
38
+ type Mode = 'static' | 'scrolling';
39
+
40
+ /** The processing wave at `time`, one value in [0.05, 1] per bar. */
41
+ function processingBars(barCount: number, time: number, mode: Mode): number[] {
42
+ const out: number[] = [];
43
+ const half = Math.floor(barCount / 2);
44
+ for (let i = 0; i < barCount; i++) {
45
+ const pos = mode === 'static' ? (i - half) / half : (i - barCount / 2) / (barCount / 2);
46
+ const centerWeight = 1 - Math.abs(pos) * 0.4;
47
+ const combined = mode === 'static'
48
+ ? Math.sin(time * 1.5 + pos * 3) * 0.25 + Math.sin(time * 0.8 - pos * 2) * 0.2 + Math.cos(time * 2 + pos) * 0.15
49
+ : Math.sin(time * 1.5 + i * 0.15) * 0.25 + Math.sin(time * 0.8 - i * 0.1) * 0.2 + Math.cos(time * 2 + i * 0.05) * 0.15;
50
+ out.push(Math.max(0.05, Math.min(1, (0.2 + combined) * centerWeight)));
51
+ }
52
+ return out;
53
+ }
54
+
55
+ /** The first frame as SVG bars, faded at both edges, for the server's paint. */
56
+ function firstFrame() {
57
+ const step = BAR_WIDTH + BAR_GAP;
58
+ const bars = processingBars(Math.floor(FIRST_FRAME_WIDTH / step), 0.03, 'static');
59
+ const centerY = HEIGHT / 2;
60
+ const fade = Math.min(0.3, FADE_WIDTH / FIRST_FRAME_WIDTH);
61
+ return html`<svg data-first-frame aria-hidden="true" class="absolute inset-0 block h-full w-full text-[gray]" viewBox=${`0 0 ${FIRST_FRAME_WIDTH} ${HEIGHT}`} preserveAspectRatio="xMinYMid meet">${svg`
62
+ <defs>
63
+ <linearGradient id="preview-live-waveform-fade" x1="0" x2="1" y1="0" y2="0">
64
+ <stop offset="0" stop-color="white" stop-opacity="0"></stop>
65
+ <stop offset=${fade} stop-color="white" stop-opacity="1"></stop>
66
+ <stop offset=${1 - fade} stop-color="white" stop-opacity="1"></stop>
67
+ <stop offset="1" stop-color="white" stop-opacity="0"></stop>
68
+ </linearGradient>
69
+ <mask id="preview-live-waveform-mask"><rect width="100%" height="100%" fill="url(#preview-live-waveform-fade)"></rect></mask>
70
+ </defs>
71
+ <g mask="url(#preview-live-waveform-mask)" fill="currentColor">
72
+ ${bars.map((v, i) => {
73
+ const h = Math.max(BASE_BAR_HEIGHT, v * HEIGHT * 0.8);
74
+ return svg`<rect x=${i * step} y=${centerY - h / 2} width=${BAR_WIDTH} height=${h} rx=${BAR_RADIUS} opacity=${0.4 + v * 0.6}></rect>`;
75
+ })}
76
+ </g>
77
+ `}</svg>`;
78
+ }
79
+
80
+ /**
81
+ * `<preview-live-waveform>`: the waveform and its controls. Light DOM; the
82
+ * canvas loop runs only while the element is connected.
83
+ */
84
+ export class PreviewLiveWaveform extends WebComponent {
85
+ readonly active = signal(false);
86
+ readonly processing = signal(true);
87
+ readonly mode = signal<Mode>('static');
88
+ readonly _ready = signal(false);
89
+
90
+ _canvas: HTMLCanvasElement | null = null;
91
+ _raf = 0;
92
+ _time = 0;
93
+ _lastUpdate = 0;
94
+ _bars: number[] = [];
95
+ _history: number[] = [];
96
+ _lastActive: number[] = [];
97
+ _transition = 0;
98
+ _fading = 0;
99
+ _stream: MediaStream | null = null;
100
+ _audio: AudioContext | null = null;
101
+ _analyser: AnalyserNode | null = null;
102
+ _reduced = false;
103
+ _resize: ResizeObserver | null = null;
104
+
105
+ connectedCallback() {
106
+ super.connectedCallback();
107
+ this._reduced = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
108
+ this._ready.set(true);
109
+ }
110
+
111
+ disconnectedCallback() {
112
+ cancelAnimationFrame(this._raf);
113
+ this._raf = 0;
114
+ this._resize?.disconnect();
115
+ this._stopMic();
116
+ super.disconnectedCallback();
117
+ }
118
+
119
+ firstUpdated() {
120
+ this._canvas = this.querySelector('canvas');
121
+ const box = this._canvas?.parentElement;
122
+ if (!this._canvas || !box) return;
123
+ this._resize = new ResizeObserver(() => this._sizeCanvas());
124
+ this._resize.observe(box);
125
+ this._sizeCanvas();
126
+ this._raf = requestAnimationFrame((t) => this._frame(t));
127
+ }
128
+
129
+ _sizeCanvas() {
130
+ const canvas = this._canvas;
131
+ const box = canvas?.parentElement;
132
+ if (!canvas || !box) return;
133
+ const rect = box.getBoundingClientRect();
134
+ const dpr = window.devicePixelRatio || 1;
135
+ canvas.width = rect.width * dpr;
136
+ canvas.height = rect.height * dpr;
137
+ canvas.style.width = `${rect.width}px`;
138
+ canvas.style.height = `${rect.height}px`;
139
+ canvas.getContext('2d')?.setTransform(dpr, 0, 0, dpr, 0, 0);
140
+ }
141
+
142
+ async _startMic() {
143
+ try {
144
+ this._stream = await navigator.mediaDevices.getUserMedia({
145
+ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true },
146
+ });
147
+ this._audio = new AudioContext();
148
+ this._analyser = this._audio.createAnalyser();
149
+ this._analyser.fftSize = 256;
150
+ this._analyser.smoothingTimeConstant = 0.8;
151
+ this._audio.createMediaStreamSource(this._stream).connect(this._analyser);
152
+ this._history = [];
153
+ } catch {
154
+ // No microphone, or permission refused: the bars stay at rest.
155
+ this.active.set(false);
156
+ }
157
+ }
158
+
159
+ _stopMic() {
160
+ this._stream?.getTracks().forEach((t) => t.stop());
161
+ this._stream = null;
162
+ if (this._audio && this._audio.state !== 'closed') this._audio.close();
163
+ this._audio = null;
164
+ this._analyser = null;
165
+ }
166
+
167
+ _toggleActive() {
168
+ const next = !this.active.get();
169
+ this.active.set(next);
170
+ if (next) {
171
+ this.processing.set(false);
172
+ this._startMic();
173
+ } else {
174
+ this._stopMic();
175
+ this._fading = 1;
176
+ }
177
+ }
178
+
179
+ _toggleProcessing() {
180
+ const next = !this.processing.get();
181
+ this.processing.set(next);
182
+ if (next) {
183
+ this._transition = 0;
184
+ if (this.active.get()) {
185
+ this.active.set(false);
186
+ this._stopMic();
187
+ }
188
+ } else {
189
+ this._fading = 1;
190
+ }
191
+ }
192
+
193
+ _toggleMode() {
194
+ this.mode.set(this.mode.get() === 'static' ? 'scrolling' : 'static');
195
+ }
196
+
197
+ _sample(width: number) {
198
+ const analyser = this._analyser;
199
+ if (!analyser) return;
200
+ const data = new Uint8Array(analyser.frequencyBinCount);
201
+ analyser.getByteFrequencyData(data);
202
+ const relevant = data.slice(Math.floor(data.length * 0.05), Math.floor(data.length * 0.4));
203
+ if (this.mode.get() === 'static') {
204
+ const half = Math.floor(Math.floor(width / (BAR_WIDTH + BAR_GAP)) / 2);
205
+ const value = (i: number) => Math.max(0.05, Math.min(1, relevant[Math.floor((i / half) * relevant.length)] / 255));
206
+ const bars: number[] = [];
207
+ for (let i = half - 1; i >= 0; i--) bars.push(value(i));
208
+ for (let i = 0; i < half; i++) bars.push(value(i));
209
+ this._bars = bars;
210
+ this._lastActive = bars;
211
+ } else {
212
+ let sum = 0;
213
+ for (const v of relevant) sum += v;
214
+ this._history.push(Math.min(1, Math.max(0.05, sum / relevant.length / 255)));
215
+ if (this._history.length > HISTORY_SIZE) this._history.shift();
216
+ this._lastActive = [...this._history];
217
+ }
218
+ }
219
+
220
+ _frame(now: number) {
221
+ this._raf = requestAnimationFrame((t) => this._frame(t));
222
+ const canvas = this._canvas;
223
+ const ctx = canvas?.getContext('2d');
224
+ if (!canvas || !ctx) return;
225
+ const rect = canvas.getBoundingClientRect();
226
+ const step = BAR_WIDTH + BAR_GAP;
227
+ const barCount = Math.floor(rect.width / step);
228
+ const mode = this.mode.get();
229
+ const active = this.active.get();
230
+ const processing = this.processing.get();
231
+
232
+ if (active && now - this._lastUpdate > UPDATE_RATE) {
233
+ this._lastUpdate = now;
234
+ this._sample(rect.width);
235
+ } else if (processing && !active && !(this._reduced && this._time > 0)) {
236
+ this._time += 0.03;
237
+ this._transition = Math.min(1, this._transition + 0.02);
238
+ let bars = processingBars(barCount, this._time, mode);
239
+ if (this._lastActive.length && this._transition < 1) {
240
+ bars = bars.map((v, i) => {
241
+ const last = this._lastActive[Math.min(i, this._lastActive.length - 1)] || 0;
242
+ return last * (1 - this._transition) + v * this._transition;
243
+ });
244
+ }
245
+ if (mode === 'static') this._bars = bars;
246
+ else this._history = bars;
247
+ } else if (!active && !processing && this._fading > 0) {
248
+ this._fading = Math.max(0, this._fading - 0.03);
249
+ const k = this._fading;
250
+ this._bars = k ? this._bars.map((v) => v * k) : [];
251
+ this._history = k ? this._history.map((v) => v * k) : [];
252
+ }
253
+
254
+ ctx.clearRect(0, 0, rect.width, rect.height);
255
+ const centerY = rect.height / 2;
256
+ ctx.fillStyle = 'gray';
257
+ const draw = (x: number, value: number) => {
258
+ const h = Math.max(BASE_BAR_HEIGHT, value * rect.height * 0.8);
259
+ ctx.globalAlpha = 0.4 + value * 0.6;
260
+ ctx.beginPath();
261
+ ctx.roundRect(x, centerY - h / 2, BAR_WIDTH, h, BAR_RADIUS);
262
+ ctx.fill();
263
+ };
264
+ if (mode === 'static') {
265
+ for (let i = 0; i < barCount && i < this._bars.length; i++) draw(i * step, this._bars[i] || 0.1);
266
+ } else {
267
+ for (let i = 0; i < barCount && i < this._history.length; i++) {
268
+ draw(rect.width - (i + 1) * step, this._history[this._history.length - 1 - i] || 0.1);
269
+ }
270
+ }
271
+ if (rect.width > 0) {
272
+ const fade = Math.min(0.3, FADE_WIDTH / rect.width);
273
+ const gradient = ctx.createLinearGradient(0, 0, rect.width, 0);
274
+ gradient.addColorStop(0, 'rgba(255,255,255,1)');
275
+ gradient.addColorStop(fade, 'rgba(255,255,255,0)');
276
+ gradient.addColorStop(1 - fade, 'rgba(255,255,255,0)');
277
+ gradient.addColorStop(1, 'rgba(255,255,255,1)');
278
+ ctx.globalCompositeOperation = 'destination-out';
279
+ ctx.globalAlpha = 1;
280
+ ctx.fillStyle = gradient;
281
+ ctx.fillRect(0, 0, rect.width, rect.height);
282
+ ctx.globalCompositeOperation = 'source-over';
283
+ }
284
+ ctx.globalAlpha = 1;
285
+ }
286
+
287
+ render() {
288
+ const active = this.active.get();
289
+ const processing = this.processing.get();
290
+ const mode = this.mode.get();
291
+ const ready = this._ready.get();
292
+ const label = active ? 'Live audio waveform' : processing ? 'Processing audio' : 'Audio waveform idle';
293
+ const button = (on: boolean, text: string, onClick: () => void) => html`<button
294
+ type="button"
295
+ data-slot="button"
296
+ data-variant=${on ? 'default' : 'outline'}
297
+ data-size="sm"
298
+ aria-pressed=${on}
299
+ class=${buttonClass({ variant: on ? 'default' : 'outline', size: 'sm' })}
300
+ @click=${onClick}
301
+ >${text}</button>`;
302
+ return html`
303
+ <div data-slot="card-content" class=${cardContentClass()}>
304
+ <div role="img" aria-label=${label} class="relative h-full w-full" style=${`height: ${HEIGHT}px`}>
305
+ ${!active && !processing ? html`<div class="absolute top-1/2 right-0 left-0 -translate-y-1/2 border-t-2 border-dotted border-muted-foreground/20"></div>` : ''}
306
+ ${ready ? '' : firstFrame()}
307
+ <canvas class="block h-full w-full" aria-hidden="true"></canvas>
308
+ </div>
309
+ </div>
310
+ <div data-slot="card-footer" class=${cn(cardFooterClass(), 'gap-2')}>
311
+ ${button(active, `${active ? 'Stop' : 'Start'} Listening`, () => this._toggleActive())}
312
+ ${button(processing, `${processing ? 'Stop' : 'Start'} Processing`, () => this._toggleProcessing())}
313
+ <button type="button" data-slot="button" data-variant="outline" data-size="sm" class=${buttonClass({ variant: 'outline', size: 'sm' })} @click=${() => this._toggleMode()}>${mode === 'static' ? 'Static' : 'Scrolling'}</button>
314
+ </div>
315
+ `;
316
+ }
317
+ }
318
+ PreviewLiveWaveform.register('preview-live-waveform');
319
+
320
+ export function liveWaveformCard() {
321
+ return html`
322
+ <div data-slot="card" data-size="default" class=${cardClass()}>
323
+ <div data-slot="card-header" class=${cardHeaderClass()}>
324
+ <div data-slot="card-title" class=${cardTitleClass()}>Live Audio Waveform</div>
325
+ <div data-slot="card-description" class=${cardDescriptionClass()}>Real-time microphone input visualization with audio reactivity</div>
326
+ </div>
327
+ <preview-live-waveform class="contents"></preview-live-waveform>
328
+ </div>
329
+ `;
330
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The preview block's empty team card: a stack of avatars over "No Team
3
+ * Members" and an invite button. A fragment helper, rendered by the server.
4
+ * Installed by `npx @webjsdev/ui add preview` at
5
+ * `components/preview/no-team-members.ts`. Ported from shadcn/ui's preview
6
+ * block.
7
+ */
8
+ import { html } from '@webjsdev/core';
9
+ import { cn } from '../../../lib/utils.ts';
10
+ import {
11
+ avatarClass,
12
+ avatarFallbackClass,
13
+ avatarGroupClass,
14
+ avatarImageClass,
15
+ } from '../../../components/avatar.ts';
16
+ import { buttonClass } from '../../../components/button.ts';
17
+ import { cardClass, cardContentClass } from '../../../components/card.ts';
18
+ import {
19
+ emptyClass,
20
+ emptyContentClass,
21
+ emptyDescriptionClass,
22
+ emptyHeaderClass,
23
+ emptyMediaClass,
24
+ emptyTitleClass,
25
+ } from '../../../components/empty.ts';
26
+
27
+ const MEMBERS = [
28
+ { src: 'https://webjs.dev/public/avatars/vivek.jpg', alt: '@vivek', fallback: 'VK' },
29
+ { src: 'https://github.com/maxleiter.png', alt: '@maxleiter', fallback: 'LR' },
30
+ { src: 'https://github.com/evilrabbit.png', alt: '@evilrabbit', fallback: 'ER' },
31
+ ];
32
+
33
+ export function noTeamMembers() {
34
+ return html`
35
+ <div data-slot="card" data-size="default" class=${cardClass()}>
36
+ <div data-slot="card-content" class=${cardContentClass()}>
37
+ <div data-slot="empty" class=${cn(emptyClass(), 'h-56 border')}>
38
+ <div data-slot="empty-header" class=${emptyHeaderClass()}>
39
+ <div data-slot="empty-icon" data-variant="default" class=${emptyMediaClass()}>
40
+ <div data-slot="avatar-group" class=${cn(avatarGroupClass(), 'grayscale')}>
41
+ ${MEMBERS.map((m) => html`
42
+ <span data-slot="avatar" data-size="lg" class=${avatarClass({ size: 'lg' })}>
43
+ <span data-slot="avatar-fallback" class=${avatarFallbackClass()}>${m.fallback}</span>
44
+ <img data-slot="avatar-image" src=${m.src} alt=${m.alt} class=${avatarImageClass()}>
45
+ </span>
46
+ `)}
47
+ </div>
48
+ </div>
49
+ <div data-slot="empty-title" class=${emptyTitleClass()}>No Team Members</div>
50
+ <div data-slot="empty-description" class=${emptyDescriptionClass()}>
51
+ Invite your team to collaborate on this project.
52
+ </div>
53
+ </div>
54
+ <div data-slot="empty-content" class=${emptyContentClass()}>
55
+ <button type="button" data-slot="button" data-variant="default" data-size="sm" class=${buttonClass({ size: 'sm' })}>Invite Members</button>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </div>
60
+ `;
61
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The preview block's not-found card: a 404 empty state with a search field
3
+ * and a way home. A fragment helper, rendered by the server. Installed by
4
+ * `npx @webjsdev/ui add preview` at `components/preview/not-found.ts`.
5
+ * Ported from shadcn/ui's preview block.
6
+ *
7
+ * The search field is a placeholder: put it in a GET `<form>` aimed at your
8
+ * search route.
9
+ */
10
+ import { html } from '@webjsdev/core';
11
+ import { cn } from '../../../lib/utils.ts';
12
+ import { buttonClass } from '../../../components/button.ts';
13
+ import { cardClass, cardContentClass } from '../../../components/card.ts';
14
+ import {
15
+ emptyClass,
16
+ emptyContentClass,
17
+ emptyDescriptionClass,
18
+ emptyHeaderClass,
19
+ emptyTitleClass,
20
+ } from '../../../components/empty.ts';
21
+ import { inputGroupAddonClass, inputGroupClass, inputGroupInputClass } from '../../../components/input-group.ts';
22
+ import { kbdClass } from '../../../components/kbd.ts';
23
+ import { SearchIcon } from '../../../lib/icons.ts';
24
+
25
+ export function notFound() {
26
+ return html`
27
+ <div data-slot="card" data-size="default" class=${cardClass()}>
28
+ <div data-slot="card-content" class=${cardContentClass()}>
29
+ <div data-slot="empty" class=${cn(emptyClass(), 'h-72')}>
30
+ <div data-slot="empty-header" class=${emptyHeaderClass()}>
31
+ <div data-slot="empty-title" class=${emptyTitleClass()}>404 Not Found</div>
32
+ <div data-slot="empty-description" class=${emptyDescriptionClass()}>The page you're looking for doesn't exist. Try searching for what you need below.</div>
33
+ </div>
34
+ <div data-slot="empty-content" class=${emptyContentClass()}>
35
+ <div role="group" data-slot="input-group" class=${cn(inputGroupClass(), 'w-3/4')}>
36
+ <input data-slot="input-group-control" name="q" aria-label="Search pages" placeholder="Try searching for pages..." class=${inputGroupInputClass()}>
37
+ <div role="group" data-slot="input-group-addon" data-align="inline-start" class=${inputGroupAddonClass()}>${SearchIcon()}</div>
38
+ <div role="group" data-slot="input-group-addon" data-align="inline-end" class=${inputGroupAddonClass({ align: 'inline-end' })}><kbd data-slot="kbd" class=${kbdClass()}>/</kbd></div>
39
+ </div>
40
+ <a href="/" data-slot="button" data-variant="link" data-size="default" class=${buttonClass({ variant: 'link' })}>Go to homepage</a>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ `;
46
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The preview block's observability card: a tinted cover photo over an
3
+ * announcement, with a call to action and a status badge. A fragment helper,
4
+ * rendered by the server. Installed by `npx @webjsdev/ui add preview` at
5
+ * `components/preview/observability-card.ts`. Ported from shadcn/ui's preview
6
+ * block.
7
+ *
8
+ * The cover is shadcn's Unsplash photo (by mymind). Swap in your own image.
9
+ */
10
+ import { html } from '@webjsdev/core';
11
+ import { cn } from '../../../lib/utils.ts';
12
+ import { badgeClass } from '../../../components/badge.ts';
13
+ import { buttonClass } from '../../../components/button.ts';
14
+ import {
15
+ cardClass,
16
+ cardDescriptionClass,
17
+ cardFooterClass,
18
+ cardHeaderClass,
19
+ cardTitleClass,
20
+ } from '../../../components/card.ts';
21
+ import { PlusIcon } from '../../../lib/icons.ts';
22
+
23
+ const COVER = 'https://images.unsplash.com/photo-1604076850742-4c7221f3101b?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D';
24
+
25
+ export function observabilityCard() {
26
+ return html`
27
+ <div data-slot="card" data-size="default" class=${cn(cardClass(), 'relative w-full max-w-md overflow-hidden pt-0')}>
28
+ <div class="absolute inset-0 z-30 aspect-video bg-primary opacity-50 mix-blend-color"></div>
29
+ <img src=${COVER} alt="Photo by mymind on Unsplash" title="Photo by mymind on Unsplash" class="relative z-20 aspect-video w-full object-cover brightness-60 grayscale">
30
+ <div data-slot="card-header" class=${cardHeaderClass()}>
31
+ <div data-slot="card-title" class=${cardTitleClass()}>Observability Plus is replacing Monitoring</div>
32
+ <div data-slot="card-description" class=${cardDescriptionClass()}>
33
+ Switch to the improved way to explore your data, with natural
34
+ language. Monitoring will no longer be available on the Pro plan in
35
+ November, 2025
36
+ </div>
37
+ </div>
38
+ <div data-slot="card-footer" class=${cardFooterClass()}>
39
+ <button type="button" data-slot="button" data-variant="default" data-size="default" class=${buttonClass()}>Create Query ${PlusIcon()}</button>
40
+ <span data-slot="badge" data-variant="secondary" class=${cn(badgeClass({ variant: 'secondary' }), 'ml-auto')}>Warning</span>
41
+ </div>
42
+ </div>
43
+ `;
44
+ }