@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,618 @@
1
+ /**
2
+ * Command: a searchable list of actions, the menu behind a command palette.
3
+ * Tier-2. It is cmdk's model, built on the platform: typing in the input
4
+ * filters and ranks the items, the arrow keys move a selection while focus
5
+ * stays in the input, and Enter runs the selected item. `<ui-command-dialog>`
6
+ * puts the same command in a native modal `<dialog>`.
7
+ *
8
+ * shadcn parity:
9
+ * Command (label, shouldFilter, loop)
10
+ * → <ui-command label should-filter="false" loop>
11
+ * CommandInput placeholder → <ui-command-input placeholder>
12
+ * CommandList → <ui-command-list>
13
+ * CommandEmpty → <ui-command-empty>No results.</ui-command-empty>
14
+ * CommandGroup heading → <ui-command-group heading="Suggestions">
15
+ * CommandItem (value, keywords, disabled, onSelect)
16
+ * → <ui-command-item value keywords="a b" disabled>, firing `ui-select`
17
+ * CommandShortcut → <ui-command-shortcut>
18
+ * CommandSeparator → <ui-command-separator>
19
+ * CommandDialog (open, title, description, showCloseButton)
20
+ * → <ui-command-dialog open title description show-close-button>
21
+ * around a <ui-command>
22
+ * onValueChange (Command) → `ui-value-change` ({ detail: { value } }) as the selection moves
23
+ * onValueChange (Input) → `ui-search-change` ({ detail: { search } })
24
+ *
25
+ * An item's value is its `value` attribute, else its text. A search ranks
26
+ * items by how well the value and `keywords` match (a prefix beats a word
27
+ * start beats a substring beats letters in order), hides the rest, hides a
28
+ * group left empty and every separator, and shows `<ui-command-empty>` when
29
+ * nothing matches. `should-filter="false"` leaves filtering to you (a list a
30
+ * server action returns). Activating an item that holds a link follows it.
31
+ *
32
+ * Keyboard (as cmdk's): ArrowDown / ArrowUp (and Ctrl+N / Ctrl+P, Ctrl+J /
33
+ * Ctrl+K) move the selection, `loop` wraps it, Home / End jump to the ends,
34
+ * Enter runs the selected item. Pointing at an item selects it.
35
+ *
36
+ * A11y (handled by the element, plus your part): the input is a
37
+ * `role="combobox"` controlling a `role="listbox"` and pointing at the
38
+ * selected `role="option"` through `aria-activedescendant`, so focus never
39
+ * leaves it. Groups are named by their heading and a disabled item is
40
+ * announced and skipped. Your part: name the command (`label`, read by a
41
+ * screen reader only), since a placeholder is not a name.
42
+ *
43
+ * @example
44
+ * ```html
45
+ * <ui-command label="Command menu" class="rounded-lg border shadow-md md:min-w-[450px]">
46
+ * <ui-command-input placeholder="Type a command or search"></ui-command-input>
47
+ * <ui-command-list>
48
+ * <ui-command-empty>No results found.</ui-command-empty>
49
+ * <ui-command-group heading="Suggestions">
50
+ * <ui-command-item>Calendar</ui-command-item>
51
+ * <ui-command-item keywords="emoji smiley">Search Emoji</ui-command-item>
52
+ * <ui-command-item disabled>Calculator</ui-command-item>
53
+ * </ui-command-group>
54
+ * <ui-command-separator></ui-command-separator>
55
+ * <ui-command-group heading="Settings">
56
+ * <ui-command-item>Profile<ui-command-shortcut>⌘P</ui-command-shortcut></ui-command-item>
57
+ * </ui-command-group>
58
+ * </ui-command-list>
59
+ * </ui-command>
60
+ * ```
61
+ */
62
+ import { WebComponent, html, prop, signal, nothing } from '@webjsdev/core';
63
+ import { cn, takeAuthoredClass } from '../lib/utils.ts';
64
+ import { inputGroupClass, inputGroupAddonClass } from './input-group.ts';
65
+ import { UiDialog, UiDialogContent } from './dialog.ts';
66
+
67
+ /** The command's classes (the element applies them). */
68
+ export const commandClass = (): string => 'cn-command flex size-full flex-col overflow-hidden';
69
+ /** The command dialog's panel classes (the element applies them). */
70
+ export const commandDialogClass = (): string => 'cn-command-dialog top-1/3 translate-y-0 overflow-hidden p-0';
71
+ /** The input's wrapper (the element applies them). */
72
+ export const commandInputWrapperClass = (): string => 'cn-command-input-wrapper';
73
+ /** The input group around the input (the element applies them). */
74
+ export const commandInputGroupClass = (): string => 'cn-command-input-group';
75
+ /** The input's classes (the element applies them). */
76
+ export const commandInputClass = (): string =>
77
+ 'cn-command-input outline-hidden disabled:cursor-not-allowed disabled:opacity-50';
78
+ /** The search icon. */
79
+ export const commandInputIconClass = (): string => 'cn-command-input-icon';
80
+ /** The list's classes (the element applies them). */
81
+ export const commandListClass = (): string => 'cn-command-list flex flex-col overflow-x-hidden overflow-y-auto';
82
+ /** The empty state's classes (the element applies them). */
83
+ export const commandEmptyClass = (): string => 'cn-command-empty';
84
+ /** A group's classes (the element applies them). */
85
+ export const commandGroupClass = (): string => 'cn-command-group';
86
+ /** A separator's classes (the element applies them). */
87
+ export const commandSeparatorClass = (): string => 'cn-command-separator';
88
+ /** An item's classes (the element applies them). */
89
+ export const commandItemClass = (): string =>
90
+ 'cn-command-item group/command-item data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0';
91
+ /** A checked item's check mark. */
92
+ export const commandItemIndicatorClass = (): string =>
93
+ 'cn-command-item-indicator ms-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100';
94
+ /** A keyboard shortcut hint's classes. */
95
+ export const commandShortcutClass = (): string => 'cn-command-shortcut';
96
+
97
+ /**
98
+ * How well `search` matches `text`, 0 for no match: a prefix scores highest,
99
+ * then a match at a word start, then a substring, then the letters in order.
100
+ * Shorter texts win ties, as in cmdk's command-score.
101
+ */
102
+ export function commandScore(text: string, search: string): number {
103
+ const t = text.toLowerCase();
104
+ const s = search.trim().toLowerCase();
105
+ if (!s) return 1;
106
+ if (!t) return 0;
107
+ const brevity = 1 / (1 + t.length / 100);
108
+ if (t.startsWith(s)) return 0.9 + 0.09 * brevity;
109
+ const at = t.indexOf(s);
110
+ if (at > 0) {
111
+ const wordStart = /[\s\-_/.:]/.test(t[at - 1]);
112
+ return (wordStart ? 0.7 : 0.5) + 0.09 * brevity;
113
+ }
114
+ let i = 0;
115
+ for (const ch of t) {
116
+ if (ch === s[i]) i++;
117
+ if (i === s.length) return 0.1 + 0.09 * brevity;
118
+ }
119
+ return 0;
120
+ }
121
+
122
+ const ROOT = 'ui-command';
123
+ let uid = 0;
124
+
125
+ // shadcn's className on each Command part lands on the element that part
126
+ // renders (the command, its input, list, empty state, groups and items), so a
127
+ // class written on the host moves there, read once at first render. The
128
+ // hosts stay boxes rather than display: contents, since a group, an item and
129
+ // the empty state hide themselves through the hidden attribute, which a
130
+ // display utility on the host would override.
131
+ function takeAuthored(part: HTMLElement): string | null {
132
+ return takeAuthoredClass(part, null);
133
+ }
134
+
135
+ type ItemState = { visible: boolean; selected: boolean; order: number };
136
+
137
+ export class UiCommand extends WebComponent({
138
+ label: String,
139
+ shouldFilter: prop(String, { attribute: 'should-filter' }),
140
+ loop: Boolean,
141
+ // The selected item's value.
142
+ value: prop(String, { reflect: true }),
143
+ }) {
144
+ readonly #search = signal('');
145
+ _id = '';
146
+
147
+ constructor() {
148
+ super();
149
+ this.label = '';
150
+ this.shouldFilter = 'true';
151
+ this.loop = false;
152
+ this.value = '';
153
+ }
154
+
155
+ connectedCallback(): void {
156
+ super.connectedCallback?.();
157
+ this._id ||= `ui-command-${++uid}`;
158
+ }
159
+
160
+ // The ids exist once the root has connected. The server never connects an
161
+ // element, so it serves none rather than a `-list` every box would share;
162
+ // hydration renders them in.
163
+ get listId(): string | null {
164
+ return this._id ? `${this._id}-list` : null;
165
+ }
166
+
167
+ get labelId(): string | null {
168
+ return this._id ? `${this._id}-label` : null;
169
+ }
170
+
171
+ // The root never hides itself, so its host can be display: contents: the
172
+ // command box is then the flex item of whatever holds it, and a `max-w-sm`
173
+ // with the box's `size-full` sizes against that parent, as shadcn's does.
174
+ // The host's box is turned off through its style, which the server serves.
175
+ render() {
176
+ const authored = takeAuthored(this);
177
+ if (typeof this.getAttribute === 'function' && !this.getAttribute('style')) this.setAttribute('style', 'display: contents');
178
+ return html`<div data-slot="command" cmdk-root="" class=${cn(commandClass(), authored)} @keydown=${this._onKeyDown}>${this.label
179
+ ? html`<label id=${this.labelId || nothing} cmdk-label="" class="sr-only">${this.label}</label>`
180
+ : ''}<slot></slot></div>`;
181
+ }
182
+
183
+ // The parts that belong to this command, not to a command nested in it.
184
+ _own<T extends Element>(selector: string): T[] {
185
+ if (typeof this.querySelectorAll !== 'function') return [];
186
+ return Array.from(this.querySelectorAll<T>(selector)).filter((el) => el.closest(ROOT) === this);
187
+ }
188
+
189
+ /** The items currently shown, in the order they are shown. */
190
+ visibleItems(): UiCommandItem[] {
191
+ return this._own<UiCommandItem>(`${ROOT}-item`)
192
+ .filter((i) => i.state?.get().visible)
193
+ .sort((a, b) => a.state?.get().order - b.state?.get().order);
194
+ }
195
+
196
+ /** Set the search text, as typing does. */
197
+ setSearch(search: string): void {
198
+ if (search === this.#search.get()) return;
199
+ this.#search.set(search);
200
+ this.dispatchEvent(new CustomEvent('ui-search-change', { bubbles: true, detail: { search } }));
201
+ this.refresh(true);
202
+ }
203
+
204
+ /**
205
+ * Re-rank and redraw the items. A new search selects the best match; a
206
+ * redraw otherwise keeps the selection where it is when it is still shown.
207
+ */
208
+ refresh(reselect = false): void {
209
+ const filter = this.shouldFilter !== 'false';
210
+ const search = this.#search.get();
211
+ const items = this._own<UiCommandItem>(`${ROOT}-item`);
212
+ const scored = items.map((item, dom) => ({
213
+ item,
214
+ dom,
215
+ score: filter ? commandScore(`${item.itemValue} ${item.keywords ?? ''}`, search) : 1,
216
+ }));
217
+ const ranked = search && filter
218
+ ? scored.filter((s) => s.score > 0).sort((a, b) => b.score - a.score || a.dom - b.dom)
219
+ : scored;
220
+ const rank = new Map(ranked.map((s, i) => [s.item, i]));
221
+ // A group sits where its best item ranks.
222
+ const groups = this._own<UiCommandGroup>(`${ROOT}-group`);
223
+ const groupRank = new Map<UiCommandGroup, number>();
224
+ for (const g of groups) {
225
+ const ranks = items.filter((i) => i.closest(`${ROOT}-group`) === g && rank.has(i)).map((i) => rank.get(i) as number);
226
+ groupRank.set(g, ranks.length ? Math.min(...ranks) : Infinity);
227
+ }
228
+ const sorting = !!search && filter;
229
+ const visible = ranked.map((s) => s.item);
230
+ const enabled = visible.filter((i) => !i.disabled);
231
+ let selected = items.find((i) => i.itemValue === this.value && rank.has(i) && !i.disabled) ?? null;
232
+ if (reselect || !selected) {
233
+ selected = sorting
234
+ ? enabled[0] ?? null
235
+ : enabled.slice().sort((a, b) => items.indexOf(a) - items.indexOf(b))[0] ?? null;
236
+ }
237
+ for (const item of items) {
238
+ const r = rank.get(item);
239
+ item.state?.set({ visible: r !== undefined, selected: item === selected, order: sorting && r !== undefined ? r : items.indexOf(item) });
240
+ }
241
+ for (const g of groups) {
242
+ const r = groupRank.get(g) ?? Infinity;
243
+ g.shown?.set(r !== Infinity);
244
+ g.order?.set(sorting && r !== Infinity ? r : 0);
245
+ }
246
+ for (const sep of this._own<UiCommandSeparator>(`${ROOT}-separator`)) sep.shown?.set(!search);
247
+ for (const empty of this._own<UiCommandEmpty>(`${ROOT}-empty`)) empty.shown?.set(visible.length === 0);
248
+ this._select(selected);
249
+ }
250
+
251
+ _select(item: UiCommandItem | null): void {
252
+ const value = item?.itemValue ?? '';
253
+ for (const i of this._own<UiCommandItem>(`${ROOT}-item`)) {
254
+ if (i.state?.get().selected !== (i === item)) i.state?.set({ ...i.state?.get(), selected: i === item });
255
+ }
256
+ const input = this._own<UiCommandInput>(`${ROOT}-input`)[0];
257
+ if (input) input.activeId?.set(item?.optionId ?? '');
258
+ item?.scrollIntoViewIfShown?.();
259
+ if (value !== this.value) {
260
+ this.value = value;
261
+ this.dispatchEvent(new CustomEvent('ui-value-change', { bubbles: true, detail: { value } }));
262
+ }
263
+ }
264
+
265
+ /** Move the selection to an item (used by pointing). */
266
+ selectItem(item: UiCommandItem): void {
267
+ if (item.disabled || !item.state?.get().visible) return;
268
+ this._select(item);
269
+ }
270
+
271
+ /** Run an item: fire its ui-select, and follow a link it holds. */
272
+ run(item: UiCommandItem | null): void {
273
+ if (!item || item.disabled) return;
274
+ const ok = item.dispatchEvent(new CustomEvent('ui-select', { bubbles: true, cancelable: true, detail: { value: item.itemValue } }));
275
+ if (!ok) return;
276
+ item.querySelector<HTMLAnchorElement>('a[href]')?.click();
277
+ }
278
+
279
+ _move(by: number | 'first' | 'last'): void {
280
+ const enabled = this.visibleItems().filter((i) => !i.disabled);
281
+ if (!enabled.length) return;
282
+ const at = enabled.findIndex((i) => i.state?.get().selected);
283
+ let next: number;
284
+ if (by === 'first') next = 0;
285
+ else if (by === 'last') next = enabled.length - 1;
286
+ else {
287
+ next = at + by;
288
+ if (this.loop) next = (next + enabled.length) % enabled.length;
289
+ else next = Math.max(0, Math.min(enabled.length - 1, next));
290
+ }
291
+ this._select(enabled[next]);
292
+ }
293
+
294
+ _onKeyDown = (e: KeyboardEvent): void => {
295
+ if (e.isComposing) return;
296
+ const ctrl = e.ctrlKey && !e.metaKey && !e.altKey;
297
+ if (e.key === 'ArrowDown' || (ctrl && (e.key === 'n' || e.key === 'j'))) { e.preventDefault(); this._move(1); }
298
+ else if (e.key === 'ArrowUp' || (ctrl && (e.key === 'p' || e.key === 'k'))) { e.preventDefault(); this._move(-1); }
299
+ else if (e.key === 'Home') { e.preventDefault(); this._move('first'); }
300
+ else if (e.key === 'End') { e.preventDefault(); this._move('last'); }
301
+ else if (e.key === 'Enter') {
302
+ e.preventDefault();
303
+ this.run(this.visibleItems().find((i) => i.state?.get().selected) ?? null);
304
+ }
305
+ };
306
+
307
+ // Parts connected after the first render (a client render appends children
308
+ // in order) are ranked once they are all in place.
309
+ _partConnected(): void {
310
+ if (this._queued) return;
311
+ this._queued = true;
312
+ queueMicrotask(() => { this._queued = false; this.refresh(); });
313
+ }
314
+
315
+ _queued = false;
316
+ }
317
+ UiCommand.register('ui-command');
318
+
319
+ // --------------------------------------------------------------------------
320
+ // <ui-command-input>
321
+ // --------------------------------------------------------------------------
322
+
323
+ export class UiCommandInput extends WebComponent({
324
+ placeholder: String,
325
+ }) {
326
+ readonly activeId = signal('');
327
+ constructor() {
328
+ super();
329
+ this.placeholder = '';
330
+ }
331
+
332
+ connectedCallback(): void {
333
+ super.connectedCallback?.();
334
+ this._root()?._partConnected();
335
+ }
336
+
337
+ _root(): UiCommand | null {
338
+ return this.closest(ROOT) as UiCommand | null;
339
+ }
340
+
341
+ render() {
342
+ const root = this._root();
343
+ const named = root?.label ? root.labelId || nothing : nothing;
344
+ return html`<div data-slot="command-input-wrapper" cmdk-input-wrapper="" class=${commandInputWrapperClass()}><div
345
+ data-slot="input-group" class=${cn(inputGroupClass(), commandInputGroupClass())}
346
+ ><input
347
+ data-slot="command-input"
348
+ cmdk-input=""
349
+ type="text"
350
+ role="combobox"
351
+ autocomplete="off"
352
+ autocorrect="off"
353
+ spellcheck="false"
354
+ aria-autocomplete="list"
355
+ aria-expanded="true"
356
+ aria-controls=${root?.listId || nothing}
357
+ aria-labelledby=${named}
358
+ aria-label=${named ? nothing : this.getAttribute?.('aria-label') || this.placeholder || nothing}
359
+ aria-activedescendant=${this.activeId.get() || nothing}
360
+ placeholder=${this.placeholder || nothing}
361
+ class=${cn(commandInputClass(), takeAuthored(this))}
362
+ @input=${this._onInput}
363
+ ><div data-slot="input-group-addon" data-align="inline-start" class=${inputGroupAddonClass()}><svg
364
+ 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"
365
+ class=${commandInputIconClass()}
366
+ ><circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.3-4.3"></path></svg></div></div></div>`;
367
+ }
368
+
369
+ _onInput = (e: Event): void => {
370
+ this._root()?.setSearch((e.target as HTMLInputElement).value);
371
+ };
372
+ }
373
+ UiCommandInput.register('ui-command-input');
374
+
375
+ // --------------------------------------------------------------------------
376
+ // <ui-command-list>
377
+ // --------------------------------------------------------------------------
378
+
379
+ export class UiCommandList extends WebComponent {
380
+ render() {
381
+ const root = this.closest?.(ROOT) as UiCommand | null;
382
+ return html`<div
383
+ data-slot="command-list"
384
+ cmdk-list=""
385
+ role="listbox"
386
+ id=${root?.listId || nothing}
387
+ aria-label=${this.getAttribute?.('aria-label') || 'Suggestions'}
388
+ class=${cn(commandListClass(), takeAuthored(this))}
389
+ ><slot></slot></div>`;
390
+ }
391
+ }
392
+ UiCommandList.register('ui-command-list');
393
+
394
+ // --------------------------------------------------------------------------
395
+ // <ui-command-empty>
396
+ // --------------------------------------------------------------------------
397
+
398
+ export class UiCommandEmpty extends WebComponent {
399
+ readonly shown = signal(false);
400
+ constructor() {
401
+ super();
402
+ }
403
+
404
+ connectedCallback(): void {
405
+ super.connectedCallback?.();
406
+ (this.closest(ROOT) as UiCommand | null)?._partConnected();
407
+ }
408
+
409
+ render() {
410
+ return html`<div data-slot="command-empty" cmdk-empty="" role="presentation" ?hidden=${!this.shown.get()} class=${cn(commandEmptyClass(), takeAuthored(this))}><slot></slot></div>`;
411
+ }
412
+ }
413
+ UiCommandEmpty.register('ui-command-empty');
414
+
415
+ // --------------------------------------------------------------------------
416
+ // <ui-command-group>
417
+ // --------------------------------------------------------------------------
418
+
419
+ export class UiCommandGroup extends WebComponent({
420
+ heading: String,
421
+ }) {
422
+ readonly shown = signal(true);
423
+ readonly order = signal(0);
424
+ _id = '';
425
+
426
+ constructor() {
427
+ super();
428
+ this.heading = '';
429
+ }
430
+
431
+ connectedCallback(): void {
432
+ super.connectedCallback?.();
433
+ this._id ||= `ui-command-group-${++uid}`;
434
+ (this.closest(ROOT) as UiCommand | null)?._partConnected();
435
+ }
436
+
437
+ updated(changedProperties: Map<string, unknown>): void {
438
+ super.updated?.(changedProperties);
439
+ this.style.order = this.order.get() ? String(this.order.get()) : '';
440
+ this.hidden = !this.shown.get();
441
+ }
442
+
443
+ render() {
444
+ // No id before connect (the server never connects an element), so the
445
+ // served group is named by aria-label instead of a shared `-heading` id.
446
+ const headingId = this.heading && this._id ? `${this._id}-heading` : nothing;
447
+ return html`<div data-slot="command-group" cmdk-group="" role="presentation" class=${cn(commandGroupClass(), takeAuthored(this))}>${this.heading
448
+ ? html`<div cmdk-group-heading="" aria-hidden="true" id=${headingId}>${this.heading}</div>`
449
+ : ''}<div cmdk-group-items="" role="group" aria-labelledby=${headingId} aria-label=${this.heading && !headingId ? this.heading : nothing} class="flex flex-col"><slot></slot></div></div>`;
450
+ }
451
+ }
452
+ UiCommandGroup.register('ui-command-group');
453
+
454
+ // --------------------------------------------------------------------------
455
+ // <ui-command-separator>
456
+ // --------------------------------------------------------------------------
457
+
458
+ export class UiCommandSeparator extends WebComponent {
459
+ readonly shown = signal(true);
460
+ constructor() {
461
+ super();
462
+ }
463
+
464
+ connectedCallback(): void {
465
+ super.connectedCallback?.();
466
+ (this.closest(ROOT) as UiCommand | null)?._partConnected();
467
+ }
468
+
469
+ render() {
470
+ return html`<div data-slot="command-separator" cmdk-separator="" role="separator" ?hidden=${!this.shown.get()} class=${commandSeparatorClass()}></div>`;
471
+ }
472
+ }
473
+ UiCommandSeparator.register('ui-command-separator');
474
+
475
+ // --------------------------------------------------------------------------
476
+ // <ui-command-item>
477
+ // --------------------------------------------------------------------------
478
+
479
+ export class UiCommandItem extends WebComponent({
480
+ value: String,
481
+ keywords: String,
482
+ disabled: Boolean,
483
+ checked: Boolean,
484
+ }) {
485
+ readonly state = signal<ItemState>({ visible: true, selected: false, order: 0 });
486
+ _id = '';
487
+
488
+ constructor() {
489
+ super();
490
+ this.value = '';
491
+ this.keywords = '';
492
+ this.disabled = false;
493
+ this.checked = false;
494
+ }
495
+
496
+ connectedCallback(): void {
497
+ super.connectedCallback?.();
498
+ this._id ||= `ui-command-item-${++uid}`;
499
+ (this.closest(ROOT) as UiCommand | null)?._partConnected();
500
+ }
501
+
502
+ get optionId(): string {
503
+ return `${this._id}-option`;
504
+ }
505
+
506
+ /** The item's value: its `value` attribute, else its text. */
507
+ get itemValue(): string {
508
+ if (this.value) return this.value;
509
+ const text = this.querySelector?.('[data-slot="command-item"]')?.textContent ?? this.textContent ?? '';
510
+ return text.trim();
511
+ }
512
+
513
+ scrollIntoViewIfShown(): void {
514
+ const option = this.querySelector?.<HTMLElement>('[data-slot="command-item"]');
515
+ if (option && typeof option.scrollIntoView === 'function') option.scrollIntoView({ block: 'nearest' });
516
+ }
517
+
518
+ updated(changedProperties: Map<string, unknown>): void {
519
+ super.updated?.(changedProperties);
520
+ const { order, visible } = this.state.get();
521
+ this.style.order = order ? String(order) : '';
522
+ this.hidden = !visible;
523
+ }
524
+
525
+ render() {
526
+ const s = this.state.get();
527
+ return html`<div
528
+ data-slot="command-item"
529
+ cmdk-item=""
530
+ role="option"
531
+ id=${this._id ? this.optionId : nothing}
532
+ aria-selected=${s.selected ? 'true' : 'false'}
533
+ data-selected=${s.selected ? 'true' : 'false'}
534
+ aria-disabled=${this.disabled ? 'true' : nothing}
535
+ data-disabled=${this.disabled ? 'true' : 'false'}
536
+ data-checked=${this.checked ? 'true' : nothing}
537
+ data-value=${this.value || nothing}
538
+ class=${cn(commandItemClass(), takeAuthored(this))}
539
+ @pointermove=${this._onPointerMove}
540
+ @click=${this._onClick}
541
+ ><slot></slot><svg
542
+ 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"
543
+ class=${commandItemIndicatorClass()}
544
+ ><path d="M20 6 9 17l-5-5"></path></svg></div>`;
545
+ }
546
+
547
+ _onPointerMove = (): void => {
548
+ if (this.state.get().selected) return;
549
+ (this.closest(ROOT) as UiCommand | null)?.selectItem(this);
550
+ };
551
+
552
+ _onClick = (e: Event): void => {
553
+ // A click on a link inside follows it natively; run the item's event too.
554
+ const root = this.closest(ROOT) as UiCommand | null;
555
+ if (!root || this.disabled) return;
556
+ const onLink = (e.target as Element).closest('a[href]');
557
+ const ok = this.dispatchEvent(new CustomEvent('ui-select', { bubbles: true, cancelable: true, detail: { value: this.itemValue } }));
558
+ if (!ok && onLink) e.preventDefault();
559
+ };
560
+ }
561
+ UiCommandItem.register('ui-command-item');
562
+
563
+ // --------------------------------------------------------------------------
564
+ // <ui-command-shortcut>
565
+ // --------------------------------------------------------------------------
566
+
567
+ export class UiCommandShortcut extends WebComponent {
568
+ // The span is the item's flex item, as shadcn's CommandShortcut is, so the
569
+ // styles' `ml-auto` pushes it to the end of the row. A shortcut never hides
570
+ // itself, so unlike the other parts its host can be display: contents,
571
+ // turned off through its style, which the server serves.
572
+ render() {
573
+ const authored = takeAuthored(this);
574
+ if (typeof this.getAttribute === 'function' && !this.getAttribute('style')) this.setAttribute('style', 'display: contents');
575
+ return html`<span data-slot="command-shortcut" class=${cn(commandShortcutClass(), authored)}><slot></slot></span>`;
576
+ }
577
+ }
578
+ UiCommandShortcut.register('ui-command-shortcut');
579
+
580
+ // --------------------------------------------------------------------------
581
+ // <ui-command-dialog>
582
+ // --------------------------------------------------------------------------
583
+
584
+ /**
585
+ * A command in a native modal dialog: a `<ui-dialog>` whose content the
586
+ * element renders itself, with a screen-reader title and description, around
587
+ * the `<ui-command>` you put inside, as in shadcn's CommandDialog.
588
+ */
589
+ export class UiCommandDialog extends UiDialog {
590
+ static rootTag = 'ui-command-dialog';
591
+ static contentTag = 'ui-command-dialog-content';
592
+ static slotPrefix = 'dialog';
593
+
594
+ // shadcn's CommandDialog passes its className to the DialogContent, so the
595
+ // class written on this host goes to the content, which puts it on the panel.
596
+ _authored: string | null = null;
597
+
598
+ render() {
599
+ this._authored = takeAuthoredClass(this, null);
600
+ const title = this.getAttribute?.('title') || 'Command Palette';
601
+ const description = this.getAttribute?.('description') || 'Search for a command to run...';
602
+ const close = this.getAttribute?.('show-close-button') ?? 'false';
603
+ return html`<div data-slot="dialog" data-state=${this.open ? 'open' : 'closed'}><ui-command-dialog-content
604
+ show-close-button=${close} class=${this._authored}><h2 data-slot="dialog-title" class="sr-only">${title}</h2><p
605
+ data-slot="dialog-description" class="sr-only">${description}</p><slot></slot></ui-command-dialog-content></div>`;
606
+ }
607
+ }
608
+ UiCommandDialog.register('ui-command-dialog');
609
+
610
+ export class UiCommandDialogContent extends UiDialogContent {
611
+ static rootTag = 'ui-command-dialog';
612
+ static slotPrefix = 'dialog';
613
+
614
+ _panelClass(): string {
615
+ return cn(super._panelClass(), commandDialogClass());
616
+ }
617
+ }
618
+ UiCommandDialogContent.register('ui-command-dialog-content');