@webjsdev/ui 0.3.16 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/README.md +71 -10
  2. package/THIRD_PARTY_NOTICES.md +349 -0
  3. package/package.json +4 -2
  4. package/packages/registry/blocks/_shared/placeholder.svg +1 -0
  5. package/packages/registry/blocks/charts/chart-area-axes.ts +72 -0
  6. package/packages/registry/blocks/charts/chart-area-default.ts +64 -0
  7. package/packages/registry/blocks/charts/chart-area-gradient.ts +82 -0
  8. package/packages/registry/blocks/charts/chart-area-icons.ts +77 -0
  9. package/packages/registry/blocks/charts/chart-area-interactive.ts +204 -0
  10. package/packages/registry/blocks/charts/chart-area-legend.ts +72 -0
  11. package/packages/registry/blocks/charts/chart-area-linear.ts +64 -0
  12. package/packages/registry/blocks/charts/chart-area-stacked-expand.ts +77 -0
  13. package/packages/registry/blocks/charts/chart-area-stacked.ts +71 -0
  14. package/packages/registry/blocks/charts/chart-area-step.ts +68 -0
  15. package/packages/registry/blocks/charts/chart-bar-active.ts +93 -0
  16. package/packages/registry/blocks/charts/chart-bar-default.ts +60 -0
  17. package/packages/registry/blocks/charts/chart-bar-horizontal.ts +62 -0
  18. package/packages/registry/blocks/charts/chart-bar-interactive.ts +185 -0
  19. package/packages/registry/blocks/charts/chart-bar-label-custom.ts +78 -0
  20. package/packages/registry/blocks/charts/chart-bar-label.ts +66 -0
  21. package/packages/registry/blocks/charts/chart-bar-mixed.ts +87 -0
  22. package/packages/registry/blocks/charts/chart-bar-multiple.ts +67 -0
  23. package/packages/registry/blocks/charts/chart-bar-negative.ts +61 -0
  24. package/packages/registry/blocks/charts/chart-bar-stacked.ts +68 -0
  25. package/packages/registry/blocks/charts/chart-line-default.ts +61 -0
  26. package/packages/registry/blocks/charts/chart-line-dots-colors.ts +86 -0
  27. package/packages/registry/blocks/charts/chart-line-dots-custom.ts +75 -0
  28. package/packages/registry/blocks/charts/chart-line-dots.ts +65 -0
  29. package/packages/registry/blocks/charts/chart-line-interactive.ts +185 -0
  30. package/packages/registry/blocks/charts/chart-line-label-custom.ts +94 -0
  31. package/packages/registry/blocks/charts/chart-line-label.ts +73 -0
  32. package/packages/registry/blocks/charts/chart-line-linear.ts +61 -0
  33. package/packages/registry/blocks/charts/chart-line-multiple.ts +71 -0
  34. package/packages/registry/blocks/charts/chart-line-step.ts +61 -0
  35. package/packages/registry/blocks/charts/chart-pie-donut-active.ts +86 -0
  36. package/packages/registry/blocks/charts/chart-pie-donut-text.ts +89 -0
  37. package/packages/registry/blocks/charts/chart-pie-donut.ts +77 -0
  38. package/packages/registry/blocks/charts/chart-pie-interactive.ts +120 -0
  39. package/packages/registry/blocks/charts/chart-pie-label-custom.ts +82 -0
  40. package/packages/registry/blocks/charts/chart-pie-label-list.ts +86 -0
  41. package/packages/registry/blocks/charts/chart-pie-label.ts +77 -0
  42. package/packages/registry/blocks/charts/chart-pie-legend.ts +79 -0
  43. package/packages/registry/blocks/charts/chart-pie-separator-none.ts +77 -0
  44. package/packages/registry/blocks/charts/chart-pie-simple.ts +77 -0
  45. package/packages/registry/blocks/charts/chart-pie-stacked.ts +99 -0
  46. package/packages/registry/blocks/charts/chart-radar-default.ts +61 -0
  47. package/packages/registry/blocks/charts/chart-radar-dots.ts +61 -0
  48. package/packages/registry/blocks/charts/chart-radar-grid-circle-fill.ts +61 -0
  49. package/packages/registry/blocks/charts/chart-radar-grid-circle-no-lines.ts +61 -0
  50. package/packages/registry/blocks/charts/chart-radar-grid-circle.ts +61 -0
  51. package/packages/registry/blocks/charts/chart-radar-grid-custom.ts +61 -0
  52. package/packages/registry/blocks/charts/chart-radar-grid-fill.ts +61 -0
  53. package/packages/registry/blocks/charts/chart-radar-grid-none.ts +60 -0
  54. package/packages/registry/blocks/charts/chart-radar-icons.ts +76 -0
  55. package/packages/registry/blocks/charts/chart-radar-label-custom.ts +77 -0
  56. package/packages/registry/blocks/charts/chart-radar-legend.ts +70 -0
  57. package/packages/registry/blocks/charts/chart-radar-lines-only.ts +68 -0
  58. package/packages/registry/blocks/charts/chart-radar-multiple.ts +68 -0
  59. package/packages/registry/blocks/charts/chart-radar-radius.ts +68 -0
  60. package/packages/registry/blocks/charts/chart-radial-grid.ts +80 -0
  61. package/packages/registry/blocks/charts/chart-radial-label.ts +85 -0
  62. package/packages/registry/blocks/charts/chart-radial-shape.ts +81 -0
  63. package/packages/registry/blocks/charts/chart-radial-simple.ts +79 -0
  64. package/packages/registry/blocks/charts/chart-radial-stacked.ts +69 -0
  65. package/packages/registry/blocks/charts/chart-radial-text.ts +82 -0
  66. package/packages/registry/blocks/charts/chart-tooltip-advanced.ts +84 -0
  67. package/packages/registry/blocks/charts/chart-tooltip-default.ts +62 -0
  68. package/packages/registry/blocks/charts/chart-tooltip-formatter.ts +75 -0
  69. package/packages/registry/blocks/charts/chart-tooltip-icons.ts +68 -0
  70. package/packages/registry/blocks/charts/chart-tooltip-indicator-line.ts +62 -0
  71. package/packages/registry/blocks/charts/chart-tooltip-indicator-none.ts +62 -0
  72. package/packages/registry/blocks/charts/chart-tooltip-label-custom.ts +65 -0
  73. package/packages/registry/blocks/charts/chart-tooltip-label-formatter.ts +66 -0
  74. package/packages/registry/blocks/charts/chart-tooltip-label-none.ts +62 -0
  75. package/packages/registry/blocks/dashboard-01/components/app-sidebar.ts +108 -0
  76. package/packages/registry/blocks/dashboard-01/components/chart-area-interactive.ts +276 -0
  77. package/packages/registry/blocks/dashboard-01/components/dashboard-data.ts +89 -0
  78. package/packages/registry/blocks/dashboard-01/components/data-table.ts +637 -0
  79. package/packages/registry/blocks/dashboard-01/components/nav-documents.ts +65 -0
  80. package/packages/registry/blocks/dashboard-01/components/nav-main.ts +61 -0
  81. package/packages/registry/blocks/dashboard-01/components/nav-secondary.ts +40 -0
  82. package/packages/registry/blocks/dashboard-01/components/nav-user.ts +66 -0
  83. package/packages/registry/blocks/dashboard-01/components/section-cards.ts +59 -0
  84. package/packages/registry/blocks/dashboard-01/components/site-header.ts +52 -0
  85. package/packages/registry/blocks/dashboard-01/page.ts +39 -0
  86. package/packages/registry/blocks/login-01/components/login-form.ts +70 -0
  87. package/packages/registry/blocks/login-01/page.ts +19 -0
  88. package/packages/registry/blocks/login-02/components/login-form.ts +68 -0
  89. package/packages/registry/blocks/login-02/page.ts +36 -0
  90. package/packages/registry/blocks/login-03/components/login-form.ts +89 -0
  91. package/packages/registry/blocks/login-03/page.ts +28 -0
  92. package/packages/registry/blocks/login-04/components/login-form.ts +91 -0
  93. package/packages/registry/blocks/login-04/page.ts +20 -0
  94. package/packages/registry/blocks/login-05/components/login-form.ts +75 -0
  95. package/packages/registry/blocks/login-05/page.ts +19 -0
  96. package/packages/registry/blocks/preview/cards/activate-agent-dialog.ts +77 -0
  97. package/packages/registry/blocks/preview/cards/analytics-card.ts +64 -0
  98. package/packages/registry/blocks/preview/cards/anomaly-alert.ts +35 -0
  99. package/packages/registry/blocks/preview/cards/bar-chart-card.ts +91 -0
  100. package/packages/registry/blocks/preview/cards/book-appointment.ts +51 -0
  101. package/packages/registry/blocks/preview/cards/codespaces-card.ts +172 -0
  102. package/packages/registry/blocks/preview/cards/contributions-activity.ts +63 -0
  103. package/packages/registry/blocks/preview/cards/contributors.ts +51 -0
  104. package/packages/registry/blocks/preview/cards/environment-variables.ts +47 -0
  105. package/packages/registry/blocks/preview/cards/feedback-form.ts +61 -0
  106. package/packages/registry/blocks/preview/cards/file-upload.ts +51 -0
  107. package/packages/registry/blocks/preview/cards/github-profile.ts +66 -0
  108. package/packages/registry/blocks/preview/cards/icon-preview-grid.ts +47 -0
  109. package/packages/registry/blocks/preview/cards/invite-team.ts +78 -0
  110. package/packages/registry/blocks/preview/cards/invoice.ts +91 -0
  111. package/packages/registry/blocks/preview/cards/live-waveform.ts +330 -0
  112. package/packages/registry/blocks/preview/cards/no-team-members.ts +61 -0
  113. package/packages/registry/blocks/preview/cards/not-found.ts +46 -0
  114. package/packages/registry/blocks/preview/cards/observability-card.ts +44 -0
  115. package/packages/registry/blocks/preview/cards/pie-chart-card.ts +84 -0
  116. package/packages/registry/blocks/preview/cards/report-bug.ts +71 -0
  117. package/packages/registry/blocks/preview/cards/shipping-address.ts +79 -0
  118. package/packages/registry/blocks/preview/cards/shortcuts.ts +57 -0
  119. package/packages/registry/blocks/preview/cards/skeleton-loading.ts +37 -0
  120. package/packages/registry/blocks/preview/cards/sleep-report.ts +85 -0
  121. package/packages/registry/blocks/preview/cards/style-overview.ts +64 -0
  122. package/packages/registry/blocks/preview/cards/typography-specimen.ts +107 -0
  123. package/packages/registry/blocks/preview/cards/ui-elements.ts +164 -0
  124. package/packages/registry/blocks/preview/cards/usage-card.ts +63 -0
  125. package/packages/registry/blocks/preview/cards/visitors.ts +71 -0
  126. package/packages/registry/blocks/preview/cards/weekly-fitness-summary.ts +54 -0
  127. package/packages/registry/blocks/preview/page.ts +103 -0
  128. package/packages/registry/blocks/preview-02/cards/account-access.ts +70 -0
  129. package/packages/registry/blocks/preview-02/cards/card-overview.ts +75 -0
  130. package/packages/registry/blocks/preview-02/cards/claimable-balance.ts +54 -0
  131. package/packages/registry/blocks/preview-02/cards/contribution-history.ts +80 -0
  132. package/packages/registry/blocks/preview-02/cards/cover-art.ts +41 -0
  133. package/packages/registry/blocks/preview-02/cards/dividend-income.ts +76 -0
  134. package/packages/registry/blocks/preview-02/cards/empty-connect-bank.ts +38 -0
  135. package/packages/registry/blocks/preview-02/cards/empty-distribute-track.ts +38 -0
  136. package/packages/registry/blocks/preview-02/cards/empty-explore-catalog.ts +39 -0
  137. package/packages/registry/blocks/preview-02/cards/faq.ts +79 -0
  138. package/packages/registry/blocks/preview-02/cards/front-door.ts +40 -0
  139. package/packages/registry/blocks/preview-02/cards/index-investing.ts +31 -0
  140. package/packages/registry/blocks/preview-02/cards/kitchen-island.ts +90 -0
  141. package/packages/registry/blocks/preview-02/cards/loading-card.ts +34 -0
  142. package/packages/registry/blocks/preview-02/cards/new-milestone.ts +53 -0
  143. package/packages/registry/blocks/preview-02/cards/notification-settings.ts +126 -0
  144. package/packages/registry/blocks/preview-02/cards/payments.ts +88 -0
  145. package/packages/registry/blocks/preview-02/cards/payout-threshold.ts +92 -0
  146. package/packages/registry/blocks/preview-02/cards/power-usage.ts +84 -0
  147. package/packages/registry/blocks/preview-02/cards/preferences.ts +89 -0
  148. package/packages/registry/blocks/preview-02/cards/qr-connect.ts +54 -0
  149. package/packages/registry/blocks/preview-02/cards/receiving-method.ts +89 -0
  150. package/packages/registry/blocks/preview-02/cards/recent-transactions.ts +101 -0
  151. package/packages/registry/blocks/preview-02/cards/release-catalog.ts +73 -0
  152. package/packages/registry/blocks/preview-02/cards/roller-shades.ts +110 -0
  153. package/packages/registry/blocks/preview-02/cards/savings-progress.ts +68 -0
  154. package/packages/registry/blocks/preview-02/cards/savings-targets.ts +132 -0
  155. package/packages/registry/blocks/preview-02/cards/sidebar-nav.ts +88 -0
  156. package/packages/registry/blocks/preview-02/cards/social-links.ts +57 -0
  157. package/packages/registry/blocks/preview-02/cards/stock-performance.ts +106 -0
  158. package/packages/registry/blocks/preview-02/cards/syncing-state.ts +37 -0
  159. package/packages/registry/blocks/preview-02/cards/transfer-funds.ts +111 -0
  160. package/packages/registry/blocks/preview-02/cards/upcoming-payments.ts +69 -0
  161. package/packages/registry/blocks/preview-02/page.ts +111 -0
  162. package/packages/registry/blocks/preview-03/cards/files-chat.ts +75 -0
  163. package/packages/registry/blocks/preview-03/cards/group-chat.ts +114 -0
  164. package/packages/registry/blocks/preview-03/cards/reasoning-chat.ts +88 -0
  165. package/packages/registry/blocks/preview-03/cards/simple-chat.ts +53 -0
  166. package/packages/registry/blocks/preview-03/components/chat-card.ts +126 -0
  167. package/packages/registry/blocks/preview-03/components/chat-player.ts +174 -0
  168. package/packages/registry/blocks/preview-03/components/part-file.ts +77 -0
  169. package/packages/registry/blocks/preview-03/components/part-reasoning.ts +25 -0
  170. package/packages/registry/blocks/preview-03/components/part-source.ts +48 -0
  171. package/packages/registry/blocks/preview-03/components/part-text.ts +69 -0
  172. package/packages/registry/blocks/preview-03/components/part-tool.ts +71 -0
  173. package/packages/registry/blocks/preview-03/components/prompt-input.ts +86 -0
  174. package/packages/registry/blocks/preview-03/page.ts +39 -0
  175. package/packages/registry/blocks/sidebar-01/components/app-sidebar.ts +113 -0
  176. package/packages/registry/blocks/sidebar-01/components/search-form.ts +33 -0
  177. package/packages/registry/blocks/sidebar-01/components/version-switcher.ts +50 -0
  178. package/packages/registry/blocks/sidebar-01/page.ts +58 -0
  179. package/packages/registry/blocks/sidebar-02/components/app-sidebar.ts +131 -0
  180. package/packages/registry/blocks/sidebar-02/components/search-form.ts +33 -0
  181. package/packages/registry/blocks/sidebar-02/components/version-switcher.ts +50 -0
  182. package/packages/registry/blocks/sidebar-02/page.ts +53 -0
  183. package/packages/registry/blocks/sidebar-03/components/app-sidebar.ts +134 -0
  184. package/packages/registry/blocks/sidebar-03/page.ts +60 -0
  185. package/packages/registry/blocks/sidebar-04/components/app-sidebar.ts +136 -0
  186. package/packages/registry/blocks/sidebar-04/page.ts +58 -0
  187. package/packages/registry/blocks/sidebar-05/components/app-sidebar.ts +147 -0
  188. package/packages/registry/blocks/sidebar-05/components/search-form.ts +33 -0
  189. package/packages/registry/blocks/sidebar-05/page.ts +58 -0
  190. package/packages/registry/blocks/sidebar-06/components/app-sidebar.ts +105 -0
  191. package/packages/registry/blocks/sidebar-06/components/nav-main.ts +56 -0
  192. package/packages/registry/blocks/sidebar-06/components/sidebar-opt-in-form.ts +44 -0
  193. package/packages/registry/blocks/sidebar-06/page.ts +57 -0
  194. package/packages/registry/blocks/sidebar-07/components/app-sidebar.ts +108 -0
  195. package/packages/registry/blocks/sidebar-07/components/nav-main.ts +61 -0
  196. package/packages/registry/blocks/sidebar-07/components/nav-projects.ts +65 -0
  197. package/packages/registry/blocks/sidebar-07/components/nav-user.ts +70 -0
  198. package/packages/registry/blocks/sidebar-07/components/team-switcher.ts +66 -0
  199. package/packages/registry/blocks/sidebar-07/page.ts +59 -0
  200. package/packages/registry/blocks/sidebar-08/components/app-sidebar.ts +122 -0
  201. package/packages/registry/blocks/sidebar-08/components/nav-main.ts +68 -0
  202. package/packages/registry/blocks/sidebar-08/components/nav-projects.ts +65 -0
  203. package/packages/registry/blocks/sidebar-08/components/nav-secondary.ts +40 -0
  204. package/packages/registry/blocks/sidebar-08/components/nav-user.ts +70 -0
  205. package/packages/registry/blocks/sidebar-08/page.ts +59 -0
  206. package/packages/registry/blocks/sidebar-09/components/app-sidebar.ts +213 -0
  207. package/packages/registry/blocks/sidebar-09/components/nav-user.ts +70 -0
  208. package/packages/registry/blocks/sidebar-09/page.ts +52 -0
  209. package/packages/registry/blocks/sidebar-10/components/app-sidebar.ts +125 -0
  210. package/packages/registry/blocks/sidebar-10/components/nav-actions.ts +84 -0
  211. package/packages/registry/blocks/sidebar-10/components/nav-favorites.ts +66 -0
  212. package/packages/registry/blocks/sidebar-10/components/nav-main.ts +37 -0
  213. package/packages/registry/blocks/sidebar-10/components/nav-secondary.ts +43 -0
  214. package/packages/registry/blocks/sidebar-10/components/nav-workspaces.ts +78 -0
  215. package/packages/registry/blocks/sidebar-10/components/team-switcher.ts +63 -0
  216. package/packages/registry/blocks/sidebar-10/page.ts +46 -0
  217. package/packages/registry/blocks/sidebar-11/components/app-sidebar.ts +114 -0
  218. package/packages/registry/blocks/sidebar-11/page.ts +63 -0
  219. package/packages/registry/blocks/sidebar-12/components/app-sidebar.ts +63 -0
  220. package/packages/registry/blocks/sidebar-12/components/calendars.ts +53 -0
  221. package/packages/registry/blocks/sidebar-12/components/date-picker.ts +26 -0
  222. package/packages/registry/blocks/sidebar-12/components/nav-user.ts +70 -0
  223. package/packages/registry/blocks/sidebar-12/page.ts +43 -0
  224. package/packages/registry/blocks/sidebar-13/components/settings-dialog.ts +114 -0
  225. package/packages/registry/blocks/sidebar-13/page.ts +21 -0
  226. package/packages/registry/blocks/sidebar-14/components/app-sidebar.ts +120 -0
  227. package/packages/registry/blocks/sidebar-14/page.ts +55 -0
  228. package/packages/registry/blocks/sidebar-15/components/calendars.ts +53 -0
  229. package/packages/registry/blocks/sidebar-15/components/date-picker.ts +26 -0
  230. package/packages/registry/blocks/sidebar-15/components/nav-favorites.ts +66 -0
  231. package/packages/registry/blocks/sidebar-15/components/nav-main.ts +35 -0
  232. package/packages/registry/blocks/sidebar-15/components/nav-secondary.ts +43 -0
  233. package/packages/registry/blocks/sidebar-15/components/nav-user.ts +70 -0
  234. package/packages/registry/blocks/sidebar-15/components/nav-workspaces.ts +75 -0
  235. package/packages/registry/blocks/sidebar-15/components/sidebar-left.ts +126 -0
  236. package/packages/registry/blocks/sidebar-15/components/sidebar-right.ts +62 -0
  237. package/packages/registry/blocks/sidebar-15/components/team-switcher.ts +63 -0
  238. package/packages/registry/blocks/sidebar-15/page.ts +47 -0
  239. package/packages/registry/blocks/sidebar-16/components/app-sidebar.ts +124 -0
  240. package/packages/registry/blocks/sidebar-16/components/nav-main.ts +67 -0
  241. package/packages/registry/blocks/sidebar-16/components/nav-projects.ts +65 -0
  242. package/packages/registry/blocks/sidebar-16/components/nav-secondary.ts +40 -0
  243. package/packages/registry/blocks/sidebar-16/components/nav-user.ts +70 -0
  244. package/packages/registry/blocks/sidebar-16/components/search-form.ts +27 -0
  245. package/packages/registry/blocks/sidebar-16/components/site-header.ts +42 -0
  246. package/packages/registry/blocks/sidebar-16/page.ts +38 -0
  247. package/packages/registry/blocks/signup-01/components/signup-form.ts +78 -0
  248. package/packages/registry/blocks/signup-01/page.ts +19 -0
  249. package/packages/registry/blocks/signup-02/components/signup-form.ts +78 -0
  250. package/packages/registry/blocks/signup-02/page.ts +36 -0
  251. package/packages/registry/blocks/signup-03/components/signup-form.ts +79 -0
  252. package/packages/registry/blocks/signup-03/page.ts +28 -0
  253. package/packages/registry/blocks/signup-04/components/signup-form.ts +100 -0
  254. package/packages/registry/blocks/signup-04/page.ts +20 -0
  255. package/packages/registry/blocks/signup-05/components/signup-form.ts +75 -0
  256. package/packages/registry/blocks/signup-05/page.ts +20 -0
  257. package/packages/registry/components/accordion.ts +20 -7
  258. package/packages/registry/components/alert-dialog.ts +58 -13
  259. package/packages/registry/components/alert.ts +11 -6
  260. package/packages/registry/components/attachment.ts +119 -0
  261. package/packages/registry/components/avatar.ts +17 -8
  262. package/packages/registry/components/badge.ts +16 -9
  263. package/packages/registry/components/breadcrumb.ts +6 -6
  264. package/packages/registry/components/bubble.ts +95 -0
  265. package/packages/registry/components/button-group.ts +73 -0
  266. package/packages/registry/components/button.ts +35 -25
  267. package/packages/registry/components/calendar.ts +566 -0
  268. package/packages/registry/components/card.ts +8 -8
  269. package/packages/registry/components/carousel.ts +352 -0
  270. package/packages/registry/components/chart-element.ts +547 -0
  271. package/packages/registry/components/chart-geometry.ts +457 -0
  272. package/packages/registry/components/chart.ts +932 -0
  273. package/packages/registry/components/checkbox.ts +22 -84
  274. package/packages/registry/components/code-block.ts +191 -0
  275. package/packages/registry/components/collapsible.ts +5 -2
  276. package/packages/registry/components/combobox.ts +802 -0
  277. package/packages/registry/components/command.ts +618 -0
  278. package/packages/registry/components/context-menu.ts +302 -0
  279. package/packages/registry/components/dialog.ts +156 -45
  280. package/packages/registry/components/direction.ts +43 -0
  281. package/packages/registry/components/drawer.ts +226 -0
  282. package/packages/registry/components/dropdown-menu.ts +262 -83
  283. package/packages/registry/components/empty.ts +88 -0
  284. package/packages/registry/components/field.ts +165 -0
  285. package/packages/registry/components/floating.ts +124 -0
  286. package/packages/registry/components/hover-card.ts +19 -8
  287. package/packages/registry/components/input-group.ts +118 -0
  288. package/packages/registry/components/input-otp.ts +365 -0
  289. package/packages/registry/components/input.ts +3 -3
  290. package/packages/registry/components/item.ts +134 -0
  291. package/packages/registry/components/kbd.ts +2 -2
  292. package/packages/registry/components/label.ts +1 -1
  293. package/packages/registry/components/marker.ts +63 -0
  294. package/packages/registry/components/menubar.ts +388 -0
  295. package/packages/registry/components/message-scroller.ts +470 -0
  296. package/packages/registry/components/message.ts +69 -0
  297. package/packages/registry/components/native-select.ts +5 -5
  298. package/packages/registry/components/navigation-menu.ts +564 -0
  299. package/packages/registry/components/pagination.ts +5 -5
  300. package/packages/registry/components/popover.ts +30 -84
  301. package/packages/registry/components/progress.ts +7 -3
  302. package/packages/registry/components/questionnaire.ts +840 -0
  303. package/packages/registry/components/radio-group.ts +18 -73
  304. package/packages/registry/components/resizable.ts +330 -0
  305. package/packages/registry/components/scroll-area.ts +46 -0
  306. package/packages/registry/components/select.ts +650 -0
  307. package/packages/registry/components/separator.ts +1 -1
  308. package/packages/registry/components/sheet.ts +128 -0
  309. package/packages/registry/components/sidebar.ts +457 -0
  310. package/packages/registry/components/skeleton.ts +1 -1
  311. package/packages/registry/components/slider.ts +333 -0
  312. package/packages/registry/components/sonner.ts +74 -7
  313. package/packages/registry/components/spinner.ts +66 -0
  314. package/packages/registry/components/switch.ts +117 -9
  315. package/packages/registry/components/table.ts +11 -9
  316. package/packages/registry/components/tabs.ts +76 -25
  317. package/packages/registry/components/textarea.ts +1 -1
  318. package/packages/registry/components/toggle-group.ts +30 -11
  319. package/packages/registry/components/toggle.ts +20 -13
  320. package/packages/registry/components/tooltip.ts +68 -7
  321. package/packages/registry/components/trace.ts +75 -0
  322. package/packages/registry/lib/icons-hugeicons.ts +955 -0
  323. package/packages/registry/lib/icons-phosphor.ts +955 -0
  324. package/packages/registry/lib/icons-remixicon.ts +955 -0
  325. package/packages/registry/lib/icons-tabler.ts +955 -0
  326. package/packages/registry/lib/icons.ts +768 -0
  327. package/packages/registry/lib/utils.ts +49 -4
  328. package/packages/registry/registry.json +4092 -60
  329. package/packages/registry/styles/shadcn-tailwind.css +654 -0
  330. package/packages/registry/styles/style-luma.css +1987 -0
  331. package/packages/registry/styles/style-lyra.css +1965 -0
  332. package/packages/registry/styles/style-maia.css +1987 -0
  333. package/packages/registry/styles/style-mira.css +1992 -0
  334. package/packages/registry/styles/style-new-york.css +1597 -0
  335. package/packages/registry/styles/style-nova.css +1990 -0
  336. package/packages/registry/styles/style-rhea.css +1987 -0
  337. package/packages/registry/styles/style-sera.css +1977 -0
  338. package/packages/registry/styles/style-vega.css +1990 -0
  339. package/packages/registry/styles/supplement.json +54 -0
  340. package/packages/registry/styles/tw-animate.css +6 -0
  341. package/packages/registry/themes/base-colors.js +8 -2
  342. package/packages/registry/themes/fonts.js +120 -0
  343. package/packages/registry/themes/index.css +2 -0
  344. package/packages/registry/themes/items.js +61 -0
  345. package/packages/registry/themes/preset.js +302 -0
  346. package/packages/registry/themes/themes.js +1193 -0
  347. package/src/commands/add.js +236 -12
  348. package/src/commands/diff.js +34 -20
  349. package/src/commands/info.js +7 -0
  350. package/src/commands/init.js +125 -8
  351. package/src/commands/list.js +43 -11
  352. package/src/commands/view.js +33 -5
  353. package/src/registry/extract.js +192 -2
  354. package/src/registry/icons.js +31 -0
  355. package/src/registry/local.js +15 -1
  356. package/src/registry/schema.js +13 -0
  357. package/src/registry/style-bake.js +506 -0
  358. package/src/utils/theme.js +110 -21
