@webjsdev/ui 0.3.17 → 0.5.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 (360) hide show
  1. package/README.md +67 -8
  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 +644 -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 +8 -8
  284. package/packages/registry/components/field.ts +20 -18
  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 +7 -4
  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/dom.ts +3 -4
  323. package/packages/registry/lib/icons-hugeicons.ts +955 -0
  324. package/packages/registry/lib/icons-phosphor.ts +955 -0
  325. package/packages/registry/lib/icons-remixicon.ts +955 -0
  326. package/packages/registry/lib/icons-tabler.ts +955 -0
  327. package/packages/registry/lib/icons.ts +768 -0
  328. package/packages/registry/lib/utils.ts +52 -8
  329. package/packages/registry/registry.json +4056 -72
  330. package/packages/registry/styles/shadcn-tailwind.css +654 -0
  331. package/packages/registry/styles/style-luma.css +1987 -0
  332. package/packages/registry/styles/style-lyra.css +1965 -0
  333. package/packages/registry/styles/style-maia.css +1987 -0
  334. package/packages/registry/styles/style-mira.css +1992 -0
  335. package/packages/registry/styles/style-new-york.css +1597 -0
  336. package/packages/registry/styles/style-nova.css +1990 -0
  337. package/packages/registry/styles/style-rhea.css +1987 -0
  338. package/packages/registry/styles/style-sera.css +1977 -0
  339. package/packages/registry/styles/style-vega.css +1990 -0
  340. package/packages/registry/styles/supplement.json +54 -0
  341. package/packages/registry/styles/tw-animate.css +6 -0
  342. package/packages/registry/themes/base-colors.js +8 -2
  343. package/packages/registry/themes/fonts.js +120 -0
  344. package/packages/registry/themes/index.css +2 -0
  345. package/packages/registry/themes/items.js +61 -0
  346. package/packages/registry/themes/preset.js +302 -0
  347. package/packages/registry/themes/themes.js +1193 -0
  348. package/src/commands/add.js +266 -14
  349. package/src/commands/diff.js +34 -20
  350. package/src/commands/info.js +7 -0
  351. package/src/commands/init.js +127 -10
  352. package/src/commands/list.js +43 -11
  353. package/src/commands/view.js +33 -5
  354. package/src/lint/rules/no-restyle.js +1 -1
  355. package/src/registry/extract.js +194 -5
  356. package/src/registry/icons.js +31 -0
  357. package/src/registry/local.js +15 -1
  358. package/src/registry/schema.js +13 -0
  359. package/src/registry/style-bake.js +506 -0
  360. package/src/utils/theme.js +110 -21
@@ -19,6 +19,7 @@
19
19
  * AlertDialogTrigger → <ui-alert-dialog-trigger>
20
20
  * AlertDialogContent → <ui-alert-dialog-content size>
21
21
  * AlertDialogHeader → <div class=${alertDialogHeaderClass()}>
22
+ * AlertDialogMedia → <div data-slot="alert-dialog-media" class=${alertDialogMediaClass()}>
22
23
  * AlertDialogTitle → <h2 class=${alertDialogTitleClass()}>
23
24
  * AlertDialogDescription → <p class=${alertDialogDescriptionClass()}>
24
25
  * AlertDialogFooter → <div class=${alertDialogFooterClass()}>
@@ -93,22 +94,30 @@
93
94
  */
94
95
  import { WebComponent, html, prop } from '@webjsdev/core';
95
96
  import { ref, createRef } from '@webjsdev/core/directives';
96
- import { ensureId } from '../lib/utils.ts';
97
+ import { cn, ensureId, takeAuthoredClass } from '../lib/utils.ts';
97
98
  import { onBeforeCache } from '../lib/dom.ts';
98
99
  import { buttonClass, type ButtonVariant, type ButtonSize } from './button.ts';
99
100
 
100
101
  export const alertDialogContentClass = (): string =>
101
- 'group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadcn-lg shadow-lg duration-200 data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg';
102
+ 'cn-alert-dialog-content group/alert-dialog-content fixed z-50 grid w-full';
102
103
 
103
104
  export const alertDialogHeaderClass = (): string =>
104
- 'grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left';
105
+ 'cn-alert-dialog-header';
105
106
 
106
107
  export const alertDialogFooterClass = (): string =>
107
- 'flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end';
108
+ 'cn-alert-dialog-footer flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end';
108
109
 
