@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
@@ -5,8 +5,21 @@
5
5
  * thumb (positioned via the `peer-checked:` variant).
6
6
  *
7
7
  * shadcn parity:
8
- * Switch (size: default | sm) → switchInputClass() on a hidden <input> +
9
- * switchTrackClass({ size }) on a sibling <span>
8
+ * Switch (size: default | sm) → <ui-switch size checked name value disabled
9
+ * required aria-label input-id>, which renders
10
+ * shadcn's switch (a `data-slot="switch"` root
11
+ * and a `switch-thumb`) around a real checkbox,
12
+ * so every shadcn style draws it
13
+ * → or, as plain markup, switchInputClass() on a
14
+ * hidden <input> + switchTrackClass({ size }) on
15
+ * a sibling <span> (the default style only)
16
+ *
17
+ * <ui-switch> renders on the server too: its checkbox is a real form control
18
+ * laid transparent over the track, so it submits, takes a <label>, and toggles
19
+ * with JavaScript off. `data-state` follows it, and the data-checked variant
20
+ * also reads the native state (a switch root whose own checkbox is checked, a
21
+ * thumb after a checked checkbox), so the look follows the control without
22
+ * script too. `ui-checked-change` reports a change ({ detail: { checked } }).
10
23
  *
11
24
  * Design tokens used: --primary, --input, --background, --foreground, --ring,
12
25
  * --primary-foreground.
@@ -29,6 +42,14 @@
29
42
  *
30
43
  * @example
31
44
  * ```html
45
+ * <ui-switch name="airplane" aria-label="Airplane mode" checked></ui-switch>
46
+ *
47
+ * <!-- With a visible label, which names the switch. -->
48
+ * <label class="inline-flex items-center gap-2">
49
+ * <ui-switch name="notify"></ui-switch> Notifications
50
+ * </label>
51
+ *
52
+ * <!-- The helpers, for a plain-markup switch. -->
32
53
  * <label class="inline-flex items-center gap-2">
33
54
  * <input type="checkbox" role="switch" name="notify" class=${switchInputClass()}>
34
55
  * <span class=${switchTrackClass()}></span>
@@ -46,27 +67,27 @@
46
67
  * <span class=${switchTrackClass({ size: 'sm' })}></span>
47
68
  * ```
48
69
  */
70
+ import { WebComponent, html, prop, nothing } from '@webjsdev/core';
49
71
  import { cn } from '../lib/utils.ts';
50
72
 
51
73
  /** Hidden native checkbox: handles form value + keyboard activation. */
52
74
  export const switchInputClass = (): string => 'peer sr-only';
53
75
 
54
76
  const TRACK_BASE =
55
- 'inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent shadow-xs transition-all outline-none peer-focus-visible:border-ring peer-focus-visible:ring-[3px] peer-focus-visible:ring-ring/50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50 bg-input dark:bg-input/80 peer-checked:bg-primary relative';
77
+ 'cn-switch peer group/switch inline-flex items-center transition-all outline-none relative';
56
78
 
57
79
  const TRACK_SIZES = {
58
- default: 'h-[1.15rem] w-8',
59
- sm: 'h-3.5 w-6',
80
+ default: 'cn-switch-size-default',
81
+ sm: 'cn-switch-size-sm',
60
82
  } as const;
61
83
 
62
84
  const THUMB_SIZES = {
63
- default:
64
- "after:size-4 after:translate-x-px peer-checked:after:translate-x-[calc(100%-2px)]",
65
- sm: "after:size-3 after:translate-x-px peer-checked:after:translate-x-[calc(100%-1px)]",
85
+ default: 'cn-switch-thumb-size-default',
86
+ sm: 'cn-switch-thumb-size-sm',
66
87
  } as const;
67
88
 
68
89
  const THUMB_BASE =
69
- 'after:pointer-events-none after:absolute after:left-0 after:rounded-full after:bg-background after:transition-transform peer-checked:after:bg-primary-foreground dark:after:bg-foreground';
90
+ 'cn-switch-thumb';
70
91
 
71
92
  export type SwitchSize = keyof typeof TRACK_SIZES;
