@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
@@ -5,8 +5,12 @@
5
5
  * APG pattern: https://www.w3.org/WAI/ARIA/apg/patterns/menu/
6
6
  *
7
7
  * shadcn parity:
8
- * DropdownMenu → <ui-dropdown-menu open>
9
- * DropdownMenuTrigger → <ui-dropdown-menu-trigger>
8
+ * DropdownMenu → <ui-dropdown-menu open trigger>
9
+ * DropdownMenuTrigger → <ui-dropdown-menu-trigger>, or, for a trigger
10
+ * that must be a direct child of something
11
+ * else (a button group's corner rules select
12
+ * direct children), the button itself named by
13
+ * the menu's `trigger="<id>"`
10
14
  * DropdownMenuContent → <ui-dropdown-menu-content side align side-offset align-offset>
11
15
  * DropdownMenuItem → <ui-dropdown-menu-item variant inset>
12
16
  * DropdownMenuCheckboxItem → <ui-dropdown-menu-item type="checkbox" checked>
@@ -135,42 +139,107 @@
135
139
  * ```
136
140
  */
137
141
  import { WebComponent, html, unsafeHTML, signal, prop } from '@webjsdev/core';
138
- import { ensureId } from '../lib/utils.ts';
142
+ import { cn, ensureId, takeAuthoredClass } from '../lib/utils.ts';
139
143
  import { onBeforeCache } from '../lib/dom.ts';
140
- import { positionFloating, type PopoverSide, type PopoverAlign } from './popover.ts';
144
+
145
+ /**
146
+ * The tag family an element belongs to: `ui-dropdown-menu` here, and the
147
+ * family a subclass names when it reuses these elements under its own tags
148
+ * (context-menu, menubar). Every tag this file looks up is built from it, so
149
+ * a subclass's elements find each other and never a dropdown's.
150
+ */
151
+ function fam(el: Element): string {
152
+ return (el.constructor as { family?: string }).family ?? 'ui-dropdown-menu';
153
+ }
154
+
155
+ /** The data-slot for one part of an element's family: `dropdown-menu-item`, `context-menu-item`. */
156
+ function slot(el: Element, part: string): string {
157
+ return fam(el).replace(/^ui-/, '') + part;
158
+ }
159
+
160
+ /**
161
+ * The tag of the element that owns one menu: the family tag itself for a
162
+ * dropdown or a context menu, and `ui-menubar-menu` for a menubar, whose
163
+ * family tag is the bar that holds several menus.
164
+ */
165
+ function rootTag(el: Element): string {
166
+ return (el.constructor as { rootTag?: string }).rootTag ?? fam(el);
167
+ }
168
+ import { positionFloating } from './floating.ts';
169
+ import type { PopoverSide, PopoverAlign } from './popover.ts';
141
170
 
142
171
  // --------------------------------------------------------------------------
143
172
  // Class helpers
144
173
  // --------------------------------------------------------------------------
145
174
 
146
175
  export const dropdownMenuContentClass = (): string =>
147
- 'fixed z-50 max-h-[--available-height] min-w-[8rem] m-0 overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md';
176
+ 'cn-dropdown-menu-content z-50 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto data-[state=closed]:overflow-hidden not-open:hidden';
148
177
 
149
178
  export const dropdownMenuItemClass = (): string =>
150
- "relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:hover:bg-destructive/10 data-[variant=destructive]:hover:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 dark:data-[variant=destructive]:hover:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
179
+ 'cn-dropdown-menu-item group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0';
151
180
 
152
181
  export const dropdownMenuCheckboxItemClass = (): string =>
153
- "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0";
182
+ 'cn-dropdown-menu-checkbox-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0';
154
183
 
155
184
  export const dropdownMenuRadioItemClass = (): string =>
156
- "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8";
185
+ 'cn-dropdown-menu-radio-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0';
157
186
 
158
187
  export const dropdownMenuLabelClass = (): string =>
159
- 'px-2 pt-2 pb-1.5 text-xs font-semibold text-muted-foreground data-[inset]:pl-8';
188
+ 'cn-dropdown-menu-label';
160
189
 
161
- export const dropdownMenuSeparatorClass = (): string => '-mx-1 my-1 h-px bg-border';
190
+ export const dropdownMenuSeparatorClass = (): string => 'cn-dropdown-menu-separator';
162
191
 
163
192
  export const dropdownMenuShortcutClass = (): string =>
164
- 'ml-auto text-xs tracking-widest text-muted-foreground';
193
+ 'cn-dropdown-menu-shortcut';
165
194
 
166
195
  export const dropdownMenuSubTriggerClass = (): string =>
167
- "flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm select-none outline-hidden focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&>svg:last-child]:ml-auto";
196
+ 'cn-dropdown-menu-sub-trigger flex cursor-default items-center select-none outline-hidden [&_svg]:pointer-events-none [&_svg]:shrink-0';
168
197
 
169
198
  export const dropdownMenuSubContentClass = (): string =>
170
- 'fixed z-50 min-w-[8rem] m-0 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg';
199
+ 'cn-dropdown-menu-sub-content z-50 origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden not-open:hidden';
200
+
201
+ const dropdownMenuItemIndicatorClass = (): string =>
202
+ 'cn-dropdown-menu-item-indicator pointer-events-none';
203
+
204
+ /**
205
+ * The classes one menu family paints its parts with. Every element reads its
206
+ * classes through its family's table, so context-menu and menubar render the
207
+ * same elements under their own `cn-context-menu-*` / `cn-menubar-*` names,
208
+ * which is what each style keys on.
209
+ */
210
+ export interface MenuClasses {
211
+ content(): string;
212
+ item(): string;
213
+ checkboxItem(): string;
214
+ radioItem(): string;
215
+ /** A checkable item's indicator; menubar styles the checkbox and radio ones apart. */
216
+ itemIndicator(type?: 'checkbox' | 'radio'): string;
217
+ label(): string;
218
+ separator(): string;
219
+ shortcut(): string;
220
+ subTrigger(): string;
221
+ subContent(): string;
222
+ }
223
+
224
+ const DROPDOWN_MENU_CLASSES: MenuClasses = {
225
+ content: dropdownMenuContentClass,
226
+ item: dropdownMenuItemClass,
227
+ checkboxItem: dropdownMenuCheckboxItemClass,
228
+ radioItem: dropdownMenuRadioItemClass,
229
+ itemIndicator: dropdownMenuItemIndicatorClass,
230
+ label: dropdownMenuLabelClass,
231
+ separator: dropdownMenuSeparatorClass,
232
+ shortcut: dropdownMenuShortcutClass,
233
+ subTrigger: dropdownMenuSubTriggerClass,
234
+ subContent: dropdownMenuSubContentClass,
235
+ };
236
+
237
+ function cls(el: Element): MenuClasses {
238
+ return (el.constructor as { classes?: MenuClasses }).classes ?? DROPDOWN_MENU_CLASSES;
239
+ }
171
240
 
172
241
  const CHEVRON_RIGHT_SVG =
173
- '<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" class="ml-auto size-4" aria-hidden="true"><polyline points="9 18 15 12 9 6"></polyline></svg>';
242
+ '<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" class="cn-rtl-flip ms-auto size-4 rtl:rotate-180" aria-hidden="true"><polyline points="9 18 15 12 9 6"></polyline></svg>';
174
243
 
175
244
  // Checked-state indicators for a checkbox / radio item. Decorative: the state
176
245
  // they draw is announced from aria-checked, so both are aria-hidden.
@@ -195,11 +264,15 @@ const ENABLED_MENU_ITEM = `${MENU_ITEM}:not([data-disabled])`;
195
264
  export class UiDropdownMenu extends WebComponent({
196
265
  open: prop(Boolean, { reflect: true }),
197
266
  }) {
267
+ static family = 'ui-dropdown-menu';
268
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
198
269
  _typeBuffer = '';
199
270
  _typeBufferTimer: number | undefined;
200
271
 
201
272
  _docClickHandler = (e: MouseEvent): void => this._onDocClick(e);
202
273
  _docPointerDownHandler = (e: Event): void => this._onDocPointerDown(e);
274
+ _externalClick = (e: MouseEvent): void => this.toggle(e);
275
+ _wiredExternal: HTMLElement | null = null;
203
276
  _keyHandler = (e: KeyboardEvent): void => this._onKeyDown(e);
204
277
  _resizeHandler = (): void => this._reposition();
205
278
 
@@ -213,10 +286,60 @@ export class UiDropdownMenu extends WebComponent({
213
286
  disconnectedCallback(): void {
214
287
  if (this.open) this._teardown();
215
288
  this._disposeBeforeCache?.();
289
+ this._wiredExternal?.removeEventListener('click', this._externalClick);
290
+ this._wiredExternal = null;
216
291
  super.disconnectedCallback?.();
217
292
  }
218
293
 
219
- toggle(): void { this.open = !this.open; }
294
+ /**
295
+ * The control a `trigger="<id>"` attribute names, when the menu has no
296
+ * <ui-dropdown-menu-trigger> child. shadcn's trigger is `asChild`, so the
297
+ * button is wherever the author put it, typically the direct child of a
298
+ * button group, whose corner rules select direct children. A wrapper there
299
+ * would be the child instead of the button, so the menu can name a button
300
+ * that lives outside it.
301
+ */
302
+ _external(): HTMLElement | null {
303
+ const id = typeof this.getAttribute === 'function' ? this.getAttribute('trigger') : null;
304
+ if (!id || typeof document === 'undefined') return null;
305
+ if (this.querySelector(`${fam(this)}-trigger`)) return null;
306
+ return document.getElementById(id);
307
+ }
308
+
309
+ /**
310
+ * The element the panel is positioned against: the control itself, as
311
+ * Radix's asChild trigger is, never the `-trigger` wrapper, which is a block
312
+ * and would lend the panel a whole row's width and start edge.
313
+ */
314
+ _anchor(): HTMLElement | null {
315
+ return this._triggerControl();
316
+ }
317
+
318
+ /** Inside the menu for an outside-click check: the menu itself, or its named trigger. */
319
+ _owns(n: EventTarget): boolean {
320
+ return n === this || (!!this._wiredExternal && n === this._wiredExternal);
321
+ }
322
+
323
+ _wireExternal(): void {
324
+ const control = this._external();
325
+ if (control === this._wiredExternal) return;
326
+ this._wiredExternal?.removeEventListener('click', this._externalClick);
327
+ control?.addEventListener('click', this._externalClick);
328
+ this._wiredExternal = control;
329
+ }
330
+
331
+ /**
332
+ * Whether the menu was last opened by a pointer. A click a keyboard
333
+ * produced (Enter or Space on the trigger) has `detail` 0; a real press
334
+ * counts its clicks. As in shadcn, a pointer open focuses the panel and
335
+ * highlights nothing, and a keyboard open moves to the first item.
336
+ */
337
+ _pointerOpen = false;
338
+
339
+ toggle(e?: MouseEvent): void {
340
+ this._pointerOpen = !!e && e.detail > 0;
341
+ this.open = !this.open;
342
+ }
220
343
  show(): void { this.open = true; }
221
344
  hide(): void { this.open = false; }
222
345
 
@@ -245,7 +368,7 @@ export class UiDropdownMenu extends WebComponent({
245
368
  }
246
369
 
247
370
  render() {
248
- return html`<div data-slot="dropdown-menu" data-state=${this.open ? 'open' : 'closed'}>
371
+ return html`<div data-slot=${rootTag(this).replace(/^ui-/, '')} data-state=${this.open ? 'open' : 'closed'}>
249
372
  <slot></slot>
250
373
  </div>`;
