@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,88 @@
1
+ /**
2
+ * Empty: the empty state for a list, table, search result, or any region with
3
+ * nothing to show yet. Tier-1 class helpers; compose with `<div>` (or a heading
4
+ * and paragraph) for each subpart.
5
+ *
6
+ * shadcn parity:
7
+ * Empty → emptyClass()
8
+ * EmptyHeader → emptyHeaderClass()
9
+ * EmptyMedia (variant: default | icon) → emptyMediaClass({ variant })
10
+ * EmptyTitle → emptyTitleClass()
11
+ * EmptyDescription → emptyDescriptionClass()
12
+ * EmptyContent → emptyContentClass()
13
+ *
14
+ * The root carries `border-dashed` but no border width, exactly as shadcn
15
+ * does, so it renders borderless by default. Add `border` beside it for the
16
+ * dashed outline: `class=${cn(emptyClass(), 'border')}`.
17
+ *
18
+ * Design tokens used: --muted, --foreground, --muted-foreground, --primary,
19
+ * --border.
20
+ *
21
+ * A11y (required for accessible output):
22
+ * Use a REAL HEADING for `emptyTitleClass()`, at the level the surrounding
23
+ * document wants (`<h2>` under the page `<h1>`, `<h3>` inside a section). The
24
+ * empty state usually replaces the list a heading already introduces, so the
25
+ * title is often a level below it.
26
+ * The media is decorative: put `aria-hidden="true"` on the icon or
27
+ * illustration, since the title already says what is missing.
28
+ * The action in `emptyContentClass()` is a real `<a href>` (navigates, e.g.
29
+ * to the create page) or a real `<button>` (acts in place). A create action
30
+ * that is a form submit keeps working without JavaScript.
31
+ * When the empty state appears in response to a user action (a search or a
32
+ * filter that matched nothing), put `role="status"` on the root so the change
33
+ * is announced; a page that simply loads empty needs no role.
34
+ *
35
+ * @example
36
+ * ```html
37
+ * <div class=${cn(emptyClass(), 'border')}>
38
+ * <div class=${emptyHeaderClass()}>
39
+ * <div class=${emptyMediaClass({ variant: 'icon' })}>
40
+ * <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>
41
+ * </div>
42
+ * <h3 class=${emptyTitleClass()}>No projects yet</h3>
43
+ * <p class=${emptyDescriptionClass()}>Create your first project to get started.</p>
44
+ * </div>
45
+ * <div class=${emptyContentClass()}>
46
+ * <a class=${buttonClass()} href="/projects/new">Create project</a>
47
+ * </div>
48
+ * </div>
49
+ * ```
50
+ */
51
+
52
+ const MEDIA_BASE =
53
+ 'cn-empty-media flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0';
54
+
55
+ const MEDIA_VARIANTS = {
56
+ default: 'cn-empty-media-default',
57
+ icon: 'cn-empty-media-icon',
58
+ } as const;
59
+
60
+ export type EmptyMediaVariant = keyof typeof MEDIA_VARIANTS;
61
+
62
+ /** Empty root: centred column with generous padding. Add `border` for the dashed outline. */
63
+ export const emptyClass = (): string =>
64
+ 'cn-empty flex w-full min-w-0 flex-1 flex-col items-center justify-center text-center text-balance';
65
+
66
+ /** Empty header: groups the media, title, and description. */
67
+ export const emptyHeaderClass = (): string =>
68
+ 'cn-empty-header flex max-w-sm flex-col items-center';
69
+
70
+ /**
71
+ * Empty media: the icon or illustration above the title. `icon` puts the icon
72
+ * on a muted tile; `default` leaves it bare (for an avatar or an illustration).
73
+ * Set `data-variant="<variant>"` on the same element for shadcn parity.
74
+ */
75
+ export function emptyMediaClass(opts: { variant?: EmptyMediaVariant } = {}): string {
76
+ return MEDIA_BASE + ' ' + MEDIA_VARIANTS[opts.variant ?? 'default'];
77
+ }
78
+
79
+ /** Empty title: what is missing, in a few words. */
80
+ export const emptyTitleClass = (): string => 'cn-empty-title';
81
+
82
+ /** Empty description: the muted line under the title, saying what to do next. */
83
+ export const emptyDescriptionClass = (): string =>
84
+ 'cn-empty-description text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary';
85
+
86
+ /** Empty content: the row for the action button(s) or a small form. */
87
+ export const emptyContentClass = (): string =>
88
+ 'cn-empty-content flex w-full max-w-sm min-w-0 flex-col items-center text-balance';
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Field: the layout system for a form, a label, a control, its helper text,
3
+ * and its error message, plus the fieldset, legend, and group that hold many
4
+ * fields. Tier-1 class helpers; compose with the native elements (`<fieldset>`,
5
+ * `<legend>`, `<label>`, `<p>`) and the kit's control helpers
6
+ * (`inputClass()`, `textareaClass()`, `checkboxClass()`, and the rest).
7
+ *
8
+ * shadcn parity:
9
+ * FieldSet → fieldSetClass()
10
+ * FieldLegend (variant: legend | label) → fieldLegendClass({ variant })
11
+ * FieldGroup → fieldGroupClass()
12
+ * Field (orientation: vertical | horizontal | responsive) → fieldClass({ orientation })
13
+ * FieldContent → fieldContentClass()
14
+ * FieldLabel → fieldLabelClass()
15
+ * FieldTitle → fieldTitleClass()
16
+ * FieldDescription → fieldDescriptionClass()
17
+ * FieldError → fieldErrorClass()
18
+ * FieldSeparator → fieldSeparatorClass() + fieldSeparatorContentClass()
19
+ *
20
+ * Set the shadcn data attributes on the same elements, because the sibling and
21
+ * group rules key on them: `data-slot="field"` + `data-orientation` on the
22
+ * field, `data-slot="field-label"` on the label, `data-slot="field-content"`
23
+ * on the content wrapper, `data-variant` on the legend, and
24
+ * `data-slot="field-group"` on the group (the `responsive` orientation reads
25
+ * the group's container width).
26
+ *
27
+ * Invalid state: put `data-invalid="true"` on the field, which turns the
28
+ * field's text destructive (`data-[invalid=true]:text-destructive`), and
29
+ * `aria-invalid="true"` on the control, which the control helpers style.
30
+ * Disabled state: `data-disabled="true"` on the field fades its label.
31
+ *
32
+ * Not the same as the `fieldClass()` / `fieldLabelClass()` in the `cn()`
33
+ * helper module (`lib/utils/cn.ts`), which are the older single-field rhythm
34
+ * helpers (`grid gap-2`). Both keep working. Import each from its own module,
35
+ * and alias one (`import { fieldClass as fieldStackClass } from ...`) if a file
36
+ * needs both.
37
+ *
38
+ * Design tokens used: --destructive, --muted-foreground, --primary,
39
+ * --background, --border.
40
+ *
41
+ * A11y (required for accessible output):
42
+ * Every control has a real `<label for>` (`fieldLabelClass()`), never a
43
+ * placeholder alone. A field carries `role="group"` (as shadcn's does) only
44
+ * when it holds more than one control; a single-control field needs no role.
45
+ * Wire the helper and error text to the control with `aria-describedby`,
46
+ * listing the description id and, when invalid, the error id
47
+ * (`aria-describedby="email-desc email-error"`). Point it only at ids that
48
+ * EXIST on the page, so render the error element only when there is an error.
49
+ * On a server validation error, re-render the form with the typed values
50
+ * kept (`value=${values.email}`), `data-invalid="true"` on the field,
51
+ * `aria-invalid="true"` on the control, and the message in
52
+ * `fieldErrorClass()` with `role="alert"`, so the user fixes the one field
53
+ * instead of retyping the form. Move focus to the first invalid control.
54
+ * Group related controls (a radio set, a checkbox list) in a `<fieldset>`
55
+ * with a `<legend>` (`fieldSetClass()` / `fieldLegendClass()`), which names
56
+ * the group. A `fieldTitleClass()` element is NOT a label: use it for the
57
+ * title inside a choice card whose `<label>` wraps the whole card.
58
+ * A decorative separator gets `role="none"`; its text (`or`) stays readable.
59
+ *
60
+ * @example
61
+ * ```html
62
+ * <form method="post" class="w-full max-w-md">
63
+ * <fieldset class=${fieldSetClass()}>
64
+ * <legend class=${fieldLegendClass()} data-variant="legend">Profile</legend>
65
+ * <p class=${fieldDescriptionClass()}>This is how others see you.</p>
66
+ * <div class=${fieldGroupClass()} data-slot="field-group">
67
+ * <div class=${fieldClass()} data-slot="field" data-orientation="vertical">
68
+ * <label class=${fieldLabelClass()} data-slot="field-label" for="name">Name</label>
69
+ * <input class=${inputClass()} id="name" name="name" value="Ada" aria-describedby="name-desc">
70
+ * <p class=${fieldDescriptionClass()} id="name-desc">Shown on your public page.</p>
71
+ * </div>
72
+ * <div class=${fieldClass()} data-slot="field" data-orientation="vertical" data-invalid="true">
73
+ * <label class=${fieldLabelClass()} data-slot="field-label" for="email">Email</label>
74
+ * <input class=${inputClass()} id="email" name="email" type="email" value="ada@" aria-invalid="true" aria-describedby="email-error">
75
+ * <div class=${fieldErrorClass()} id="email-error" role="alert">Enter a valid email address.</div>
76
+ * </div>
77
+ * <div class=${fieldSeparatorClass()} role="none"><span class=${fieldSeparatorContentClass()}>Notifications</span></div>
78
+ * <div class=${fieldClass({ orientation: 'horizontal' })} data-slot="field" data-orientation="horizontal">
79
+ * <input class=${checkboxClass()} data-slot="checkbox" type="checkbox" id="digest" name="digest">
80
+ * <label class=${fieldLabelClass()} data-slot="field-label" for="digest">Send me a weekly digest</label>
81
+ * </div>
82
+ * </div>
83
+ * </fieldset>
84
+ * </form>
85
+ * ```
86
+ */
87
+
88
+ export type FieldLegendVariant = 'legend' | 'label';
89
+ export type FieldOrientation = 'vertical' | 'horizontal' | 'responsive';
90
+
91
+ const LEGEND_VARIANTS = {
92
+ legend: 'cn-field-legend-variant-legend',
93
+ label: 'cn-field-legend-variant-label',
94
+ } as const;
95
+
96
+ // shadcn's `*:w-full` widens a field's control because the control is the
97
+ // field's child. A `<ui-select>` host is `display: contents` and its trigger
98
+ // (or, before it upgrades, the native select) sits two levels down, so the
99
+ // same width reaches through the host to it.
100
+ const ORIENTATIONS = {
101
+ vertical: 'cn-field-orientation-vertical flex-col *:w-full [&>.sr-only]:w-auto [&>ui-select_:is(select,[data-slot=select-trigger])]:w-full',
102
+ horizontal: 'cn-field-orientation-horizontal flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
103
+ responsive: 'cn-field-orientation-responsive flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px [&>ui-select_:is(select,[data-slot=select-trigger])]:w-full @md/field-group:[&>ui-select_:is(select,[data-slot=select-trigger])]:w-auto',
104
+ } as const;
105
+
106
+ /** Field set: a native `<fieldset>` holding a legend and a group of fields. */
107
+ export const fieldSetClass = (): string =>
108
+ 'cn-field-set flex flex-col';
109
+
110
+ /**
111
+ * Field legend: the `<legend>` naming a field set. `legend` is section-sized,
112
+ * `label` matches a field label (for a radio or checkbox set). Set
113
+ * `data-variant="<variant>"` on the same element so a following description
114
+ * tightens its spacing.
115
+ */
116
+ export function fieldLegendClass(opts: { variant?: FieldLegendVariant } = {}): string {
117
+ return 'cn-field-legend ' + LEGEND_VARIANTS[opts.variant ?? 'legend'];
118
+ }
119
+
120
+ /** Field group: stacks fields, and is the container `responsive` fields measure. */
121
+ export const fieldGroupClass = (): string =>
122
+ 'cn-field-group group/field-group @container/field-group flex w-full flex-col';
123
+
124
+ /**
125
+ * Field: one label + control + text unit. `vertical` stacks them, `horizontal`
126
+ * puts the control beside the label (checkbox, switch), and `responsive` stacks
127
+ * on a narrow group and goes side by side from the group's `md` width.
128
+ */
129
+ export function fieldClass(opts: { orientation?: FieldOrientation } = {}): string {
130
+ return (
131
+ 'cn-field group/field flex w-full ' +
132
+ ORIENTATIONS[opts.orientation ?? 'vertical']
133
+ );
134
+ }
135
+
136
+ /** Field content: wraps a label and description beside a horizontal control. */
137
+ export const fieldContentClass = (): string =>
138
+ 'cn-field-content group/field-content flex flex-1 flex-col leading-snug';
139
+
140
+ /** Field label: the `<label for>` of the control. Fades when the field is data-disabled. */
141
+ export const fieldLabelClass = (): string =>
142
+ 'cn-label cn-field-label group/field-label peer/field-label flex w-fit items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col';
143
+
144
+ /** Field title: label-styled text that is not a `<label>` (a choice card's heading). */
145
+ export const fieldTitleClass = (): string =>
146
+ 'cn-field-title flex w-fit items-center';
147
+
148
+ /** Field description: the muted helper text under (or beside) the control. */
149
+ export const fieldDescriptionClass = (): string =>
150
+ 'cn-field-description leading-normal font-normal group-has-data-horizontal/field:text-balance last:mt-0 nth-last-2:-mt-1 [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary';
151
+
152
+ /** Field error: the inline validation message. Give it an id the control's aria-describedby lists. */
153
+ export const fieldErrorClass = (): string => 'cn-field-error font-normal';
154
+
155
+ /**
156
+ * Field separator: a horizontal rule between fields, drawn by the element's own
157
+ * `::before`, with optional centred text in a `fieldSeparatorContentClass()`
158
+ * span.
159
+ */
160
+ export const fieldSeparatorClass = (): string =>
161
+ 'cn-field-separator relative before:absolute before:inset-x-0 before:top-1/2 before:h-px before:bg-border';
162
+
163
+ /** Field separator content: the text on the separator line (`or`, a section name). */
164
+ export const fieldSeparatorContentClass = (): string =>
165
+ 'cn-field-separator-content relative mx-auto block w-fit bg-background';
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Floating placement: positions a panel beside the element that opened it.
3
+ * Tier-2 support module. The kit's overlays that measure their own placement
4
+ * (tooltip, hover card, the dropdown, context and menubar menus, select,
5
+ * combobox) import `positionFloating` from here, and so does a hand-built
6
+ * popover that wants measured placement.
7
+ *
8
+ * It is its own module because it reads the window and the elements' boxes,
9
+ * which is browser code. Kept beside the popover's class helpers, it would make
10
+ * every page importing `popoverContentClass` ship to the browser whole, the
11
+ * same reason `cn()` and the DOM helpers are separate modules.
12
+ */
13
+ import type { PopoverSide, PopoverAlign } from './popover.ts';
14
+
15
+ /**
16
+ * Places `content` beside `trigger`, flipping to the opposite side when it
17
+ * does not fit, and keeps it 8px inside the viewport.
18
+ *
19
+ * `radix` names the component the way Radix does (`dropdown-menu`,
20
+ * `tooltip`), and makes this set the variables Radix's positioner sets on the
21
+ * panel, which shadcn's classes read: `--radix-<name>-trigger-width` /
22
+ * `-height`, `--radix-<name>-content-available-width` / `-height` and
23
+ * `--radix-<name>-content-transform-origin`. Without them a class such as
24
+ * `w-(--radix-dropdown-menu-trigger-width)` resolves to nothing, and a fixed
25
+ * panel with no width stretches across the viewport.
26
+ */
27
+ export function positionFloating(
28
+ trigger: HTMLElement,
29
+ content: HTMLElement,
30
+ opts: {
31
+ side?: PopoverSide;
32
+ align?: PopoverAlign;
33
+ sideOffset?: number;
34
+ alignOffset?: number;
35
+ radix?: string;
36
+ } = {},
37
+ ): void {
38
+ const side = opts.side ?? 'bottom';
39
+ const align = opts.align ?? 'center';
40
+ const sideOffset = opts.sideOffset ?? 4;
41
+ const alignOffset = opts.alignOffset ?? 0;
42
+ const tr = trigger.getBoundingClientRect();
43
+ const vars = opts.radix ? `--radix-${opts.radix}` : '';
44
+ // The trigger's size first: a panel sized from it can only be measured
45
+ // once it is set.
46
+ if (vars) {
47
+ content.style.setProperty(`${vars}-trigger-width`, `${tr.width}px`);
48
+ content.style.setProperty(`${vars}-trigger-height`, `${tr.height}px`);
49
+ }
50
+ const cr = content.getBoundingClientRect();
51
+ const vw = window.innerWidth;
52
+ const vh = window.innerHeight;
53
+
54
+ let top = 0;
55
+ let left = 0;
56
+ let actualSide = side;
57
+
58
+ const fitsBottom = tr.bottom + sideOffset + cr.height <= vh;
59
+ const fitsTop = tr.top - sideOffset - cr.height >= 0;
60
+ const fitsRight = tr.right + sideOffset + cr.width <= vw;
61
+ const fitsLeft = tr.left - sideOffset - cr.width >= 0;
62
+
63
+ if (side === 'bottom' && !fitsBottom && fitsTop) actualSide = 'top';
64
+ else if (side === 'top' && !fitsTop && fitsBottom) actualSide = 'bottom';
65
+ else if (side === 'right' && !fitsRight && fitsLeft) actualSide = 'left';
66
+ else if (side === 'left' && !fitsLeft && fitsRight) actualSide = 'right';
67
+
68
+ if (actualSide === 'bottom') top = tr.bottom + sideOffset;
69
+ else if (actualSide === 'top') top = tr.top - sideOffset - cr.height;
70
+ else if (actualSide === 'right' || actualSide === 'left') {
71
+ if (align === 'start') top = tr.top;
72
+ else if (align === 'end') top = tr.bottom - cr.height;
73
+ else top = tr.top + (tr.height - cr.height) / 2;
74
+ }
75
+
76
+ if (actualSide === 'right') left = tr.right + sideOffset;
77
+ else if (actualSide === 'left') left = tr.left - sideOffset - cr.width;
78
+ else {
79
+ if (align === 'start') left = tr.left;
80
+ else if (align === 'end') left = tr.right - cr.width;
81
+ else left = tr.left + (tr.width - cr.width) / 2;
82
+ }
83
+
84
+ // alignOffset shifts the popover along the align axis. For align='start',
85
+ // positive shifts AWAY from the start edge; align='end' reverses; center
86
+ // is a no-op. Axis is perpendicular to the chosen side.
87
+ if (align !== 'center' && alignOffset !== 0) {
88
+ const dir = align === 'start' ? 1 : -1;
89
+ if (actualSide === 'top' || actualSide === 'bottom') {
90
+ left += dir * alignOffset;
91
+ } else {
92
+ top += dir * alignOffset;
93
+ }
94
+ }
95
+
96
+ left = Math.max(8, Math.min(left, vw - cr.width - 8));
97
+ top = Math.max(8, Math.min(top, vh - cr.height - 8));
98
+
99
+ content.style.top = `${top}px`;
100
+ content.style.left = `${left}px`;
101
+ if (vars) {
102
+ // What Radix's size and transform-origin middleware report, with no
103
+ // collision padding and no arrow.
104
+ const availableHeight =
105
+ actualSide === 'bottom' ? vh - tr.bottom - sideOffset
106
+ : actualSide === 'top' ? tr.top - sideOffset
107
+ : vh;
108
+ const availableWidth =
109
+ actualSide === 'right' ? vw - tr.right - sideOffset
110
+ : actualSide === 'left' ? tr.left - sideOffset
111
+ : vw;
112
+ const along = align === 'start' ? '0%' : align === 'end' ? '100%' : '50%';
113
+ const origin =
114
+ actualSide === 'bottom' ? `${along} 0px`
115
+ : actualSide === 'top' ? `${along} 100%`
116
+ : actualSide === 'right' ? `0px ${along}`
117
+ : `100% ${along}`;
118
+ content.style.setProperty(`${vars}-content-available-height`, `${Math.max(0, availableHeight)}px`);
119
+ content.style.setProperty(`${vars}-content-available-width`, `${Math.max(0, availableWidth)}px`);
120
+ content.style.setProperty(`${vars}-content-transform-origin`, origin);
121
+ }
122
+ content.setAttribute('data-side', actualSide);
123
+ content.setAttribute('data-align', align);
124
+ }
@@ -21,8 +21,9 @@
21
21
  * `side-offset`: number, default 4. Pixels between trigger and content.
22
22
  * `align-offset`: number, default 0. Pixels of cross-axis shift.
23
23
  *
24
- * Events: none dispatched at present; observe the reflected `open`
25
- * attribute from CSS or JS.
24
+ * Events:
25
+ * `ui-open-change` on <ui-hover-card>: `{ detail: { open } }` on every open
26
+ * and close, shadcn's `onOpenChange`. The `open` attribute is reflected too.
26
27
  *
27
28
  * Programmatic API on <ui-hover-card>: `.show()` · `.hide()`.
28
29
  *
@@ -70,16 +71,18 @@
70
71
  * ```
71
72
  */
72
73
  import { WebComponent, html, prop } from '@webjsdev/core';
73
- import { ensureId } from '../lib/utils.ts';
74
+ import { cn, ensureId, takeAuthoredClass } from '../lib/utils.ts';
74
75
  import { onBeforeCache } from '../lib/dom.ts';
75
- import { positionFloating, type PopoverSide, type PopoverAlign } from './popover.ts';
76
+ import { positionFloating } from './floating.ts';
77
+ import type { PopoverSide, PopoverAlign } from './popover.ts';
76
78
 
77
79
  // `fixed m-0` opts out of the UA `[popover]` auto-centering margin so
78
80
  // JS-computed top/left from positionFloating lands correctly. shadcn's
79
- // visual layer sits on top. UA `[popover]:not(:popover-open) {
80
- // display: none }` handles closed-state hiding.
81
+ // visual layer sits on top. `not-open:hidden` hides a closed panel, which
82
+ // the UA `[popover]:not(:popover-open)` rule cannot do once any author
83
+ // `display` applies (see popoverContentClass).
81
84
  export const hoverCardContentClass = (): string =>
82
- 'fixed z-50 w-64 m-0 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden';
85
+ 'cn-hover-card-content z-50 origin-(--radix-hover-card-content-transform-origin) outline-hidden not-open:hidden';
83
86
 
84
87
  // --------------------------------------------------------------------------
85
88
  // <ui-hover-card>
@@ -314,6 +317,7 @@ export class UiHoverCard extends WebComponent({
314
317
  // engines with no Popover API: Escape has to work regardless of that.
315
318
  if (this.open) this._bindEscape();
316
319
  else this._unbindEscape();
320
+ this.dispatchEvent(new CustomEvent('ui-open-change', { detail: { open: this.open }, bubbles: true }));
317
321
  // Wait one microtask for <ui-hover-card-content>'s inner [popover]
318
322
  // element to commit; we drive its showPopover() / hidePopover() and
319
323
  // refresh the trigger's aria-expanded.
@@ -352,6 +356,7 @@ export class UiHoverCard extends WebComponent({
352
356
  align: (contentHost.getAttribute('align') ?? 'center') as PopoverAlign,
353
357
  sideOffset: Number(contentHost.getAttribute('side-offset') ?? 4),
354
358
  alignOffset: Number(contentHost.getAttribute('align-offset') ?? 0),
359
+ radix: this.localName.slice(3),
355
360
  });
356
361
  }
357
362
  }
@@ -419,12 +424,18 @@ UiHoverCardTrigger.register('ui-hover-card-trigger');
419
424
  // --------------------------------------------------------------------------
420
425
 
421
426
  export class UiHoverCardContent extends WebComponent {
427
+ _authored: string | null = null;
428
+
429
+ // shadcn's className on HoverCardContent lands on the card panel (a `w-80`,
430
+ // say), so the class written on this host moves there, read once at first
431
+ // render.
422
432
  render() {
433
+ this._authored = takeAuthoredClass(this, null);
423
434
  return html`<div
424
435
  data-slot="hover-card-content"
425
436
  role="dialog"
426
437
  popover="manual"
427
- class=${hoverCardContentClass()}
438
+ class=${cn(hoverCardContentClass(), this._authored)}
428
439
  @mouseenter=${this._onEnter}
429
440
  @mouseleave=${this._onLeave}
430
441
  @focusin=${this._onEnter}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Input group: an input or textarea with addons inside its border (an icon, a
3
+ * prefix such as "https://", a button, a counter), sharing one focus ring.
4
+ * Tier-1 class helper; compose with a real `<input>` or `<textarea>`.
5
+ *
6
+ * shadcn parity:
7
+ * InputGroup → inputGroupClass()
8
+ * InputGroupAddon (align: inline-start | inline-end | block-start | block-end)
9
+ * → inputGroupAddonClass({ align }), alias inputGroupAddonVariants,
10
+ * plus the same `data-align` on the addon (the styles pad the
11
+ * control beside it by it)
12
+ * InputGroupButton (size) → inputGroupButtonClass({ size }) with buttonClass({ variant })
13
+ * InputGroupText → inputGroupTextClass()
14
+ * InputGroupInput / InputGroupTextarea
15
+ * → inputGroupInputClass() / inputGroupTextareaClass()
16
+ *
17
+ * The group draws the border and the focus ring, so the control inside drops
18
+ * its own. Clicking an addon focuses the control through a `<label for>`, with
19
+ * no script: make the addon a `<label>` pointing at the control's id.
20
+ *
21
+ * A11y (required for accessible output): the control still needs its own
22
+ * accessible name, from a visible `<label for>` outside the group or an
23
+ * `aria-label` on the control; an addon's text is not its name. A decorative
24
+ * icon addon takes `aria-hidden="true"`. An addon button is a real
25
+ * `<button type="button">` with its own name.
26
+ *
27
+ * Design tokens used: --input, --ring, --muted-foreground, --destructive.
28
+ *
29
+ * @example
30
+ * ```html
31
+ * <div class=${inputGroupClass()} data-slot="input-group" role="group">
32
+ * <label class=${inputGroupAddonClass()} data-slot="input-group-addon" data-align="inline-start" for="site">https://</label>
33
+ * <input class=${inputGroupInputClass()} data-slot="input-group-control" id="site" name="site" aria-label="Website">
34
+ * </div>
35
+ * ```
36
+ */
37
+ import { cn } from '../lib/utils.ts';
38
+ import { inputClass } from './input.ts';
39
+ import { textareaClass } from './textarea.ts';
40
+ import { buttonClass, type ButtonVariant } from './button.ts';
41
+
42
+ /** Set `data-slot="input-group"` on the element. */
43
+ export function inputGroupClass(): string {
44
+ return 'group/input-group cn-input-group relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto';
45
+ }
46
+
47
+ const INPUT_GROUP_ADDON_BASE =
48
+ 'cn-input-group-addon flex cursor-text items-center justify-center select-none';
49
+
50
+ const INPUT_GROUP_ADDON_ALIGNS = {
51
+ 'inline-start': 'cn-input-group-addon-align-inline-start order-first',
52
+ 'inline-end': 'cn-input-group-addon-align-inline-end order-last',
53
+ 'block-start': 'cn-input-group-addon-align-block-start order-first w-full justify-start',
54
+ 'block-end': 'cn-input-group-addon-align-block-end order-last w-full justify-start',
55
+ } as const;
56
+
57
+ /** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
58
+ export function inputGroupAddonClass(opts: { align?: keyof typeof INPUT_GROUP_ADDON_ALIGNS } = {}): string {
59
+ return cn(INPUT_GROUP_ADDON_BASE, INPUT_GROUP_ADDON_ALIGNS[opts.align ?? 'inline-start']);
60
+ }
61
+
62
+ /**
63
+ * shadcn's name for {@link inputGroupAddonClass}, so shadcn code ports verbatim. Like cva,
64
+ * it merges a `className` into the result.
65
+ */
66
+ export function inputGroupAddonVariants(opts: { align?: keyof typeof INPUT_GROUP_ADDON_ALIGNS } & { className?: string } = {}): string {
67
+ return cn(inputGroupAddonClass(opts), opts.className);
68
+ }
69
+
70
+ const INPUT_GROUP_BUTTON_BASE =
71
+ 'cn-input-group-button flex items-center shadow-none';
72
+
73
+ const INPUT_GROUP_BUTTON_SIZES = {
74
+ xs: 'cn-input-group-button-size-xs',
75
+ sm: 'cn-input-group-button-size-sm',
76
+ 'icon-xs': 'cn-input-group-button-size-icon-xs',
77
+ 'icon-sm': 'cn-input-group-button-size-icon-sm',
78
+ } as const;
79
+
80
+ /**
81
+ * The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match.
82
+ *
83
+ * shadcn's InputGroupButton IS its Button (`variant` defaulting to ghost)
84
+ * with these classes on top, so the button's own classes come first and the
85
+ * group's size wins a conflict.
86
+ */
87
+ export function inputGroupButtonClass(opts: { size?: keyof typeof INPUT_GROUP_BUTTON_SIZES; variant?: ButtonVariant } = {}): string {
88
+ return cn(buttonClass({ variant: opts.variant ?? 'ghost' }), INPUT_GROUP_BUTTON_BASE, INPUT_GROUP_BUTTON_SIZES[opts.size ?? 'xs']);
89
+ }
90
+
91
+ /**
92
+ * shadcn's name for {@link inputGroupButtonClass}, so shadcn code ports verbatim. Like cva,
93
+ * it merges a `className` into the result.
94
+ */
95
+ export function inputGroupButtonVariants(opts: { size?: keyof typeof INPUT_GROUP_BUTTON_SIZES; variant?: ButtonVariant } & { className?: string } = {}): string {
96
+ return cn(inputGroupButtonClass(opts), opts.className);
97
+ }
98
+
99
+ /** A part with no `data-slot` of its own. */
100
+ export function inputGroupTextClass(): string {
101
+ return 'cn-input-group-text flex items-center [&_svg]:pointer-events-none';
102
+ }
103
+
104
+ /**
105
+ * Set `data-slot="input-group-control"` on the element. shadcn's
106
+ * InputGroupInput is its Input with these classes on top, so the input's own
107
+ * base (its `outline-none` and focus treatment included) comes first and the
108
+ * group's resets win a conflict. Without it a focused control shows the
109
+ * browser's own outline inside the group's ring.
110
+ */
111
+ export function inputGroupInputClass(): string {
112
+ return cn(inputClass(), 'cn-input-group-input flex-1');
113
+ }
114
+
115
+ /** Set `data-slot="input-group-control"` on the element. The Textarea's classes, then the group's, as shadcn composes it. */
116
+ export function inputGroupTextareaClass(): string {
117
+ return cn(textareaClass(), 'cn-input-group-textarea flex-1 resize-none');
118
+ }