72
93
 
@@ -74,3 +95,90 @@ export function switchTrackClass(opts: { size?: SwitchSize } = {}): string {
74
95
  const size = opts.size ?? 'default';
75
96
  return cn(TRACK_BASE, TRACK_SIZES[size], THUMB_BASE, THUMB_SIZES[size]);
76
97
  }
98
+
99
+ // --------------------------------------------------------------------------
100
+ // <ui-switch>
101
+ // --------------------------------------------------------------------------
102
+
103
+ /**
104
+ * shadcn's Switch: a root and a thumb around a real checkbox. The authored
105
+ * attributes that belong to the control (`name`, `value`, `checked`,
106
+ * `disabled`, `required`, `aria-label`, `aria-labelledby`,
107
+ * `aria-describedby`, `aria-invalid`, and `input-id` for a `<label for>`) are
108
+ * passed to it. `aria-invalid` also lands on the root, where every style draws
109
+ * the error ring (shadcn's root is the control itself).
110
+ */
111
+ export class UiSwitch extends WebComponent({
112
+ size: prop<SwitchSize>(String, { reflect: true }),
113
+ checked: prop(Boolean),
114
+ disabled: prop(Boolean),
115
+ required: prop(Boolean),
116
+ name: prop(String),
117
+ value: prop(String),
118
+ inputId: prop(String, { attribute: 'input-id' }),
119
+ // Observed so a re-validation that sets or clears it re-renders the switch.
120
+ invalid: prop(String, { attribute: 'aria-invalid' }),
121
+ }) {
122
+ constructor() {
123
+ super();
124
+ this.size = 'default';
125
+ this.checked = false;
126
+ this.disabled = false;
127
+ this.required = false;
128
+ this.name = '';
129
+ this.value = '';
130
+ this.inputId = '';
131
+ this.invalid = '';
132
+ }
133
+
134
+ _attr(name: string): string | null {
135
+ return typeof this.getAttribute === 'function' ? this.getAttribute(name) : null;
136
+ }
137
+
138
+ _onChange = (e: Event): void => {
139
+ const input = e.target as HTMLInputElement;
140
+ this.checked = input.checked;
141
+ this.dispatchEvent(new CustomEvent('ui-checked-change', { detail: { checked: input.checked }, bubbles: true }));
142
+ };
143
+
144
+ // The focus ring sits on the root and keys on the checkbox inside having
145
+ // keyboard focus: in shadcn the focused element IS the root (a Radix
146
+ // button), here it is the real checkbox the root contains.
147
+ // The root is the box, as shadcn's root (a Radix button) is: a flex item
148
+ // its row centres. A block host around it added a line box of its own and
149
+ // sat the switch a few pixels high, so the host is display: contents,
150
+ // through its style, which the server serves.
151
+ render() {
152
+ if (typeof this.getAttribute === 'function' && !this.getAttribute('style')) this.setAttribute('style', 'display: contents');
153
+ const size = this.size === 'sm' ? 'sm' : 'default';
154
+ const state = this.checked ? 'checked' : 'unchecked';
155
+ return html`<span
156
+ data-slot="switch"
157
+ data-size=${size}
158
+ data-state=${state}
159
+ aria-invalid=${this.invalid === 'true' ? 'true' : nothing}
160
+ ?data-disabled=${this.disabled}
161
+ class=${cn('cn-switch peer group/switch relative inline-flex items-center transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 data-disabled:cursor-not-allowed data-disabled:opacity-50 has-[>input:focus-visible]:ring-[3px] has-[>input:focus-visible]:ring-ring/50', TRACK_SIZES[size])}
162
+ ><input
163
+ type="checkbox"
164
+ role="switch"
165
+ id=${this.inputId || nothing}
166
+ name=${this.name || nothing}
167
+ value=${this.value || nothing}
168
+ ?checked=${this.checked}
169
+ ?disabled=${this.disabled}
170
+ ?required=${this.required}
171
+ aria-label=${this._attr('aria-label') ?? nothing}
172
+ aria-labelledby=${this._attr('aria-labelledby') ?? nothing}
173
+ aria-describedby=${this._attr('aria-describedby') ?? nothing}
174
+ aria-invalid=${this.invalid === 'true' ? 'true' : nothing}
175
+ class="peer absolute inset-0 z-10 m-0 size-full cursor-pointer appearance-none opacity-0 disabled:cursor-not-allowed"
176
+ @change=${this._onChange}
177
+ ><span
178
+ data-slot="switch-thumb"
179
+ data-state=${state}
180
+ class=${cn('cn-switch-thumb cn-switch-knob pointer-events-none block ring-0 transition-transform', THUMB_SIZES[size])}
181
+ ></span></span>`;
182
+ }
183
+ }
184
+ UiSwitch.register('ui-switch');
@@ -42,24 +42,26 @@
42
42
  * ```
43
43
  */
44
44
 
45
- export const tableContainerClass = (): string => 'relative w-full overflow-x-auto';
45
+ export const tableContainerClass = (): string => 'cn-table-container';
46
46
 
47
- export const tableClass = (): string => 'w-full caption-bottom text-sm';
47
+ export const tableClass = (): string => 'cn-table';
48
48
 
49
- export const tableHeaderClass = (): string => '[&_tr]:border-b';
49
+ export const tableHeaderClass = (): string => 'cn-table-header';
50
50
 
51
- export const tableBodyClass = (): string => '[&_tr:last-child]:border-0';
51
+ export const tableBodyClass = (): string => 'cn-table-body';
52
52
 
53
53
  export const tableFooterClass = (): string =>
54
- 'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0';
54
+ 'cn-table-footer';
55
55
 
56
56
  export const tableRowClass = (): string =>
57
- 'border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted';
57
+ 'cn-table-row has-aria-expanded:bg-muted/50';
58
58
 
59
+ // The ported styles write a physical text-left; the logical one here keeps an
60
+ // RTL table's headings at its start, as shadcn's RTL install does.
59
61
  export const tableHeadClass = (): string =>
60
- 'h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]';
62
+ 'cn-table-head text-start';
61
63
 
62
64
  export const tableCellClass = (): string =>
63
- 'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]';
65
+ 'cn-table-cell';
64
66
 
65
- export const tableCaptionClass = (): string => 'mt-4 text-sm text-muted-foreground';
67
+ export const tableCaptionClass = (): string => 'cn-table-caption';
@@ -8,7 +8,7 @@
8
8
  * shadcn parity:
9
9
  * Tabs → <ui-tabs value orientation>
10
10
  * TabsList → <ui-tabs-list variant>
11
- * TabsTrigger → <ui-tabs-trigger value>
11
+ * TabsTrigger → <ui-tabs-trigger value disabled>
12
12
  * TabsContent → <ui-tabs-content value>
13
13
  *
14
14
  * Attributes on <ui-tabs>:
@@ -16,11 +16,18 @@
16
16
  * `orientation`: "horizontal" (default) | "vertical".
17
17
  *
18
18
  * Attributes on <ui-tabs-list>:
19
- * `variant`: "default" (default, pill-on-muted) | "underline".
19
+ * `variant`: "default" (default, pill-on-muted) | "line" (shadcn's name;
20
+ * "underline", the kit's earlier name, is an alias). The list is served
21
+ * `data-variant="line"` for either, which is what every style keys on.
20
22
  *
21
23
  * Attributes on <ui-tabs-trigger> / <ui-tabs-content>:
22
24
  * `value`: string. Identifier this trigger / panel pair shares.
23
25
  *
26
+ * Attributes on <ui-tabs-trigger>:
27
+ * `disabled`: boolean (reflected). The rendered `<button>` is disabled, so it
28
+ * takes the `disabled:` styles and `data-disabled`, a click never selects its
29
+ * tab, and Arrow / Home / End skip it.
30
+ *
24
31
  * Events:
25
32
  * `ui-value-change` on <ui-tabs>: `{ detail: { value } }` after a change.
26
33
  *
@@ -28,6 +35,7 @@
28
35
  * ArrowRight / ArrowLeft next / previous (horizontal)
29
36
  * ArrowDown / ArrowUp next / previous (vertical)
30
37
  * Home / End first / last
38
+ * (a `disabled` trigger is skipped by all four)
31
39
  * Enter / Space activate (native button activation)
32
40
  *
33
41
  * A11y (owned by the element, nothing to supply beyond trigger names):
@@ -65,7 +73,7 @@
65
73
  * ```
