@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,365 @@
1
+ /**
2
+ * Input OTP: a one-time code typed into a row of boxes. Tier-2. It ENHANCES
3
+ * one real `<input>` (D13): you author the input, so without JavaScript the
4
+ * page shows an ordinary text field that the form submits, autofills from an
5
+ * SMS (`autocomplete="one-time-code"`) and pastes into. With JavaScript the
6
+ * element lays that same input, transparent, over shadcn's slots and draws
7
+ * each character in its box, so typing, pasting, autofill and the mobile
8
+ * keyboard all still go to the real input.
9
+ *
10
+ * shadcn parity:
11
+ * InputOTP maxLength → <ui-input-otp> around <input maxlength="6" ...>
12
+ * pattern → the input's `pattern` (a keystroke that would
13
+ * make the value stop matching is refused)
14
+ * InputOTPGroup → <ui-input-otp-group>
15
+ * InputOTPSlot index → <ui-input-otp-slot index="0">
16
+ * InputOTPSeparator → <ui-input-otp-separator>
17
+ * onChange → `ui-value-change` ({ detail: { value } }); the input fires `input`
18
+ * onComplete → `ui-complete` ({ detail: { value } }) once every slot is filled
19
+ *
20
+ * A11y (handled by the element, plus your part): the real input is the only
21
+ * thing assistive technology meets, so it keeps its own name, value and
22
+ * focus. The slots, group and separator are drawn decoration, hidden from the
23
+ * accessibility tree. An `aria-invalid` on the input reaches the slots for
24
+ * the error styling. Your part: a `<label for>` (or `aria-label`) on the input,
25
+ * and `inputmode="numeric"` for a numeric code so phones show the number pad.
26
+ *
27
+ * @example
28
+ * ```html
29
+ * <label for="otp" class=${labelClass()}>One-time code</label>
30
+ * <ui-input-otp>
31
+ * <input id="otp" name="otp" class=${inputClass()} maxlength="6" pattern="[0-9]*"
32
+ * inputmode="numeric" autocomplete="one-time-code">
33
+ * <ui-input-otp-group>
34
+ * <ui-input-otp-slot index="0"></ui-input-otp-slot>
35
+ * <ui-input-otp-slot index="1"></ui-input-otp-slot>
36
+ * <ui-input-otp-slot index="2"></ui-input-otp-slot>
37
+ * </ui-input-otp-group>
38
+ * <ui-input-otp-separator></ui-input-otp-separator>
39
+ * <ui-input-otp-group>
40
+ * <ui-input-otp-slot index="3"></ui-input-otp-slot>
41
+ * <ui-input-otp-slot index="4"></ui-input-otp-slot>
42
+ * <ui-input-otp-slot index="5"></ui-input-otp-slot>
43
+ * </ui-input-otp-group>
44
+ * </ui-input-otp>
45
+ * ```
46
+ */
47
+ import { WebComponent, html, signal } from '@webjsdev/core';
48
+ import { takeAuthoredClass } from '../lib/utils.ts';
49
+
50
+ /** The row's classes (the element applies them). */
51
+ export const inputOtpClass = (): string =>
52
+ 'cn-input-otp relative flex items-center has-disabled:opacity-50';
53
+ /** A group's classes (the element applies them). */
54
+ export const inputOtpGroupClass = (): string => 'cn-input-otp-group flex items-center';
55
+ /** A slot's classes (the element applies them, to the slot's own host). */
56
+ export const inputOtpSlotClass = (): string =>
57
+ 'cn-input-otp-slot relative flex items-center justify-center data-[active=true]:z-10';
58
+ /** The fake caret's box. */
59
+ export const inputOtpCaretClass = (): string =>
60
+ 'cn-input-otp-caret pointer-events-none absolute inset-0 flex items-center justify-center';
61
+ /** The fake caret's line. */
62
+ export const inputOtpCaretLineClass = (): string => 'cn-input-otp-caret-line';
63
+ /** The separator's classes (the element applies them). */
64
+ export const inputOtpSeparatorClass = (): string => 'cn-input-otp-separator flex items-center';
65
+
66
+ // The real input, laid transparent over the slots so it takes every click,
67
+ // keystroke, paste and autofill while the slots do the drawing.
68
+ const OVERLAY =
69
+ 'position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;box-shadow:none;background:transparent;color:transparent;-webkit-text-fill-color:transparent;caret-color:transparent;font-size:1px;letter-spacing:-0.5em;z-index:20;';
70
+
71
+ const ROOT = 'ui-input-otp';
72
+
73
+ export class UiInputOtp extends WebComponent {
74
+ readonly #enhanced = signal(false);
75
+ _observer: MutationObserver | null = null;
76
+ _waiting: MutationObserver | null = null;
77
+ _form: HTMLFormElement | null = null;
78
+ _savedStyle: string | null = null;
79
+ _last = '';
80
+ _focused = false;
81
+ _disabled: boolean | null = null;
82
+
83
+ constructor() {
84
+ super();
85
+ }
86
+
87
+ /** The real input this element enhances. */
88
+ get input(): HTMLInputElement | null {
89
+ // The server renders the element with no DOM queries available.
90
+ return typeof this.querySelector === 'function' ? this.querySelector('input') : null;
91
+ }
92
+
93
+ /** The code typed so far. */
94
+ get value(): string {
95
+ return this.input?.value ?? '';
96
+ }
97
+
98
+ /** How many characters the code has: the input's maxlength, else the slots. */
99
+ get maxLength(): number {
100
+ const m = this.input?.maxLength ?? -1;
101
+ return m > 0 ? m : this._slots().length;
102
+ }
103
+
104
+ connectedCallback(): void {
105
+ super.connectedCallback?.();
106
+ queueMicrotask(() => {
107
+ if (this._enhance() || this._waiting) return;
108
+ this._waiting = new MutationObserver(() => {
109
+ if (this._enhance()) { this._waiting?.disconnect(); this._waiting = null; }
110
+ });
111
+ this._waiting.observe(this, { childList: true, subtree: true });
112
+ });
113
+ }
114
+
115
+ disconnectedCallback(): void {
116
+ this._waiting?.disconnect();
117
+ this._observer?.disconnect();
118
+ const input = this.input;
119
+ if (input) {
120
+ input.removeEventListener('input', this._onInput);
121
+ input.removeEventListener('focus', this._onFocus);
122
+ input.removeEventListener('blur', this._onBlur);
123
+ input.removeEventListener('keyup', this._sync);
124
+ input.removeEventListener('click', this._sync);
125
+ input.removeEventListener('select', this._sync);
126
+ if (this._savedStyle !== null) input.setAttribute('style', this._savedStyle);
127
+ else input.removeAttribute('style');
128
+ }
129
+ document.removeEventListener('selectionchange', this._sync);
130
+ this._form?.removeEventListener('reset', this._onReset);
131
+ super.disconnectedCallback?.();
132
+ }
133
+
134
+ /** Take over from the plain input. True once it has (or already had). */
135
+ _enhance(): boolean {
136
+ if (this.#enhanced.get()) return true;
137
+ const input = this.input;
138
+ if (!input) return false;
139
+ this._savedStyle = input.getAttribute('style');
140
+ input.setAttribute('style', (this._savedStyle ?? '') + OVERLAY);
141
+ input.addEventListener('input', this._onInput);
142
+ input.addEventListener('focus', this._onFocus);
143
+ input.addEventListener('blur', this._onBlur);
144
+ input.addEventListener('keyup', this._sync);
145
+ input.addEventListener('click', this._sync);
146
+ input.addEventListener('select', this._sync);
147
+ this._form = input.form;
148
+ this._form?.addEventListener('reset', this._onReset);
149
+ this._observer = new MutationObserver(() => this._sync());
150
+ this._observer.observe(input, { attributes: true });
151
+ this._last = input.value;
152
+ this.#enhanced.set(true);
153
+ this._sync();
154
+ return true;
155
+ }
156
+
157
+ // A part connected after the input (a client render appends children in
158
+ // order) asks to be drawn.
159
+ _partConnected(): void {
160
+ if (this.#enhanced.get()) queueMicrotask(() => this._sync());
161
+ }
162
+
163
+ render() {
164
+ const disabled = !!this.input?.disabled;
165
+ return html`<div data-slot="input-otp" ?data-disabled=${disabled} class=${inputOtpClass()}><slot></slot></div>`;
166
+ }
167
+
168
+ _slots(): UiInputOtpSlot[] {
169
+ return Array.from(this.querySelectorAll<UiInputOtpSlot>(`${ROOT}-slot`));
170
+ }
171
+
172
+ _pattern(): RegExp | null {
173
+ const p = this.input?.getAttribute('pattern');
174
+ if (!p) return null;
175
+ // HTML compiles `pattern` with the v flag; an engine without it gets u.
176
+ for (const flags of ['v', 'u']) {
177
+ try { return new RegExp(`^(?:${p})$`, flags); } catch { /* next */ }
178
+ }
179
+ return null;
180
+ }
181
+
182
+ // Refuse an edit that breaks the pattern or the length, as input-otp does.
183
+ _onInput = (): void => {
184
+ const input = this.input;
185
+ if (!input) return;
186
+ const re = this._pattern();
187
+ const v = input.value;
188
+ if ((re && v && !re.test(v)) || v.length > this.maxLength) {
189
+ const at = Math.max(0, (input.selectionStart ?? this._last.length) - (v.length - this._last.length));
190
+ input.value = this._last;
191
+ input.setSelectionRange(at, at);
192
+ this._sync();
193
+ return;
194
+ }
195
+ if (v !== this._last) {
196
+ this._last = v;
197
+ this.dispatchEvent(new CustomEvent('ui-value-change', { bubbles: true, detail: { value: v } }));
198
+ if (v.length === this.maxLength) {
199
+ this.dispatchEvent(new CustomEvent('ui-complete', { bubbles: true, detail: { value: v } }));
200
+ }
201
+ }
202
+ this._sync();
203
+ };
204
+
205
+ _onFocus = (): void => {
206
+ this._focused = true;
207
+ document.addEventListener('selectionchange', this._sync);
208
+ // Typing continues the code, so the caret starts at its end.
209
+ const input = this.input;
210
+ if (input) {
211
+ queueMicrotask(() => {
212
+ const end = input.value.length;
213
+ input.setSelectionRange(end, end);
214
+ this._sync();
215
+ });
216
+ }
217
+ this._sync();
218
+ };
219
+
220
+ _onBlur = (): void => {
221
+ this._focused = false;
222
+ document.removeEventListener('selectionchange', this._sync);
223
+ this._sync();
224
+ };
225
+
226
+ _onReset = (): void => {
227
+ queueMicrotask(() => { this._last = this.input?.value ?? ''; this._sync(); });
228
+ };
229
+
230
+ // Push the value, the caret and the state into every drawn part. It runs
231
+ // several times per keystroke (input, keyup, each selectionchange), so it
232
+ // hands a part new state only when something it draws changed: every
233
+ // attribute write re-checks the page's :has() rules, and a page carrying
234
+ // the kit's styles has hundreds of them, which made each keystroke wait on
235
+ // style recalculation.
236
+ _sync = (): void => {
237
+ const input = this.input;
238
+ if (!input || !this.#enhanced.get()) return;
239
+ const value = input.value;
240
+ const max = this.maxLength;
241
+ const start = Math.min(input.selectionStart ?? value.length, max - 1);
242
+ const end = input.selectionEnd ?? start;
243
+ const invalid = input.getAttribute('aria-invalid') === 'true';
244
+ this._slots().forEach((slot) => {
245
+ const i = Number(slot.index);
246
+ const char = value[i] ?? '';
247
+ const active = this._focused && (end > start ? i >= start && i < end : i === start);
248
+ const next = { shown: true, char, active, caret: active && !char, invalid };
249
+ // A slot not upgraded yet has no state signal; the next sync reaches it.
250
+ const s = slot.state?.get();
251
+ if (s && (s.shown !== next.shown || s.char !== next.char || s.active !== next.active || s.caret !== next.caret || s.invalid !== next.invalid)) {
252
+ slot.state?.set(next);
253
+ }
254
+ });
255
+ this.querySelectorAll<UiInputOtpGroup | UiInputOtpSeparator>(`${ROOT}-group, ${ROOT}-separator`).forEach((part) => {
256
+ if (!part.shown?.get()) part.shown?.set(true);
257
+ });
258
+ const disabled = !!input.disabled;
259
+ if (disabled !== this._disabled) {
260
+ this._disabled = disabled;
261
+ this.requestUpdate();
262
+ }
263
+ };
264
+ }
265
+ UiInputOtp.register('ui-input-otp');
266
+
267
+ // --------------------------------------------------------------------------
268
+ // <ui-input-otp-group>
269
+ // --------------------------------------------------------------------------
270
+
271
+ export class UiInputOtpGroup extends WebComponent {
272
+ readonly shown = signal(false);
273
+ constructor() {
274
+ super();
275
+ }
276
+
277
+ connectedCallback(): void {
278
+ super.connectedCallback?.();
279
+ (this.closest(ROOT) as UiInputOtp | null)?._partConnected();
280
+ }
281
+
282
+ render() {
283
+ return html`<div data-slot="input-otp-group" ?hidden=${!this.shown.get()} class=${inputOtpGroupClass()}><slot></slot></div>`;
284
+ }
285
+ }
286
+ UiInputOtpGroup.register('ui-input-otp-group');
287
+
288
+ // --------------------------------------------------------------------------
289
+ // <ui-input-otp-slot>
290
+ // --------------------------------------------------------------------------
291
+
292
+ type SlotState = { shown: boolean; char: string; active: boolean; caret: boolean; invalid: boolean };
293
+
294
+ export class UiInputOtpSlot extends WebComponent({
295
+ index: Number,
296
+ }) {
297
+ readonly state = signal<SlotState>({ shown: false, char: '', active: false, caret: false, invalid: false });
298
+ _authored: string | null = null;
299
+
300
+ constructor() {
301
+ super();
302
+ this.index = 0;
303
+ }
304
+
305
+ connectedCallback(): void {
306
+ // The author's own classes, read once: later the host carries ours too.
307
+ this._authored = takeAuthoredClass(this);
308
+ super.connectedCallback?.();
309
+ (this.closest(ROOT) as UiInputOtp | null)?._partConnected();
310
+ }
311
+
312
+ // shadcn's slot classes use first: / last: for the joined corners, which
313
+ // only work on the elements that are siblings in the group: the slot hosts
314
+ // themselves, not a box inside each. So the slot styles its own host.
315
+ // Each write is guarded: an attribute set to the value it already has still
316
+ // invalidates style, and the page re-checks its :has() rules for it.
317
+ updated(changedProperties: Map<string, unknown>): void {
318
+ super.updated?.(changedProperties);
319
+ const s = this.state.get();
320
+ const set = (name: string, value: string | null) => {
321
+ if (this.getAttribute(name) === value) return;
322
+ if (value === null) this.removeAttribute(name);
323
+ else this.setAttribute(name, value);
324
+ };
325
+ set('class', [inputOtpSlotClass(), this._authored].filter(Boolean).join(' '));
326
+ set('data-slot', 'input-otp-slot');
327
+ set('data-active', s.active ? 'true' : 'false');
328
+ set('aria-hidden', 'true');
329
+ set('aria-invalid', s.invalid ? 'true' : null);
330
+ if (this.hidden !== !s.shown) this.hidden = !s.shown;
331
+ }
332
+
333
+ // The caret is always in the slot and only its class changes. Inserting or
334
+ // removing an element makes the browser re-check every :has() rule on the
335
+ // page, which on a page carrying the kit's styles took longer than a frame
336
+ // on each keystroke; a class change on a leaf is nearly free.
337
+ render() {
338
+ const s = this.state.get();
339
+ return html`${s.char}<div class=${s.caret ? inputOtpCaretClass() : 'hidden'}><div class=${inputOtpCaretLineClass()}></div></div>`;
340
+ }
341
+ }
342
+ UiInputOtpSlot.register('ui-input-otp-slot');
343
+
344
+ // --------------------------------------------------------------------------
345
+ // <ui-input-otp-separator>
346
+ // --------------------------------------------------------------------------
347
+
348
+ export class UiInputOtpSeparator extends WebComponent {
349
+ readonly shown = signal(false);
350
+ constructor() {
351
+ super();
352
+ }
353
+
354
+ connectedCallback(): void {
355
+ super.connectedCallback?.();
356
+ (this.closest(ROOT) as UiInputOtp | null)?._partConnected();
357
+ }
358
+
359
+ render() {
360
+ return html`<div data-slot="input-otp-separator" role="separator" aria-hidden="true" ?hidden=${!this.shown.get()} class=${inputOtpSeparatorClass()}><svg
361
+ 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" aria-hidden="true"
362
+ ><path d="M5 12h14"></path></svg></div>`;
363
+ }
364
+ }
365
+ UiInputOtpSeparator.register('ui-input-otp-separator');
@@ -56,13 +56,13 @@
56
56
  import { cn } from '../lib/utils.ts';
57
57
 
58
58
  const INPUT_BASE =
59
- 'h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30';
59
+ 'cn-input w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50';
60
60
 
61
61
  const INPUT_FOCUS =
62
- 'focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50';
62
+ 'cn-input-focus';
63
63
 
64
64
  const INPUT_INVALID =
65
- 'aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40';
65
+ 'cn-input-invalid';
66
66
 
67
67
  /** Compose Tailwind classes for a native `<input>`. */
68
68
  export function inputClass(): string {
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Item: a flexible row for lists of things (a person, a file, a setting), with
3
+ * media, a title and description, and actions. Tier-1 class helper; compose
4
+ * with a plain element, or an `<a>` / `<button>` when the whole row acts.
5
+ *
6
+ * shadcn parity:
7
+ * ItemGroup / ItemSeparator → itemGroupClass() / itemSeparatorClass()
8
+ * Item (variant: default | outline | muted, size: default | sm | xs)
9
+ * → itemClass({ variant, size }), alias itemVariants
10
+ * ItemMedia (variant: default | icon | image)
11
+ * → itemMediaClass({ variant }), alias itemMediaVariants
12
+ * ItemContent / ItemTitle / ItemDescription / ItemActions / ItemHeader / ItemFooter
13
+ * → itemContentClass() ... itemFooterClass()
14
+ *
15
+ * Every part takes its `data-slot` (shown on each helper), which is what the
16
+ * styles use to lay the parts out relative to each other.
17
+ *
18
+ * A11y (required for accessible output): a group of items is a list, so render
19
+ * it as `<ul role="list">` with each item an `<li>`, or keep `role="list"` /
20
+ * `role="listitem"` on divs. A whole-row link is a real `<a>` holding the
21
+ * content, never a click handler on a div. Media that only decorates takes
22
+ * `alt=""` or `aria-hidden="true"`, and an icon-only action needs
23
+ * `aria-label`.
24
+ *
25
+ * Design tokens used: --border, --muted, --muted-foreground, --accent, --ring.
26
+ *
27
+ * @example
28
+ * ```html
29
+ * <div class=${itemClass({ variant: 'outline' })} data-slot="item" data-variant="outline">
30
+ * <div class=${itemContentClass()} data-slot="item-content">
31
+ * <div class=${itemTitleClass()} data-slot="item-title">Two-factor authentication</div>
32
+ * <p class=${itemDescriptionClass()} data-slot="item-description">Verify it is you with a code.</p>
33
+ * </div>
34
+ * <div class=${itemActionsClass()} data-slot="item-actions">
35
+ * <button class=${buttonClass({ variant: 'outline', size: 'sm' })} type="button">Enable</button>
36
+ * </div>
37
+ * </div>
38
+ * ```
39
+ */
40
+ import { cn } from '../lib/utils.ts';
41
+
42
+ /** Set `data-slot="item-group"` on the element. */
43
+ export function itemGroupClass(): string {
44
+ return 'cn-item-group group/item-group flex w-full flex-col';
45
+ }
46
+
47
+ /**
48
+ * Set `data-slot="item-separator"` on the element. shadcn's ItemSeparator is a
49
+ * horizontal Separator, so the line's own size and colour come with it, and
50
+ * the style adds its margin.
51
+ */
52
+ export function itemSeparatorClass(): string {
53
+ return 'cn-item-separator h-px w-full shrink-0 bg-border';
54
+ }
55
+
56
+ const ITEM_BASE =
57
+ 'cn-item group/item flex w-full flex-wrap items-center transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors';
58
+
59
+ const ITEM_VARIANTS = {
60
+ default: 'cn-item-variant-default',
61
+ outline: 'cn-item-variant-outline',
62
+ muted: 'cn-item-variant-muted',
63
+ } as const;
64
+
65
+ const ITEM_SIZES = {
66
+ default: 'cn-item-size-default',
67
+ sm: 'cn-item-size-sm',
68
+ xs: 'cn-item-size-xs',
69
+ } as const;
70
+
71
+ /** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
72
+ export function itemClass(opts: { variant?: keyof typeof ITEM_VARIANTS; size?: keyof typeof ITEM_SIZES } = {}): string {
73
+ return cn(ITEM_BASE, ITEM_VARIANTS[opts.variant ?? 'default'], ITEM_SIZES[opts.size ?? 'default']);
74
+ }
75
+
76
+ /**
77
+ * shadcn's name for {@link itemClass}, so shadcn code ports verbatim. Like cva,
78
+ * it merges a `className` into the result.
79
+ */
80
+ export function itemVariants(opts: { variant?: keyof typeof ITEM_VARIANTS; size?: keyof typeof ITEM_SIZES } & { className?: string } = {}): string {
81
+ return cn(itemClass(opts), opts.className);
82
+ }
83
+
84
+ const ITEM_MEDIA_BASE =
85
+ 'cn-item-media flex shrink-0 items-center justify-center [&_svg]:pointer-events-none';
86
+
87
+ const ITEM_MEDIA_VARIANTS = {
88
+ default: 'cn-item-media-variant-default',
89
+ icon: 'cn-item-media-variant-icon',
90
+ image: 'cn-item-media-variant-image',
91
+ } as const;
92
+
93
+ /** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
94
+ export function itemMediaClass(opts: { variant?: keyof typeof ITEM_MEDIA_VARIANTS } = {}): string {
95
+ return cn(ITEM_MEDIA_BASE, ITEM_MEDIA_VARIANTS[opts.variant ?? 'default']);
96
+ }
97
+
98
+ /**
99
+ * shadcn's name for {@link itemMediaClass}, so shadcn code ports verbatim. Like cva,
100
+ * it merges a `className` into the result.
101
+ */
102
+ export function itemMediaVariants(opts: { variant?: keyof typeof ITEM_MEDIA_VARIANTS } & { className?: string } = {}): string {
103
+ return cn(itemMediaClass(opts), opts.className);
104
+ }
105
+
106
+ /** Set `data-slot="item-content"` on the element. */
107
+ export function itemContentClass(): string {
108
+ return 'cn-item-content flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none';
109
+ }
110
+
111
+ /** Set `data-slot="item-title"` on the element. */
112
+ export function itemTitleClass(): string {
113
+ return 'cn-item-title line-clamp-1 flex w-fit items-center';
114
+ }
115
+
116
+ /** Set `data-slot="item-description"` on the element. */
117
+ export function itemDescriptionClass(): string {
118
+ return 'cn-item-description line-clamp-2 font-normal [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary';
119
+ }
120
+
121
+ /** Set `data-slot="item-actions"` on the element. */
122
+ export function itemActionsClass(): string {
123
+ return 'cn-item-actions flex items-center';
124
+ }
125
+
126
+ /** Set `data-slot="item-header"` on the element. */
127
+ export function itemHeaderClass(): string {
128
+ return 'cn-item-header flex basis-full items-center justify-between';
129
+ }
130
+
131
+ /** Set `data-slot="item-footer"` on the element. */
132
+ export function itemFooterClass(): string {
133
+ return 'cn-item-footer flex basis-full items-center justify-between';
134
+ }
@@ -55,6 +55,6 @@
55
55
  */
56
56
 
57
57
  export const kbdClass = (): string =>
58
- "pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none [&_svg:not([class*='size-'])]:size-3 [[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10";
58
+ 'cn-kbd pointer-events-none inline-flex items-center justify-center select-none';
59
59
 
60
- export const kbdGroupClass = (): string => 'inline-flex items-center gap-1';
60
+ export const kbdGroupClass = (): string => 'cn-kbd-group inline-flex items-center';
@@ -42,5 +42,5 @@
42
42
 
43
43
  /** Compose Tailwind classes for a native `<label>`. */
44
44
  export function labelClass(): string {
45
- return 'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50';
45
+ return 'cn-label flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed';
46
46
  }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Marker: a small inline note in a stream of content, such as "Today" between
3
+ * chat messages or "Edited" under a post, with an optional icon. Tier-1
4
+ * class helper; compose with a plain element.
5
+ *
6
+ * shadcn parity:
7
+ * Marker (variant: default | separator | border)
8
+ * → markerClass({ variant }), alias markerVariants
9
+ * MarkerIcon → markerIconClass()
10
+ * MarkerContent → markerContentClass()
11
+ *
12
+ * The `separator` variant draws a rule on both sides of the content, and
13
+ * `border` underlines the whole marker. Set `data-variant` to the variant you
14
+ * pass, which is what the content's centring keys on.
15
+ *
16
+ * A11y (required for accessible output): a marker is text, so it needs no
17
+ * role. When it announces a change in a live log (a date divider inside a
18
+ * chat), it is read in order with the messages around it, which is usually
19
+ * right. Hide a purely decorative icon with `aria-hidden="true"`.
20
+ *
21
+ * Design tokens used: --muted-foreground, --foreground, --border.
22
+ *
23
+ * @example
24
+ * ```html
25
+ * <div class=${markerClass({ variant: 'separator' })} data-variant="separator">
26
+ * <span class=${markerContentClass()}>Today</span>
27
+ * </div>
28
+ * ```
29
+ */
30
+ import { cn } from '../lib/utils.ts';
31
+
32
+ const BASE = 'cn-marker group/marker relative flex w-full items-center';
33
+
34
+ const VARIANTS = {
35
+ default: 'cn-marker-variant-default',
36
+ separator: 'cn-marker-variant-separator',
37
+ border: 'cn-marker-variant-border',
38
+ } as const;
39
+
40
+ export type MarkerVariant = keyof typeof VARIANTS;
41
+
42
+ /** The marker row. Pair with `data-variant` set to the same variant. */
43
+ export function markerClass(opts: { variant?: MarkerVariant } = {}): string {
44
+ return cn(BASE, VARIANTS[opts.variant ?? 'default']);
45
+ }
46
+
47
+ /**
48
+ * shadcn's name for {@link markerClass}, so shadcn code ports verbatim. Like
49
+ * cva, it merges a `className` into the result.
50
+ */
51
+ export function markerVariants(opts: { variant?: MarkerVariant } & { className?: string } = {}): string {
52
+ return cn(markerClass(opts), opts.className);
53
+ }
54
+
55
+ /** The leading icon. */
56
+ export function markerIconClass(): string {
57
+ return 'cn-marker-icon shrink-0';
58
+ }
59
+
60
+ /** The marker's text. */
61
+ export function markerContentClass(): string {
62
+ return 'cn-marker-content min-w-0 wrap-break-word';
63
+ }