109
- export const alertDialogTitleClass = (): string => 'text-lg font-semibold';
110
+ export const alertDialogTitleClass = (): string => 'cn-alert-dialog-title';
110
111
 
111
- export const alertDialogDescriptionClass = (): string => 'text-sm text-muted-foreground';
112
+ export const alertDialogDescriptionClass = (): string => 'cn-alert-dialog-description';
113
+
114
+ /**
115
+ * The media slot of the header: an icon or image shown beside (or, in the
116
+ * small size, above) the title. Mark the element `data-slot="alert-dialog-media"`
117
+ * so the header's grid makes room for it. Decorative media takes
118
+ * `aria-hidden="true"`; the dialog's name still comes from its title.
119
+ */
120
+ export const alertDialogMediaClass = (): string => 'cn-alert-dialog-media';
112
121
 
113
122
  // Pre-hydration paint fallback (see dialog.ts for the long version).
114
123
  const STYLES = `
@@ -119,7 +128,10 @@ ui-alert-dialog-content { display: grid; }
119
128
  // Fills the viewport (fixed inset-0), NOT 0x0 (#730): WebKit makes a
120
129
  // top-layer <dialog> the containing block for its position:fixed descendants,
121
130
  // so a 0x0 host collapsed the fixed content panel to 0x0 (invisible on iOS).
122
- const NATIVE_DIALOG_CLASS = 'fixed inset-0 border-0 bg-transparent p-0 m-0 max-w-none max-h-none overflow-visible text-inherit backdrop:bg-black/50';
131
+ const NATIVE_DIALOG_CLASS = 'fixed inset-0 border-0 bg-transparent p-0 m-0 max-w-none max-h-none overflow-visible text-inherit backdrop:bg-transparent';
132
+
133
+ /** The overlay behind the panel, which each style dims in its own way. */
134
+ export const alertDialogOverlayClass = (): string => 'cn-alert-dialog-overlay fixed inset-0 z-50';
123
135
 
124
136
  function installStyles(): void {
125
137
  if (typeof document === 'undefined') return;
@@ -309,10 +321,20 @@ export class UiAlertDialog extends WebComponent({
309
321
  if (!changedProperties.has('open')) return;
310
322
  // Skip the constructor's initial open=false set so we don't fire
311
323
  // teardown for the closed-on-mount state.
312
- if (changedProperties.get('open') === undefined) return;
324
+ // One written `open` still opens on that first update (shadcn's
325
+ // `defaultOpen`).
326
+ const initial = changedProperties.get('open') === undefined;
327
+ if (initial && !this.open) return;
328
+ // The content renders its data-state from this element's `open`, and
329
+ // nothing else re-renders it, so ask it to now. Every shadcn style
330
+ // animates out on data-closed: left closed while the native dialog
331
+ // opens, the content played its exit animation as it appeared.
332
+ this._content?.requestUpdate?.();
313
333
  // Defer one microtask so the content child has rendered its inner
314
- // native <dialog>; that's where showModal() / close() act.
315
- queueMicrotask(() => {
334
+ // native <dialog>; that's where showModal() / close() act. On the first
335
+ // update the content may not have rendered yet, so that one waits.
336
+ queueMicrotask(async () => {
337
+ if (initial) await this._content?.updateComplete;
316
338
  if (this.open) this._setup();
317
339
  else this._teardown();
318
340
  });
@@ -482,6 +504,13 @@ export class UiAlertDialogContent extends WebComponent({
482
504
  if (native?.open) native.close();
483
505
  }
484
506
 
507
+ // shadcn's className on the content lands on the panel it renders, so the
508
+ // class written on this host moves there, read once at first render.
509
+ _authored: string | null = null;
510
+ _hostClass(): string | null {
511
+ return (this._authored = takeAuthoredClass(this, null));
512
+ }
513
+
485
514
  render() {
486
515
  const parentOpen = !!this._parent()?.open;
487
516
  return html`<dialog