66
74
  */
67
75
  import { WebComponent, html, prop } from '@webjsdev/core';
68
- import { cn, ensureId } from '../lib/utils.ts';
76
+ import { cn, ensureId, takeAuthoredClass } from '../lib/utils.ts';
69
77
 
70
78
  // A tab `value` becomes part of an id, so reduce it to id-safe characters.
71
79
  const idSafe = (s: string): string => s.replace(/[^A-Za-z0-9_-]/g, '-');
@@ -74,39 +82,66 @@ const idSafe = (s: string): string => s.replace(/[^A-Za-z0-9_-]/g, '-');
74
82
  // Class helpers
75
83
  // --------------------------------------------------------------------------
76
84
 
77
- const TABS_BASE = 'group/tabs flex gap-2 data-[orientation=horizontal]:flex-col';
85
+ const TABS_BASE = 'cn-tabs group/tabs flex';
78
86
 
79
87
  const TABS_LIST_BASE =
80
- 'group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=underline]:rounded-none';
88
+ 'cn-tabs-list group/tabs-list inline-flex w-fit items-center justify-center text-muted-foreground';
81
89
 
82
90
  const TABS_LIST_VARIANTS = {
83
- default: 'bg-muted',
84
- underline: 'gap-1 bg-transparent',
91
+ default: 'cn-tabs-list-variant-default bg-muted',
92
+ line: 'cn-tabs-list-variant-line gap-1 bg-transparent',
85
93
  } as const;