@@ -93,9 +93,9 @@
93
93
  * </ui-dialog-content>
94
94
  * ```
95
95
  */
96
- import { WebComponent, html, unsafeHTML, prop } from '@webjsdev/core';
96
+ import { WebComponent, html, unsafeHTML, prop, nothing } from '@webjsdev/core';
97
97
  import { ref, createRef } from '@webjsdev/core/directives';
98
- import { ensureId } from '../lib/utils.ts';
98
+ import { cn, ensureId, takeAuthoredClass } from '../lib/utils.ts';
99
99
  import { onBeforeCache } from '../lib/dom.ts';
100
100
  import { buttonClass } from './button.ts';
101
101
 
@@ -109,7 +109,7 @@ import { buttonClass } from './button.ts';
109
109
  // The description is independent of the NAME, so it is wired on every path,
110
110
  // including the two authored-name early returns below. An author who names the
111
111
  // dialog still gets their description node described.
112
- function wireDialogDescription(host: Element, panel: Element): void {
112
+ function wireDialogDescription(host: Element, panel: Element, prefix: string): void {
113
113
  const authored = host.getAttribute('aria-describedby');
114
114
  if (authored) {
115
115
  panel.setAttribute('aria-describedby', authored);
@@ -121,13 +121,13 @@ function wireDialogDescription(host: Element, panel: Element): void {
121
121
  // re-open, and the stale aria-describedby survives pointing at a dead IDREF.
122
122
  panel.removeAttribute('aria-describedby');
123
123
  const desc =
124
- host.querySelector('[data-slot="dialog-description"]') ?? host.querySelector('p');
124
+ host.querySelector(`[data-slot="${prefix}-description"]`) ?? host.querySelector('p');
125
125
  if (desc) {
126
126
  panel.setAttribute('aria-describedby', ensureId(desc as HTMLElement, 'ui-dialog-desc'));
127
127
  }
128
128
  }
129
129
 
130
- export function wireDialogLabels(host: Element, panelSelector: string): void {
130
+ export function wireDialogLabels(host: Element, panelSelector: string, prefix = 'dialog'): void {
131
131
  const panel = host.querySelector(panelSelector);
132
132
  if (!panel) return;
133
133
  // A name the author put on <ui-dialog-content> is where they naturally write
@@ -141,7 +141,7 @@ export function wireDialogLabels(host: Element, panelSelector: string): void {
141
141
  const authoredLabelledBy = host.getAttribute('aria-labelledby');
142
142
  if (authoredLabelledBy) {
143
143
  panel.setAttribute('aria-labelledby', authoredLabelledBy);
144
- wireDialogDescription(host, panel);
144
+ wireDialogDescription(host, panel, prefix);
145
145
  return;
146
146
  }
147
147
  const authoredLabel = host.getAttribute('aria-label');
@@ -150,7 +150,7 @@ export function wireDialogLabels(host: Element, panelSelector: string): void {
150
150
  // An authored name replaces the title as the NAME, so any stale
151
151
  // aria-labelledby from an earlier open must go, or it would win over it.
152
152
  panel.removeAttribute('aria-labelledby');
153
- wireDialogDescription(host, panel);
153
+ wireDialogDescription(host, panel, prefix);
154
154
  return;
155
155
  }
156
156
  // Same re-resolve rule: clear what a previous open wrote, or a removed title
@@ -158,11 +158,11 @@ export function wireDialogLabels(host: Element, panelSelector: string): void {
158
158
  // suppresses the floor below, which exists to prevent exactly that state.
159
159
  panel.removeAttribute('aria-labelledby');
160
160
  const title =
161
- host.querySelector('[data-slot="dialog-title"]') ?? host.querySelector('h1, h2, h3');
161
+ host.querySelector(`[data-slot="${prefix}-title"]`) ?? host.querySelector('h1, h2, h3');
162
162
  if (title) {
163
163
  panel.setAttribute('aria-labelledby', ensureId(title as HTMLElement, 'ui-dialog-title'));
164
164
  }
165
- wireDialogDescription(host, panel);
165
+ wireDialogDescription(host, panel, prefix);
166
166
  // APG: a modal MUST have an accessible name. Everything above supplies one
167
167
  // only when the author gave the dialog a title node or named it directly, so
168
168
  // a title-less dialog shipped unnamed and was announced as a bare "dialog".
@@ -178,22 +178,30 @@ export function wireDialogLabels(host: Element, panelSelector: string): void {
178
178
  // --------------------------------------------------------------------------
179
179
 
180
180
  export const dialogHeaderClass = (): string =>
181
- 'flex flex-col gap-2 text-center sm:text-left';
181
+ 'cn-dialog-header flex flex-col';
182
182
 
183
183
  export const dialogTitleClass = (): string =>
184
- 'text-lg leading-none font-semibold';
184
+ 'cn-dialog-title';
185
185
 
186
186
  export const dialogDescriptionClass = (): string =>
187
- 'text-sm text-muted-foreground';
187
+ 'cn-dialog-description';
188
188
 
189
189
  export const dialogFooterClass = (): string =>
190
- 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end';
190
+ 'cn-dialog-footer flex flex-col-reverse gap-2 sm:flex-row sm:justify-end';
191
191
 
192
192
  export const dialogContentClass = (): string =>
193
- 'fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none sm:max-w-lg';
193
+ 'cn-dialog-content fixed z-50 w-full outline-none';
194
194
 
195
195
  export const dialogCloseButtonClass = (): string =>
196
- "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
196
+ 'cn-dialog-close';
197
+
198
+ /**
199
+ * The overlay behind the panel: shadcn's DialogOverlay, which each style
200
+ * dims and blurs in its own way. It is a real element inside the native
201
+ * dialog rather than the dialog's `::backdrop`, because a style's classes
202
+ * reach an element, not a pseudo-element.
203
+ */
204
+ export const dialogOverlayClass = (): string => 'cn-dialog-overlay fixed inset-0 isolate z-50';
197
205
 
198
206
  const DIALOG_CLOSE_X_SVG =
199
207
  '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"></path></svg>';
@@ -207,10 +215,12 @@ const DIALOG_CLOSE_X_SVG =
207
215
  // `display: block` in the top layer.
208
216
  // --------------------------------------------------------------------------
209
217
 
210
- const STYLES = `
211
- ui-dialog:not([open]) ui-dialog-content { display: none !important; }
212
- ui-dialog[open] { display: contents; }
213
- ui-dialog-content { display: grid; }
218
+ // Exported for the elements that reuse the dialog machinery under their own
219
+ // tags (sheet), which pass their tags to installOverlayStyles().
220
+ export const overlayStyles = (root: string, content: string): string => `
221
+ ${root}:not([open]) ${content} { display: none !important; }
222
+ ${root}[open] { display: contents; }
223
+ ${content} { display: grid; }
214
224
  `;
