@webjsdev/ui 0.3.17 → 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 +66 -7
  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 +8 -8
  284. package/packages/registry/components/field.ts +20 -18
  285. package/packages/registry/components/floating.ts +124 -0
  286. package/packages/registry/components/hover-card.ts +19 -8
  287. package/packages/registry/components/input-group.ts +118 -0
  288. package/packages/registry/components/input-otp.ts +365 -0
  289. package/packages/registry/components/input.ts +3 -3
  290. package/packages/registry/components/item.ts +134 -0
  291. package/packages/registry/components/kbd.ts +2 -2
  292. package/packages/registry/components/label.ts +1 -1
  293. package/packages/registry/components/marker.ts +63 -0
  294. package/packages/registry/components/menubar.ts +388 -0
  295. package/packages/registry/components/message-scroller.ts +470 -0
  296. package/packages/registry/components/message.ts +69 -0
  297. package/packages/registry/components/native-select.ts +5 -5
  298. package/packages/registry/components/navigation-menu.ts +564 -0
  299. package/packages/registry/components/pagination.ts +5 -5
  300. package/packages/registry/components/popover.ts +30 -84
  301. package/packages/registry/components/progress.ts +7 -3
  302. package/packages/registry/components/questionnaire.ts +840 -0
  303. package/packages/registry/components/radio-group.ts +18 -73
  304. package/packages/registry/components/resizable.ts +330 -0
  305. package/packages/registry/components/scroll-area.ts +46 -0
  306. package/packages/registry/components/select.ts +650 -0
  307. package/packages/registry/components/separator.ts +1 -1
  308. package/packages/registry/components/sheet.ts +128 -0
  309. package/packages/registry/components/sidebar.ts +457 -0
  310. package/packages/registry/components/skeleton.ts +1 -1
  311. package/packages/registry/components/slider.ts +333 -0
  312. package/packages/registry/components/sonner.ts +74 -7
  313. package/packages/registry/components/spinner.ts +7 -4
  314. package/packages/registry/components/switch.ts +117 -9
  315. package/packages/registry/components/table.ts +11 -9
  316. package/packages/registry/components/tabs.ts +76 -25
  317. package/packages/registry/components/textarea.ts +1 -1
  318. package/packages/registry/components/toggle-group.ts +30 -11
  319. package/packages/registry/components/toggle.ts +20 -13
  320. package/packages/registry/components/tooltip.ts +68 -7
  321. package/packages/registry/components/trace.ts +75 -0
  322. package/packages/registry/lib/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 +4056 -72
  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,128 @@