86
94
 
87
- export type TabsListVariant = keyof typeof TABS_LIST_VARIANTS;
95
+ /** The list's look: `line` is shadcn's name, and `underline` an alias for it. */
96
+ export type TabsListVariant = keyof typeof TABS_LIST_VARIANTS | 'underline';
97
+
98
+ /** The variant every style keys on, with `underline` read as `line`. */
99
+ export function tabsListVariant(variant: TabsListVariant | string | null | undefined): keyof typeof TABS_LIST_VARIANTS {
100
+ return variant === 'line' || variant === 'underline' ? 'line' : 'default';
101
+ }
88
102
 
89
103
  /** Optional helper exposing the tabs-list class for advanced overrides. */
90
104
  export function tabsListClass(opts: { variant?: TabsListVariant } = {}): string {
91
- const variant = opts.variant ?? 'default';
92
- return cn(TABS_LIST_BASE, TABS_LIST_VARIANTS[variant]);
105
+ return cn(TABS_LIST_BASE, TABS_LIST_VARIANTS[tabsListVariant(opts.variant)]);
106
+ }
107
+
108
+ /**
109
+ * shadcn's name for {@link tabsListClass}, so shadcn code ports verbatim
110
+ * (`tabsListVariants({ ... })` is shadcn's `cva` export for `TabsList`). Like cva, it
111
+ * merges a `className` into the result.
112
+ */
113
+ export function tabsListVariants(opts: { variant?: TabsListVariant } & { className?: string } = {}): string {
114
+ return cn(tabsListClass(opts), opts.className);
93
115
  }
94
116
 
95
117
  // The trigger is rendered as a native <button role="tab">, which gives
96
118
  // us cursor-pointer + Enter/Space activation + focus for free. The class
97
119
  // here is essentially shadcn's tabs.tsx trigger output.