251
374
  }
@@ -263,7 +386,10 @@ export class UiDropdownMenu extends WebComponent({
263
386
  // render, so the trigger button and the menu are not in place at
264
387
  // connect. Defer to the next frame, when the projection has run.
265
388
  if (typeof requestAnimationFrame === 'function') {
266
- requestAnimationFrame(() => this._wireAria());
389
+ requestAnimationFrame(() => {
390
+ this._wireExternal();
391
+ this._wireAria();
392
+ });
267
393
  }
268
394
  // Close (and tear down) before a back/forward snapshot so the menu does not
269
395
  // restore open (#766). Closing the root also hides any open submenu.
@@ -286,8 +412,8 @@ export class UiDropdownMenu extends WebComponent({
286
412
  // the menu, and the menu is labelled back by the trigger. Done at runtime
287
413
  // because the menu is JS-driven (never shown without script).
288
414
  _triggerControl(): HTMLElement | null {
289
- const trigger = this.querySelector('ui-dropdown-menu-trigger');
290
- if (!trigger) return null;
415
+ const trigger = this.querySelector(`${fam(this)}-trigger`);
416
+ if (!trigger) return this._external();
291
417
  return (
292
418
  trigger.querySelector<HTMLElement>('button, [role="button"], a[href], [tabindex]') ??
293
419
  (trigger as HTMLElement)
@@ -295,7 +421,7 @@ export class UiDropdownMenu extends WebComponent({
295
421
  }
296
422
 
297
423
  _menuEl(): HTMLElement | null {
298
- return this.querySelector('ui-dropdown-menu-content [role="menu"]');
424
+ return this.querySelector(`${fam(this)}-content [role="menu"]`);
299
425
  }
300
426
 
301
427
  _wireAria(): void {
@@ -317,19 +443,19 @@ export class UiDropdownMenu extends WebComponent({
317
443
  // menuitem that opens it, with that menuitem pointing back via aria-controls.
318
444
  // Only the root panel was wired, so every submenu shipped as an unnamed menu.
319
445
  _wireSubmenuAria(): void {
320
- this.querySelectorAll<HTMLElement>('ui-dropdown-menu-sub').forEach((sub) => {
446
+ this.querySelectorAll<HTMLElement>(`${fam(this)}-sub`).forEach((sub) => {
321
447
  // NOT `:scope >`: the sub renders its own wrapper div with a <slot>, so the
322
448
  // trigger and content are grandchildren, not direct children. Match on the
323
449
  // nearest enclosing sub instead, which also keeps a NESTED submenu's nodes
324
450
  // from being wired to its outer sub.
325
451
  const owns = (el: Element | null): boolean =>
326
- !!el && el.closest('ui-dropdown-menu-sub') === sub;
452
+ !!el && el.closest(`${fam(this)}-sub`) === sub;
327
453
  const trigger = Array.from(
328
- sub.querySelectorAll<HTMLElement>(`ui-dropdown-menu-sub-trigger ${MENU_ITEM}`),
329
- ).find((el) => owns(el.closest('ui-dropdown-menu-sub-trigger')));
454
+ sub.querySelectorAll<HTMLElement>(`${fam(this)}-sub-trigger ${MENU_ITEM}`),
455
+ ).find((el) => owns(el.closest(`${fam(this)}-sub-trigger`)));
330
456
  const panel = Array.from(
331
- sub.querySelectorAll<HTMLElement>('ui-dropdown-menu-sub-content [role="menu"]'),
332
- ).find((el) => owns(el.closest('ui-dropdown-menu-sub-content')));
457
+ sub.querySelectorAll<HTMLElement>(`${fam(this)}-sub-content [role="menu"]`),
458
+ ).find((el) => owns(el.closest(`${fam(this)}-sub-content`)));
333
459
  if (!trigger || !panel) return;
334
460
  trigger.setAttribute('aria-controls', ensureId(panel, 'ui-submenu'));
335
461
  if (!panel.hasAttribute('aria-label') && !panel.hasAttribute('aria-labelledby')) {
@@ -339,7 +465,7 @@ export class UiDropdownMenu extends WebComponent({
339
465
  }
340
466
 
341
467
  _content(): HTMLElement | null {
342
- return this.querySelector('ui-dropdown-menu-content [popover]');
468
+ return this.querySelector(`${fam(this)}-content [popover]`);
343
469
  }
344
470
 
345
471
  _syncContentPopover(content: HTMLElement): void {
@@ -353,16 +479,24 @@ export class UiDropdownMenu extends WebComponent({
353
479
  else if (!this.open && p.matches(':popover-open')) p.hidePopover();
354
480
  }
355
481
 
482
+ /**
483
+ * The panel's offsets when its content element names none: shadcn's
484
+ * dropdown sits 4px off its trigger, a menubar menu 8px off and 4px back.
485
+ */
486
+ static placement = { sideOffset: 4, alignOffset: 0 };
487
+
356
488
  _reposition(): void {
357
- const trigger = this.querySelector<HTMLElement>('ui-dropdown-menu-trigger');
489
+ const placement = (this.constructor as typeof UiDropdownMenu).placement;
490
+ const trigger = this._anchor();
358
491
  const content = this._content();
359
- const host = this.querySelector<HTMLElement>('ui-dropdown-menu-content');
492
+ const host = this.querySelector<HTMLElement>(`${fam(this)}-content`);
360
493
  if (!trigger || !content || !host) return;
361
494
  positionFloating(trigger, content, {
362
495
  side: (host.getAttribute('side') ?? 'bottom') as PopoverSide,
363
496
  align: (host.getAttribute('align') ?? 'start') as PopoverAlign,
364
- sideOffset: Number(host.getAttribute('side-offset') ?? 4),
365
- alignOffset: Number(host.getAttribute('align-offset') ?? 0),
497
+ sideOffset: Number(host.getAttribute('side-offset') ?? placement.sideOffset),
498
+ alignOffset: Number(host.getAttribute('align-offset') ?? placement.alignOffset),
499
+ radix: fam(this).slice(3),
366
500
  });
367
501
  }
368
502
 
@@ -374,8 +508,12 @@ export class UiDropdownMenu extends WebComponent({
374
508
  window.addEventListener('resize', this._resizeHandler);
375
509
  window.addEventListener('scroll', this._resizeHandler, true);
376
510
  queueMicrotask(() => {
511
+ if (this._pointerOpen) {
512
+ this._menuEl()?.focus();
513
+ return;
514
+ }
377
515
  const first = this.querySelector<HTMLElement>(
378
- `ui-dropdown-menu-item:not([data-disabled]) ${MENU_ITEM}`,
516
+ `${fam(this)}-item:not([data-disabled]) ${MENU_ITEM}`,
379
517
  );
380
518
  first?.focus();
381
519
  });
@@ -388,7 +526,7 @@ export class UiDropdownMenu extends WebComponent({
388
526
  this._focusWasInsideAtPointerDown = false;
389
527
  window.removeEventListener('resize', this._resizeHandler);
390
528
  window.removeEventListener('scroll', this._resizeHandler, true);
391
- this.querySelectorAll<UiDropdownMenuSub>('ui-dropdown-menu-sub[open]').forEach(
529
+ this.querySelectorAll<UiDropdownMenuSub>(`${fam(this)}-sub[open]`).forEach(
392
530
  (sub) => sub.hide(),
393
531
  );
394
532
  }
@@ -402,13 +540,13 @@ export class UiDropdownMenu extends WebComponent({
402
540
 
403
541
  _onDocPointerDown(e: Event): void {
404
542
  if (!this.open) return;
405
- if (e.composedPath().some((n) => n === this)) return;
543
+ if (e.composedPath().some((n) => this._owns(n))) return;
406
544
  this._focusWasInsideAtPointerDown = this._focusIsInside();
407
545
  }
408
546
 
409
547
  _onDocClick(e: MouseEvent): void {
410
548
  if (!this.open) return;
411
- if (e.composedPath().some((n) => n === this)) return;
549
+ if (e.composedPath().some((n) => this._owns(n))) return;
412
550
  // An outside click dismisses the menu, and it is still a close of a
413
551
  // popover="manual" panel, so it owes the same focus care as Escape: leaving
414
552
  // focus on an item that is about to become display:none drops it to <body>.
@@ -440,10 +578,10 @@ export class UiDropdownMenu extends WebComponent({
440
578
  // submenu first"). Focus on the sub-trigger itself is focus in the ROOT
441
579
  // panel, so that case closes the whole menu, which is why this reads the
442
580
  // panel rather than walking up to any open <ui-dropdown-menu-sub>.
443
- const subContent = context?.closest('ui-dropdown-menu-sub-content');
444
- const sub = subContent?.closest('ui-dropdown-menu-sub') as UiDropdownMenuSub | null;
581
+ const subContent = context?.closest(`${fam(this)}-sub-content`);
582
+ const sub = subContent?.closest(`${fam(this)}-sub`) as UiDropdownMenuSub | null;
445
583
  if (sub) {
446
- sub.querySelector<HTMLElement>(`ui-dropdown-menu-sub-trigger ${MENU_ITEM}`)?.focus();
584
+ sub.querySelector<HTMLElement>(`${fam(this)}-sub-trigger ${MENU_ITEM}`)?.focus();
447
585
  sub.hide();
448
586
  return;
449
587
  }
@@ -476,7 +614,8 @@ export class UiDropdownMenu extends WebComponent({
476
614
  items[(idx + 1) % items.length].focus();
477
615
  } else if (e.key === 'ArrowUp') {
478
616
  e.preventDefault();
479
- items[(idx - 1 + items.length) % items.length].focus();
617
+ // From the panel itself (a pointer open), ArrowUp goes to the last item.
618
+ items[idx < 0 ? items.length - 1 : (idx - 1 + items.length) % items.length].focus();
480
619
  } else if (e.key === 'Home') {
481
620
  e.preventDefault();
482
621
  items[0].focus();
@@ -485,10 +624,10 @@ export class UiDropdownMenu extends WebComponent({
485
624
  items[items.length - 1].focus();
486
625
  } else if (e.key === 'ArrowRight') {
487
626
  // Open submenu owned by the focused sub-trigger and move focus into it.
488
- const subTrigger = active?.closest('ui-dropdown-menu-sub-trigger');
627
+ const subTrigger = active?.closest(`${fam(this)}-sub-trigger`);
489
628
  if (subTrigger) {
490
629
  e.preventDefault();
491
- const sub = subTrigger.closest('ui-dropdown-menu-sub') as UiDropdownMenuSub | null;
630
+ const sub = subTrigger.closest(`${fam(this)}-sub`) as UiDropdownMenuSub | null;
492
631
  // The sub owns the open-then-focus sequencing: its panel is
493
632
  // popover="manual" and only becomes visible a microtask later, so
494
633
  // focusing from here races the reveal and loses (see the method).
@@ -496,11 +635,11 @@ export class UiDropdownMenu extends WebComponent({
496
635
  }
497
636
  } else if (e.key === 'ArrowLeft') {
498
637
  // Inside a sub-content: close the submenu and refocus its trigger.
499
- if (context.closest('ui-dropdown-menu-sub-content')) {
638
+ if (context.closest(`${fam(this)}-sub-content`)) {
500
639
  e.preventDefault();
501
- const sub = context.closest('ui-dropdown-menu-sub') as UiDropdownMenuSub | null;
640
+ const sub = context.closest(`${fam(this)}-sub`) as UiDropdownMenuSub | null;
502
641
  const trigger = sub?.querySelector<HTMLElement>(
503
- `ui-dropdown-menu-sub-trigger ${MENU_ITEM}`,
642
+ `${fam(this)}-sub-trigger ${MENU_ITEM}`,
504
643
  );
505
644
  trigger?.focus();
506
645
  sub?.hide();
@@ -516,8 +655,8 @@ export class UiDropdownMenu extends WebComponent({
516
655
  // too, so preventing Space unconditionally would swallow it there with
517
656
  // nothing to handle it, and the user could not type a space into their own
518
657
  // input. Bail before touching the event when the focus is not an item.
519
- const subTrigger = active?.closest('ui-dropdown-menu-sub-trigger');
520
- const activeItem = active?.closest('ui-dropdown-menu-item') as UiDropdownMenuItem | null;
658
+ const subTrigger = active?.closest(`${fam(this)}-sub-trigger`);
659
+ const activeItem = active?.closest(`${fam(this)}-item`) as UiDropdownMenuItem | null;
521
660
  if (!subTrigger && !activeItem) return;
522
661
  // Space while a typeahead search is in flight belongs to the SEARCH, or a
523
662
  // multi-word item is unreachable past its first word ("Status bar" could
@@ -533,7 +672,7 @@ export class UiDropdownMenu extends WebComponent({
533
672
  if (subTrigger) {
534
673
  // Same as ArrowRight on a sub-trigger: open it and move focus in.
535
674
  if (!subTrigger.hasAttribute('data-disabled')) {
536
- const sub = subTrigger.closest('ui-dropdown-menu-sub') as UiDropdownMenuSub | null;
675
+ const sub = subTrigger.closest(`${fam(this)}-sub`) as UiDropdownMenuSub | null;
537
676
  sub?.openAndFocusFirstItem();
538
677
  }
539
678
  return;
@@ -566,14 +705,16 @@ UiDropdownMenu.register('ui-dropdown-menu');
566
705
  // --------------------------------------------------------------------------
567
706
 
568
707
  export class UiDropdownMenuTrigger extends WebComponent {
708
+ static family = 'ui-dropdown-menu';
709
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
569
710
  render() {
570
711
  return html`<div
571
- data-slot="dropdown-menu-trigger"
712
+ data-slot=${slot(this, '-trigger')}
572
713
  @click=${this._onClick}
573
714
  ><slot></slot></div>`;
574
715
  }
575
716
 
576
- _onClick = (): void => (this.closest('ui-dropdown-menu') as UiDropdownMenu | null)?.toggle();
717
+ _onClick = (e: MouseEvent): void => (this.closest(rootTag(this)) as UiDropdownMenu | null)?.toggle(e);
577
718
  }
578
719
  UiDropdownMenuTrigger.register('ui-dropdown-menu-trigger');
579
720
 
@@ -582,13 +723,25 @@ UiDropdownMenuTrigger.register('ui-dropdown-menu-trigger');
582
723
  // --------------------------------------------------------------------------
583
724
 
584
725
  export class UiDropdownMenuContent extends WebComponent {
726
+ static family = 'ui-dropdown-menu';
727
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
728
+ _authored: string | null = null;
729
+
730
+ // The class an author writes on the content is shadcn's `className` on
731
+ // DropdownMenuContent, which lands on the menu panel (a `w-40`, say), so it
732
+ // moves from this host onto the panel. `text-start` undoes the legacy HTML
733
+ // `align` attribute: `align="end"` here means "align the panel's end with
734
+ // the trigger's", but browsers also map it to `text-align: end`, which every
735
+ // label and item in the menu would inherit.
585
736
  render() {
737
+ this._authored = takeAuthoredClass(this, null);
586
738
  return html`<div
587
- data-slot="dropdown-menu-content"
739
+ data-slot=${slot(this, '-content')}
588
740
  role="menu"
589
741
  aria-orientation="vertical"
590
742
  popover="manual"
591
- class=${dropdownMenuContentClass()}
743
+ tabindex="-1"
744
+ class=${cn(cls(this).content(), 'text-start', this._authored)}
592
745
  ><slot></slot></div>`;
593
746
  }
594
747
  }
@@ -609,11 +762,13 @@ export class UiDropdownMenuItem extends WebComponent({
609
762
  checked: prop(Boolean, { reflect: true }),
610
763
  value: prop(String, { reflect: true }),
611
764
  }) {
765
+ static family = 'ui-dropdown-menu';
766
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
612
767
  // Keyboard / pointer highlight state for the own-rendered menuitem. A
613
768
  // local signal bound with ?data-highlighted keeps the highlight in the
614
769
  // declarative template instead of an imperative setAttribute on
615
770
  // e.currentTarget (the lit-idiomatic form).
616
- #highlighted = signal(false);
771
+ readonly #highlighted = signal(false);
617
772
 
618
773
  constructor() {
619
774
  super();
@@ -645,7 +800,7 @@ export class UiDropdownMenuItem extends WebComponent({
645
800
  // shapes differ by the indicator anyway.
646
801
  if (checkbox || radio) {
647
802
  return html`<div
648
- data-slot=${`dropdown-menu-${this.type}-item`}
803
+ data-slot=${slot(this, `-${this.type}-item`)}
649
804
  role=${checkbox ? 'menuitemcheckbox' : 'menuitemradio'}
650
805
  tabindex="-1"
651
806
  data-variant=${this.variant}
@@ -655,17 +810,17 @@ export class UiDropdownMenuItem extends WebComponent({
655
810
  aria-checked=${String(this.checked)}
656
811
  data-state=${this.checked ? 'checked' : 'unchecked'}
657
812
  ?data-highlighted=${this.#highlighted.get()}
658
- class=${checkbox ? dropdownMenuCheckboxItemClass() : dropdownMenuRadioItemClass()}
813
+ class=${checkbox ? cls(this).checkboxItem() : cls(this).radioItem()}
659
814
  @click=${this._onClick}
660
815
  @pointerenter=${this._onPointerEnter}
661
816
  @focus=${this._onFocus}
662
817
  @blur=${this._onBlur}
663
818
  ><span
664
- class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center"
819
+ class=${cls(this).itemIndicator(checkbox ? 'checkbox' : 'radio')}
665
820
  >${this.checked ? unsafeHTML(radio ? RADIO_DOT_SVG : CHECK_SVG) : ''}</span><slot></slot></div>`;
666
821
  }
667
822
  return html`<div
668
- data-slot="dropdown-menu-item"
823
+ data-slot=${slot(this, '-item')}
669
824
  role="menuitem"
670
825
  tabindex="-1"
671
826
  data-variant=${this.variant}
@@ -673,7 +828,7 @@ export class UiDropdownMenuItem extends WebComponent({
673
828
  ?data-disabled=${disabled}
674
829
  aria-disabled=${disabled ? 'true' : 'false'}
675
830
  ?data-highlighted=${this.#highlighted.get()}
676
- class=${dropdownMenuItemClass()}
831
+ class=${cls(this).item()}
677
832
  @click=${this._onClick}
678
833
  @pointerenter=${this._onPointerEnter}
679
834
  @focus=${this._onFocus}
@@ -702,7 +857,7 @@ export class UiDropdownMenuItem extends WebComponent({
702
857
  }),
703
858
  );
704
859
  if (!proceed) return;
705
- (this.closest('ui-dropdown-menu') as UiDropdownMenu | null)?._closeAndRestoreFocus();
860
+ (this.closest(rootTag(this)) as UiDropdownMenu | null)?._closeAndRestoreFocus();
706
861
  }
707
862
 
708
863
  // The radio set is the nearest <ui-dropdown-menu-group>, which is the APG
@@ -711,9 +866,9 @@ export class UiDropdownMenuItem extends WebComponent({
711
866
  _radioScope(): Element | null {
712
867
  if (typeof this.closest !== 'function') return null;
713
868
  return (
714
- this.closest('ui-dropdown-menu-group') ??
715
- this.closest('ui-dropdown-menu-sub-content') ??
716
- this.closest('ui-dropdown-menu-content')
869
+ this.closest(`${fam(this)}-group`) ??
870
+ this.closest(`${fam(this)}-sub-content`) ??
871
+ this.closest(`${fam(this)}-content`)
717
872
  );
718
873
  }
719
874
 
@@ -727,7 +882,7 @@ export class UiDropdownMenuItem extends WebComponent({
727
882
  // is unreflected, so an item configured through the property alone would
728
883
  // be invisible to an attribute query and survive as a second checked item.
729
884
  // The scope re-check keeps a nested group's items out of this set.
730
- Array.from(scope.querySelectorAll<UiDropdownMenuItem>('ui-dropdown-menu-item'))
885
+ Array.from(scope.querySelectorAll<UiDropdownMenuItem>(`${fam(this)}-item`))
731
886
  .filter((it) => it.type === 'radio' && it._radioScope() === scope)
732
887
  .forEach((it) => {
733
888
  it.checked = it === this;
@@ -755,6 +910,8 @@ UiDropdownMenuItem.register('ui-dropdown-menu-item');
755
910
  // --------------------------------------------------------------------------
756
911
 
757
912
  export class UiDropdownMenuLabel extends WebComponent({ inset: Boolean }) {
913
+ static family = 'ui-dropdown-menu';
914
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
758
915
  constructor() {
759
916
  super();
760
917
  this.inset = false;
@@ -762,9 +919,9 @@ export class UiDropdownMenuLabel extends WebComponent({ inset: Boolean }) {
762
919
 
763
920
  render() {
764
921
  return html`<div
765
- data-slot="dropdown-menu-label"
922
+ data-slot=${slot(this, '-label')}
766
923
  ?data-inset=${this.inset}
767
- class=${dropdownMenuLabelClass()}
924
+ class=${cls(this).label()}
768
925
  ><slot></slot></div>`;
769
926
  }
770
927
  }
@@ -775,11 +932,13 @@ UiDropdownMenuLabel.register('ui-dropdown-menu-label');
775
932
  // --------------------------------------------------------------------------
776
933
 
777
934
  export class UiDropdownMenuSeparator extends WebComponent {
935
+ static family = 'ui-dropdown-menu';
936
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
778
937
  render() {
779
938
  return html`<div
780
- data-slot="dropdown-menu-separator"
939
+ data-slot=${slot(this, '-separator')}
781
940
  role="separator"
782
- class=${dropdownMenuSeparatorClass()}
941
+ class=${cls(this).separator()}
783
942
  ></div>`;
784
943
  }
785
944
  }
@@ -790,10 +949,16 @@ UiDropdownMenuSeparator.register('ui-dropdown-menu-separator');
790
949
  // --------------------------------------------------------------------------
791
950
 
792
951
  export class UiDropdownMenuShortcut extends WebComponent {
952
+ static family = 'ui-dropdown-menu';
953
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
954
+ // The span is the item's flex item, as shadcn's shortcut is, so the styles'
955
+ // `ms-auto` pushes it to the end of the row. The host's box is turned off
956
+ // through its style, which the server serves.
793
957
  render() {
958
+ if (typeof this.getAttribute === 'function' && !this.getAttribute('style')) this.setAttribute('style', 'display: contents');
794
959
  return html`<span
795
- data-slot="dropdown-menu-shortcut"
796
- class=${dropdownMenuShortcutClass()}
960
+ data-slot=${slot(this, '-shortcut')}
961
+ class=${cls(this).shortcut()}
797
962
  ><slot></slot></span>`;
798
963
  }
799
964
  }
@@ -804,6 +969,8 @@ UiDropdownMenuShortcut.register('ui-dropdown-menu-shortcut');
804
969
  // --------------------------------------------------------------------------
805
970
 
806
971
  export class UiDropdownMenuGroup extends WebComponent {
972
+ static family = 'ui-dropdown-menu';
973
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
807
974
  // role="group", NOT role="radiogroup". radiogroup is the grouping role for
808
975
  // role="radio"; the grouping role ARIA specifies for menuitemradio is plain
809
976
  // group, so a radio set inside this element is already correctly grouped.
@@ -822,20 +989,20 @@ export class UiDropdownMenuGroup extends WebComponent {
822
989
  const label = attr('aria-label');
823
990
  if (labelledBy) {
824
991
  return html`<div
825
- data-slot="dropdown-menu-group"
992
+ data-slot=${slot(this, '-group')}
826
993
  role="group"
827
994
  aria-labelledby=${labelledBy}
828
995
  ><slot></slot></div>`;
829
996
  }
830
997
  if (label) {
831
998
  return html`<div
832
- data-slot="dropdown-menu-group"
999
+ data-slot=${slot(this, '-group')}
833
1000
  role="group"
834
1001
  aria-label=${label}
835
1002
  ><slot></slot></div>`;
836
1003
  }
837
1004
  return html`<div
838
- data-slot="dropdown-menu-group"
1005
+ data-slot=${slot(this, '-group')}
839
1006
  role="group"
840
1007
  ><slot></slot></div>`;
841
1008
  }
@@ -849,6 +1016,8 @@ UiDropdownMenuGroup.register('ui-dropdown-menu-group');
849
1016
  export class UiDropdownMenuSub extends WebComponent({
850
1017
  open: prop(Boolean, { reflect: true }),
851
1018
  }) {
1019
+ static family = 'ui-dropdown-menu';
1020
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
852
1021
  _closeTimer: number | undefined;
853
1022
 
854
1023
  constructor() {
@@ -883,7 +1052,7 @@ export class UiDropdownMenuSub extends WebComponent({
883
1052
 
884
1053
  _panelIsOpen(): boolean {
885
1054
  const panel = this.querySelector<HTMLElement & { showPopover?: () => void }>(
886
- 'ui-dropdown-menu-sub-content [popover]',
1055
+ `${fam(this)}-sub-content [popover]`,
887
1056
  );
888
1057
  // Gate on showPopover, not just on matches, like the two sibling call sites.
889
1058
  // `:popover-open` is an unknown pseudo-class where the Popover API is
@@ -898,13 +1067,13 @@ export class UiDropdownMenuSub extends WebComponent({
898
1067
  if (!this._focusFirstOnOpen) return;
899
1068
  this._focusFirstOnOpen = false;
900
1069
  this.querySelector<HTMLElement>(
901
- `ui-dropdown-menu-sub-content ${ENABLED_MENU_ITEM}`,
1070
+ `${fam(this)}-sub-content ${ENABLED_MENU_ITEM}`,
902
1071
  )?.focus();
903
1072
  }
904
1073
 
905
1074
  render() {
906
1075
  return html`<div
907
- data-slot="dropdown-menu-sub"
1076
+ data-slot=${slot(this, '-sub')}
908
1077
  data-state=${this.open ? 'open' : 'closed'}
909
1078
  @pointerenter=${this._cancelCloseHandler}
910
1079
  @pointerleave=${this._scheduleCloseHandler}
@@ -918,7 +1087,7 @@ export class UiDropdownMenuSub extends WebComponent({
918
1087
  }
919
1088
 
920
1089
  _afterRender(): void {
921
- const subContent = this.querySelector<HTMLElement>('ui-dropdown-menu-sub-content [popover]');
1090
+ const subContent = this.querySelector<HTMLElement>(`${fam(this)}-sub-content [popover]`);
922
1091
  if (subContent) {
923
1092
  const p = subContent as HTMLElement & {
924
1093
  showPopover?: () => void;
@@ -963,24 +1132,27 @@ export class UiDropdownMenuSub extends WebComponent({
963
1132
 
964
1133
  _position(): void {
965
1134
  const trigger = this.querySelector<HTMLElement>(
966
- 'ui-dropdown-menu-sub-trigger [role="menuitem"]',
1135
+ `${fam(this)}-sub-trigger [role="menuitem"]`,
967
1136
  );
968
1137
  const content = this.querySelector<HTMLElement>(
969
- 'ui-dropdown-menu-sub-content [popover]',
1138
+ `${fam(this)}-sub-content [popover]`,
970
1139
  );
971
- const contentHost = this.querySelector<HTMLElement>('ui-dropdown-menu-sub-content');
1140
+ const contentHost = this.querySelector<HTMLElement>(`${fam(this)}-sub-content`);
972
1141
  if (!trigger || !content || !contentHost) return;
973
1142
  positionFloating(trigger, content, {
974
1143
  side: (contentHost.getAttribute('side') ?? 'right') as PopoverSide,
975
1144
  align: (contentHost.getAttribute('align') ?? 'start') as PopoverAlign,
976
1145
  sideOffset: Number(contentHost.getAttribute('side-offset') ?? -4),
977
1146
  alignOffset: Number(contentHost.getAttribute('align-offset') ?? 0),
1147
+ radix: fam(this).slice(3),
978
1148
  });
979
1149
  }
980
1150
  }
981
1151
  UiDropdownMenuSub.register('ui-dropdown-menu-sub');
982
1152
 
983
1153
  export class UiDropdownMenuSubTrigger extends WebComponent({ inset: Boolean }) {
1154
+ static family = 'ui-dropdown-menu';
1155
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
984
1156
  constructor() {
985
1157
  super();
986
1158
  this.inset = false;
@@ -989,14 +1161,14 @@ export class UiDropdownMenuSubTrigger extends WebComponent({ inset: Boolean }) {
989
1161
  // SSR-safe: linkedom doesn't implement closest() on custom elements.
990
1162
  _sub(): UiDropdownMenuSub | null {
991
1163
  if (typeof this.closest !== 'function') return null;
992
- return this.closest('ui-dropdown-menu-sub') as UiDropdownMenuSub | null;
1164
+ return this.closest(`${fam(this)}-sub`) as UiDropdownMenuSub | null;
993
1165
  }
994
1166
 
995
1167
  render() {
996
1168
  const open = !!this._sub()?.open;
997
1169
  const disabled = typeof this.hasAttribute === 'function' && this.hasAttribute('data-disabled');
998
1170
  return html`<div
999
- data-slot="dropdown-menu-sub-trigger"
1171
+ data-slot=${slot(this, '-sub-trigger')}
1000
1172
  role="menuitem"
1001
1173
  tabindex="-1"
1002
1174
  aria-haspopup="menu"
@@ -1005,7 +1177,7 @@ export class UiDropdownMenuSubTrigger extends WebComponent({ inset: Boolean }) {
1005
1177
  data-state=${open ? 'open' : 'closed'}
1006
1178
  ?data-inset=${this.inset}
1007
1179
  ?data-disabled=${disabled}
1008
- class=${dropdownMenuSubTriggerClass()}
1180
+ class=${cls(this).subTrigger()}
1009
1181
  @click=${this._onClick}
1010
1182
  @pointerenter=${this._onPointerEnter}
1011
1183
  ><slot></slot>${unsafeHTML(CHEVRON_RIGHT_SVG)}</div>`;
@@ -1031,13 +1203,20 @@ export class UiDropdownMenuSubTrigger extends WebComponent({ inset: Boolean }) {
1031
1203
  UiDropdownMenuSubTrigger.register('ui-dropdown-menu-sub-trigger');
1032
1204
 
1033
1205
  export class UiDropdownMenuSubContent extends WebComponent {
1206
+ static family = 'ui-dropdown-menu';
1207
+ static classes: MenuClasses = DROPDOWN_MENU_CLASSES;
1208
+ _authored: string | null = null;
1209
+
1210
+ // As on the content: shadcn's className on the sub-content lands on the
1211
+ // submenu panel, so the class written on this host moves there.
1034
1212
  render() {
1213
+ this._authored = takeAuthoredClass(this, null);
1035
1214
  return html`<div
1036
- data-slot="dropdown-menu-sub-content"
1215
+ data-slot=${slot(this, '-sub-content')}
1037
1216
  role="menu"
1038
1217
  aria-orientation="vertical"
1039
1218
  popover="manual"
1040
- class=${dropdownMenuSubContentClass()}
1219
+ class=${cn(cls(this).subContent(), this._authored)}
1041
1220
  ><slot></slot></div>`;
1042
1221
  }
1043
1222
  }