215
225
 
216
226
  // Clears the UA defaults on <dialog> so it becomes an invisible top-layer
@@ -224,15 +234,18 @@ ui-dialog-content { display: grid; }
224
234
  // the same fixed panel against the viewport, so it worked on Android). A
225
235
  // viewport-sized transparent host gives the panel a correct containing block
226
236
  // on both engines; the panel still centers itself and the ::backdrop covers
227
- // the screen.
228
- const NATIVE_DIALOG_CLASS = 'fixed inset-0 border-0 bg-transparent p-0 m-0 max-w-none max-h-none overflow-visible text-inherit backdrop:bg-black/50';
237
+ // the screen. The backdrop itself stays clear: the overlay element the content
238
+ // renders is what the styles dim.
239
+ export const NATIVE_DIALOG_CLASS = 'fixed inset-0 border-0 bg-transparent p-0 m-0 max-w-none max-h-none overflow-visible text-inherit backdrop:bg-transparent';
229
240
 
230
- function installStyles(): void {
241
+ /** Inject the pre-hydration rules for one root / content tag pair, once. */
242
+ export function installOverlayStyles(root: string, content: string): void {
231
243
  if (typeof document === 'undefined') return;
232
- if (document.getElementById('ui-dialog-styles')) return;
244
+ const id = `${root}-styles`;
245
+ if (document.getElementById(id)) return;
233
246
  const style = document.createElement('style');
234
- style.id = 'ui-dialog-styles';
235
- style.textContent = STYLES;
247
+ style.id = id;
248
+ style.textContent = overlayStyles(root, content);
236
249
  document.head.appendChild(style);
237
250
  }
238
251
 
@@ -375,6 +388,12 @@ function unlockScroll(): void {
375
388
  export class UiDialog extends WebComponent({
376
389
  open: prop(Boolean, { reflect: true }),
377
390
  }) {
391
+ // The tags this element pairs with. A subclass registered under its own tags
392
+ // (sheet) overrides these, which is the only thing that differs.
393
+ static rootTag = 'ui-dialog';
394
+ static contentTag = 'ui-dialog-content';
395
+ static slotPrefix = 'dialog';
396
+
378
397
  constructor() {
379
398
  super();
380
399
  this.open = false;
@@ -384,7 +403,8 @@ export class UiDialog extends WebComponent({
384
403
  _scrollLocked?: boolean;
385
404
 
386
405
  connectedCallback(): void {
387
- installStyles();
406
+ const ctor = this.constructor as typeof UiDialog;
407
+ installOverlayStyles(ctor.rootTag, ctor.contentTag);
388
408
  // Legacy <ui-dialog-overlay> isn't supported anymore; the native
389
409
  // ::backdrop pseudo replaces it. Strip it if a stale doc uses it.
390
410
  this.querySelector<HTMLElement>(':scope > ui-dialog-overlay')?.remove();
@@ -408,7 +428,7 @@ export class UiDialog extends WebComponent({
408
428
  get isOpen(): boolean { return this.open; }
409
429
 
410
430
  render() {
411
- return html`<div data-slot="dialog" data-state=${this.open ? 'open' : 'closed'}>
431
+ return html`<div data-slot=${(this.constructor as typeof UiDialog).slotPrefix} data-state=${this.open ? 'open' : 'closed'}>
412
432
  <slot></slot>
413
433
  </div>`;
414
434
  }
@@ -418,12 +438,24 @@ export class UiDialog extends WebComponent({
418
438
  // Constructor sets open=false, which records a (undefined -> false)
419
439
  // transition in the first update. Skip it so the dialog doesn't
420
440
  // emit a teardown + ui-open-change for the initial state.
421
- if (changedProperties.get('open') === undefined) return;
441
+ // A dialog written `open` opens on that first update, though: it is
442
+ // shadcn's `defaultOpen`, which opens without an onOpenChange.
443
+ const initial = changedProperties.get('open') === undefined;
444
+ if (initial && !this.open) return;
445
+ // The content renders its data-state from this element's `open`, and
446
+ // nothing else re-renders it, so ask it to now. Every shadcn style
447
+ // animates out on data-closed: left closed while the native dialog
448
+ // opens, the content played its exit animation as it appeared.
449
+ this._content?.requestUpdate?.();
422
450
  // Defer one microtask so the content child has committed its own
423
451
  // render (the native <dialog> element lives in the content's template).
424
- queueMicrotask(() => {
452
+ // On the first update the content may not have rendered at all yet, so
453
+ // that one waits for it.
454
+ queueMicrotask(async () => {
455
+ if (initial) await this._content?.updateComplete;
425
456
  if (this.open) this._setup();
426
457
  else this._teardown();
458
+ if (initial) return;
427
459
  this.dispatchEvent(
428
460
  new CustomEvent('ui-open-change', { detail: { open: this.open }, bubbles: true }),
429
461
  );
@@ -431,7 +463,7 @@ export class UiDialog extends WebComponent({
431
463
  }
432
464
 
433
465
  get _content(): UiDialogContent | null {
434
- return this.querySelector('ui-dialog-content') as UiDialogContent | null;
466
+ return this.querySelector((this.constructor as typeof UiDialog).contentTag) as UiDialogContent | null;
435
467
  }
436
468
 
437
469
  _setup(): void {
@@ -472,15 +504,18 @@ UiDialog.register('ui-dialog');
472
504
  // --------------------------------------------------------------------------
473
505
 
474
506
  export class UiDialogTrigger extends WebComponent {
507
+ static rootTag = 'ui-dialog';
508
+ static slotPrefix = 'dialog';
509
+
475
510
  render() {
476
511
  return html`<div
477
- data-slot="dialog-trigger"
512
+ data-slot=${`${(this.constructor as typeof UiDialogTrigger).slotPrefix}-trigger`}
478
513
  @click=${this._onClick}
479
514
  ><slot></slot></div>`;
480
515
  }
481
516
 
482
517
  _onClick = (): void => {
483
- (this.closest('ui-dialog') as UiDialog | null)?.show();
518
+ (this.closest((this.constructor as typeof UiDialogTrigger).rootTag) as UiDialog | null)?.show();
484
519
  };
485
520
  }
486
521
  UiDialogTrigger.register('ui-dialog-trigger');
@@ -498,6 +533,9 @@ UiDialogTrigger.register('ui-dialog-trigger');
498
533
  export class UiDialogContent extends WebComponent({
499
534
  showCloseButton: prop(String, { reflect: true, attribute: 'show-close-button' }),
500
535
  }) {
536
+ static rootTag = 'ui-dialog';
537
+ static slotPrefix = 'dialog';
538
+
501
539
  // ref to the own-rendered native <dialog>. render() creates it, so a
502
540
  // ref() binding is the lit-idiomatic handle (no querySelector against
503
541
  // a string selector into the component's own output).
@@ -514,11 +552,50 @@ export class UiDialogContent extends WebComponent({
514
552
  // (#730). A direct querySelector is robust on every engine, and matches what
515
553
  // the tooltip / popover components already do.
516
554
  _native(): HTMLDialogElement | null {
517
- return this.querySelector<HTMLDialogElement>('dialog[data-slot="dialog-native"]');
555
+ return this.querySelector<HTMLDialogElement>(`dialog[data-slot="${this._prefix()}-native"]`);
556
+ }
557
+
558
+ _prefix(): string {
559
+ return (this.constructor as typeof UiDialogContent).slotPrefix;
560
+ }
561
+
562
+ // shadcn's className on the content lands on the panel it renders, so the
563
+ // class written on this host moves there, read once at first render.
564
+ _authored: string | null = null;
565
+ _hostClass(): string | null {
566
+ return (this._authored = takeAuthoredClass(this, null));
567
+ }
568
+
569
+ /** The visible panel's classes. A subclass (sheet) supplies its own. */
570
+ _panelClass(): string {
571
+ return dialogContentClass();
572
+ }
573
+
574
+ /**
575
+ * The edge the panel is attached to, written as data-side on the panel. A
576
+ * dialog is centred, so null, which omits the attribute; a sheet returns its
577
+ * side.
578
+ */
579
+ _side(): string | null {
580
+ return null;
581
+ }
582
+
583
+ /**
584
+ * A drawer's direction, written as data-vaul-drawer-direction on the panel,
585
+ * the attribute shadcn's drawer styles key on. Null (omitted) for a dialog
586
+ * or a sheet.
587
+ */
588
+ _drawerDirection(): string | null {
589
+ return null;
590
+ }
591
+
592
+ /** Markup placed before the slotted content (a drawer's drag handle). */
593
+ _panelLead(): unknown {
594
+ return '';
518
595
  }
519
596
 
520
597
  showModal(): void {
521
- wireDialogLabels(this, 'dialog[data-slot="dialog-native"]');
598
+ wireDialogLabels(this, `dialog[data-slot="${this._prefix()}-native"]`, this._prefix());
522
599
  const native = this._native();
523
600
  if (native && !native.open) native.showModal();
524
601
  }
@@ -531,31 +608,54 @@ export class UiDialogContent extends WebComponent({
531
608
  render() {
532
609
  const wantClose = this.showCloseButton !== 'false';
533
610
  const parentOpen = !!this._parent()?.open;
611
+ const prefix = this._prefix();
534
612
  return html`<dialog
535
- data-slot="dialog-native"
613
+ data-slot=${`${prefix}-native`}
536
614
  role="dialog"
537
615
  class=${NATIVE_DIALOG_CLASS}
538
616
  ${ref(this.#dialog)}
539
617
  @close=${this._onNativeClose}
540
618
  @click=${this._onNativeBackdropClick}
541
619
  ><div
542
- data-slot="dialog-content"
620
+ data-slot=${`${prefix}-overlay`}
543
621
  data-state=${parentOpen ? 'open' : 'closed'}
544
- class=${dialogContentClass()}
622
+ aria-hidden="true"
623
+ class=${this._overlayClass()}
624
+ ></div><div
625
+ data-slot=${`${prefix}-content`}
626
+ data-state=${parentOpen ? 'open' : 'closed'}
627
+ data-side=${this._side() ?? nothing}
628
+ data-vaul-drawer-direction=${this._drawerDirection() ?? nothing}
629
+ class=${cn(this._panelClass(), this._hostClass())}
545
630
  >
631
+ ${this._panelLead()}
546
632
  <slot></slot>
547
633
  ${wantClose
548
634
  ? html`<button
549
635
  type="button"
550
636
  aria-label="Close"
551
- data-slot="dialog-close"
552
- class=${dialogCloseButtonClass()}
637
+ data-slot=${`${prefix}-close`}
638
+ class=${cn(buttonClass({ variant: 'ghost', size: 'icon-sm' }), this._closeClass())}
553
639
  @click=${this._onAutoCloseClick}
554
640
  >${unsafeHTML(DIALOG_CLOSE_X_SVG)}</button>`
555
641
  : ''}
556
642
  </div></dialog>`;
557
643
  }
558
644
 
645
+ /**
646
+ * The auto-injected close button's own classes, over a ghost icon button,
647
+ * as shadcn renders `<Button variant="ghost" size="icon-sm">`. A subclass
648
+ * may supply its own.
649
+ */
650
+ _closeClass(): string {
651
+ return dialogCloseButtonClass();
652
+ }
653
+
654
+ /** The overlay's classes. A subclass (sheet, drawer) supplies its own. */
655
+ _overlayClass(): string {
656
+ return dialogOverlayClass();
657
+ }
658
+
559
659
  _onAutoCloseClick = (): void => {
560
660
  this._parent()?.hide();
561
661
  };
@@ -565,17 +665,18 @@ export class UiDialogContent extends WebComponent({
565
665
  if (p?.open) p.open = false;
566
666
  };
567
667
 
568
- // Backdrop-click closes the dialog: the click target on the backdrop is
569
- // the <dialog> element itself (the inner content panel catches its own
668
+ // A click outside the panel closes the dialog: it lands on the overlay, or
669
+ // on the <dialog> element itself (the inner content panel catches its own
570
670
  // clicks).
571
671
  _onNativeBackdropClick = (e: MouseEvent): void => {
572
- if (e.target === e.currentTarget) this._parent()?.hide();
672
+ const overlay = (e.target as Element | null)?.getAttribute?.('data-slot') === `${this._prefix()}-overlay`;
673
+ if (e.target === e.currentTarget || overlay) this._parent()?.hide();
573
674
  };
574
675
 
575
676
  // SSR-safe: linkedom doesn't implement closest() on custom elements.
576
677
  _parent(): UiDialog | null {
577
678
  if (typeof this.closest !== 'function') return null;
578
- return this.closest('ui-dialog') as UiDialog | null;
679
+ return this.closest((this.constructor as typeof UiDialogContent).rootTag) as UiDialog | null;
579
680
  }
580
681
  }
581
682
  UiDialogContent.register('ui-dialog-content');
@@ -584,16 +685,26 @@ UiDialogContent.register('ui-dialog-content');
584
685
  // <ui-dialog-close>
585
686
  // --------------------------------------------------------------------------
586
687
 
688
+ // shadcn's DialogClose is `asChild` around the author's button, so in a footer
689
+ // the BUTTON is the flex item: a phone's column footer stretches it full width.
690
+ // Here the host and its wrapper are display: contents, which leaves the
691
+ // authored button that item, and the click still reaches the wrapper. The host
692
+ // box is turned off through its style, which the server serves.
587
693
  export class UiDialogClose extends WebComponent {
694
+ static rootTag = 'ui-dialog';
695
+ static slotPrefix = 'dialog';
696
+
588
697
  render() {
698
+ if (typeof this.getAttribute === 'function' && !this.getAttribute('style')) this.setAttribute('style', 'display: contents');
589
699
  return html`<div
590
- data-slot="dialog-close"
700
+ data-slot=${`${(this.constructor as typeof UiDialogClose).slotPrefix}-close`}
701
+ class="contents"
591
702
  @click=${this._onClick}
592
703
  ><slot></slot></div>`;
593
704
  }
594
705
 
595
706
  _onClick = (): void => {
596
- (this.closest('ui-dialog') as UiDialog | null)?.hide();
707
+ (this.closest((this.constructor as typeof UiDialogClose).rootTag) as UiDialog | null)?.hide();
597
708
  };
598
709
  }
599
710
  UiDialogClose.register('ui-dialog-close');
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Direction: right-to-left and left-to-right layout. Tier-1, and deliberately
3
+ * thin, because the platform already has the provider: the `dir` attribute.
4
+ *
5
+ * shadcn parity:
6
+ * DirectionProvider dir="rtl" → dir="rtl" on any ancestor element (the
7
+ * page's <html>, or one region of it)
8
+ * useDirection() → readDirection(element)
9
+ *
10
+ * shadcn needs a React provider so its Radix components can read the
11
+ * direction. Here every component styles itself with logical properties
12
+ * (`ps-*`, `ms-*`, `start-*`, `text-start`, `rounded-s-*`), which the browser
13
+ * resolves from the nearest `dir`, so setting `dir="rtl"` on an ancestor is
14
+ * the whole of it: padding, alignment, icon sides and inner corners all flip
15
+ * with no script. `readDirection()` is for the rare code that must branch on
16
+ * the direction itself, such as a keyboard handler mapping ArrowLeft to
17
+ * "next" in RTL.
18
+ *
19
+ * A11y (required for accessible output): set `dir` together with `lang` on
20
+ * the same element (`<html lang="ar" dir="rtl">`), since a screen reader picks
21
+ * its voice from `lang` and the layout comes from `dir`. Arrow-key navigation
22
+ * should follow the visual direction, which is what `readDirection()` is for.
23
+ *
24
+ * @example
25
+ * ```html
26
+ * <section dir="rtl" lang="ar">
27
+ * <button class=${buttonClass()} type="button">حفظ</button>
28
+ * </section>
29
+ * ```
30
+ */
31
+
32
+ export type Direction = 'ltr' | 'rtl';
33
+
34
+ /**
35
+ * The direction in effect for an element: the nearest ancestor's `dir`
36
+ * attribute (`auto` and anything else count as left-to-right), else
37
+ * left-to-right. Reads attributes only, so it also runs during server
38
+ * rendering where there is no computed style.
39
+ */
40
+ export function readDirection(el: Element | null | undefined): Direction {
41
+ const holder = el?.closest?.('[dir]');
42
+ return holder?.getAttribute('dir')?.toLowerCase() === 'rtl' ? 'rtl' : 'ltr';
43
+ }