98
120
  const TABS_TRIGGER_CLASS = [
99
- "relative inline-flex h-[calc(100%-1px)] flex-1 cursor-pointer select-none items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=underline]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
100
- // These mirror shadcn's tabs.tsx (modulo variant=line → variant=underline).
121
+ 'cn-tabs-trigger relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap text-foreground/60 transition-all hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0',
122
+ // These mirror shadcn's tabs.tsx.
101
123
  // Light-mode active state uses bg-background + shadow only; dark mode
102
124
  // additionally borders. Adding light-mode border made the underline
103
125
  // variant look like outline and made default look like two buttons.
104
- 'group-data-[variant=underline]/tabs-list:bg-transparent group-data-[variant=underline]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=underline]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=underline]/tabs-list:data-[state=active]:bg-transparent',
105
- 'data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground',
106
- 'after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=underline]/tabs-list:data-[state=active]:after:opacity-100',
126
+ // shadcn keeps all three inline in every style; the part names carry the
127
+ // new-york spelling of the same rules.
128
+ 'cn-tabs-trigger-part-2 group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent',
129
+ 'cn-tabs-trigger-part-3 data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground',
130
+ 'cn-tabs-trigger-part-4 after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-end-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100',
107
131
  ].join(' ');
108
132
 
109
- const TABS_CONTENT_CLASS = 'flex-1 outline-none';
133
+ const TABS_CONTENT_CLASS = 'cn-tabs-content flex-1 outline-none';
134
+
135
+ /**
136
+ * The class an author wrote on a tabs part, as shadcn's `className`: it
137
+ * belongs on the element the part RENDERS (the tablist, the tab button, the
138
+ * panel), which is what shadcn's styles and an author's utilities target. It
139
+ * is read once from the host, before the part re-renders, and the host then
140
+ * carries `hostClass` instead (or nothing).
141
+ */
142
+ function takeAuthored(part: HTMLElement, hostClass: string | null): string | null {
143
+ return takeAuthoredClass(part, hostClass);
144
+ }
110
145
 
111
146
  // --------------------------------------------------------------------------
112
147
  // <ui-tabs> owns active `value` + `orientation`. Children read its state