1
+ /**
2
+ * Sheet: a dialog that slides in from an edge of the screen (a side panel, a
3
+ * mobile menu, a filter drawer). Tier-2. It IS a dialog, the way shadcn's
4
+ * Sheet is the Dialog primitive with a side: the same native `<dialog>`
5
+ * opened with `showModal()`, the same focus trap, Escape and backdrop close,
6
+ * focus restoration, scroll lock and label wiring, attached to an edge.
7
+ *
8
+ * shadcn parity:
9
+ * Sheet → <ui-sheet open>
10
+ * SheetTrigger → <ui-sheet-trigger>
11
+ * SheetContent (side: top | right | bottom | left)
12
+ * → <ui-sheet-content side="right">
13
+ * SheetClose → <ui-sheet-close>
14
+ * SheetHeader / SheetFooter
15
+ * → <div class=${sheetHeaderClass()}> / <div class=${sheetFooterClass()}>
16
+ * SheetTitle / SheetDescription
17
+ * → <h2 data-slot="sheet-title" class=${sheetTitleClass()}> /
18
+ * <p data-slot="sheet-description" class=${sheetDescriptionClass()}>
19
+ *
20
+ * `side` names a physical edge, as shadcn's does, so `side="right"` stays on
21
+ * the right under `dir="rtl"`. Pick the side from the reading direction when
22
+ * a panel should follow it.
23
+ *
24
+ * A11y (handled by the element, plus one obligation): the native `<dialog>`
25
+ * carries `role="dialog"`, and on open it is named by the `sheet-title` node
26
+ * (falling back to the first heading, then to a generic name) and described by
27
+ * the `sheet-description` node. Focus moves into the sheet, Tab stays inside,
28
+ * Escape and a backdrop click close it, and focus returns to the trigger. Give
29
+ * every sheet a real title, since a generic "Dialog" name says nothing about
30
+ * what opened, and put the trigger's own accessible name on a real `<button>`.
31
+ *
32
+ * @example
33
+ * ```html
34
+ * <ui-sheet>
35
+ * <ui-sheet-trigger><button class=${buttonClass({ variant: 'outline' })} type="button">Filters</button></ui-sheet-trigger>
36
+ * <ui-sheet-content side="right">
37
+ * <div class=${sheetHeaderClass()}>
38
+ * <h2 data-slot="sheet-title" class=${sheetTitleClass()}>Filters</h2>
39
+ * <p data-slot="sheet-description" class=${sheetDescriptionClass()}>Narrow the list.</p>
40
+ * </div>
41
+ * </ui-sheet-content>
42
+ * </ui-sheet>
43
+ * ```
44
+ */
45
+ import { UiDialog, UiDialogTrigger, UiDialogContent, UiDialogClose } from './dialog.ts';
46
+
47
+ export type SheetSide = 'top' | 'right' | 'bottom' | 'left';
48
+
49
+ /** The visible panel. The element applies it; exported for a custom shell. */
50
+ export function sheetContentClass(): string {
51
+ return 'cn-sheet-content data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10';
52
+ }
53
+
54
+ /** The auto-injected close button in the corner. */
55
+ export function sheetCloseButtonClass(): string {
56
+ return 'cn-sheet-close';
57
+ }
58
+
59
+ /** The overlay behind the panel, which each style dims in its own way. */
60
+ export function sheetOverlayClass(): string {
61
+ return 'cn-sheet-overlay fixed inset-0 z-50 duration-100 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0';
62
+ }
63
+
64
+ /** The title and description block at the top. */
65
+ export function sheetHeaderClass(): string {
66
+ return 'cn-sheet-header flex flex-col';
67
+ }
68
+
69
+ /** The actions block, pushed to the bottom. */
70
+ export function sheetFooterClass(): string {
71
+ return 'cn-sheet-footer mt-auto flex flex-col';
72
+ }
73
+
74
+ /** The sheet's title. Mark it `data-slot="sheet-title"` so the sheet is named by it. */
75
+ export function sheetTitleClass(): string {
76
+ return 'cn-sheet-title cn-font-heading';
77
+ }
78
+
79
+ /** The sheet's description. Mark it `data-slot="sheet-description"`. */
80
+ export function sheetDescriptionClass(): string {
81
+ return 'cn-sheet-description';
82
+ }
83
+
84
+ export class UiSheet extends UiDialog {
85
+ static rootTag = 'ui-sheet';
86
+ static contentTag = 'ui-sheet-content';
87
+ static slotPrefix = 'sheet';
88
+ }
89
+ UiSheet.register('ui-sheet');
90
+
91
+ export class UiSheetTrigger extends UiDialogTrigger {
92
+ static rootTag = 'ui-sheet';
93
+ static slotPrefix = 'sheet';
94
+ }
95
+ UiSheetTrigger.register('ui-sheet-trigger');
96
+
97
+ export class UiSheetClose extends UiDialogClose {
98
+ static rootTag = 'ui-sheet';
99
+ static slotPrefix = 'sheet';
100
+ }
101
+ UiSheetClose.register('ui-sheet-close');
102
+
103
+ export class UiSheetContent extends UiDialogContent {
104
+ static rootTag = 'ui-sheet';
105
+ static slotPrefix = 'sheet';
106
+
107
+ // `side` is read straight from the attribute rather than declared as a
108
+ // reactive prop: the element is built on the dialog's factory base, and the
109
+ // side is something an author writes once in markup. Attribute reads work
110
+ // during server rendering too, so the first paint already carries data-side.
111
+ _side(): SheetSide {
112
+ const s = this.getAttribute?.('side');
113
+ return s === 'top' || s === 'bottom' || s === 'left' ? s : 'right';
114
+ }
115
+
116
+ _panelClass(): string {
117
+ return sheetContentClass();
118
+ }
119
+
120
+ _closeClass(): string {
121
+ return sheetCloseButtonClass();
122
+ }
123
+
124
+ _overlayClass(): string {
125
+ return sheetOverlayClass();
126
+ }
127
+ }
128
+ UiSheetContent.register('ui-sheet-content');
@@ -0,0 +1,457 @@
1
+ /**
2
+ * Sidebar: an application's side navigation, collapsible to icons or off
3
+ * canvas, and a sheet on a phone. Tier 2 for the parts with state (the
4
+ * provider, the sidebar, its trigger and rail, and the inset beside it) and
5
+ * Tier 1 for everything inside, which is markup with classes, as in shadcn.
6
+ *
7
+ * shadcn parity:
8
+ * SidebarProvider (defaultOpen, open)
9
+ * → <ui-sidebar-provider default-open="false" open>
10
+ * Sidebar (side, variant, collapsible)
11
+ * → <ui-sidebar side="left" | "right" variant="sidebar" | "floating" | "inset"
12
+ * collapsible="offcanvas" | "icon" | "none">
13
+ * SidebarTrigger / SidebarRail / SidebarInset
14
+ * → <ui-sidebar-trigger> / <ui-sidebar-rail> / <ui-sidebar-inset>
15
+ * SidebarHeader / Footer / Content / Separator / Input
16
+ * → <div data-slot="sidebar-header" data-sidebar="header" class=${sidebarHeaderClass()}>
17
+ * and so on (sidebarInputClass() on an <input>)
18
+ * SidebarGroup / GroupLabel / GroupAction / GroupContent
19
+ * → sidebarGroupClass() / sidebarGroupLabelClass() / sidebarGroupActionClass() /
20
+ * sidebarGroupContentClass()
21
+ * SidebarMenu / MenuItem → <ul class=${sidebarMenuClass()}> / <li class=${sidebarMenuItemClass()}>
22
+ * SidebarMenuButton (variant, size, isActive)
23
+ * → <a data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size
24
+ * data-active class=${sidebarMenuButtonClass({ variant, size })}>
25
+ * (sidebarMenuButtonVariants is the same helper under shadcn's name)
26
+ * SidebarMenuAction showOnHover / MenuBadge / MenuSkeleton
27
+ * → sidebarMenuActionClass({ showOnHover }) / sidebarMenuBadgeClass() /
28
+ * sidebarMenuSkeleton({ showIcon })
29
+ * SidebarMenuSub / SubItem / SubButton (size, isActive)
30
+ * → sidebarMenuSubClass() / sidebarMenuSubItemClass() /
31
+ * sidebarMenuSubButtonClass({ size })
32
+ * useSidebar() → the provider: open, state, isMobile, openMobile, toggle(), setOpen()
33
+ * onOpenChange → `ui-open-change` ({ detail: { open } }) on the provider
34
+ *
35
+ * The open state is kept in the `sidebar_state` cookie, as in shadcn, so a
36
+ * page can read it on the server and render `default-open` to match, with no
37
+ * flash. Ctrl+B (Cmd+B on a Mac) toggles it. Below 768px the sidebar opens
38
+ * as a sheet from its side instead, `--sidebar-width-mobile` wide (18rem
39
+ * when no ancestor sets it, shadcn's SIDEBAR_WIDTH_MOBILE).
40
+ *
41
+ * For a collapsed icon sidebar, wrap a menu button in a `<ui-tooltip>` whose
42
+ * content carries `hidden group-data-[collapsible=icon]:block`, so the label
43
+ * shows only when the text does not.
44
+ *
45
+ * A11y (handled by the elements, plus your part): the trigger is named
46
+ * "Toggle Sidebar", the inset is the page's `main` landmark, and on a phone
47
+ * the sheet is a modal dialog named "Sidebar" with Escape and focus return.
48
+ * Your part: put the menu in a `<nav aria-label>`, mark the current page's
49
+ * button `data-active="true"` and `aria-current="page"`, and give a
50
+ * collapsed icon button a name (its text stays in the markup, hidden by the
51
+ * width, so a screen reader still reads it).
52
+ *
53
+ * @example
54
+ * ```html
55
+ * <ui-sidebar-provider>
56
+ * <ui-sidebar collapsible="icon">
57
+ * <div data-slot="sidebar-content" data-sidebar="content" class=${sidebarContentClass()}>
58
+ * <nav aria-label="Main" data-slot="sidebar-group" data-sidebar="group" class=${sidebarGroupClass()}>
59
+ * <ul data-slot="sidebar-menu" data-sidebar="menu" class=${sidebarMenuClass()}>
60
+ * <li data-slot="sidebar-menu-item" data-sidebar="menu-item" class=${sidebarMenuItemClass()}>
61
+ * <a href="/inbox" data-slot="sidebar-menu-button" data-sidebar="menu-button" data-active="true"
62
+ * aria-current="page" class=${sidebarMenuButtonClass()}><span>Inbox</span></a>
63
+ * </li>
64
+ * </ul>
65
+ * </nav>
66
+ * </div>
67
+ * <ui-sidebar-rail></ui-sidebar-rail>
68
+ * </ui-sidebar>
69
+ * <ui-sidebar-inset>
70
+ * <header class="flex h-12 items-center px-4"><ui-sidebar-trigger></ui-sidebar-trigger></header>
71
+ * </ui-sidebar-inset>
72
+ * </ui-sidebar-provider>
73
+ * ```
74
+ */
75
+ import { WebComponent, html, prop, signal } from '@webjsdev/core';
76
+ import { cn, takeAuthoredClass } from '../lib/utils.ts';
77
+ import { buttonClass } from './button.ts';
78
+ import { inputClass } from './input.ts';
79
+ import { separatorClass } from './separator.ts';
80
+ import { skeletonClass } from './skeleton.ts';
81
+ import './sheet.ts';
82
+
83
+ const COOKIE = 'sidebar_state';
84
+ const COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
85
+ const MOBILE_QUERY = '(max-width: 767px)';
86
+ const PROVIDER = 'ui-sidebar-provider';
87
+
88
+ // --------------------------------------------------------------------------
89
+ // Class helpers (Tier 1)
90
+ // --------------------------------------------------------------------------
91
+
92
+ /** The provider's wrapper (the element applies them). */
93
+ export function sidebarWrapperClass(): string {
94
+ return 'group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar';
95
+ }
96
+
97
+ /** The header. */
98
+ export function sidebarHeaderClass(): string {
99
+ return 'cn-sidebar-header flex flex-col';
100
+ }
101
+
102
+ /** The footer. */
103
+ export function sidebarFooterClass(): string {
104
+ return 'cn-sidebar-footer flex flex-col';
105
+ }
106
+
107
+ /** A separator in the sidebar, on a separator element. */
108
+ export function sidebarSeparatorClass(): string {
109
+ return cn(separatorClass(), 'cn-sidebar-separator w-auto');
110
+ }
111
+
112
+ /** The search field in the sidebar, on an <input>. */
113
+ export function sidebarInputClass(): string {
114
+ return cn(inputClass(), 'cn-sidebar-input');
115
+ }
116
+
117
+ /** The scrolling content. */
118
+ export function sidebarContentClass(): string {
119
+ return 'cn-sidebar-content flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden';
120
+ }
121
+
122
+ /** A group. */
123
+ export function sidebarGroupClass(): string {
124
+ return 'cn-sidebar-group relative flex w-full min-w-0 flex-col';
125
+ }
126
+
127
+ /** A group's label. */
128
+ export function sidebarGroupLabelClass(): string {
129
+ return 'cn-sidebar-group-label flex shrink-0 items-center outline-hidden [&>svg]:shrink-0';
130
+ }
131
+
132
+ /** A group's action button. */
133
+ export function sidebarGroupActionClass(): string {
134
+ return 'cn-sidebar-group-action flex aspect-square items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0';
135
+ }
136
+
137
+ /** A group's content. */
138
+ export function sidebarGroupContentClass(): string {
139
+ return 'cn-sidebar-group-content w-full';
140
+ }
141
+
142
+ /** A menu (<ul>). */
143
+ export function sidebarMenuClass(): string {
144
+ return 'cn-sidebar-menu flex w-full min-w-0 flex-col';
145
+ }
146
+
147
+ /** A menu item (<li>). */
148
+ export function sidebarMenuItemClass(): string {
149
+ return 'group/menu-item relative';
150
+ }
151
+
152
+ const MENU_BUTTON_VARIANTS = {
153
+ default: 'cn-sidebar-menu-button-variant-default',
154
+ outline: 'cn-sidebar-menu-button-variant-outline',
155
+ } as const;
156
+
157
+ const MENU_BUTTON_SIZES = {
158
+ default: 'cn-sidebar-menu-button-size-default',
159
+ sm: 'cn-sidebar-menu-button-size-sm',
160
+ lg: 'cn-sidebar-menu-button-size-lg',
161
+ } as const;
162
+
163
+ export type SidebarMenuButtonVariant = keyof typeof MENU_BUTTON_VARIANTS;
164
+ export type SidebarMenuButtonSize = keyof typeof MENU_BUTTON_SIZES;
165
+
166
+ /** A menu button (an <a> or a <button>); mark the current one `data-active="true"`. */
167
+ export function sidebarMenuButtonClass(opts: { variant?: SidebarMenuButtonVariant; size?: SidebarMenuButtonSize } = {}): string {
168
+ return cn(
169
+ 'cn-sidebar-menu-button peer/menu-button group/menu-button flex w-full items-center overflow-hidden outline-hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate',
170
+ MENU_BUTTON_VARIANTS[opts.variant ?? 'default'],
171
+ MENU_BUTTON_SIZES[opts.size ?? 'default'],
172
+ );
173
+ }
174
+
175
+ /** shadcn's name for {@link sidebarMenuButtonClass}. Like cva, it merges a `className`. */
176
+ export function sidebarMenuButtonVariants(opts: { variant?: SidebarMenuButtonVariant; size?: SidebarMenuButtonSize; className?: string } = {}): string {
177
+ return cn(sidebarMenuButtonClass(opts), opts.className);
178
+ }
179
+
180
+ /** A menu item's action button; `showOnHover` hides it until the item is hovered or focused. */
181
+ export function sidebarMenuActionClass(opts: { showOnHover?: boolean } = {}): string {
182
+ return cn(
183
+ 'cn-sidebar-menu-action flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0',
184
+ opts.showOnHover ? 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0' : '',
185
+ );
186
+ }
187
+
188
+ /** A menu item's badge. */
189
+ export function sidebarMenuBadgeClass(): string {
190
+ return 'cn-sidebar-menu-badge flex items-center justify-center tabular-nums select-none group-data-[collapsible=icon]:hidden';
191
+ }
192
+
193
+ /**
194
+ * A loading placeholder for a menu item. `width` is the text bar's width
195
+ * (shadcn picks a random one, which would differ between server and client).
196
+ */
197
+ export function sidebarMenuSkeleton(opts: { showIcon?: boolean; width?: string } = {}) {
198
+ return html`<div data-slot="sidebar-menu-skeleton" data-sidebar="menu-skeleton" class="cn-sidebar-menu-skeleton flex items-center">${opts.showIcon
199
+ ? html`<div data-sidebar="menu-skeleton-icon" class=${cn(skeletonClass(), 'cn-sidebar-menu-skeleton-icon')}></div>`
200
+ : ''}<div data-sidebar="menu-skeleton-text" style=${`--skeleton-width: ${opts.width ?? '70%'}`} class=${cn(skeletonClass(), 'cn-sidebar-menu-skeleton-text max-w-(--skeleton-width) flex-1')}></div></div>`;
201
+ }
202
+
203
+ /** A submenu (<ul>). */
204
+ export function sidebarMenuSubClass(): string {
205
+ return 'cn-sidebar-menu-sub flex min-w-0 flex-col';
206
+ }
207
+
208
+ /** A submenu item (<li>). */
209
+ export function sidebarMenuSubItemClass(): string {
210
+ return 'group/menu-sub-item relative';
211
+ }
212
+
213
+ /** A submenu button (an <a>); `size` is "sm" or "md", set as `data-size`. */
214
+ export function sidebarMenuSubButtonClass(): string {
215
+ return 'cn-sidebar-menu-sub-button flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0';
216
+ }
217
+
218
+ // --------------------------------------------------------------------------
219
+ // <ui-sidebar-provider>
220
+ // --------------------------------------------------------------------------
221
+
222
+ function providerOf(el: Element): UiSidebarProvider | null {
223
+ return (typeof el.closest === 'function' ? el.closest(PROVIDER) : null) as UiSidebarProvider | null;
224
+ }
225
+
226
+ export class UiSidebarProvider extends WebComponent({
227
+ defaultOpen: prop(String, { attribute: 'default-open' }),
228
+ open: prop(Boolean, { reflect: true }),
229
+ }) {
230
+ readonly #openMobile = signal(false);
231
+ get openMobile() { return this.#openMobile.get(); }
232
+ set openMobile(v) { this.#openMobile.set(v); }
233
+ readonly #isMobile = signal(false);
234
+ get isMobile() { return this.#isMobile.get(); }
235
+ set isMobile(v) { this.#isMobile.set(v); }
236
+ _query: MediaQueryList | null = null;
237
+ _parsed = false;
238
+
239
+ constructor() {
240
+ super();
241
+ this.defaultOpen = 'true';
242
+ this.open = false;
243
+ }
244
+
245
+ /** "expanded" or "collapsed", as shadcn's `state`. */
246
+ get state(): 'expanded' | 'collapsed' {
247
+ return this.open ? 'expanded' : 'collapsed';
248
+ }
249
+
250
+ willUpdate(changedProperties: Map<string, unknown>): void {
251
+ super.willUpdate?.(changedProperties);
252
+ if (this._parsed) return;
253
+ this._parsed = true;
254
+ // An `open` attribute wins; otherwise default-open decides.
255
+ if (!this.hasAttribute?.('open')) this.open = this.defaultOpen !== 'false';
256
+ }
257
+
258
+ connectedCallback(): void {
259
+ super.connectedCallback?.();
260
+ window.addEventListener('keydown', this._onKeyDown);
261
+ if (typeof matchMedia === 'function') {
262
+ this._query = matchMedia(MOBILE_QUERY);
263
+ this.isMobile = this._query.matches;
264
+ this._query.addEventListener('change', this._onQuery);
265
+ }
266
+ }
267
+
268
+ disconnectedCallback(): void {
269
+ window.removeEventListener('keydown', this._onKeyDown);
270
+ this._query?.removeEventListener('change', this._onQuery);
271
+ super.disconnectedCallback?.();
272
+ }
273
+
274
+ render() {
275
+ return html`<div
276
+ data-slot="sidebar-wrapper"
277
+ style="--sidebar-width: 16rem; --sidebar-width-icon: 3rem"
278
+ class=${sidebarWrapperClass()}
279
+ ><slot></slot></div>`;
280
+ }
281
+
282
+ updated(changedProperties: Map<string, unknown>): void {
283
+ super.updated?.(changedProperties);
284
+ // `isMobile` and `openMobile` are signals, so a part that reads them
285
+ // re-renders on its own; only the `open` property needs the nudge.
286
+ if (changedProperties.has('open')) {
287
+ for (const part of Array.from(this.querySelectorAll<WebComponent>('ui-sidebar, ui-sidebar-trigger, ui-sidebar-rail'))) {
288
+ if (providerOf(part) === this) part.requestUpdate?.();
289
+ }
290
+ }
291
+ }
292
+
293
+ /** Open or close the desktop sidebar, keeping the choice in the cookie. */
294
+ setOpen(open: boolean): void {
295
+ if (open === this.open) return;
296
+ this.open = open;
297
+ if (typeof document !== 'undefined') document.cookie = `${COOKIE}=${open}; path=/; max-age=${COOKIE_MAX_AGE}`;
298
+ this.dispatchEvent(new CustomEvent('ui-open-change', { bubbles: true, detail: { open } }));
299
+ }
300
+
301
+ /** Open or close the phone sheet. */
302
+ setOpenMobile(open: boolean): void {
303
+ this.openMobile = open;
304
+ }
305
+
306
+ /** Toggle the sheet on a phone, the sidebar otherwise. */
307
+ toggle(): void {
308
+ if (this.isMobile) this.setOpenMobile(!this.openMobile);
309
+ else this.setOpen(!this.open);
310
+ }
311
+
312
+ _onQuery = (e: MediaQueryListEvent): void => {
313
+ this.isMobile = e.matches;
314
+ };
315
+
316
+ _onKeyDown = (e: KeyboardEvent): void => {
317
+ if (e.key === 'b' && (e.metaKey || e.ctrlKey)) {
318
+ e.preventDefault();
319
+ this.toggle();
320
+ }
321
+ };
322
+ }
323
+ UiSidebarProvider.register('ui-sidebar-provider');
324
+
325
+ // --------------------------------------------------------------------------
326
+ // <ui-sidebar>
327
+ // --------------------------------------------------------------------------
328
+
329
+ export class UiSidebar extends WebComponent({
330
+ side: prop<'left' | 'right'>(String),
331
+ variant: prop<'sidebar' | 'floating' | 'inset'>(String),
332
+ collapsible: prop<'offcanvas' | 'icon' | 'none'>(String),
333
+ }) {
334
+ _authored: string | null = null;
335
+
336
+ constructor() {
337
+ super();
338
+ this.side = 'left';
339
+ this.variant = 'sidebar';
340
+ this.collapsible = 'offcanvas';
341
+ }
342
+
343
+ _host(attrs: Record<string, string | null>, cls: string): void {
344
+ if (typeof this.setAttribute !== 'function') return;
345
+ this.setAttribute('class', cn(cls, this._authored));
346
+ for (const [k, v] of Object.entries(attrs)) {
347
+ if (v === null) this.removeAttribute(k);
348
+ else this.setAttribute(k, v);
349
+ }
350
+ }
351
+
352
+ // The sidebar's state and its group / peer markers sit on its own host:
353
+ // the inset beside it styles itself with peer-data-*, which needs a real
354
+ // sibling, and everything inside reads group-data-*.
355
+ render() {
356
+ this._authored = takeAuthoredClass(this);
357
+ const provider = providerOf(this);
358
+ const side = this.side === 'right' ? 'right' : 'left';
359
+ const floating = this.variant === 'floating' || this.variant === 'inset';
360
+ if (this.collapsible === 'none') {
361
+ this._host({ 'data-slot': 'sidebar', 'data-state': null, 'data-collapsible': null, 'data-variant': null, 'data-side': null },
362
+ 'flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground');
363
+ return html`<slot></slot>`;
364
+ }
365
+ if (provider?.isMobile) {
366
+ this._host({ 'data-slot': null, 'data-state': null, 'data-collapsible': null, 'data-variant': null, 'data-side': null }, 'contents');
367
+ return html`<ui-sheet ?open=${!!provider.openMobile} @ui-open-change=${(e: CustomEvent) => {
368
+ if (e.target === e.currentTarget) provider.setOpenMobile(!!e.detail?.open);
369
+ }}><ui-sheet-content
370
+ side=${side}
371
+ show-close-button="false"
372
+ data-sidebar="sidebar"
373
+ data-slot="sidebar"
374
+ data-mobile="true"
375
+ style="--sidebar-width: var(--sidebar-width-mobile, 18rem)"
376
+ class="w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground"
377
+ ><h2 data-slot="sheet-title" class="sr-only">Sidebar</h2><p data-slot="sheet-description" class="sr-only">Displays the mobile sidebar.</p><div class="flex h-full w-full flex-col"><slot></slot></div></ui-sheet-content></ui-sheet>`;
378
+ }
379
+ const state = provider?.state ?? 'expanded';
380
+ this._host({
381
+ 'data-slot': 'sidebar',
382
+ 'data-state': state,
383
+ 'data-collapsible': state === 'collapsed' ? this.collapsible : '',
384
+ 'data-variant': this.variant,
385
+ 'data-side': side,
386
+ }, 'group peer hidden text-sidebar-foreground md:block');
387
+ return html`<div
388
+ data-slot="sidebar-gap"
389
+ class=${cn(
390
+ 'cn-sidebar-gap relative w-(--sidebar-width) bg-transparent group-data-[collapsible=offcanvas]:w-0 group-data-[side=right]:rotate-180',
391
+ floating ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]' : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
392
+ )}
393
+ ></div><div
394
+ data-slot="sidebar-container"
395
+ data-side=${side}
396
+ class=${cn(
397
+ 'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex',
398
+ floating ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]' : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',
399
+ )}
400
+ ><div data-sidebar="sidebar" data-slot="sidebar-inner" class="cn-sidebar-inner flex size-full flex-col"><slot></slot></div></div>`;
401
+ }
402
+ }
403
+ UiSidebar.register('ui-sidebar');
404
+
405
+ // --------------------------------------------------------------------------
406
+ // <ui-sidebar-trigger> and <ui-sidebar-rail>
407
+ // --------------------------------------------------------------------------
408
+
409
+ export class UiSidebarTrigger extends WebComponent {
410
+ render() {
411
+ return html`<button
412
+ type="button"
413
+ data-sidebar="trigger"
414
+ data-slot="sidebar-trigger"
415
+ class=${cn(buttonClass({ variant: 'ghost', size: 'icon-sm' }), 'cn-sidebar-trigger')}
416
+ @click=${() => providerOf(this)?.toggle()}
417
+ ><svg 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" class="cn-rtl-flip rtl:rotate-180"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M9 3v18"></path></svg><span class="sr-only">Toggle Sidebar</span></button>`;
418
+ }
419
+ }
420
+ UiSidebarTrigger.register('ui-sidebar-trigger');
421
+
422
+ export class UiSidebarRail extends WebComponent {
423
+ render() {
424
+ return html`<button
425
+ type="button"
426
+ data-sidebar="rail"
427
+ data-slot="sidebar-rail"
428
+ aria-label="Toggle Sidebar"
429
+ tabindex="-1"
430
+ title="Toggle Sidebar"
431
+ class="cn-sidebar-rail absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2 in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize [[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar [[data-side=left][data-collapsible=offcanvas]_&]:-right-2 [[data-side=right][data-collapsible=offcanvas]_&]:-left-2"
432
+ @click=${() => providerOf(this)?.toggle()}
433
+ ></button>`;
434
+ }
435
+ }
436
+ UiSidebarRail.register('ui-sidebar-rail');
437
+
438
+ // --------------------------------------------------------------------------
439
+ // <ui-sidebar-inset>
440
+ // --------------------------------------------------------------------------
441
+
442
+ export class UiSidebarInset extends WebComponent {
443
+ _authored: string | null = null;
444
+
445
+ // The inset is the sidebar's following sibling, so peer-data-* reaches it
446
+ // only on its own host, which is also the page's main landmark.
447
+ render() {
448
+ this._authored = takeAuthoredClass(this);
449
+ if (typeof this.setAttribute === 'function') {
450
+ this.setAttribute('class', cn('cn-sidebar-inset relative flex w-full flex-1 flex-col', this._authored));
451
+ this.setAttribute('data-slot', 'sidebar-inset');
452
+ this.setAttribute('role', 'main');
453
+ }
454
+ return html`<slot></slot>`;
455
+ }
456
+ }
457
+ UiSidebarInset.register('ui-sidebar-inset');
@@ -20,4 +20,4 @@
20
20
  * ```
21
21
  */
22
22
 
23
- export const skeletonClass = (): string => 'animate-pulse rounded-md bg-accent';
23
+ export const skeletonClass = (): string => 'cn-skeleton animate-pulse';