@hypoth-ui/cli 0.0.1 → 0.1.1

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,266 @@
1
+ /**
2
+ * Accordion compound component exports.
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { Accordion } from "@/components/ui";
7
+ *
8
+ * // Single expand mode
9
+ * <Accordion.Root type="single" defaultValue="item-1" collapsible>
10
+ * <Accordion.Item value="item-1">
11
+ * <Accordion.Trigger>Section 1</Accordion.Trigger>
12
+ * <Accordion.Content>Content 1</Accordion.Content>
13
+ * </Accordion.Item>
14
+ * <Accordion.Item value="item-2">
15
+ * <Accordion.Trigger>Section 2</Accordion.Trigger>
16
+ * <Accordion.Content>Content 2</Accordion.Content>
17
+ * </Accordion.Item>
18
+ * </Accordion.Root>
19
+ *
20
+ * // Multiple expand mode
21
+ * <Accordion.Root type="multiple" defaultValue={["item-1", "item-2"]}>
22
+ * ...
23
+ * </Accordion.Root>
24
+ * ```
25
+ */
26
+
27
+ import {
28
+ type HTMLAttributes,
29
+ type ReactNode,
30
+ createElement,
31
+ forwardRef,
32
+ useCallback,
33
+ useEffect,
34
+ useRef,
35
+ useState,
36
+ } from "react";
37
+
38
+ // ============================================================================
39
+ // Types
40
+ // ============================================================================
41
+
42
+ export type AccordionType = "single" | "multiple";
43
+ export type AccordionOrientation = "horizontal" | "vertical";
44
+
45
+ interface AccordionSingleProps {
46
+ type: "single";
47
+ /** Controlled value */
48
+ value?: string;
49
+ /** Default value (uncontrolled) */
50
+ defaultValue?: string;
51
+ /** Called when value changes */
52
+ onValueChange?: (value: string) => void;
53
+ /** Allow collapsing all items */
54
+ collapsible?: boolean;
55
+ }
56
+
57
+ interface AccordionMultipleProps {
58
+ type: "multiple";
59
+ /** Controlled value */
60
+ value?: string[];
61
+ /** Default value (uncontrolled) */
62
+ defaultValue?: string[];
63
+ /** Called when value changes */
64
+ onValueChange?: (value: string[]) => void;
65
+ }
66
+
67
+ type AccordionRootBaseProps = HTMLAttributes<HTMLElement> & {
68
+ children?: ReactNode;
69
+ orientation?: AccordionOrientation;
70
+ };
71
+
72
+ export type AccordionRootProps = AccordionRootBaseProps &
73
+ (AccordionSingleProps | AccordionMultipleProps);
74
+
75
+ export interface AccordionItemProps extends HTMLAttributes<HTMLElement> {
76
+ children?: ReactNode;
77
+ /** Unique value identifying this item */
78
+ value: string;
79
+ /** Disable this item */
80
+ disabled?: boolean;
81
+ }
82
+
83
+ export interface AccordionTriggerProps extends HTMLAttributes<HTMLElement> {
84
+ children?: ReactNode;
85
+ }
86
+
87
+ export interface AccordionContentProps extends HTMLAttributes<HTMLElement> {
88
+ children?: ReactNode;
89
+ /** Keep mounted when collapsed */
90
+ forceMount?: boolean;
91
+ }
92
+
93
+ // ============================================================================
94
+ // Components
95
+ // ============================================================================
96
+
97
+ /**
98
+ * Accordion root component.
99
+ */
100
+ const AccordionRoot = forwardRef<HTMLElement, AccordionRootProps>(
101
+ function AccordionRoot(props, ref) {
102
+ const { children, className, type = "single", orientation = "vertical" } = props;
103
+
104
+ // Handle single vs multiple mode
105
+ const isSingle = type === "single";
106
+ const singleProps = props as AccordionSingleProps;
107
+ const multipleProps = props as AccordionMultipleProps;
108
+
109
+ // State management
110
+ const [internalValue, setInternalValue] = useState<string | string[]>(() => {
111
+ if (isSingle) {
112
+ return singleProps.defaultValue ?? "";
113
+ }
114
+ return multipleProps.defaultValue ?? [];
115
+ });
116
+
117
+ const isControlled = isSingle
118
+ ? singleProps.value !== undefined
119
+ : multipleProps.value !== undefined;
120
+
121
+ const value = isControlled
122
+ ? isSingle
123
+ ? singleProps.value
124
+ : multipleProps.value
125
+ : internalValue;
126
+
127
+ const elementRef = useRef<HTMLElement>(null);
128
+
129
+ // Combine refs
130
+ const combinedRef = (node: HTMLElement | null) => {
131
+ (elementRef as React.MutableRefObject<HTMLElement | null>).current = node;
132
+ if (typeof ref === "function") {
133
+ ref(node);
134
+ } else if (ref) {
135
+ (ref as React.MutableRefObject<HTMLElement | null>).current = node;
136
+ }
137
+ };
138
+
139
+ const handleChange = useCallback(
140
+ (event: Event) => {
141
+ const customEvent = event as CustomEvent<{ value: string }>;
142
+ const newValue = customEvent.detail.value;
143
+
144
+ if (isSingle) {
145
+ if (!isControlled) {
146
+ setInternalValue(newValue);
147
+ }
148
+ (singleProps.onValueChange as ((v: string) => void) | undefined)?.(newValue);
149
+ } else {
150
+ // Parse JSON array
151
+ let parsedValue: string[] = [];
152
+ try {
153
+ parsedValue = JSON.parse(newValue);
154
+ } catch {
155
+ parsedValue = newValue ? [newValue] : [];
156
+ }
157
+
158
+ if (!isControlled) {
159
+ setInternalValue(parsedValue);
160
+ }
161
+ (multipleProps.onValueChange as ((v: string[]) => void) | undefined)?.(parsedValue);
162
+ }
163
+ },
164
+ [isSingle, isControlled, singleProps.onValueChange, multipleProps.onValueChange]
165
+ );
166
+
167
+ // Attach event listeners
168
+ useEffect(() => {
169
+ const element = elementRef.current;
170
+ if (!element) return;
171
+
172
+ element.addEventListener("ds:change", handleChange);
173
+
174
+ return () => {
175
+ element.removeEventListener("ds:change", handleChange);
176
+ };
177
+ }, [handleChange]);
178
+
179
+ // Convert value to string for WC
180
+ const valueString = isSingle ? (value as string) : JSON.stringify(value);
181
+
182
+ // Extract collapsible from single props
183
+ const collapsible = isSingle ? singleProps.collapsible : undefined;
184
+
185
+ return createElement(
186
+ "ds-accordion",
187
+ {
188
+ ref: combinedRef,
189
+ class: className,
190
+ type,
191
+ value: isControlled ? valueString : undefined,
192
+ "default-value": !isControlled ? valueString : undefined,
193
+ collapsible: isSingle && collapsible ? true : undefined,
194
+ orientation,
195
+ },
196
+ children
197
+ );
198
+ }
199
+ );
200
+ AccordionRoot.displayName = "Accordion.Root";
201
+
202
+ /**
203
+ * Accordion item component.
204
+ */
205
+ const AccordionItem = forwardRef<HTMLElement, AccordionItemProps>(function AccordionItem(
206
+ { children, className, value, disabled = false, ...props },
207
+ ref
208
+ ) {
209
+ return createElement(
210
+ "ds-accordion-item",
211
+ {
212
+ ref,
213
+ class: className,
214
+ value,
215
+ disabled: disabled || undefined,
216
+ ...props,
217
+ },
218
+ children
219
+ );
220
+ });
221
+ AccordionItem.displayName = "Accordion.Item";
222
+
223
+ /**
224
+ * Accordion trigger component.
225
+ */
226
+ const AccordionTrigger = forwardRef<HTMLElement, AccordionTriggerProps>(function AccordionTrigger(
227
+ { children, className, ...props },
228
+ ref
229
+ ) {
230
+ return createElement("ds-accordion-trigger", { ref, class: className, ...props }, children);
231
+ });
232
+ AccordionTrigger.displayName = "Accordion.Trigger";
233
+
234
+ /**
235
+ * Accordion content component.
236
+ */
237
+ const AccordionContent = forwardRef<HTMLElement, AccordionContentProps>(function AccordionContent(
238
+ { children, className, forceMount = false, ...props },
239
+ ref
240
+ ) {
241
+ return createElement(
242
+ "ds-accordion-content",
243
+ {
244
+ ref,
245
+ class: className,
246
+ "force-mount": forceMount || undefined,
247
+ ...props,
248
+ },
249
+ children
250
+ );
251
+ });
252
+ AccordionContent.displayName = "Accordion.Content";
253
+
254
+ // ============================================================================
255
+ // Compound Component
256
+ // ============================================================================
257
+
258
+ export const Accordion = {
259
+ Root: AccordionRoot,
260
+ Item: AccordionItem,
261
+ Trigger: AccordionTrigger,
262
+ Content: AccordionContent,
263
+ };
264
+
265
+ // Also export individual components
266
+ export { AccordionRoot, AccordionItem, AccordionTrigger, AccordionContent };
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Accordion Content component - expandable content section.
3
+ *
4
+ * @element ds-accordion-content
5
+ *
6
+ * @slot - Accordion content
7
+ */
8
+
9
+ import { type Presence, createPresence, prefersReducedMotion } from "@hypoth-ui/primitives-dom";
10
+ import { html } from "lit";
11
+ import { property, state } from "lit/decorators.js";
12
+ import { DSElement } from "../../base/ds-element.js";
13
+ import { define } from "../../registry/define.js";
14
+
15
+ export class DsAccordionContent extends DSElement {
16
+ /** Keep mounted when collapsed (for animations) */
17
+ @property({ type: Boolean, attribute: "force-mount" })
18
+ forceMount = false;
19
+
20
+ /** Internal expanded state */
21
+ @state()
22
+ private expanded = false;
23
+
24
+ /** Trigger ID for aria-labelledby */
25
+ @state()
26
+ private triggerId = "";
27
+
28
+ /** Whether we're animating out */
29
+ @state()
30
+ private isAnimatingOut = false;
31
+
32
+ private presence: Presence | null = null;
33
+
34
+ override connectedCallback(): void {
35
+ super.connectedCallback();
36
+ this.setAttribute("role", "region");
37
+ this.updateVisibility();
38
+ }
39
+
40
+ override disconnectedCallback(): void {
41
+ super.disconnectedCallback();
42
+ this.presence?.destroy();
43
+ this.presence = null;
44
+ }
45
+
46
+ /**
47
+ * Set the expanded state (called by parent).
48
+ */
49
+ public setExpanded(expanded: boolean): void {
50
+ const wasExpanded = this.expanded;
51
+ this.expanded = expanded;
52
+ this.setAttribute("data-state", expanded ? "open" : "closed");
53
+
54
+ if (wasExpanded && !expanded) {
55
+ // Collapsing - animate out
56
+ this.handleCollapse();
57
+ } else {
58
+ this.isAnimatingOut = false;
59
+ this.updateVisibility();
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Set the trigger ID for aria-labelledby.
65
+ */
66
+ public setTriggerId(id: string): void {
67
+ this.triggerId = id;
68
+ this.setAttribute("aria-labelledby", id);
69
+ }
70
+
71
+ private handleCollapse(): void {
72
+ if (!this.forceMount && !prefersReducedMotion()) {
73
+ this.isAnimatingOut = true;
74
+
75
+ this.presence?.destroy();
76
+ this.presence = createPresence({
77
+ onExitComplete: () => {
78
+ this.isAnimatingOut = false;
79
+ this.updateVisibility();
80
+ },
81
+ });
82
+ this.presence.hide(this);
83
+ } else {
84
+ this.updateVisibility();
85
+ }
86
+ }
87
+
88
+ private updateVisibility(): void {
89
+ if (this.forceMount) {
90
+ this.hidden = false;
91
+ return;
92
+ }
93
+
94
+ if (this.isAnimatingOut) {
95
+ this.hidden = false;
96
+ return;
97
+ }
98
+
99
+ this.hidden = !this.expanded;
100
+ }
101
+
102
+ override render() {
103
+ return html`<slot></slot>`;
104
+ }
105
+ }
106
+
107
+ define("ds-accordion-content", DsAccordionContent);
108
+
109
+ declare global {
110
+ interface HTMLElementTagNameMap {
111
+ "ds-accordion-content": DsAccordionContent;
112
+ }
113
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Accordion Item component - container for trigger and content.
3
+ *
4
+ * @element ds-accordion-item
5
+ *
6
+ * @slot - Accordion trigger and content
7
+ */
8
+
9
+ import { html } from "lit";
10
+ import { property, state } from "lit/decorators.js";
11
+ import { DSElement } from "../../base/ds-element.js";
12
+ import { define } from "../../registry/define.js";
13
+ import type { DsAccordionContent } from "./accordion-content.js";
14
+ import type { DsAccordionTrigger } from "./accordion-trigger.js";
15
+
16
+ export class DsAccordionItem extends DSElement {
17
+ /** Unique value identifying this item */
18
+ @property({ reflect: true })
19
+ value = "";
20
+
21
+ /** Disable this item */
22
+ @property({ type: Boolean, reflect: true })
23
+ disabled = false;
24
+
25
+ /** Internal expanded state */
26
+ @state()
27
+ private expanded = false;
28
+
29
+ /** ID for ARIA relationships */
30
+ private contentId = "";
31
+ private triggerId = "";
32
+
33
+ override connectedCallback(): void {
34
+ super.connectedCallback();
35
+
36
+ // Generate IDs
37
+ const id = crypto.randomUUID().slice(0, 8);
38
+ this.contentId = `accordion-content-${this.value}-${id}`;
39
+ this.triggerId = `accordion-trigger-${this.value}-${id}`;
40
+
41
+ this.setAttribute("data-state", "closed");
42
+ }
43
+
44
+ /**
45
+ * Set the expanded state (called by parent).
46
+ */
47
+ public setExpanded(expanded: boolean): void {
48
+ this.expanded = expanded;
49
+ this.setAttribute("data-state", expanded ? "open" : "closed");
50
+ this.updateChildren();
51
+ }
52
+
53
+ /**
54
+ * Get whether the item is expanded.
55
+ */
56
+ public isExpanded(): boolean {
57
+ return this.expanded;
58
+ }
59
+
60
+ /**
61
+ * Get the content ID.
62
+ */
63
+ public getContentId(): string {
64
+ return this.contentId;
65
+ }
66
+
67
+ /**
68
+ * Get the trigger ID.
69
+ */
70
+ public getTriggerId(): string {
71
+ return this.triggerId;
72
+ }
73
+
74
+ private updateChildren(): void {
75
+ const trigger = this.querySelector("ds-accordion-trigger") as DsAccordionTrigger | null;
76
+ const content = this.querySelector("ds-accordion-content") as DsAccordionContent | null;
77
+
78
+ if (trigger) {
79
+ trigger.id = this.triggerId;
80
+ trigger.setExpanded(this.expanded);
81
+ trigger.setContentId(this.contentId);
82
+ if (this.disabled) {
83
+ trigger.setAttribute("aria-disabled", "true");
84
+ } else {
85
+ trigger.removeAttribute("aria-disabled");
86
+ }
87
+ }
88
+
89
+ if (content) {
90
+ content.id = this.contentId;
91
+ content.setExpanded(this.expanded);
92
+ content.setTriggerId(this.triggerId);
93
+ }
94
+ }
95
+
96
+ override updated(): void {
97
+ this.updateChildren();
98
+ }
99
+
100
+ override render() {
101
+ return html`<slot></slot>`;
102
+ }
103
+ }
104
+
105
+ define("ds-accordion-item", DsAccordionItem);
106
+
107
+ declare global {
108
+ interface HTMLElementTagNameMap {
109
+ "ds-accordion-item": DsAccordionItem;
110
+ }
111
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Accordion Trigger component - button that toggles accordion item.
3
+ *
4
+ * @element ds-accordion-trigger
5
+ *
6
+ * @slot - Trigger label content
7
+ */
8
+
9
+ import { html } from "lit";
10
+ import { state } from "lit/decorators.js";
11
+ import { DSElement } from "../../base/ds-element.js";
12
+ import { emitEvent } from "../../events/emit.js";
13
+ import { define } from "../../registry/define.js";
14
+ import type { DsAccordionItem } from "./accordion-item.js";
15
+
16
+ export class DsAccordionTrigger extends DSElement {
17
+ /** Internal expanded state */
18
+ @state()
19
+ private expanded = false;
20
+
21
+ /** Content panel ID */
22
+ @state()
23
+ private contentId = "";
24
+
25
+ override connectedCallback(): void {
26
+ super.connectedCallback();
27
+
28
+ // Set ARIA role and attributes
29
+ this.setAttribute("role", "button");
30
+ this.setAttribute("tabindex", "0");
31
+
32
+ // Handle click and keyboard
33
+ this.addEventListener("click", this.handleClick);
34
+ this.addEventListener("keydown", this.handleKeyDown);
35
+ }
36
+
37
+ override disconnectedCallback(): void {
38
+ super.disconnectedCallback();
39
+ this.removeEventListener("click", this.handleClick);
40
+ this.removeEventListener("keydown", this.handleKeyDown);
41
+ }
42
+
43
+ /**
44
+ * Set the expanded state (called by parent).
45
+ */
46
+ public setExpanded(expanded: boolean): void {
47
+ this.expanded = expanded;
48
+ this.updateAccessibility();
49
+ }
50
+
51
+ /**
52
+ * Set the content ID for aria-controls.
53
+ */
54
+ public setContentId(id: string): void {
55
+ this.contentId = id;
56
+ this.updateAccessibility();
57
+ }
58
+
59
+ private handleClick = (): void => {
60
+ if (this.hasAttribute("aria-disabled")) return;
61
+ this.toggle();
62
+ };
63
+
64
+ private handleKeyDown = (event: KeyboardEvent): void => {
65
+ if (this.hasAttribute("aria-disabled")) return;
66
+
67
+ if (event.key === "Enter" || event.key === " ") {
68
+ event.preventDefault();
69
+ this.toggle();
70
+ }
71
+ };
72
+
73
+ private toggle(): void {
74
+ const item = this.closest("ds-accordion-item") as DsAccordionItem | null;
75
+ if (!item) return;
76
+
77
+ emitEvent(this, "ds:accordion-toggle", {
78
+ detail: { value: item.value },
79
+ bubbles: true,
80
+ });
81
+ }
82
+
83
+ private updateAccessibility(): void {
84
+ this.setAttribute("aria-expanded", String(this.expanded));
85
+ if (this.contentId) {
86
+ this.setAttribute("aria-controls", this.contentId);
87
+ }
88
+ }
89
+
90
+ override updated(): void {
91
+ this.updateAccessibility();
92
+ }
93
+
94
+ override render() {
95
+ return html`<slot></slot>`;
96
+ }
97
+ }
98
+
99
+ define("ds-accordion-trigger", DsAccordionTrigger);
100
+
101
+ declare global {
102
+ interface HTMLElementTagNameMap {
103
+ "ds-accordion-trigger": DsAccordionTrigger;
104
+ }
105
+ }