@@ -492,10 +521,15 @@ export class UiAlertDialogContent extends WebComponent({
492
521
  @cancel=${this._onNativeCancel}
493
522
  @close=${this._onNativeClose}
494
523
  ><div
524
+ data-slot="alert-dialog-overlay"
525
+ data-state=${parentOpen ? 'open' : 'closed'}
526
+ aria-hidden="true"
527
+ class=${alertDialogOverlayClass()}
528
+ ></div><div
495
529
  data-slot="alert-dialog-content"
496
530
  data-size=${this.size}
497
531
  data-state=${parentOpen ? 'open' : 'closed'}
498
- class=${alertDialogContentClass()}
532
+ class=${cn(alertDialogContentClass(), this._hostClass())}
499
533
  ><slot></slot></div></dialog>`;
500
534
  }
501
535
 
@@ -542,6 +576,15 @@ UiAlertDialogContent.register('ui-alert-dialog-content');
542
576
 
543
577
  const ALERT_DIALOG_ACTION_GRID_STRETCH = 'group-data-[size=sm]/alert-dialog-content:w-full';
544
578
 
579
+ // The action and the cancel render the button shadcn's AlertDialogAction /
580
+ // AlertDialogCancel are, so the BUTTON is the footer's flex or grid item: on a
581
+ // phone the column footer stretches it full width. The host draws no box of
582
+ // its own, turned off through its style, which the server serves, and a class
583
+ // written on it lands on the button, as shadcn's className does.
584
+ function boxless(host: HTMLElement): void {
585
+ if (typeof host.getAttribute === 'function' && !host.getAttribute('style')) host.setAttribute('style', 'display: contents');
586
+ }
587
+
545
588
  export class UiAlertDialogCancel extends WebComponent({
546
589
  variant: prop<ButtonVariant>(String, { reflect: true }),
547
590
  size: prop<ButtonSize>(String, { reflect: true }),
@@ -553,10 +596,11 @@ export class UiAlertDialogCancel extends WebComponent({
553
596
  }
554
597
 
555
598
  render() {
599
+ boxless(this);
556
600
  return html`<button
557
601
  type="button"
558
602
  data-slot="alert-dialog-cancel"
559
- class="${buttonClass({ variant: this.variant, size: this.size })} ${ALERT_DIALOG_ACTION_GRID_STRETCH}"
603
+ class=${cn(buttonClass({ variant: this.variant, size: this.size }), ALERT_DIALOG_ACTION_GRID_STRETCH, takeAuthoredClass(this, null))}
560
604
  @click=${this._onClick}
561
605
  ><slot></slot></button>`;
562
606
  }
@@ -576,10 +620,11 @@ export class UiAlertDialogAction extends WebComponent({
576
620
  }
577
621
 
578
622
  render() {
623
+ boxless(this);
579
624
  return html`<button
580
625
  type="button"
581
626
  data-slot="alert-dialog-action"
582
- class="${buttonClass({ variant: this.variant, size: this.size })} ${ALERT_DIALOG_ACTION_GRID_STRETCH}"
627
+ class=${cn(buttonClass({ variant: this.variant, size: this.size }), ALERT_DIALOG_ACTION_GRID_STRETCH, takeAuthoredClass(this, null))}
583
628
  @click=${this._onClick}
584
629
  ><slot></slot></button>`;
585
630
  }
@@ -6,6 +6,8 @@
6
6
  * Alert (variant: default | destructive) → alertClass({ variant })
7
7
  * AlertTitle → alertTitleClass()
8
8
  * AlertDescription → alertDescriptionClass()
9
+ * AlertAction → alertActionClass() with data-slot="alert-action"
10
+ * (a button or link in the alert's corner)
9
11
  *
10
12
  * A11y (required for accessible output): put role="alert" on the container
11
13
  * for an urgent, interrupting message, or role="status" for a polite,
@@ -37,12 +39,11 @@
37
39
  import { cn } from '../lib/utils.ts';
38
40
 
39
41
  const BASE =
40
- 'relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current';
42
+ 'cn-alert group/alert relative w-full';
41
43
 
42
44
  const VARIANTS = {
43
- default: 'bg-card text-card-foreground',
44
- destructive:
45
- 'bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current',
45
+ default: 'cn-alert-variant-default',
46
+ destructive: 'cn-alert-variant-destructive',
46
47
  } as const;
47
48
 
48
49
  export type AlertVariant = keyof typeof VARIANTS;
@@ -52,7 +53,11 @@ export function alertClass(opts: { variant?: AlertVariant } = {}): string {
52
53
  }
53
54
 
54
55
  export const alertTitleClass = (): string =>
55
- 'col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight';
56
+ 'cn-alert-title';
56
57
 
57
58
  export const alertDescriptionClass = (): string =>
58
- 'col-start-2 grid justify-items-start gap-1 text-sm text-muted-foreground [&_p]:leading-relaxed';
59
+ 'cn-alert-description';
60
+
61
+ /** The alert's action, in its corner. Set `data-slot="alert-action"`, which the alert reserves room for. */
62
+ export const alertActionClass = (): string =>
63
+ 'cn-alert-action';
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Attachment: a file or image attached to a message or a form, as a compact
3
+ * card with its media, name, details and actions. Tier-1 class helper;
4
+ * compose with plain elements.
5
+ *
6
+ * shadcn parity:
7
+ * AttachmentGroup → attachmentGroupClass()
8
+ * Attachment (variant, size) → attachmentClass({ ... }), alias attachmentVariants
9
+ * AttachmentMedia → attachmentMediaClass({ ... }), alias attachmentMediaVariants
10
+ * AttachmentContent / AttachmentTitle / AttachmentDescription
11
+ * → attachmentContentClass() / attachmentTitleClass() / attachmentDescriptionClass()
12
+ * AttachmentActions / AttachmentAction / AttachmentTrigger
13
+ * → attachmentActionsClass() / attachmentActionClass() / attachmentTriggerClass()
14
+ *
15
+ * Every part takes its `data-slot`, which the styles key on.
16
+ *
17
+ * A11y (required for accessible output): the file name is the attachment's
18
+ * accessible name, so keep it in real text (the title), not only in an image.
19
+ * An image preview needs `alt` (or `alt=""` when the title already names it).
20
+ * Each icon-only action (remove, download) is a `<button>` with an
21
+ * `aria-label` naming the file ("Remove report.pdf"), and a trigger that opens
22
+ * the file is a real link or button.
23
+ *
24
+ * Design tokens used: --border, --muted, --muted-foreground, --background.
25
+ *
26
+ * @example
27
+ * ```html
28
+ * <div class=${attachmentClass()} data-slot="attachment">
29
+ * <div class=${attachmentContentClass()} data-slot="attachment-content">
30
+ * <span class=${attachmentTitleClass()} data-slot="attachment-title">report.pdf</span>
31
+ * <span class=${attachmentDescriptionClass()} data-slot="attachment-description">2.4 MB</span>
32
+ * </div>
33
+ * </div>
34
+ * ```
35
+ */
36
+ import { cn } from '../lib/utils.ts';
37
+
38
+ const ATTACHMENT_BASE =
39
+ 'cn-attachment group/attachment relative flex max-w-full min-w-0 shrink-0 flex-wrap border bg-card text-card-foreground transition-colors has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed';
40
+
41
+ const ATTACHMENT_SIZES = {
42
+ default: 'cn-attachment-size-default',
43
+ sm: 'cn-attachment-size-sm',
44
+ xs: 'cn-attachment-size-xs',
45
+ } as const;
46
+
47
+ const ATTACHMENT_ORIENTATIONS = {
48
+ horizontal: 'cn-attachment-orientation-horizontal items-center',
49
+ vertical: 'cn-attachment-orientation-vertical flex-col',
50
+ } as const;
51
+
52
+ /** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
53
+ export function attachmentClass(opts: { size?: keyof typeof ATTACHMENT_SIZES; orientation?: keyof typeof ATTACHMENT_ORIENTATIONS } = {}): string {
54
+ return cn(ATTACHMENT_BASE, ATTACHMENT_SIZES[opts.size ?? 'default'], ATTACHMENT_ORIENTATIONS[opts.orientation ?? 'horizontal']);
55
+ }
56
+
57
+ /**
58
+ * shadcn's name for {@link attachmentClass}, so shadcn code ports verbatim. Like cva,
59
+ * it merges a `className` into the result.
60
+ */
61
+ export function attachmentVariants(opts: { size?: keyof typeof ATTACHMENT_SIZES; orientation?: keyof typeof ATTACHMENT_ORIENTATIONS } & { className?: string } = {}): string {
62
+ return cn(attachmentClass(opts), opts.className);
63
+ }
64
+
65
+ const ATTACHMENT_MEDIA_BASE =
66
+ 'cn-attachment-media relative flex aspect-square shrink-0 items-center justify-center overflow-hidden group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive [&_svg]:pointer-events-none';
67
+
68
+ const ATTACHMENT_MEDIA_VARIANTS = {
69
+ icon: 'cn-attachment-media-variant-icon',
70
+ image: 'cn-attachment-media-variant-image *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover',
71
+ } as const;
72
+
73
+ /** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
74
+ export function attachmentMediaClass(opts: { variant?: keyof typeof ATTACHMENT_MEDIA_VARIANTS } = {}): string {
75
+ return cn(ATTACHMENT_MEDIA_BASE, ATTACHMENT_MEDIA_VARIANTS[opts.variant ?? 'icon']);
76
+ }
77
+
78
+ /**
79
+ * shadcn's name for {@link attachmentMediaClass}, so shadcn code ports verbatim. Like cva,
80
+ * it merges a `className` into the result.
81
+ */
82
+ export function attachmentMediaVariants(opts: { variant?: keyof typeof ATTACHMENT_MEDIA_VARIANTS } & { className?: string } = {}): string {
83
+ return cn(attachmentMediaClass(opts), opts.className);
84
+ }
85
+
86
+ /** Set `data-slot="attachment-content"` on the element. */
87
+ export function attachmentContentClass(): string {
88
+ return 'cn-attachment-content max-w-full min-w-0 flex-1';
89
+ }
90
+
91
+ /** Set `data-slot="attachment-title"` on the element. */
92
+ export function attachmentTitleClass(): string {
93
+ return 'cn-attachment-title block max-w-full min-w-0 truncate group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer';
94
+ }
95
+
96
+ /** Set `data-slot="attachment-description"` on the element. */
97
+ export function attachmentDescriptionClass(): string {
98
+ return 'cn-attachment-description block min-w-0 truncate text-muted-foreground group-data-[state=error]/attachment:text-destructive/80';
99
+ }
100
+
101
+ /** Set `data-slot="attachment-actions"` on the element. */
102
+ export function attachmentActionsClass(): string {
103
+ return 'cn-attachment-actions flex shrink-0 items-center';
104
+ }
105
+
106
+ /** Set `data-slot="attachment-action"` on the element. */
107
+ export function attachmentActionClass(): string {
108
+ return 'cn-attachment-action';
109
+ }
110
+
111
+ /** Set `data-slot="attachment-trigger"` on the element. */
112
+ export function attachmentTriggerClass(): string {
113
+ return 'cn-attachment-trigger absolute inset-0 z-10 outline-none';
114
+ }
115
+
116
+ /** Set `data-slot="attachment-group"` on the element. */
117
+ export function attachmentGroupClass(): string {
118
+ return 'cn-attachment-group flex min-w-0 scroll-fade-x snap-x snap-mandatory scrollbar-none overflow-x-auto overscroll-x-contain *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start';
119
+ }
@@ -1,7 +1,15 @@
1
1
  /**
2
2
  * Avatar: circular user image with fallback. Tier-1 class helpers;
3
- * compose with a native `<span>` or `<img>`. The fallback shows when the
4
- * `<img>` is missing or fails to load (`onerror`).
3
+ * compose with a native `<span>` or `<img>`. As in shadcn, one of the two
4
+ * shows, never both, and with no script: the image is laid over the fallback
5
+ * (`absolute inset-0` inside the `relative` root), so a loaded image covers
6
+ * it, and a missing or broken one leaves the fallback showing. A broken
7
+ * image paints neither its alt text (`text-transparent`) nor, in Chromium,
8
+ * its broken-image glyph: a broken `<img>` renders a `::before` box (a loaded
9
+ * one never does), and the full-height block it gets here pushes the glyph
10
+ * out of the clipped box. Safari ignores that box and draws its glyph over
11
+ * the initials (Firefox can too at larger sizes), so where that matters hide
12
+ * the image on failure with script (`onerror`).
5
13
  *
6
14
  * shadcn parity:
7
15
  * Avatar (size: default | sm | lg) → avatarClass({ size }) with `data-size`
@@ -43,23 +51,24 @@ import { cn } from '../lib/utils.ts';
43
51
  export type AvatarSize = 'default' | 'sm' | 'lg';
44
52
 
45
53
  const AVATAR_BASE =
46
- 'group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6';
54
+ 'cn-avatar group/avatar relative flex shrink-0 select-none';
47
55
 
48
56
  export function avatarClass(_opts: { size?: AvatarSize } = {}): string {
49
57
  // Size driven by data-size attribute on the element (matches shadcn).
50
58
  return cn(AVATAR_BASE);
51
59
  }
52
60
 
53
- export const avatarImageClass = (): string => 'aspect-square size-full';
61
+ export const avatarImageClass = (): string =>
62
+ 'cn-avatar-image absolute inset-0 aspect-square size-full object-cover overflow-hidden text-transparent before:block before:h-full';
54
63
 
55
64
  export const avatarFallbackClass = (): string =>
56
- 'flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs';
65
+ 'cn-avatar-fallback flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs';
57
66
 
58
67
  export const avatarBadgeClass = (): string =>
59
- 'absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground ring-2 ring-background select-none group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2 group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2';
68
+ 'cn-avatar-badge absolute end-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2 group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2';
60
69
 
61
70
  export const avatarGroupClass = (): string =>
62
- 'group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background';
71
+ 'cn-avatar-group group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background';
63
72
 
64
73
  export const avatarGroupCountClass = (): string =>
65
- 'relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3';
74
+ 'cn-avatar-group-count relative flex shrink-0 items-center justify-center ring-2 ring-background';
@@ -26,17 +26,15 @@
26
26
  import { cn } from '../lib/utils.ts';
27
27
 
28
28
  const BASE =
29
- 'inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3';
29
+ 'cn-badge group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none';
30
30
 
31
31
  const VARIANTS = {
32
- default: 'bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
33
- secondary: 'bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
34
- destructive:
35
- 'bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90',
36
- outline:
37
- 'border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
38
- ghost: '[a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
39
- link: 'text-primary underline-offset-4 [a&]:hover:underline',
32
+ default: 'cn-badge-variant-default',
33
+ secondary: 'cn-badge-variant-secondary',
34
+ destructive: 'cn-badge-variant-destructive',
35
+ outline: 'cn-badge-variant-outline',
36
+ ghost: 'cn-badge-variant-ghost',
37
+ link: 'cn-badge-variant-link',
40
38
  } as const;
41
39
 
42
40
  export type BadgeVariant = keyof typeof VARIANTS;
@@ -44,3 +42,12 @@ export type BadgeVariant = keyof typeof VARIANTS;
44
42
  export function badgeClass(opts: { variant?: BadgeVariant } = {}): string {
45
43
  return cn(BASE, VARIANTS[opts.variant ?? 'default']);
46
44
  }
45
+
46
+ /**
47
+ * shadcn's name for {@link badgeClass}, so shadcn code ports verbatim
48
+ * (`badgeVariants({ ... })` is shadcn's `cva` export for `Badge`). Like cva, it
49
+ * merges a `className` into the result.
50
+ */
51
+ export function badgeVariants(opts: { variant?: BadgeVariant } & { className?: string } = {}): string {
52
+ return cn(badgeClass(opts), opts.className);
53
+ }
@@ -37,14 +37,14 @@
37
37
  */
38
38
 
39
39
  export const breadcrumbListClass = (): string =>
40
- 'flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5';
40
+ 'cn-breadcrumb-list flex flex-wrap items-center wrap-break-word';
41
41
 
42
- export const breadcrumbItemClass = (): string => 'inline-flex items-center gap-1.5';
42
+ export const breadcrumbItemClass = (): string => 'cn-breadcrumb-item inline-flex items-center';
43
43
 
44
- export const breadcrumbLinkClass = (): string => 'transition-colors hover:text-foreground';
44
+ export const breadcrumbLinkClass = (): string => 'cn-breadcrumb-link';
45
45
 
46
- export const breadcrumbPageClass = (): string => 'font-normal text-foreground';
46
+ export const breadcrumbPageClass = (): string => 'cn-breadcrumb-page';
47
47
 
48
- export const breadcrumbSeparatorClass = (): string => '[&>svg]:size-3.5';
48
+ export const breadcrumbSeparatorClass = (): string => 'cn-breadcrumb-separator';
49
49
 
50
- export const breadcrumbEllipsisClass = (): string => 'flex size-9 items-center justify-center';
50
+ export const breadcrumbEllipsisClass = (): string => 'cn-breadcrumb-ellipsis flex items-center justify-center';
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Bubble: a chat speech bubble, the group that stacks several from one sender,
3
+ * and the emoji reactions pinned to its corner. Tier-1 class helper; pair with
4
+ * the message helpers for the row, avatar and header around it.
5
+ *
6
+ * shadcn parity:
7
+ * BubbleGroup → bubbleGroupClass()
8
+ * Bubble (variant: default | secondary | muted | tinted | outline | ghost | destructive)
9
+ * → bubbleClass({ variant }), alias bubbleVariants
10
+ * BubbleContent → bubbleContentClass()
11
+ * BubbleReactions (side: top | bottom, align: start | end)
12
+ * → bubbleReactionsClass({ side, align }), alias bubbleReactionsVariants
13
+ *
14
+ * The variant colours the content, so put `data-slot="bubble-content"` on the
15
+ * inner element and `data-variant` on the bubble. Inside a message with
16
+ * `data-align="end"` the bubble follows to the inline end.
17
+ *
18
+ * A11y (required for accessible output): the bubble is text inside a message,
19
+ * so it needs no role of its own. Reactions are buttons when they act (with an
20
+ * `aria-label` such as "2 people reacted with thumbs up", since an emoji alone
21
+ * reads poorly) and plain text when they only show a count.
22
+ *
23
+ * Design tokens used: --primary, --secondary, --muted, --accent, --border,
24
+ * --destructive.
25
+ *
26
+ * @example
27
+ * ```html
28
+ * <div class=${bubbleClass()} data-slot="bubble" data-variant="default">
29
+ * <div class=${bubbleContentClass()} data-slot="bubble-content">Shipping it now.</div>
30
+ * </div>
31
+ * ```
32
+ */
33
+ import { cn } from '../lib/utils.ts';
34
+
35
+ /** Set `data-slot="bubble-group"` on the element. */
36
+ export function bubbleGroupClass(): string {
37
+ return 'cn-bubble-group flex min-w-0 flex-col';
38
+ }
39
+
40
+ const BUBBLE_BASE =
41
+ 'cn-bubble group/bubble relative flex w-fit min-w-0 flex-col';
42
+
43
+ const BUBBLE_VARIANTS = {
44
+ default: 'cn-bubble-variant-default',
45
+ secondary: 'cn-bubble-variant-secondary',
46
+ muted: 'cn-bubble-variant-muted',
47
+ tinted: 'cn-bubble-variant-tinted',
48
+ outline: 'cn-bubble-variant-outline',
49
+ ghost: 'cn-bubble-variant-ghost',
50
+ destructive: 'cn-bubble-variant-destructive',
51
+ } as const;
52
+
53
+ /** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
54
+ export function bubbleClass(opts: { variant?: keyof typeof BUBBLE_VARIANTS } = {}): string {
55
+ return cn(BUBBLE_BASE, BUBBLE_VARIANTS[opts.variant ?? 'default']);
56
+ }
57
+
58
+ /**
59
+ * shadcn's name for {@link bubbleClass}, so shadcn code ports verbatim. Like cva,
60
+ * it merges a `className` into the result.
61
+ */
62
+ export function bubbleVariants(opts: { variant?: keyof typeof BUBBLE_VARIANTS } & { className?: string } = {}): string {
63
+ return cn(bubbleClass(opts), opts.className);
64
+ }
65
+
66
+ /** Set `data-slot="bubble-content"` on the element. */
67
+ export function bubbleContentClass(): string {
68
+ return 'cn-bubble-content w-fit max-w-full min-w-0 overflow-hidden wrap-break-word [button]:text-start [button,a]:transition-colors';
69
+ }
70
+
71
+ const BUBBLE_REACTIONS_BASE =
72
+ 'cn-bubble-reactions absolute z-10 flex w-fit items-center justify-center';
73
+
74
+ const BUBBLE_REACTIONS_SIDES = {
75
+ top: 'cn-bubble-reactions-side-top',
76
+ bottom: 'cn-bubble-reactions-side-bottom',
77
+ } as const;
78
+
79
+ const BUBBLE_REACTIONS_ALIGNS = {
80
+ start: 'cn-bubble-reactions-align-start',
81
+ end: 'cn-bubble-reactions-align-end',
82
+ } as const;
83
+
84
+ /** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
85
+ export function bubbleReactionsClass(opts: { side?: keyof typeof BUBBLE_REACTIONS_SIDES; align?: keyof typeof BUBBLE_REACTIONS_ALIGNS } = {}): string {
86
+ return cn(BUBBLE_REACTIONS_BASE, BUBBLE_REACTIONS_SIDES[opts.side ?? 'bottom'], BUBBLE_REACTIONS_ALIGNS[opts.align ?? 'end']);
87
+ }
88
+
89
+ /**
90
+ * shadcn's name for {@link bubbleReactionsClass}, so shadcn code ports verbatim. Like cva,
91
+ * it merges a `className` into the result.
92
+ */
93
+ export function bubbleReactionsVariants(opts: { side?: keyof typeof BUBBLE_REACTIONS_SIDES; align?: keyof typeof BUBBLE_REACTIONS_ALIGNS } & { className?: string } = {}): string {
94
+ return cn(bubbleReactionsClass(opts), opts.className);
95
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Button group: a row (or column) of buttons that share their borders, so
3
+ * they read as one control. Tier-1 class helper; compose with a real
4
+ * container element and real buttons.
5
+ *
6
+ * shadcn parity:
7
+ * ButtonGroup (orientation: horizontal | vertical)
8
+ * → buttonGroupClass({ orientation }), alias buttonGroupVariants
9
+ * ButtonGroupText → buttonGroupTextClass()
10
+ * ButtonGroupSeparator → buttonGroupSeparatorClass() with separatorClass({ orientation })
11
+ *
12
+ * The group flattens the inner corners and drops the doubled border between
13
+ * neighbours, by logical side, so it reads correctly under `dir="rtl"`. A
14
+ * nested group (a group of groups) keeps its own gap.
15
+ *
16
+ * A11y (required for accessible output): put `role="group"` on the container
17
+ * and name it with `aria-label` (or `aria-labelledby`) when the buttons share
18
+ * a purpose a screen-reader user needs to hear ("Text alignment"). Each button
19
+ * keeps its own accessible name; an icon-only one needs `aria-label`. Set
20
+ * `data-orientation` to match the orientation you pass, and a separator inside
21
+ * the group is decorative, so give it `role="none"` or `aria-hidden="true"`.
22
+ *
23
+ * Design tokens used: --border, --input, --muted.
24
+ *
25
+ * @example
26
+ * ```html
27
+ * <div class=${buttonGroupClass()} role="group" aria-label="Text alignment" data-orientation="horizontal">
28
+ * <button class=${buttonClass({ variant: 'outline' })} type="button">Left</button>
29
+ * <button class=${buttonClass({ variant: 'outline' })} type="button">Center</button>
30
+ * <button class=${buttonClass({ variant: 'outline' })} type="button">Right</button>
31
+ * </div>
32
+ * ```
33
+ */
34
+ import { cn } from '../lib/utils.ts';
35
+
36
+ const BASE =
37
+ "cn-button-group group/button-group flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1";
38
+
39
+ const ORIENTATIONS = {
40
+ horizontal:
41
+ 'cn-button-group-orientation-horizontal [&>*:not(:first-child)]:rounded-s-none [&>*:not(:first-child)]:border-s-0 [&>*:not(:last-child)]:rounded-e-none',
42
+ vertical:
43
+ 'cn-button-group-orientation-vertical flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',
44
+ } as const;
45
+
46
+ export type ButtonGroupOrientation = keyof typeof ORIENTATIONS;
47
+
48
+ /** The group container. Pair with `role="group"` and `data-orientation`. */
49
+ export function buttonGroupClass(opts: { orientation?: ButtonGroupOrientation } = {}): string {
50
+ return cn(BASE, ORIENTATIONS[opts.orientation ?? 'horizontal']);
51
+ }
52
+
53
+ /**
54
+ * shadcn's name for {@link buttonGroupClass}, so shadcn code ports verbatim
55
+ * (`buttonGroupVariants({ ... })` is shadcn's `cva` export for `ButtonGroup`).
56
+ * Like cva, it merges a `className` into the result.
57
+ */
58
+ export function buttonGroupVariants(opts: { orientation?: ButtonGroupOrientation } & { className?: string } = {}): string {
59
+ return cn(buttonGroupClass(opts), opts.className);
60
+ }
61
+
62
+ /** A non-interactive label or value sitting inside the group. */
63
+ export function buttonGroupTextClass(): string {
64
+ return 'cn-button-group-text flex items-center [&_svg]:pointer-events-none';
65
+ }
66
+
67
+ /**
68
+ * A divider between buttons. Compose with the separator helper:
69
+ * `cn(separatorClass({ orientation: 'vertical' }), buttonGroupSeparatorClass())`.
70
+ */
71
+ export function buttonGroupSeparatorClass(): string {
72
+ return 'cn-button-group-separator relative self-stretch data-horizontal:mx-px data-horizontal:w-auto data-vertical:my-px data-vertical:h-auto';
73
+ }