@@ -149,11 +184,13 @@ export class UiTabs extends WebComponent({
149
184
  return { trigger: `${this.scopeId}-trigger-${v}`, panel: `${this.scopeId}-panel-${v}` };
150
185
  }
151
186
 
187
+
152
188
  render() {
189
+ const authored = takeAuthored(this, null);
153
190
  return html`<div
154
191
  data-slot="tabs"
155
192
  data-orientation=${this.orientation}
156
- class=${TABS_BASE}
193
+ class=${cn(TABS_BASE, authored)}
157
194
  ><slot></slot></div>`;
158
195
  }
159
196
 
@@ -196,14 +233,16 @@ export class UiTabsList extends WebComponent({
196
233
  return this.closest('ui-tabs') as UiTabs | null;
197
234
  }
198
235
 
236
+
199
237
  render() {
238
+ const authored = takeAuthored(this, 'contents');
200
239
  const orientation = this._tabs?.orientation ?? 'horizontal';
201
240
  return html`<div
202
241
  data-slot="tabs-list"
203
242
  role="tablist"
204
243
  aria-orientation=${orientation}
205
- data-variant=${this.variant}
206
- class=${tabsListClass({ variant: this.variant })}
244
+ data-variant=${tabsListVariant(this.variant)}
245
+ class=${cn(tabsListClass({ variant: this.variant }), authored)}
207
246
  ><slot></slot></div>`;
208
247
  }
209
248
  }
@@ -215,10 +254,12 @@ UiTabsList.register('ui-tabs-list');
215
254
 
216
255
  export class UiTabsTrigger extends WebComponent({
217
256
  value: prop(String, { reflect: true }),
257
+ disabled: prop(Boolean, { reflect: true }),
218
258
  }) {
219
259
  constructor() {
220
260
  super();
221
261
  this.value = '';
262
+ this.disabled = false;
222
263
  }
223
264
 
224
265
  // render() runs server-side too. webjs resolves closest() at SSR against
@@ -229,7 +270,9 @@ export class UiTabsTrigger extends WebComponent({
229
270
  return this.closest('ui-tabs') as UiTabs | null;
230
271
  }
231
272
 
273
+
232
274
  render() {
275
+ const authored = takeAuthored(this, 'contents');
233
276
  const tabs = this._tabs;
234
277
  const active = !!tabs && tabs.value === this.value && this.value !== '';
235
278
  const ids = tabs && this.value ? tabs.idsFor(this.value) : null;
@@ -242,14 +285,16 @@ export class UiTabsTrigger extends WebComponent({
242
285
  data-state=${active ? 'active' : 'inactive'}
243
286
  aria-selected=${String(active)}
244
287
  tabindex=${active ? '0' : '-1'}
245
- class=${TABS_TRIGGER_CLASS}
288
+ ?disabled=${this.disabled}
289
+ ?data-disabled=${this.disabled}
290
+ class=${cn(TABS_TRIGGER_CLASS, authored)}
246
291
  @click=${this._onClick}
247
292
  @keydown=${this._onKeyDown}
248
293
  ><slot></slot></button>`;
249
294
  }
250
295
 
251
296
  _onClick = (): void => {
252
- if (this.value) this._tabs?.setAttribute('value', this.value);
297
+ if (this.value && !this.disabled) this._tabs?.setAttribute('value', this.value);
253
298
  };
254
299
 
255
300
  _onKeyDown = (e: KeyboardEvent): void => {
@@ -260,8 +305,10 @@ export class UiTabsTrigger extends WebComponent({
260
305
  // a nested <ui-tabs> inside a panel, and arrow nav at the boundary would
261
306
  // jump into the inner group and set this group's value to an inner-only
262
307
  // value (hiding every panel). Same scoping dropdown-menu applies to items.
308
+ // A disabled trigger is skipped by every key, as Radix's roving focus
309
+ // skips an item that is not focusable.
263
310
  const triggers = Array.from(tabs.querySelectorAll<UiTabsTrigger>('ui-tabs-trigger')).filter(
264
- (t) => t._tabs === tabs,
311
+ (t) => t._tabs === tabs && (!t.disabled || t === this),
265
312
  );
266
313
  const idx = triggers.indexOf(this);
267
314
  const nextKey = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';
@@ -270,8 +317,8 @@ export class UiTabsTrigger extends WebComponent({
270
317
  let target: UiTabsTrigger | null = null;
271
318
  if (e.key === nextKey) target = triggers[(idx + 1) % triggers.length] ?? null;
272
319
  else if (e.key === prevKey) target = triggers[(idx - 1 + triggers.length) % triggers.length] ?? null;
273
- else if (e.key === 'Home') target = triggers[0] ?? null;
274
- else if (e.key === 'End') target = triggers[triggers.length - 1] ?? null;
320
+ else if (e.key === 'Home') target = triggers.find((t) => !t.disabled) ?? null;
321
+ else if (e.key === 'End') target = [...triggers].reverse().find((t) => !t.disabled) ?? null;
275
322
  // Enter/Space already handled natively by <button>; no preventDefault needed.
276
323
 
277
324
  if (target) {
@@ -307,7 +354,11 @@ export class UiTabsContent extends WebComponent({
307
354
  return this.closest('ui-tabs') as UiTabs | null;
308
355
  }
309
356
 
357
+
310
358
  render() {
359
+ // The panel's host keeps no class of its own (it toggles `hidden`, which a
360
+ // `display` utility would override), so the authored class moves whole.
361
+ const authored = takeAuthored(this, null);
311
362
  const tabs = this._tabs;
312
363
  const active = !!tabs && tabs.value === this.value && this.value !== '';
313
364
  const ids = tabs && this.value ? tabs.idsFor(this.value) : null;
@@ -326,7 +377,7 @@ export class UiTabsContent extends WebComponent({
326
377
  aria-labelledby=${ids ? ids.trigger : ''}
327
378
  tabindex="0"
328
379
  data-state=${active ? 'active' : 'inactive'}
329
- class=${TABS_CONTENT_CLASS}
380
+ class=${cn(TABS_CONTENT_CLASS, authored)}
330
381
  ><slot></slot></section>`;
331
382
  }
332
383
  }
@@ -40,7 +40,7 @@
40
40
  import { cn } from '../lib/utils.ts';
41
41
 
42
42
  const TEXTAREA_BASE =
43
- 'flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:ring-destructive/40';
43
+ 'cn-textarea flex field-sizing-content min-h-16 w-full outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50';
44
44
 
45
45
  /** Compose Tailwind classes for a native `<textarea>`. */
46
46
  export function textareaClass(): string {
@@ -18,7 +18,11 @@
18
18
  * multiple: comma-separated values.
19
19
  * `variant`: "default" (default) | "outline".
20
20
  * `size`: "default" (default) | "sm" | "lg".
21
- * `spacing`: "0" (default, joined corners) | "default" (gapped).
21
+ * `spacing`: shadcn's number: "0" joins the items' corners, and N gaps
22
+ * them by N spacing units. Left out, the style decides:
23
+ * shadcn's styles gap by 2, as shadcn's default does, and
24
+ * new-york joins them. "default" is the kit's earlier name
25
+ * for a gap, read as 1.
22
26
  * `orientation`: "horizontal" (default) | "vertical".
23
27
  *
24
28
  * Attributes on <ui-toggle-group-item>:
@@ -72,20 +76,33 @@
72
76
  * </ui-toggle-group>
73
77
  * ```
74
78
  */
75
- import { WebComponent, html, prop } from '@webjsdev/core';
79
+ import { WebComponent, html, prop, nothing } from '@webjsdev/core';
76
80
  import { cn } from '../lib/utils.ts';
77
81
  import { toggleClass, type ToggleVariant, type ToggleSize } from './toggle.ts';
78
82
 
79
83
  const ROOT_BASE =
80
- 'group/toggle-group flex w-fit items-center rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch';
84
+ 'cn-toggle-group group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] data-vertical:flex-col data-vertical:items-stretch';
85
+
86
+ /**
87
+ * The spacing a group renders: the author's number, `default` read as 1, or
88
+ * null when the author set none, which leaves `data-spacing` off so the style
89
+ * decides (a gap of 2 in shadcn's styles, joined items in new-york).
90
+ */
91
+ export function toggleGroupSpacing(raw: string | null | undefined): string | null {
92
+ if (raw === null || raw === undefined || raw === '') return null;
93
+ return raw === 'default' ? '1' : raw;
94
+ }
81
95
 
82
96
  // The `disabled:` variants inside toggleClass() key on the :disabled pseudo,
83
97
  // which only ever matches a real form control. An item's host IS the button
84
98
  // here (a custom element), so `disabled` on it is inert as far as CSS and the
85
99
  // browser are concerned, and the disabled look has to come from the
86
- // aria-disabled variant instead.
100
+ // aria-disabled variant instead. The same goes for the non-text cursor and
101
+ // unselectable label a native button gets from the browser. All of those live
102
+ // on `.cn-toggle-group-item` in each style (styles/supplement.json for the
103
+ // ported ones), so a style that sets its own cursor keeps it.
87
104
  const ITEM_EXTRA =
88
- 'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l';
105
+ 'cn-toggle-group-item shrink-0 focus:z-10 focus-visible:z-10';
89
106
 
90
107
  // --------------------------------------------------------------------------
91
108
  // <ui-toggle-group>
@@ -111,7 +128,7 @@ export class UiToggleGroup extends WebComponent({
111
128
  this.type = 'single';
112
129
  this.variant = 'default';
113
130
  this.size = 'default';
114
- this.spacing = '0';
131
+ this.spacing = '';
115
132
  this.orientation = 'horizontal';
116
133
  }
117
134
 
@@ -121,14 +138,15 @@ export class UiToggleGroup extends WebComponent({
121
138
  }
122
139
 
123
140
  render() {
124
- const gap = this.spacing === '0' ? '' : 'gap-1';
141
+ const spacing = toggleGroupSpacing(this.spacing);
125
142
  return html`<div
126
143
  data-slot="toggle-group"
127
144
  role="group"
128
- class=${cn(ROOT_BASE, gap)}
145
+ class=${ROOT_BASE}
146
+ style=${`--gap: ${spacing ?? 2}`}
129
147
  data-variant=${this.variant}
130
148
  data-size=${this.size}
131
- data-spacing=${this.spacing}
149
+ data-spacing=${spacing ?? nothing}
132
150
  data-orientation=${this.orientation}
133
151
  @ui-toggle-item-click=${this._onItemClick}
134
152
  ><slot></slot></div>`;
@@ -283,10 +301,11 @@ export class UiToggleGroupItem extends WebComponent({
283
301
  const group = this._group;
284
302
  const variant = (group?.variant ?? 'default') as ToggleVariant;
285
303
  const size = (group?.size ?? 'default') as ToggleSize;
286
- const spacing = group?.spacing ?? '0';
304
+ const spacing = toggleGroupSpacing(group?.spacing);
287
305
  this.dataset.variant = variant;
288
306
  this.dataset.size = size;
289
- this.dataset.spacing = spacing;
307
+ if (spacing === null) this.removeAttribute('data-spacing');
308
+ else this.dataset.spacing = spacing;
290
309
  this.dataset.state = this.pressed ? 'on' : 'off';
291
310
  // role and data-slot are set HERE as well as in connectedCallback, because
292
311
  // SSR runs render() but NOT connectedCallback. Without this the served item
@@ -70,25 +70,23 @@
70
70
  import { WebComponent, html, prop } from '@webjsdev/core';
71
71
  import { cn } from '../lib/utils.ts';
72
72
 
73
- // cursor-pointer + select-none on BASE for both call sites: the
74
- // class-helper applied to a native <button> (where shadcn's upstream
75
- // also omits it; see the same convention the button fix applies) and
76
- // the <ui-toggle> custom element. select-none prevents drag-selecting
77
- // icon/label glyphs that aren't meant to be selectable. disabled:
78
- // pointer-events-none below already suppresses cursor for disabled buttons.
73
+ // shadcn's base form, verbatim, so it sets no cursor. On a native <button> the
74
+ // browser supplies one (the default arrow), and new-york adds cursor-pointer
75
+ // plus select-none on `.cn-toggle` as the kit's own convention.
76
+ // <ui-toggle-group-item>, whose host is the button, gets no browser default, so
77
+ // it takes its cursor from `.cn-toggle-group-item` (styles/supplement.json).
79
78
  const BASE =
80
- "inline-flex cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap select-none transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
79
+ 'cn-toggle group/toggle inline-flex items-center justify-center whitespace-nowrap outline-none hover:bg-muted focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0';
81
80
 
82
81
  const VARIANTS = {
83
- default: 'bg-transparent',
84
- outline:
85
- 'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',
82
+ default: 'cn-toggle-variant-default',
83
+ outline: 'cn-toggle-variant-outline',
86
84
  } as const;
87
85
 
88
86
  const SIZES = {
89
- default: 'h-9 min-w-9 px-2',
90
- sm: 'h-8 min-w-8 px-1.5',
91
- lg: 'h-10 min-w-10 px-2.5',
87
+ default: 'cn-toggle-size-default',
88
+ sm: 'cn-toggle-size-sm',
89
+ lg: 'cn-toggle-size-lg',
92
90
  } as const;
93
91
 
94
92
  export type ToggleVariant = keyof typeof VARIANTS;
@@ -98,6 +96,15 @@ export function toggleClass(opts: { variant?: ToggleVariant; size?: ToggleSize }
98
96
  return cn(BASE, VARIANTS[opts.variant ?? 'default'], SIZES[opts.size ?? 'default']);
99
97
  }
100
98
 
99
+ /**
100
+ * shadcn's name for {@link toggleClass}, so shadcn code ports verbatim
101
+ * (`toggleVariants({ ... })` is shadcn's `cva` export for `Toggle`). Like cva, it
102
+ * merges a `className` into the result.
103
+ */
104
+ export function toggleVariants(opts: { variant?: ToggleVariant; size?: ToggleSize } & { className?: string } = {}): string {
105
+ return cn(toggleClass(opts), opts.className);
106
+ }
107
+
101
108
  // --------------------------------------------------------------------------
102
109
  // <ui-toggle> wraps a native <button> and tracks pressed state. Native
103
110
  // <button> handles Enter/Space → click + focus + disabled semantics for