@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,324 @@
1
+ /**
2
+ * ContextMenu component - right-click context menu.
3
+ *
4
+ * Opens at pointer position on right-click or long-press.
5
+ *
6
+ * @element ds-context-menu
7
+ *
8
+ * @slot trigger - Area that triggers the context menu
9
+ * @slot - Menu content (ds-context-menu-content)
10
+ *
11
+ * @fires ds:open - Fired when menu opens
12
+ * @fires ds:close - Fired when menu closes
13
+ * @fires ds:select - Fired when an item is selected
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <ds-context-menu>
18
+ * <div slot="trigger">Right-click me</div>
19
+ * <ds-context-menu-content>
20
+ * <ds-context-menu-item value="copy">Copy</ds-context-menu-item>
21
+ * <ds-context-menu-item value="paste">Paste</ds-context-menu-item>
22
+ * </ds-context-menu-content>
23
+ * </ds-context-menu>
24
+ * ```
25
+ */
26
+
27
+ import {
28
+ type MenuBehavior,
29
+ type Presence,
30
+ createMenuBehavior,
31
+ createPresence,
32
+ prefersReducedMotion,
33
+ } from "@hypoth-ui/primitives-dom";
34
+ import { html } from "lit";
35
+ import { property, state } from "lit/decorators.js";
36
+ import { DSElement } from "../../base/ds-element.js";
37
+ import { StandardEvents, emitEvent } from "../../events/emit.js";
38
+ import { define } from "../../registry/define.js";
39
+
40
+ // Import child components to ensure they're registered
41
+ import type { DsContextMenuContent } from "./context-menu-content.js";
42
+ import "./context-menu-content.js";
43
+ import "./context-menu-item.js";
44
+ import "./context-menu-separator.js";
45
+ import "./context-menu-label.js";
46
+
47
+ export class DsContextMenu extends DSElement {
48
+ /** Whether the menu is open */
49
+ @property({ type: Boolean, reflect: true })
50
+ open = false;
51
+
52
+ /** Whether to animate open/close transitions */
53
+ @property({ type: Boolean })
54
+ animated = true;
55
+
56
+ /** Position X for menu */
57
+ @state()
58
+ private pointerX = 0;
59
+
60
+ /** Position Y for menu */
61
+ @state()
62
+ private pointerY = 0;
63
+
64
+ private menuBehavior: MenuBehavior | null = null;
65
+ private presence: Presence | null = null;
66
+ private longPressTimer: ReturnType<typeof setTimeout> | null = null;
67
+
68
+ override connectedCallback(): void {
69
+ super.connectedCallback();
70
+
71
+ // Listen for context menu triggers
72
+ this.addEventListener("contextmenu", this.handleContextMenu);
73
+
74
+ // Listen for long-press on touch devices
75
+ this.addEventListener("touchstart", this.handleTouchStart, { passive: true });
76
+ this.addEventListener("touchend", this.handleTouchEnd, { passive: true });
77
+ this.addEventListener("touchmove", this.handleTouchMove, { passive: true });
78
+
79
+ // Listen for item selection
80
+ this.addEventListener("ds:select", this.handleItemSelect);
81
+
82
+ // Initialize menu behavior
83
+ this.initMenuBehavior();
84
+ }
85
+
86
+ override disconnectedCallback(): void {
87
+ super.disconnectedCallback();
88
+ this.removeEventListener("contextmenu", this.handleContextMenu);
89
+ this.removeEventListener("touchstart", this.handleTouchStart);
90
+ this.removeEventListener("touchend", this.handleTouchEnd);
91
+ this.removeEventListener("touchmove", this.handleTouchMove);
92
+ this.removeEventListener("ds:select", this.handleItemSelect);
93
+ this.cleanup();
94
+ }
95
+
96
+ /**
97
+ * Initializes the menu behavior primitive.
98
+ */
99
+ private initMenuBehavior(): void {
100
+ this.menuBehavior = createMenuBehavior({
101
+ defaultOpen: this.open,
102
+ loop: true,
103
+ onOpenChange: (open) => {
104
+ // Sync state when behavior changes (e.g., from escape or outside click)
105
+ if (!open && this.open) {
106
+ this.handleBehaviorClose();
107
+ }
108
+ },
109
+ onSelect: (value) => {
110
+ emitEvent(this, StandardEvents.SELECT, { detail: { value } });
111
+ },
112
+ });
113
+ }
114
+
115
+ /**
116
+ * Handles close triggered by the behavior (escape/outside click).
117
+ */
118
+ private handleBehaviorClose(): void {
119
+ const content = this.querySelector("ds-context-menu-content") as DsContextMenuContent | null;
120
+
121
+ if (this.animated && content && !prefersReducedMotion()) {
122
+ this.presence = createPresence({
123
+ onExitComplete: () => {
124
+ this.completeClose();
125
+ },
126
+ });
127
+ this.presence.hide(content);
128
+ } else {
129
+ this.open = false;
130
+ emitEvent(this, StandardEvents.CLOSE);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Opens the menu at the specified position.
136
+ */
137
+ public show(x: number, y: number): void {
138
+ if (this.open) {
139
+ this.close();
140
+ }
141
+
142
+ this.pointerX = x;
143
+ this.pointerY = y;
144
+ this.open = true;
145
+ this.menuBehavior?.open("first");
146
+ emitEvent(this, StandardEvents.OPEN);
147
+ }
148
+
149
+ /**
150
+ * Closes the menu.
151
+ */
152
+ public close(): void {
153
+ if (!this.open) return;
154
+
155
+ const content = this.querySelector("ds-context-menu-content") as DsContextMenuContent | null;
156
+
157
+ // Close the behavior
158
+ this.menuBehavior?.close();
159
+
160
+ if (this.animated && content && !prefersReducedMotion()) {
161
+ this.presence = createPresence({
162
+ onExitComplete: () => {
163
+ this.completeClose();
164
+ },
165
+ });
166
+ this.presence.hide(content);
167
+ } else {
168
+ this.open = false;
169
+ emitEvent(this, StandardEvents.CLOSE);
170
+ }
171
+ }
172
+
173
+ private completeClose(): void {
174
+ this.presence?.destroy();
175
+ this.presence = null;
176
+ this.open = false;
177
+ emitEvent(this, StandardEvents.CLOSE);
178
+ }
179
+
180
+ private handleContextMenu = (event: MouseEvent): void => {
181
+ const target = event.target as HTMLElement;
182
+ const trigger = target.closest('[slot="trigger"]');
183
+
184
+ if (trigger && this.contains(trigger)) {
185
+ event.preventDefault();
186
+ this.show(event.clientX, event.clientY);
187
+ }
188
+ };
189
+
190
+ private handleTouchStart = (event: TouchEvent): void => {
191
+ const target = event.target as HTMLElement;
192
+ const trigger = target.closest('[slot="trigger"]');
193
+
194
+ if (trigger && this.contains(trigger)) {
195
+ const touch = event.touches[0];
196
+ if (touch) {
197
+ // Start long-press timer (500ms)
198
+ this.longPressTimer = setTimeout(() => {
199
+ this.show(touch.clientX, touch.clientY);
200
+ }, 500);
201
+ }
202
+ }
203
+ };
204
+
205
+ private handleTouchEnd = (): void => {
206
+ if (this.longPressTimer) {
207
+ clearTimeout(this.longPressTimer);
208
+ this.longPressTimer = null;
209
+ }
210
+ };
211
+
212
+ private handleTouchMove = (): void => {
213
+ // Cancel long-press if finger moves
214
+ if (this.longPressTimer) {
215
+ clearTimeout(this.longPressTimer);
216
+ this.longPressTimer = null;
217
+ }
218
+ };
219
+
220
+ private handleItemSelect = (): void => {
221
+ this.close();
222
+ };
223
+
224
+ private positionContent(): void {
225
+ const content = this.querySelector("ds-context-menu-content") as HTMLElement | null;
226
+ if (!content) return;
227
+
228
+ // Position at pointer with viewport boundary checking
229
+ let x = this.pointerX;
230
+ let y = this.pointerY;
231
+
232
+ const rect = content.getBoundingClientRect();
233
+ const viewportWidth = window.innerWidth;
234
+ const viewportHeight = window.innerHeight;
235
+
236
+ // Adjust if would overflow right
237
+ if (x + rect.width > viewportWidth) {
238
+ x = viewportWidth - rect.width - 8;
239
+ }
240
+
241
+ // Adjust if would overflow bottom
242
+ if (y + rect.height > viewportHeight) {
243
+ y = viewportHeight - rect.height - 8;
244
+ }
245
+
246
+ // Ensure not negative
247
+ x = Math.max(8, x);
248
+ y = Math.max(8, y);
249
+
250
+ content.style.left = `${x}px`;
251
+ content.style.top = `${y}px`;
252
+ }
253
+
254
+ private registerMenuItems(): void {
255
+ const content = this.querySelector("ds-context-menu-content");
256
+ if (!content || !this.menuBehavior) return;
257
+
258
+ const items = content.querySelectorAll<HTMLElement>("ds-context-menu-item:not([disabled])");
259
+
260
+ items.forEach((item) => {
261
+ this.menuBehavior?.registerItem(item);
262
+ });
263
+ }
264
+
265
+ private cleanup(): void {
266
+ this.menuBehavior?.destroy();
267
+ this.menuBehavior = null;
268
+ this.presence?.destroy();
269
+ this.presence = null;
270
+
271
+ if (this.longPressTimer) {
272
+ clearTimeout(this.longPressTimer);
273
+ this.longPressTimer = null;
274
+ }
275
+ }
276
+
277
+ override async updated(changedProperties: Map<string, unknown>): Promise<void> {
278
+ super.updated(changedProperties);
279
+
280
+ if (changedProperties.has("open")) {
281
+ const content = this.querySelector("ds-context-menu-content") as DsContextMenuContent | null;
282
+
283
+ if (this.open) {
284
+ content?.removeAttribute("hidden");
285
+
286
+ if (content) {
287
+ content.dataState = "open";
288
+ }
289
+
290
+ await this.updateComplete;
291
+
292
+ // Position content at pointer location
293
+ this.positionContent();
294
+
295
+ // Register menu items with behavior
296
+ this.registerMenuItems();
297
+
298
+ // Set content element (activates dismiss layer, roving focus, type-ahead)
299
+ // Note: Context menu handles positioning manually, not via anchor
300
+ this.menuBehavior?.setContentElement(content);
301
+ } else {
302
+ content?.setAttribute("hidden", "");
303
+
304
+ // Clear content element
305
+ this.menuBehavior?.setContentElement(null);
306
+ }
307
+ }
308
+ }
309
+
310
+ override render() {
311
+ return html`
312
+ <slot name="trigger"></slot>
313
+ <slot></slot>
314
+ `;
315
+ }
316
+ }
317
+
318
+ define("ds-context-menu", DsContextMenu);
319
+
320
+ declare global {
321
+ interface HTMLElementTagNameMap {
322
+ "ds-context-menu": DsContextMenu;
323
+ }
324
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * ContextMenu component exports.
3
+ */
4
+
5
+ export { DsContextMenu } from "./context-menu.js";
6
+ export { DsContextMenuContent } from "./context-menu-content.js";
7
+ export { DsContextMenuItem, type ContextMenuItemVariant } from "./context-menu-item.js";
8
+ export { DsContextMenuSeparator } from "./context-menu-separator.js";
9
+ export { DsContextMenuLabel } from "./context-menu-label.js";
@@ -0,0 +1,263 @@
1
+ "use client";
2
+
3
+ import { type ReactNode, createElement, forwardRef, useEffect, useRef } from "react";
4
+
5
+ // Define types locally (mirroring WC types)
6
+ export type DataTableSortDirection = "asc" | "desc" | "none";
7
+
8
+ export interface DataTableColumn {
9
+ id: string;
10
+ header: string;
11
+ accessor?: string;
12
+ sortable?: boolean;
13
+ resizable?: boolean;
14
+ width?: string;
15
+ minWidth?: string;
16
+ maxWidth?: string;
17
+ align?: "left" | "center" | "right";
18
+ }
19
+
20
+ export interface DataTableSort {
21
+ column: string;
22
+ direction: DataTableSortDirection;
23
+ }
24
+
25
+ export interface DataTablePagination {
26
+ page: number;
27
+ pageSize: number;
28
+ total: number;
29
+ }
30
+
31
+ export interface DataTableProps {
32
+ /**
33
+ * Enable virtualization for large datasets.
34
+ * @default false
35
+ */
36
+ virtualized?: boolean;
37
+
38
+ /**
39
+ * Row height for virtualization (in pixels).
40
+ * @default 48
41
+ */
42
+ rowHeight?: number;
43
+
44
+ /**
45
+ * Number of overscan rows for virtualization.
46
+ * @default 5
47
+ */
48
+ overscan?: number;
49
+
50
+ /**
51
+ * Total number of rows (for server-side pagination).
52
+ * @default 0
53
+ */
54
+ totalRows?: number;
55
+
56
+ /**
57
+ * Current page (1-indexed).
58
+ * @default 1
59
+ */
60
+ page?: number;
61
+
62
+ /**
63
+ * Page size.
64
+ * @default 10
65
+ */
66
+ pageSize?: number;
67
+
68
+ /**
69
+ * Available page sizes as comma-separated string.
70
+ * @default "10,25,50,100"
71
+ */
72
+ pageSizes?: string;
73
+
74
+ /**
75
+ * Enable row selection.
76
+ * @default false
77
+ */
78
+ selectable?: boolean;
79
+
80
+ /**
81
+ * Selection mode.
82
+ * @default "multiple"
83
+ */
84
+ selectionMode?: "single" | "multiple";
85
+
86
+ /**
87
+ * Show loading state.
88
+ * @default false
89
+ */
90
+ loading?: boolean;
91
+
92
+ /**
93
+ * Sort column ID.
94
+ */
95
+ sortColumn?: string;
96
+
97
+ /**
98
+ * Sort direction.
99
+ * @default "none"
100
+ */
101
+ sortDirection?: "asc" | "desc" | "none";
102
+
103
+ /**
104
+ * Filter/search query.
105
+ */
106
+ filter?: string;
107
+
108
+ /**
109
+ * Empty state message.
110
+ * @default "No data available"
111
+ */
112
+ emptyMessage?: string;
113
+
114
+ /**
115
+ * Callback when sort changes.
116
+ */
117
+ onSort?: (detail: { column: string; direction: "asc" | "desc" | "none" }) => void;
118
+
119
+ /**
120
+ * Callback when page changes.
121
+ */
122
+ onPageChange?: (detail: { page: number }) => void;
123
+
124
+ /**
125
+ * Callback when page size changes.
126
+ */
127
+ onPageSizeChange?: (detail: { pageSize: number }) => void;
128
+
129
+ /**
130
+ * Callback when row selection changes.
131
+ */
132
+ onSelectionChange?: (detail: { selectedRows: string[] }) => void;
133
+
134
+ /**
135
+ * Table content (use Table sub-components).
136
+ */
137
+ children?: ReactNode;
138
+
139
+ /**
140
+ * Additional class name.
141
+ */
142
+ className?: string;
143
+ }
144
+
145
+ /**
146
+ * DataTable component for displaying large datasets with virtualization,
147
+ * pagination, sorting, and selection support.
148
+ *
149
+ * @example
150
+ * ```tsx
151
+ * <DataTable
152
+ * totalRows={100}
153
+ * page={1}
154
+ * pageSize={10}
155
+ * selectable
156
+ * onPageChange={(detail) => console.log(detail.page)}
157
+ * >
158
+ * <Table>
159
+ * <TableHeader>...</TableHeader>
160
+ * <TableBody>...</TableBody>
161
+ * </Table>
162
+ * </DataTable>
163
+ * ```
164
+ */
165
+ export const DataTable = forwardRef<HTMLElement, DataTableProps>(function DataTable(
166
+ {
167
+ virtualized = false,
168
+ rowHeight = 48,
169
+ overscan = 5,
170
+ totalRows = 0,
171
+ page = 1,
172
+ pageSize = 10,
173
+ pageSizes = "10,25,50,100",
174
+ selectable = false,
175
+ selectionMode = "multiple",
176
+ loading = false,
177
+ sortColumn,
178
+ sortDirection = "none",
179
+ filter,
180
+ emptyMessage = "No data available",
181
+ onSort,
182
+ onPageChange,
183
+ onPageSizeChange,
184
+ onSelectionChange,
185
+ children,
186
+ className,
187
+ },
188
+ forwardedRef
189
+ ) {
190
+ const internalRef = useRef<HTMLElement>(null);
191
+
192
+ // Sync forwarded ref with internal ref
193
+ useEffect(() => {
194
+ if (typeof forwardedRef === "function") {
195
+ forwardedRef(internalRef.current);
196
+ } else if (forwardedRef) {
197
+ (forwardedRef as React.MutableRefObject<HTMLElement | null>).current = internalRef.current;
198
+ }
199
+ }, [forwardedRef]);
200
+
201
+ // Set up event listeners
202
+ useEffect(() => {
203
+ const element = internalRef.current;
204
+ if (!element) return;
205
+
206
+ const handleSort = (e: Event) => {
207
+ const event = e as CustomEvent;
208
+ onSort?.(event.detail);
209
+ };
210
+
211
+ const handlePageChange = (e: Event) => {
212
+ const event = e as CustomEvent;
213
+ onPageChange?.(event.detail);
214
+ };
215
+
216
+ const handlePageSizeChange = (e: Event) => {
217
+ const event = e as CustomEvent;
218
+ onPageSizeChange?.(event.detail);
219
+ };
220
+
221
+ const handleSelectionChange = (e: Event) => {
222
+ const event = e as CustomEvent;
223
+ onSelectionChange?.(event.detail);
224
+ };
225
+
226
+ element.addEventListener("ds:sort", handleSort);
227
+ element.addEventListener("ds:page-change", handlePageChange);
228
+ element.addEventListener("ds:page-size-change", handlePageSizeChange);
229
+ element.addEventListener("ds:selection-change", handleSelectionChange);
230
+
231
+ return () => {
232
+ element.removeEventListener("ds:sort", handleSort);
233
+ element.removeEventListener("ds:page-change", handlePageChange);
234
+ element.removeEventListener("ds:page-size-change", handlePageSizeChange);
235
+ element.removeEventListener("ds:selection-change", handleSelectionChange);
236
+ };
237
+ }, [onSort, onPageChange, onPageSizeChange, onSelectionChange]);
238
+
239
+ return createElement(
240
+ "ds-data-table",
241
+ {
242
+ ref: internalRef,
243
+ virtualized: virtualized || undefined,
244
+ "row-height": rowHeight,
245
+ overscan,
246
+ "total-rows": totalRows,
247
+ page,
248
+ "page-size": pageSize,
249
+ "page-sizes": pageSizes,
250
+ selectable: selectable || undefined,
251
+ "selection-mode": selectionMode,
252
+ loading: loading || undefined,
253
+ "sort-column": sortColumn,
254
+ "sort-direction": sortDirection,
255
+ filter,
256
+ "empty-message": emptyMessage,
257
+ class: className,
258
+ },
259
+ children
260
+ );
261
+ });
262
+
263
+ DataTable.displayName = "DataTable";