@hypoth-ui/cli 0.0.1 → 0.1.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 (375) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -115
  3. package/dist/{add-PDBC4JTE.js → add-V5PW73GC.js} +29 -17
  4. package/dist/{chunk-5LTQ2XVL.js → chunk-27CLUUVC.js} +0 -2
  5. package/dist/{chunk-YPKFYE45.js → chunk-NWIRSZUQ.js} +6 -13
  6. package/dist/{chunk-GJ6JOQ3Q.js → chunk-PBK72SJJ.js} +1 -1
  7. package/dist/{diff-BQEXG7HU.js → diff-776UATCA.js} +2 -2
  8. package/dist/index.js +5 -5
  9. package/dist/{init-7AZXYAPJ.js → init-GDU2PW7K.js} +10 -13
  10. package/dist/{list-X6ZLM2NQ.js → list-XDP5I537.js} +3 -3
  11. package/package.json +16 -12
  12. package/registry/components.json +1820 -206
  13. package/templates/accordion/index.tsx +266 -0
  14. package/templates/accordion/wc/accordion-content.ts +113 -0
  15. package/templates/accordion/wc/accordion-item.ts +111 -0
  16. package/templates/accordion/wc/accordion-trigger.ts +105 -0
  17. package/templates/accordion/wc/accordion.ts +213 -0
  18. package/templates/accordion/wc/index.ts +12 -0
  19. package/templates/alert/index.tsx +177 -0
  20. package/templates/alert/wc/alert.ts +167 -0
  21. package/templates/alert/wc/index.ts +1 -0
  22. package/templates/alert-dialog/index.tsx +360 -0
  23. package/templates/alert-dialog/wc/alert-dialog-action.ts +43 -0
  24. package/templates/alert-dialog/wc/alert-dialog-cancel.ts +43 -0
  25. package/templates/alert-dialog/wc/alert-dialog-content.ts +42 -0
  26. package/templates/alert-dialog/wc/alert-dialog-description.ts +34 -0
  27. package/templates/alert-dialog/wc/alert-dialog-footer.ts +25 -0
  28. package/templates/alert-dialog/wc/alert-dialog-header.ts +25 -0
  29. package/templates/alert-dialog/wc/alert-dialog-title.ts +34 -0
  30. package/templates/alert-dialog/wc/alert-dialog-trigger.ts +46 -0
  31. package/templates/alert-dialog/wc/alert-dialog.ts +302 -0
  32. package/templates/alert-dialog/wc/index.ts +13 -0
  33. package/templates/aspect-ratio/index.tsx +50 -0
  34. package/templates/aspect-ratio/wc/aspect-ratio.ts +78 -0
  35. package/templates/aspect-ratio/wc/index.ts +5 -0
  36. package/templates/avatar/avatar-group.tsx +88 -0
  37. package/templates/avatar/avatar.tsx +124 -0
  38. package/templates/avatar/index.tsx +33 -0
  39. package/templates/avatar/wc/avatar-group.ts +112 -0
  40. package/templates/avatar/wc/avatar.ts +184 -0
  41. package/templates/avatar/wc/index.ts +5 -0
  42. package/templates/badge/index.tsx +140 -0
  43. package/templates/badge/wc/badge.ts +119 -0
  44. package/templates/badge/wc/index.ts +9 -0
  45. package/templates/breadcrumb/index.tsx +157 -0
  46. package/templates/breadcrumb/wc/breadcrumb-item.ts +30 -0
  47. package/templates/breadcrumb/wc/breadcrumb-link.ts +70 -0
  48. package/templates/breadcrumb/wc/breadcrumb-list.ts +30 -0
  49. package/templates/breadcrumb/wc/breadcrumb-page.ts +32 -0
  50. package/templates/breadcrumb/wc/breadcrumb-separator.ts +31 -0
  51. package/templates/breadcrumb/wc/breadcrumb.ts +55 -0
  52. package/templates/breadcrumb/wc/index.ts +10 -0
  53. package/templates/button/button.tsx +119 -0
  54. package/templates/button/index.ts +1 -0
  55. package/templates/button/wc/button.ts +169 -0
  56. package/templates/calendar/index.tsx +149 -0
  57. package/templates/calendar/wc/calendar.ts +316 -0
  58. package/templates/calendar/wc/index.ts +4 -0
  59. package/templates/card/index.tsx +108 -0
  60. package/templates/card/wc/card-content.ts +25 -0
  61. package/templates/card/wc/card-footer.ts +25 -0
  62. package/templates/card/wc/card-header.ts +25 -0
  63. package/templates/card/wc/card.ts +43 -0
  64. package/templates/card/wc/index.ts +8 -0
  65. package/templates/checkbox/checkbox.tsx +85 -0
  66. package/templates/checkbox/wc/checkbox.ts +247 -0
  67. package/templates/collapsible/index.tsx +172 -0
  68. package/templates/collapsible/wc/collapsible-content.ts +97 -0
  69. package/templates/collapsible/wc/collapsible-trigger.ts +39 -0
  70. package/templates/collapsible/wc/collapsible.ts +143 -0
  71. package/templates/collapsible/wc/index.ts +7 -0
  72. package/templates/combobox/combobox-content.tsx +141 -0
  73. package/templates/combobox/combobox-context.ts +36 -0
  74. package/templates/combobox/combobox-empty.tsx +38 -0
  75. package/templates/combobox/combobox-input.tsx +159 -0
  76. package/templates/combobox/combobox-loading.tsx +38 -0
  77. package/templates/combobox/combobox-option.tsx +99 -0
  78. package/templates/combobox/combobox-root.tsx +207 -0
  79. package/templates/combobox/combobox-tag.tsx +62 -0
  80. package/templates/combobox/index.ts +62 -0
  81. package/templates/combobox/wc/combobox-content.ts +97 -0
  82. package/templates/combobox/wc/combobox-input.ts +134 -0
  83. package/templates/combobox/wc/combobox-option.ts +111 -0
  84. package/templates/combobox/wc/combobox-tag.ts +103 -0
  85. package/templates/combobox/wc/combobox.ts +981 -0
  86. package/templates/combobox/wc/index.ts +5 -0
  87. package/templates/command/index.tsx +279 -0
  88. package/templates/command/wc/command-empty.ts +24 -0
  89. package/templates/command/wc/command-group.ts +60 -0
  90. package/templates/command/wc/command-input.ts +136 -0
  91. package/templates/command/wc/command-item.ts +78 -0
  92. package/templates/command/wc/command-list.ts +103 -0
  93. package/templates/command/wc/command-loading.ts +24 -0
  94. package/templates/command/wc/command-separator.ts +23 -0
  95. package/templates/command/wc/command.ts +176 -0
  96. package/templates/context-menu/index.tsx +262 -0
  97. package/templates/context-menu/wc/context-menu-content.ts +41 -0
  98. package/templates/context-menu/wc/context-menu-item.ts +83 -0
  99. package/templates/context-menu/wc/context-menu-label.ts +30 -0
  100. package/templates/context-menu/wc/context-menu-separator.ts +28 -0
  101. package/templates/context-menu/wc/context-menu.ts +324 -0
  102. package/templates/context-menu/wc/index.ts +9 -0
  103. package/templates/data-table/index.tsx +263 -0
  104. package/templates/data-table/wc/data-table.ts +405 -0
  105. package/templates/data-table/wc/index.ts +10 -0
  106. package/templates/date-picker/date-picker-calendar.tsx +352 -0
  107. package/templates/date-picker/date-picker-content.tsx +121 -0
  108. package/templates/date-picker/date-picker-context.ts +46 -0
  109. package/templates/date-picker/date-picker-root.tsx +201 -0
  110. package/templates/date-picker/date-picker-trigger.tsx +95 -0
  111. package/templates/date-picker/index.ts +44 -0
  112. package/templates/date-picker/wc/date-picker-calendar.ts +457 -0
  113. package/templates/date-picker/wc/date-picker.ts +592 -0
  114. package/templates/date-picker/wc/date-utils.ts +467 -0
  115. package/templates/date-picker/wc/index.ts +3 -0
  116. package/templates/dialog/dialog-close.tsx +57 -0
  117. package/templates/dialog/dialog-content.tsx +106 -0
  118. package/templates/dialog/dialog-context.ts +24 -0
  119. package/templates/dialog/dialog-description.tsx +51 -0
  120. package/templates/dialog/dialog-root.tsx +104 -0
  121. package/templates/dialog/dialog-title.tsx +38 -0
  122. package/templates/dialog/dialog-trigger.tsx +94 -0
  123. package/templates/dialog/index.ts +52 -0
  124. package/templates/dialog/wc/dialog-content.ts +59 -0
  125. package/templates/dialog/wc/dialog-description.ts +58 -0
  126. package/templates/dialog/wc/dialog-title.ts +56 -0
  127. package/templates/dialog/wc/dialog.ts +411 -0
  128. package/templates/drawer/index.tsx +263 -0
  129. package/templates/drawer/wc/drawer-content.ts +150 -0
  130. package/templates/drawer/wc/drawer-description.ts +34 -0
  131. package/templates/drawer/wc/drawer-footer.ts +25 -0
  132. package/templates/drawer/wc/drawer-header.ts +25 -0
  133. package/templates/drawer/wc/drawer-title.ts +34 -0
  134. package/templates/drawer/wc/drawer.ts +348 -0
  135. package/templates/drawer/wc/index.ts +10 -0
  136. package/templates/dropdown-menu/index.tsx +454 -0
  137. package/templates/dropdown-menu/wc/dropdown-menu-checkbox-item.ts +93 -0
  138. package/templates/dropdown-menu/wc/dropdown-menu-content.ts +43 -0
  139. package/templates/dropdown-menu/wc/dropdown-menu-item.ts +85 -0
  140. package/templates/dropdown-menu/wc/dropdown-menu-label.ts +31 -0
  141. package/templates/dropdown-menu/wc/dropdown-menu-radio-group.ts +80 -0
  142. package/templates/dropdown-menu/wc/dropdown-menu-radio-item.ts +101 -0
  143. package/templates/dropdown-menu/wc/dropdown-menu-separator.ts +28 -0
  144. package/templates/dropdown-menu/wc/dropdown-menu.ts +358 -0
  145. package/templates/dropdown-menu/wc/index.ts +12 -0
  146. package/templates/field/field-description.tsx +39 -0
  147. package/templates/field/field-error.tsx +37 -0
  148. package/templates/field/field.tsx +46 -0
  149. package/templates/field/index.ts +4 -0
  150. package/templates/field/label.tsx +40 -0
  151. package/templates/field/wc/field-description.ts +42 -0
  152. package/templates/field/wc/field-error.ts +46 -0
  153. package/templates/field/wc/field.ts +210 -0
  154. package/templates/field/wc/label.ts +54 -0
  155. package/templates/file-upload/file-upload-context.ts +26 -0
  156. package/templates/file-upload/file-upload-dropzone.tsx +111 -0
  157. package/templates/file-upload/file-upload-input.tsx +86 -0
  158. package/templates/file-upload/file-upload-item.tsx +105 -0
  159. package/templates/file-upload/file-upload-root.tsx +115 -0
  160. package/templates/file-upload/index.ts +50 -0
  161. package/templates/file-upload/wc/file-upload.ts +380 -0
  162. package/templates/file-upload/wc/index.ts +1 -0
  163. package/templates/hover-card/index.tsx +203 -0
  164. package/templates/hover-card/wc/hover-card-content.ts +50 -0
  165. package/templates/hover-card/wc/hover-card.ts +382 -0
  166. package/templates/hover-card/wc/index.ts +6 -0
  167. package/templates/icon/icon.tsx +76 -0
  168. package/templates/icon/wc/icon-adapter.ts +108 -0
  169. package/templates/icon/wc/icon.ts +161 -0
  170. package/templates/input/input.tsx +130 -0
  171. package/templates/input/wc/input.ts +216 -0
  172. package/templates/layout/app-shell.tsx +177 -0
  173. package/templates/layout/box.tsx +53 -0
  174. package/templates/layout/center.tsx +42 -0
  175. package/templates/layout/container.tsx +43 -0
  176. package/templates/layout/flow.tsx +83 -0
  177. package/templates/layout/grid.tsx +79 -0
  178. package/templates/layout/index.ts +33 -0
  179. package/templates/layout/inline.tsx +16 -0
  180. package/templates/layout/page.tsx +43 -0
  181. package/templates/layout/section.tsx +39 -0
  182. package/templates/layout/spacer.tsx +30 -0
  183. package/templates/layout/split.tsx +47 -0
  184. package/templates/layout/stack.tsx +16 -0
  185. package/templates/layout/wc/app-shell.ts +58 -0
  186. package/templates/layout/wc/box.ts +117 -0
  187. package/templates/layout/wc/center.ts +78 -0
  188. package/templates/layout/wc/container.ts +77 -0
  189. package/templates/layout/wc/flow.ts +149 -0
  190. package/templates/layout/wc/footer.ts +57 -0
  191. package/templates/layout/wc/grid.ts +142 -0
  192. package/templates/layout/wc/header.ts +57 -0
  193. package/templates/layout/wc/index.ts +41 -0
  194. package/templates/layout/wc/main.ts +46 -0
  195. package/templates/layout/wc/page.ts +81 -0
  196. package/templates/layout/wc/section.ts +65 -0
  197. package/templates/layout/wc/spacer.ts +77 -0
  198. package/templates/layout/wc/split.ts +94 -0
  199. package/templates/layout/wc/wrap.ts +93 -0
  200. package/templates/layout/wrap.tsx +46 -0
  201. package/templates/link/link.tsx +109 -0
  202. package/templates/link/wc/link.ts +124 -0
  203. package/templates/list/index.tsx +55 -0
  204. package/templates/list/list-item.tsx +117 -0
  205. package/templates/list/list.tsx +115 -0
  206. package/templates/list/wc/index.ts +5 -0
  207. package/templates/list/wc/list-item.ts +127 -0
  208. package/templates/list/wc/list.ts +114 -0
  209. package/templates/menu/index.ts +49 -0
  210. package/templates/menu/menu-content.tsx +109 -0
  211. package/templates/menu/menu-context.ts +17 -0
  212. package/templates/menu/menu-item.tsx +108 -0
  213. package/templates/menu/menu-label.tsx +32 -0
  214. package/templates/menu/menu-root.tsx +108 -0
  215. package/templates/menu/menu-separator.tsx +24 -0
  216. package/templates/menu/menu-trigger.tsx +104 -0
  217. package/templates/menu/wc/menu-content.ts +67 -0
  218. package/templates/menu/wc/menu-item.ts +109 -0
  219. package/templates/menu/wc/menu.ts +449 -0
  220. package/templates/navigation-menu/index.tsx +328 -0
  221. package/templates/navigation-menu/wc/index.ts +12 -0
  222. package/templates/navigation-menu/wc/navigation-menu-content.ts +30 -0
  223. package/templates/navigation-menu/wc/navigation-menu-indicator.ts +30 -0
  224. package/templates/navigation-menu/wc/navigation-menu-item.ts +60 -0
  225. package/templates/navigation-menu/wc/navigation-menu-link.ts +97 -0
  226. package/templates/navigation-menu/wc/navigation-menu-list.ts +30 -0
  227. package/templates/navigation-menu/wc/navigation-menu-trigger.ts +110 -0
  228. package/templates/navigation-menu/wc/navigation-menu-viewport.ts +85 -0
  229. package/templates/navigation-menu/wc/navigation-menu.ts +272 -0
  230. package/templates/number-input/index.ts +46 -0
  231. package/templates/number-input/number-input-context.ts +38 -0
  232. package/templates/number-input/number-input-decrement.tsx +53 -0
  233. package/templates/number-input/number-input-field.tsx +93 -0
  234. package/templates/number-input/number-input-increment.tsx +53 -0
  235. package/templates/number-input/number-input-root.tsx +137 -0
  236. package/templates/number-input/wc/index.ts +1 -0
  237. package/templates/number-input/wc/number-input.ts +283 -0
  238. package/templates/pagination/index.tsx +198 -0
  239. package/templates/pagination/wc/index.ts +11 -0
  240. package/templates/pagination/wc/pagination-content.ts +30 -0
  241. package/templates/pagination/wc/pagination-ellipsis.ts +28 -0
  242. package/templates/pagination/wc/pagination-item.ts +30 -0
  243. package/templates/pagination/wc/pagination-link.ts +76 -0
  244. package/templates/pagination/wc/pagination-next.ts +69 -0
  245. package/templates/pagination/wc/pagination-previous.ts +69 -0
  246. package/templates/pagination/wc/pagination.ts +156 -0
  247. package/templates/pin-input/index.ts +39 -0
  248. package/templates/pin-input/pin-input-context.ts +30 -0
  249. package/templates/pin-input/pin-input-field.tsx +186 -0
  250. package/templates/pin-input/pin-input-root.tsx +120 -0
  251. package/templates/pin-input/wc/index.ts +1 -0
  252. package/templates/pin-input/wc/pin-input.ts +259 -0
  253. package/templates/popover/popover.tsx +121 -0
  254. package/templates/popover/wc/popover-content.ts +66 -0
  255. package/templates/popover/wc/popover.ts +343 -0
  256. package/templates/progress/index.tsx +117 -0
  257. package/templates/progress/wc/index.ts +4 -0
  258. package/templates/progress/wc/progress.ts +174 -0
  259. package/templates/radio/radio.tsx +43 -0
  260. package/templates/radio/wc/radio-group.ts +261 -0
  261. package/templates/radio/wc/radio.ts +145 -0
  262. package/templates/scroll-area/index.tsx +144 -0
  263. package/templates/scroll-area/wc/index.ts +8 -0
  264. package/templates/scroll-area/wc/scroll-area-scrollbar.ts +143 -0
  265. package/templates/scroll-area/wc/scroll-area-thumb.ts +225 -0
  266. package/templates/scroll-area/wc/scroll-area-viewport.ts +120 -0
  267. package/templates/scroll-area/wc/scroll-area.ts +63 -0
  268. package/templates/select/index.ts +57 -0
  269. package/templates/select/select-content.tsx +243 -0
  270. package/templates/select/select-context.ts +30 -0
  271. package/templates/select/select-group.tsx +53 -0
  272. package/templates/select/select-label.tsx +34 -0
  273. package/templates/select/select-option.tsx +97 -0
  274. package/templates/select/select-root.tsx +153 -0
  275. package/templates/select/select-separator.tsx +27 -0
  276. package/templates/select/select-trigger.tsx +112 -0
  277. package/templates/select/select-value.tsx +48 -0
  278. package/templates/select/wc/index.ts +6 -0
  279. package/templates/select/wc/select-content.ts +89 -0
  280. package/templates/select/wc/select-group.ts +82 -0
  281. package/templates/select/wc/select-label.ts +49 -0
  282. package/templates/select/wc/select-option.ts +111 -0
  283. package/templates/select/wc/select-trigger.ts +101 -0
  284. package/templates/select/wc/select.ts +840 -0
  285. package/templates/separator/index.tsx +49 -0
  286. package/templates/separator/wc/index.ts +5 -0
  287. package/templates/separator/wc/separator.ts +60 -0
  288. package/templates/sheet/index.tsx +291 -0
  289. package/templates/sheet/wc/index.ts +12 -0
  290. package/templates/sheet/wc/sheet-close.ts +43 -0
  291. package/templates/sheet/wc/sheet-content.ts +47 -0
  292. package/templates/sheet/wc/sheet-description.ts +34 -0
  293. package/templates/sheet/wc/sheet-footer.ts +25 -0
  294. package/templates/sheet/wc/sheet-header.ts +25 -0
  295. package/templates/sheet/wc/sheet-overlay.ts +23 -0
  296. package/templates/sheet/wc/sheet-title.ts +34 -0
  297. package/templates/sheet/wc/sheet.ts +336 -0
  298. package/templates/skeleton/index.tsx +131 -0
  299. package/templates/skeleton/wc/index.ts +10 -0
  300. package/templates/skeleton/wc/skeleton.ts +107 -0
  301. package/templates/slider/index.ts +41 -0
  302. package/templates/slider/slider-context.ts +36 -0
  303. package/templates/slider/slider-range.tsx +59 -0
  304. package/templates/slider/slider-root.tsx +166 -0
  305. package/templates/slider/slider-thumb.tsx +213 -0
  306. package/templates/slider/slider-track.tsx +113 -0
  307. package/templates/slider/wc/index.ts +1 -0
  308. package/templates/slider/wc/slider.ts +465 -0
  309. package/templates/spinner/spinner.tsx +64 -0
  310. package/templates/spinner/wc/spinner.ts +70 -0
  311. package/templates/stepper/index.tsx +230 -0
  312. package/templates/stepper/wc/index.ts +12 -0
  313. package/templates/stepper/wc/stepper-content.ts +30 -0
  314. package/templates/stepper/wc/stepper-description.ts +25 -0
  315. package/templates/stepper/wc/stepper-indicator.ts +30 -0
  316. package/templates/stepper/wc/stepper-item.ts +55 -0
  317. package/templates/stepper/wc/stepper-separator.ts +29 -0
  318. package/templates/stepper/wc/stepper-title.ts +25 -0
  319. package/templates/stepper/wc/stepper-trigger.ts +67 -0
  320. package/templates/stepper/wc/stepper.ts +164 -0
  321. package/templates/switch/switch.tsx +90 -0
  322. package/templates/switch/wc/switch.ts +228 -0
  323. package/templates/table/body.tsx +21 -0
  324. package/templates/table/cell.tsx +44 -0
  325. package/templates/table/head.tsx +112 -0
  326. package/templates/table/header.tsx +21 -0
  327. package/templates/table/index.tsx +93 -0
  328. package/templates/table/root.tsx +82 -0
  329. package/templates/table/row.tsx +36 -0
  330. package/templates/table/wc/index.ts +9 -0
  331. package/templates/table/wc/table-body.ts +32 -0
  332. package/templates/table/wc/table-cell.ts +58 -0
  333. package/templates/table/wc/table-head.ts +129 -0
  334. package/templates/table/wc/table-header.ts +32 -0
  335. package/templates/table/wc/table-row.ts +50 -0
  336. package/templates/table/wc/table.ts +93 -0
  337. package/templates/tabs/index.tsx +222 -0
  338. package/templates/tabs/wc/index.ts +8 -0
  339. package/templates/tabs/wc/tabs-content.ts +82 -0
  340. package/templates/tabs/wc/tabs-list.ts +56 -0
  341. package/templates/tabs/wc/tabs-trigger.ts +136 -0
  342. package/templates/tabs/wc/tabs.ts +202 -0
  343. package/templates/tag/index.tsx +186 -0
  344. package/templates/tag/wc/index.ts +4 -0
  345. package/templates/tag/wc/tag.ts +166 -0
  346. package/templates/text/text.tsx +100 -0
  347. package/templates/text/wc/text.ts +94 -0
  348. package/templates/textarea/textarea.tsx +134 -0
  349. package/templates/textarea/wc/textarea.ts +280 -0
  350. package/templates/time-picker/index.ts +42 -0
  351. package/templates/time-picker/time-picker-context.ts +28 -0
  352. package/templates/time-picker/time-picker-root.tsx +113 -0
  353. package/templates/time-picker/time-picker-segment.tsx +91 -0
  354. package/templates/time-picker/wc/index.ts +1 -0
  355. package/templates/time-picker/wc/time-picker.ts +221 -0
  356. package/templates/toast/index.tsx +71 -0
  357. package/templates/toast/provider.tsx +228 -0
  358. package/templates/toast/toast.tsx +142 -0
  359. package/templates/toast/use-toast.ts +89 -0
  360. package/templates/toast/wc/index.ts +15 -0
  361. package/templates/toast/wc/toast-controller.ts +282 -0
  362. package/templates/toast/wc/toast-provider.ts +161 -0
  363. package/templates/toast/wc/toast.ts +165 -0
  364. package/templates/tooltip/tooltip.tsx +62 -0
  365. package/templates/tooltip/wc/tooltip-content.ts +64 -0
  366. package/templates/tooltip/wc/tooltip.ts +289 -0
  367. package/templates/tree/index.tsx +60 -0
  368. package/templates/tree/tree-item.tsx +131 -0
  369. package/templates/tree/tree.tsx +138 -0
  370. package/templates/tree/wc/index.ts +11 -0
  371. package/templates/tree/wc/tree-item.ts +273 -0
  372. package/templates/tree/wc/tree-utils.ts +143 -0
  373. package/templates/tree/wc/tree.ts +139 -0
  374. package/templates/visually-hidden/visually-hidden.tsx +45 -0
  375. package/templates/visually-hidden/wc/visually-hidden.ts +64 -0
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Dialog Root component - provides context to all Dialog compound components.
3
+ */
4
+
5
+ import { type DialogRole, createDialogBehavior } from "@hypoth-ui/primitives-dom";
6
+ import { type ReactNode, useCallback, useMemo, useState } from "react";
7
+ import { useStableId } from "../../hooks/use-stable-id.js";
8
+ import { DialogProvider } from "./dialog-context.js";
9
+
10
+ export interface DialogRootProps {
11
+ /** Dialog content */
12
+ children?: ReactNode;
13
+ /** Custom ID for the dialog (SSR-safe auto-generated if not provided) */
14
+ id?: string;
15
+ /** Controlled open state */
16
+ open?: boolean;
17
+ /** Default open state (uncontrolled) */
18
+ defaultOpen?: boolean;
19
+ /** Called when open state changes */
20
+ onOpenChange?: (open: boolean) => void;
21
+ /** Dialog role */
22
+ role?: DialogRole;
23
+ /** Whether dialog is modal (traps focus) */
24
+ modal?: boolean;
25
+ }
26
+
27
+ /**
28
+ * Root component for Dialog compound pattern.
29
+ * Provides context to Trigger, Content, Title, Description, and Close.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <Dialog.Root>
34
+ * <Dialog.Trigger>Open</Dialog.Trigger>
35
+ * <Dialog.Content>
36
+ * <Dialog.Title>Dialog Title</Dialog.Title>
37
+ * <Dialog.Description>Dialog description</Dialog.Description>
38
+ * <Dialog.Close>Close</Dialog.Close>
39
+ * </Dialog.Content>
40
+ * </Dialog.Root>
41
+ * ```
42
+ */
43
+ export function DialogRoot({
44
+ children,
45
+ id,
46
+ open: controlledOpen,
47
+ defaultOpen = false,
48
+ onOpenChange,
49
+ role = "dialog",
50
+ modal = true,
51
+ }: DialogRootProps) {
52
+ // Generate SSR-safe stable ID using React 18's useId under the hood
53
+ const stableId = useStableId({ id, prefix: "dialog" });
54
+
55
+ // Support both controlled and uncontrolled modes
56
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
57
+ const isControlled = controlledOpen !== undefined;
58
+ const open = isControlled ? controlledOpen : internalOpen;
59
+
60
+ // Track description presence for aria-describedby
61
+ const [descriptionId, setDescriptionId] = useState<string | null>(null);
62
+
63
+ const setOpen = useCallback(
64
+ (nextOpen: boolean) => {
65
+ if (!isControlled) {
66
+ setInternalOpen(nextOpen);
67
+ }
68
+ onOpenChange?.(nextOpen);
69
+ },
70
+ [isControlled, onOpenChange]
71
+ );
72
+
73
+ // Create behavior instance - intentionally created once with initial values
74
+ // biome-ignore lint/correctness/useExhaustiveDependencies: behavior is created once, open state synced via setOpen callback
75
+ const behavior = useMemo(
76
+ () =>
77
+ createDialogBehavior({
78
+ defaultOpen: open,
79
+ role,
80
+ closeOnEscape: true,
81
+ closeOnOutsideClick: true,
82
+ onOpenChange: setOpen,
83
+ // Use SSR-safe stable ID generator
84
+ generateId: () => stableId,
85
+ }),
86
+ [stableId]
87
+ );
88
+
89
+ const contextValue = useMemo(
90
+ () => ({
91
+ behavior,
92
+ open,
93
+ setOpen,
94
+ modal,
95
+ descriptionId,
96
+ setDescriptionId,
97
+ }),
98
+ [behavior, open, setOpen, modal, descriptionId]
99
+ );
100
+
101
+ return <DialogProvider value={contextValue}>{children}</DialogProvider>;
102
+ }
103
+
104
+ DialogRoot.displayName = "Dialog.Root";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Dialog Title component - accessible title for the dialog.
3
+ */
4
+
5
+ import { type HTMLAttributes, type ReactNode, forwardRef } from "react";
6
+ import { useDialogContext } from "./dialog-context.js";
7
+
8
+ export interface DialogTitleProps extends HTMLAttributes<HTMLHeadingElement> {
9
+ /** Title content */
10
+ children?: ReactNode;
11
+ }
12
+
13
+ /**
14
+ * Accessible title for the dialog.
15
+ * Automatically linked to dialog via aria-labelledby.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * <Dialog.Content>
20
+ * <Dialog.Title>Confirm Action</Dialog.Title>
21
+ * ...
22
+ * </Dialog.Content>
23
+ * ```
24
+ */
25
+ export const DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(
26
+ ({ children, ...restProps }, ref) => {
27
+ const { behavior } = useDialogContext("Dialog.Title");
28
+ const titleProps = behavior.getTitleProps();
29
+
30
+ return (
31
+ <h2 ref={ref} id={titleProps.id} {...restProps}>
32
+ {children}
33
+ </h2>
34
+ );
35
+ }
36
+ );
37
+
38
+ DialogTitle.displayName = "Dialog.Title";
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Dialog Trigger component - opens the dialog when activated.
3
+ */
4
+
5
+ import {
6
+ type ButtonHTMLAttributes,
7
+ type ReactNode,
8
+ forwardRef,
9
+ useCallback,
10
+ useEffect,
11
+ useRef,
12
+ } from "react";
13
+ import { Slot } from "../../primitives/slot.js";
14
+ import { useDialogContext } from "./dialog-context.js";
15
+
16
+ export interface DialogTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
17
+ /** Trigger content */
18
+ children?: ReactNode;
19
+ /** Render as child element (polymorphic) */
20
+ asChild?: boolean;
21
+ }
22
+
23
+ /**
24
+ * Trigger button that opens the dialog.
25
+ * Supports asChild for custom trigger elements.
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * <Dialog.Trigger>Open Dialog</Dialog.Trigger>
30
+ *
31
+ * <Dialog.Trigger asChild>
32
+ * <button className="custom-button">Custom Trigger</button>
33
+ * </Dialog.Trigger>
34
+ * ```
35
+ */
36
+ export const DialogTrigger = forwardRef<HTMLButtonElement, DialogTriggerProps>(
37
+ ({ children, asChild = false, onClick, ...restProps }, ref) => {
38
+ const { behavior, open, setOpen } = useDialogContext("Dialog.Trigger");
39
+ const internalRef = useRef<HTMLButtonElement>(null);
40
+
41
+ // Register trigger element with behavior
42
+ useEffect(() => {
43
+ const element = internalRef.current;
44
+ behavior.setTriggerElement(element);
45
+ return () => {
46
+ behavior.setTriggerElement(null);
47
+ };
48
+ }, [behavior]);
49
+
50
+ // Handle click to open dialog
51
+ const handleClick = useCallback(
52
+ (event: React.MouseEvent<HTMLButtonElement>) => {
53
+ setOpen(true);
54
+ onClick?.(event);
55
+ },
56
+ [setOpen, onClick]
57
+ );
58
+
59
+ // Get trigger props from behavior
60
+ const triggerProps = behavior.getTriggerProps();
61
+
62
+ const Component = asChild ? Slot : "button";
63
+
64
+ // Merge refs
65
+ const mergedRef = useCallback(
66
+ (element: HTMLButtonElement | null) => {
67
+ (internalRef as React.MutableRefObject<HTMLButtonElement | null>).current = element;
68
+ if (typeof ref === "function") {
69
+ ref(element);
70
+ } else if (ref) {
71
+ (ref as React.MutableRefObject<HTMLButtonElement | null>).current = element;
72
+ }
73
+ },
74
+ [ref]
75
+ );
76
+
77
+ return (
78
+ <Component
79
+ ref={mergedRef}
80
+ type={asChild ? undefined : "button"}
81
+ id={triggerProps.id}
82
+ aria-haspopup={triggerProps["aria-haspopup"]}
83
+ aria-expanded={open ? "true" : "false"}
84
+ aria-controls={triggerProps["aria-controls"]}
85
+ onClick={handleClick}
86
+ {...restProps}
87
+ >
88
+ {children}
89
+ </Component>
90
+ );
91
+ }
92
+ );
93
+
94
+ DialogTrigger.displayName = "Dialog.Trigger";
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Dialog compound component exports.
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { Dialog } from "@/components/ui";
7
+ *
8
+ * <Dialog.Root>
9
+ * <Dialog.Trigger>Open Dialog</Dialog.Trigger>
10
+ * <Dialog.Content>
11
+ * <Dialog.Title>Dialog Title</Dialog.Title>
12
+ * <Dialog.Description>Dialog description</Dialog.Description>
13
+ * <Dialog.Close>Close</Dialog.Close>
14
+ * </Dialog.Content>
15
+ * </Dialog.Root>
16
+ * ```
17
+ */
18
+
19
+ import { DialogClose, type DialogCloseProps } from "./dialog-close.js";
20
+ import {
21
+ DialogContent,
22
+ type DialogContentProps,
23
+ type DialogContentSize,
24
+ } from "./dialog-content.js";
25
+ import { DialogDescription, type DialogDescriptionProps } from "./dialog-description.js";
26
+ import { DialogRoot, type DialogRootProps } from "./dialog-root.js";
27
+ import { DialogTitle, type DialogTitleProps } from "./dialog-title.js";
28
+ import { DialogTrigger, type DialogTriggerProps } from "./dialog-trigger.js";
29
+
30
+ // Compound component
31
+ export const Dialog = {
32
+ Root: DialogRoot,
33
+ Trigger: DialogTrigger,
34
+ Content: DialogContent,
35
+ Title: DialogTitle,
36
+ Description: DialogDescription,
37
+ Close: DialogClose,
38
+ };
39
+
40
+ // Type exports
41
+ export type {
42
+ DialogCloseProps,
43
+ DialogContentProps,
44
+ DialogContentSize,
45
+ DialogDescriptionProps,
46
+ DialogRootProps,
47
+ DialogTitleProps,
48
+ DialogTriggerProps,
49
+ };
50
+
51
+ // Re-export DialogRole from primitives-dom
52
+ export type { DialogRole } from "@hypoth-ui/primitives-dom";
@@ -0,0 +1,59 @@
1
+ import { html } from "lit";
2
+ import { property } from "lit/decorators.js";
3
+ import { DSElement } from "../../base/ds-element.js";
4
+ import { define } from "../../registry/define.js";
5
+
6
+ export type DialogContentSize = "sm" | "md" | "lg" | "xl" | "full";
7
+ export type DialogContentState = "open" | "closed";
8
+
9
+ /**
10
+ * Dialog content container component.
11
+ *
12
+ * Contains the dialog's content including title, description, and actions.
13
+ * Receives accessibility attributes from parent ds-dialog.
14
+ *
15
+ * @element ds-dialog-content
16
+ *
17
+ * @slot - Dialog content (title, description, body, actions)
18
+ *
19
+ * @csspart container - The content container element
20
+ *
21
+ * @attr {string} data-state - Animation state ("open" or "closed")
22
+ *
23
+ * @example
24
+ * ```html
25
+ * <ds-dialog-content size="lg">
26
+ * <ds-dialog-title>Large Dialog</ds-dialog-title>
27
+ * <p>Dialog body content here.</p>
28
+ * <div class="ds-dialog__footer">
29
+ * <button>Cancel</button>
30
+ * <button>Confirm</button>
31
+ * </div>
32
+ * </ds-dialog-content>
33
+ * ```
34
+ */
35
+ export class DsDialogContent extends DSElement {
36
+ /** Size variant of the dialog */
37
+ @property({ type: String, reflect: true })
38
+ size: DialogContentSize = "md";
39
+
40
+ /** Animation state (open or closed) - set by parent ds-dialog */
41
+ @property({ type: String, reflect: true, attribute: "data-state" })
42
+ dataState: DialogContentState = "open";
43
+
44
+ override render() {
45
+ return html`
46
+ <div class="ds-dialog-content" part="container" data-size=${this.size}>
47
+ <slot></slot>
48
+ </div>
49
+ `;
50
+ }
51
+ }
52
+
53
+ define("ds-dialog-content", DsDialogContent);
54
+
55
+ declare global {
56
+ interface HTMLElementTagNameMap {
57
+ "ds-dialog-content": DsDialogContent;
58
+ }
59
+ }
@@ -0,0 +1,58 @@
1
+ import { html, nothing } from "lit";
2
+ import { state } from "lit/decorators.js";
3
+ import { DSElement } from "../../base/ds-element.js";
4
+ import { define } from "../../registry/define.js";
5
+
6
+ /**
7
+ * Dialog description component.
8
+ *
9
+ * Renders the dialog's accessible description. The parent ds-dialog
10
+ * automatically connects this to the dialog content via aria-describedby.
11
+ *
12
+ * @element ds-dialog-description
13
+ *
14
+ * @csspart description - The description element
15
+ *
16
+ * @example
17
+ * ```html
18
+ * <ds-dialog-description>
19
+ * This action cannot be undone.
20
+ * </ds-dialog-description>
21
+ * ```
22
+ */
23
+ export class DsDialogDescription extends DSElement {
24
+ /** Preserved text content from initial children */
25
+ @state()
26
+ private descriptionText = "";
27
+
28
+ override connectedCallback(): void {
29
+ // Capture original text content before Lit renders
30
+ this.descriptionText = this.textContent?.trim() ?? "";
31
+
32
+ super.connectedCallback();
33
+
34
+ // Generate ID if not provided
35
+ if (!this.id) {
36
+ this.id = `dialog-desc-${crypto.randomUUID().slice(0, 8)}`;
37
+ }
38
+ }
39
+
40
+ override render() {
41
+ // Only render p if there's content
42
+ if (!this.descriptionText) {
43
+ return nothing;
44
+ }
45
+
46
+ return html`
47
+ <p class="ds-dialog-description" part="description">${this.descriptionText}</p>
48
+ `;
49
+ }
50
+ }
51
+
52
+ define("ds-dialog-description", DsDialogDescription);
53
+
54
+ declare global {
55
+ interface HTMLElementTagNameMap {
56
+ "ds-dialog-description": DsDialogDescription;
57
+ }
58
+ }
@@ -0,0 +1,56 @@
1
+ import { html, nothing } from "lit";
2
+ import { state } from "lit/decorators.js";
3
+ import { DSElement } from "../../base/ds-element.js";
4
+ import { define } from "../../registry/define.js";
5
+
6
+ /**
7
+ * Dialog title component.
8
+ *
9
+ * Renders the dialog's accessible title. The parent ds-dialog
10
+ * automatically connects this to the dialog content via aria-labelledby.
11
+ *
12
+ * @element ds-dialog-title
13
+ *
14
+ * @csspart title - The title element
15
+ *
16
+ * @example
17
+ * ```html
18
+ * <ds-dialog-title>Confirm Deletion</ds-dialog-title>
19
+ * ```
20
+ */
21
+ export class DsDialogTitle extends DSElement {
22
+ /** Preserved text content from initial children */
23
+ @state()
24
+ private titleText = "";
25
+
26
+ override connectedCallback(): void {
27
+ // Capture original text content before Lit renders
28
+ this.titleText = this.textContent?.trim() ?? "";
29
+
30
+ super.connectedCallback();
31
+
32
+ // Generate ID if not provided
33
+ if (!this.id) {
34
+ this.id = `dialog-title-${crypto.randomUUID().slice(0, 8)}`;
35
+ }
36
+ }
37
+
38
+ override render() {
39
+ // Only render h2 if there's content (avoid empty heading a11y violation)
40
+ if (!this.titleText) {
41
+ return nothing;
42
+ }
43
+
44
+ return html`
45
+ <h2 class="ds-dialog-title" part="title">${this.titleText}</h2>
46
+ `;
47
+ }
48
+ }
49
+
50
+ define("ds-dialog-title", DsDialogTitle);
51
+
52
+ declare global {
53
+ interface HTMLElementTagNameMap {
54
+ "ds-dialog-title": DsDialogTitle;
55
+ }
56
+ }