@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,150 @@
1
+ /**
2
+ * DrawerContent component - container for drawer content with swipe support.
3
+ *
4
+ * @element ds-drawer-content
5
+ *
6
+ * @slot - Drawer content (header, body, footer)
7
+ *
8
+ * @fires ds:drawer-close - Fired when swipe gesture dismisses drawer
9
+ */
10
+
11
+ import { html } from "lit";
12
+ import { property, state } from "lit/decorators.js";
13
+ import { DSElement } from "../../base/ds-element.js";
14
+ import { emitEvent } from "../../events/emit.js";
15
+ import { define } from "../../registry/define.js";
16
+ import type { DrawerSide } from "./drawer.js";
17
+
18
+ export class DsDrawerContent extends DSElement {
19
+ /** Side of the screen the drawer appears from (set by parent) */
20
+ @property({ reflect: true })
21
+ side: DrawerSide = "bottom";
22
+
23
+ /** Data state for animations */
24
+ @property({ attribute: "data-state", reflect: true })
25
+ dataState: "open" | "closed" = "closed";
26
+
27
+ /** Whether swipe-to-dismiss is enabled (set by parent) */
28
+ @property({ type: Boolean, attribute: "swipe-dismiss" })
29
+ swipeDismiss = true;
30
+
31
+ /** Current swipe offset during drag */
32
+ @state()
33
+ private swipeOffset = 0;
34
+
35
+ /** Whether currently dragging */
36
+ @state()
37
+ private isDragging = false;
38
+
39
+ private startY = 0;
40
+ private startX = 0;
41
+
42
+ override connectedCallback(): void {
43
+ super.connectedCallback();
44
+
45
+ // Add touch event listeners for swipe-to-dismiss
46
+ this.addEventListener("touchstart", this.handleTouchStart, { passive: true });
47
+ this.addEventListener("touchmove", this.handleTouchMove, { passive: false });
48
+ this.addEventListener("touchend", this.handleTouchEnd, { passive: true });
49
+ }
50
+
51
+ override disconnectedCallback(): void {
52
+ super.disconnectedCallback();
53
+ this.removeEventListener("touchstart", this.handleTouchStart);
54
+ this.removeEventListener("touchmove", this.handleTouchMove);
55
+ this.removeEventListener("touchend", this.handleTouchEnd);
56
+ }
57
+
58
+ private handleTouchStart = (event: TouchEvent): void => {
59
+ if (!this.swipeDismiss) return;
60
+
61
+ const touch = event.touches[0];
62
+ if (!touch) return;
63
+
64
+ this.startY = touch.clientY;
65
+ this.startX = touch.clientX;
66
+ this.isDragging = true;
67
+ };
68
+
69
+ private handleTouchMove = (event: TouchEvent): void => {
70
+ if (!this.swipeDismiss || !this.isDragging) return;
71
+
72
+ const touch = event.touches[0];
73
+ if (!touch) return;
74
+
75
+ const deltaY = touch.clientY - this.startY;
76
+ const deltaX = touch.clientX - this.startX;
77
+
78
+ // Calculate offset based on side
79
+ let offset = 0;
80
+ switch (this.side) {
81
+ case "bottom":
82
+ offset = Math.max(0, deltaY);
83
+ break;
84
+ case "top":
85
+ offset = Math.max(0, -deltaY);
86
+ break;
87
+ case "left":
88
+ offset = Math.max(0, -deltaX);
89
+ break;
90
+ case "right":
91
+ offset = Math.max(0, deltaX);
92
+ break;
93
+ }
94
+
95
+ if (offset > 0) {
96
+ event.preventDefault();
97
+ this.swipeOffset = offset;
98
+ this.updateSwipeTransform();
99
+ }
100
+ };
101
+
102
+ private handleTouchEnd = (): void => {
103
+ if (!this.swipeDismiss || !this.isDragging) return;
104
+
105
+ this.isDragging = false;
106
+
107
+ // If swiped more than 100px or 30% of content height, close
108
+ const threshold = Math.min(100, this.offsetHeight * 0.3);
109
+
110
+ if (this.swipeOffset > threshold) {
111
+ emitEvent(this, "ds:drawer-close", { bubbles: true });
112
+ } else {
113
+ // Reset position
114
+ this.swipeOffset = 0;
115
+ this.style.transform = "";
116
+ }
117
+ };
118
+
119
+ private updateSwipeTransform(): void {
120
+ switch (this.side) {
121
+ case "bottom":
122
+ this.style.transform = `translateY(${this.swipeOffset}px)`;
123
+ break;
124
+ case "top":
125
+ this.style.transform = `translateY(-${this.swipeOffset}px)`;
126
+ break;
127
+ case "left":
128
+ this.style.transform = `translateX(-${this.swipeOffset}px)`;
129
+ break;
130
+ case "right":
131
+ this.style.transform = `translateX(${this.swipeOffset}px)`;
132
+ break;
133
+ }
134
+ }
135
+
136
+ override render() {
137
+ return html`
138
+ <div class="ds-drawer__handle"></div>
139
+ <slot></slot>
140
+ `;
141
+ }
142
+ }
143
+
144
+ define("ds-drawer-content", DsDrawerContent);
145
+
146
+ declare global {
147
+ interface HTMLElementTagNameMap {
148
+ "ds-drawer-content": DsDrawerContent;
149
+ }
150
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * DrawerDescription component - description for the drawer.
3
+ *
4
+ * @element ds-drawer-description
5
+ *
6
+ * @slot - Description content
7
+ */
8
+
9
+ import { html } from "lit";
10
+ import { DSElement } from "../../base/ds-element.js";
11
+ import { define } from "../../registry/define.js";
12
+
13
+ export class DsDrawerDescription extends DSElement {
14
+ override connectedCallback(): void {
15
+ super.connectedCallback();
16
+
17
+ // Generate ID if not present (for aria-describedby)
18
+ if (!this.id) {
19
+ this.id = `drawer-desc-${crypto.randomUUID().slice(0, 8)}`;
20
+ }
21
+ }
22
+
23
+ override render() {
24
+ return html`<slot></slot>`;
25
+ }
26
+ }
27
+
28
+ define("ds-drawer-description", DsDrawerDescription);
29
+
30
+ declare global {
31
+ interface HTMLElementTagNameMap {
32
+ "ds-drawer-description": DsDrawerDescription;
33
+ }
34
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * DrawerFooter component - footer section for drawer actions.
3
+ *
4
+ * @element ds-drawer-footer
5
+ *
6
+ * @slot - Footer content (action buttons)
7
+ */
8
+
9
+ import { html } from "lit";
10
+ import { DSElement } from "../../base/ds-element.js";
11
+ import { define } from "../../registry/define.js";
12
+
13
+ export class DsDrawerFooter extends DSElement {
14
+ override render() {
15
+ return html`<slot></slot>`;
16
+ }
17
+ }
18
+
19
+ define("ds-drawer-footer", DsDrawerFooter);
20
+
21
+ declare global {
22
+ interface HTMLElementTagNameMap {
23
+ "ds-drawer-footer": DsDrawerFooter;
24
+ }
25
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * DrawerHeader component - header section for drawer.
3
+ *
4
+ * @element ds-drawer-header
5
+ *
6
+ * @slot - Header content (title and description)
7
+ */
8
+
9
+ import { html } from "lit";
10
+ import { DSElement } from "../../base/ds-element.js";
11
+ import { define } from "../../registry/define.js";
12
+
13
+ export class DsDrawerHeader extends DSElement {
14
+ override render() {
15
+ return html`<slot></slot>`;
16
+ }
17
+ }
18
+
19
+ define("ds-drawer-header", DsDrawerHeader);
20
+
21
+ declare global {
22
+ interface HTMLElementTagNameMap {
23
+ "ds-drawer-header": DsDrawerHeader;
24
+ }
25
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * DrawerTitle component - title for the drawer.
3
+ *
4
+ * @element ds-drawer-title
5
+ *
6
+ * @slot - Title content
7
+ */
8
+
9
+ import { html } from "lit";
10
+ import { DSElement } from "../../base/ds-element.js";
11
+ import { define } from "../../registry/define.js";
12
+
13
+ export class DsDrawerTitle extends DSElement {
14
+ override connectedCallback(): void {
15
+ super.connectedCallback();
16
+
17
+ // Generate ID if not present (for aria-labelledby)
18
+ if (!this.id) {
19
+ this.id = `drawer-title-${crypto.randomUUID().slice(0, 8)}`;
20
+ }
21
+ }
22
+
23
+ override render() {
24
+ return html`<slot></slot>`;
25
+ }
26
+ }
27
+
28
+ define("ds-drawer-title", DsDrawerTitle);
29
+
30
+ declare global {
31
+ interface HTMLElementTagNameMap {
32
+ "ds-drawer-title": DsDrawerTitle;
33
+ }
34
+ }
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Drawer component - mobile-optimized slide-in panel with swipe gestures.
3
+ *
4
+ * Drawer is a Sheet variant optimized for mobile with touch gesture support.
5
+ * It slides in from the bottom by default and can be dismissed by swiping down.
6
+ *
7
+ * @element ds-drawer
8
+ *
9
+ * @slot trigger - Button or element that opens the drawer
10
+ * @slot - Drawer content (ds-drawer-content)
11
+ *
12
+ * @fires ds:open - Fired when drawer opens
13
+ * @fires ds:close - Fired when drawer closes
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <ds-drawer>
18
+ * <button slot="trigger">Open Menu</button>
19
+ * <ds-drawer-content>
20
+ * <ds-drawer-header>
21
+ * <ds-drawer-title>Navigation</ds-drawer-title>
22
+ * </ds-drawer-header>
23
+ * <nav>Menu items...</nav>
24
+ * </ds-drawer-content>
25
+ * </ds-drawer>
26
+ * ```
27
+ */
28
+
29
+ import {
30
+ type DialogBehavior,
31
+ type Presence,
32
+ createDialogBehavior,
33
+ createPresence,
34
+ prefersReducedMotion,
35
+ } from "@hypoth-ui/primitives-dom";
36
+ import { html } from "lit";
37
+ import { property, state } from "lit/decorators.js";
38
+ import { DSElement } from "../../base/ds-element.js";
39
+ import { StandardEvents, emitEvent } from "../../events/emit.js";
40
+ import { define } from "../../registry/define.js";
41
+ import { devWarn, hasRequiredChild, Warnings } from "../../utils/dev-warnings.js";
42
+
43
+ // Import child components to ensure they're registered
44
+ import type { DsDrawerContent } from "./drawer-content.js";
45
+ import "./drawer-content.js";
46
+ import "./drawer-header.js";
47
+ import "./drawer-footer.js";
48
+ import "./drawer-title.js";
49
+ import "./drawer-description.js";
50
+
51
+ export type DrawerSide = "top" | "right" | "bottom" | "left";
52
+
53
+ export class DsDrawer extends DSElement {
54
+ /** Whether the drawer is open */
55
+ @property({ type: Boolean, reflect: true })
56
+ open = false;
57
+
58
+ /** Side of the screen the drawer appears from */
59
+ @property({ reflect: true })
60
+ side: DrawerSide = "bottom";
61
+
62
+ /** Whether swipe-to-dismiss is enabled */
63
+ @property({ type: Boolean, attribute: "swipe-dismiss" })
64
+ swipeDismiss = true;
65
+
66
+ /** Whether Escape key closes the drawer */
67
+ @property({ type: Boolean, attribute: "close-on-escape" })
68
+ closeOnEscape = true;
69
+
70
+ /** Whether clicking the overlay closes the drawer */
71
+ @property({ type: Boolean, attribute: "close-on-overlay" })
72
+ closeOnOverlay = true;
73
+
74
+ /** Whether to animate open/close transitions */
75
+ @property({ type: Boolean })
76
+ animated = true;
77
+
78
+ /** Whether the drawer is closing (for animation) */
79
+ @state()
80
+ private isClosing = false;
81
+
82
+ private dialogBehavior: DialogBehavior | null = null;
83
+ private presence: Presence | null = null;
84
+
85
+ override connectedCallback(): void {
86
+ super.connectedCallback();
87
+
88
+ // Listen for trigger clicks via event delegation
89
+ this.addEventListener("click", this.handleTriggerClick);
90
+
91
+ // Listen for close requests from child components
92
+ this.addEventListener("ds:drawer-close", this.handleCloseRequest as EventListener);
93
+
94
+ // Initialize dialog behavior
95
+ this.initDialogBehavior();
96
+ }
97
+
98
+ override disconnectedCallback(): void {
99
+ super.disconnectedCallback();
100
+ this.removeEventListener("click", this.handleTriggerClick);
101
+ this.removeEventListener("ds:drawer-close", this.handleCloseRequest as EventListener);
102
+ this.cleanup();
103
+ }
104
+
105
+ /**
106
+ * Initializes the dialog behavior primitive.
107
+ */
108
+ private initDialogBehavior(): void {
109
+ this.dialogBehavior = createDialogBehavior({
110
+ defaultOpen: this.open,
111
+ role: "dialog",
112
+ closeOnEscape: this.closeOnEscape,
113
+ closeOnOutsideClick: this.closeOnOverlay,
114
+ onOpenChange: (open) => {
115
+ // Sync state when behavior changes (e.g., from escape or outside click)
116
+ if (!open && this.open) {
117
+ this.handleBehaviorClose();
118
+ }
119
+ },
120
+ });
121
+
122
+ // Set trigger element if one exists
123
+ const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
124
+ if (trigger) {
125
+ this.dialogBehavior.setTriggerElement(trigger);
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Handles close triggered by the behavior (escape/outside click).
131
+ */
132
+ private handleBehaviorClose(): void {
133
+ const content = this.querySelector("ds-drawer-content") as DsDrawerContent | null;
134
+
135
+ // If animated, use presence for exit animation
136
+ if (this.animated && content && !prefersReducedMotion()) {
137
+ this.isClosing = true;
138
+
139
+ // Create presence for exit animation
140
+ this.presence = createPresence({
141
+ onExitComplete: () => {
142
+ this.completeClose();
143
+ },
144
+ });
145
+ this.presence.hide(content);
146
+ } else {
147
+ // No animation - close immediately
148
+ this.open = false;
149
+ this.isClosing = false;
150
+ emitEvent(this, StandardEvents.CLOSE);
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Opens the drawer.
156
+ */
157
+ public show(): void {
158
+ if (this.open) return;
159
+
160
+ // Store trigger element for focus return
161
+ const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
162
+ if (trigger) {
163
+ this.dialogBehavior?.setTriggerElement(trigger);
164
+ } else if (document.activeElement instanceof HTMLElement) {
165
+ this.dialogBehavior?.setTriggerElement(document.activeElement);
166
+ }
167
+
168
+ this.open = true;
169
+ this.dialogBehavior?.open();
170
+ emitEvent(this, StandardEvents.OPEN);
171
+ }
172
+
173
+ /**
174
+ * Closes the drawer.
175
+ */
176
+ public close(): void {
177
+ if (!this.open) return;
178
+
179
+ const content = this.querySelector("ds-drawer-content") as DsDrawerContent | null;
180
+
181
+ // Close the behavior (deactivates focus trap and dismiss layer)
182
+ this.dialogBehavior?.close();
183
+
184
+ // If animated, use presence for exit animation
185
+ if (this.animated && content && !prefersReducedMotion()) {
186
+ this.isClosing = true;
187
+
188
+ // Create presence for exit animation
189
+ this.presence = createPresence({
190
+ onExitComplete: () => {
191
+ this.completeClose();
192
+ },
193
+ });
194
+ this.presence.hide(content);
195
+ } else {
196
+ // No animation - close immediately
197
+ this.open = false;
198
+ this.isClosing = false;
199
+ emitEvent(this, StandardEvents.CLOSE);
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Completes the close after exit animation.
205
+ */
206
+ private completeClose(): void {
207
+ this.presence?.destroy();
208
+ this.presence = null;
209
+ this.open = false;
210
+ this.isClosing = false;
211
+ emitEvent(this, StandardEvents.CLOSE);
212
+ }
213
+
214
+ private handleTriggerClick = (event: Event): void => {
215
+ const target = event.target as HTMLElement;
216
+ const trigger = target.closest('[slot="trigger"]');
217
+
218
+ if (trigger && this.contains(trigger)) {
219
+ // Store trigger before opening
220
+ this.dialogBehavior?.setTriggerElement(trigger as HTMLElement);
221
+ this.show();
222
+ }
223
+ };
224
+
225
+ private handleCloseRequest = (): void => {
226
+ this.close();
227
+ };
228
+
229
+ private handleOverlayClick = (): void => {
230
+ if (this.closeOnOverlay) {
231
+ this.close();
232
+ }
233
+ };
234
+
235
+ private cleanup(): void {
236
+ this.dialogBehavior?.destroy();
237
+ this.dialogBehavior = null;
238
+ this.presence?.destroy();
239
+ this.presence = null;
240
+ }
241
+
242
+ override async updated(changedProperties: Map<string, unknown>): Promise<void> {
243
+ super.updated(changedProperties);
244
+
245
+ if (changedProperties.has("open")) {
246
+ const content = this.querySelector("ds-drawer-content") as DsDrawerContent | null;
247
+
248
+ if (this.open) {
249
+ // Wait for the next microtask to ensure DOM is committed
250
+ await this.updateComplete;
251
+
252
+ // Set data-state to open for entry animation
253
+ if (content) {
254
+ content.dataState = "open";
255
+ content.side = this.side;
256
+ }
257
+
258
+ // Set content element on behavior (activates focus trap and dismiss layer)
259
+ this.dialogBehavior?.setContentElement(content);
260
+ this.updateContentAccessibility();
261
+ } else {
262
+ // Clear content element on behavior
263
+ this.dialogBehavior?.setContentElement(null);
264
+ }
265
+ }
266
+
267
+ // Sync behavior options when they change
268
+ if (changedProperties.has("closeOnEscape") || changedProperties.has("closeOnOverlay")) {
269
+ // Re-create behavior with new options
270
+ const wasOpen = this.dialogBehavior?.state.open;
271
+ this.dialogBehavior?.destroy();
272
+ this.initDialogBehavior();
273
+ if (wasOpen) {
274
+ this.dialogBehavior?.open();
275
+ const content = this.querySelector("ds-drawer-content") as HTMLElement | null;
276
+ this.dialogBehavior?.setContentElement(content);
277
+ }
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Updates accessibility attributes on drawer content.
283
+ */
284
+ private updateContentAccessibility(): void {
285
+ const content = this.querySelector("ds-drawer-content");
286
+ if (!content || !this.dialogBehavior) return;
287
+
288
+ // Get props from behavior
289
+ const contentProps = this.dialogBehavior.getContentProps();
290
+
291
+ // Set role on content
292
+ content.setAttribute("role", "dialog");
293
+ content.setAttribute("aria-modal", contentProps["aria-modal"]);
294
+
295
+ // Dev warning: Check for required drawer title
296
+ if (!hasRequiredChild(this, "ds-drawer-title") && !this.getAttribute("aria-label")) {
297
+ devWarn(Warnings.dialogMissingTitle("ds-drawer"));
298
+ }
299
+
300
+ // Connect title via aria-labelledby
301
+ const title = this.querySelector("ds-drawer-title");
302
+ if (title) {
303
+ const titleProps = this.dialogBehavior.getTitleProps();
304
+ if (!title.id) {
305
+ title.id = titleProps.id;
306
+ }
307
+ content.setAttribute("aria-labelledby", title.id);
308
+ }
309
+
310
+ // Connect description via aria-describedby
311
+ const description = this.querySelector("ds-drawer-description");
312
+ if (description) {
313
+ const descProps = this.dialogBehavior.getDescriptionProps();
314
+ if (!description.id) {
315
+ description.id = descProps.id;
316
+ }
317
+ content.setAttribute("aria-describedby", description.id);
318
+ this.dialogBehavior.setHasDescription(true);
319
+ } else {
320
+ // Dev warning: Title without description
321
+ if (title) {
322
+ devWarn(Warnings.dialogMissingDescription("ds-drawer"));
323
+ }
324
+ this.dialogBehavior.setHasDescription(false);
325
+ }
326
+ }
327
+
328
+ override render() {
329
+ return html`
330
+ <slot name="trigger"></slot>
331
+ <div
332
+ class="ds-drawer__overlay"
333
+ ?hidden=${!this.open}
334
+ ?data-closing=${this.isClosing}
335
+ @click=${this.handleOverlayClick}
336
+ ></div>
337
+ <slot ?hidden=${!this.open}></slot>
338
+ `;
339
+ }
340
+ }
341
+
342
+ define("ds-drawer", DsDrawer);
343
+
344
+ declare global {
345
+ interface HTMLElementTagNameMap {
346
+ "ds-drawer": DsDrawer;
347
+ }
348
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Drawer component exports.
3
+ */
4
+
5
+ export { DsDrawer, type DrawerSide } from "./drawer.js";
6
+ export { DsDrawerContent } from "./drawer-content.js";
7
+ export { DsDrawerHeader } from "./drawer-header.js";
8
+ export { DsDrawerFooter } from "./drawer-footer.js";
9
+ export { DsDrawerTitle } from "./drawer-title.js";
10
+ export { DsDrawerDescription } from "./drawer-description.js";