@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,85 @@
1
+ /**
2
+ * NavigationMenuViewport component - container for content panels.
3
+ *
4
+ * Renders the active content panel with smooth transitions.
5
+ *
6
+ * @element ds-navigation-menu-viewport
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 DsNavigationMenuViewport extends DSElement {
14
+ private contentObserver: MutationObserver | null = null;
15
+
16
+ override connectedCallback(): void {
17
+ super.connectedCallback();
18
+ this.setAttribute("hidden", "");
19
+ this.setAttribute("data-state", "closed");
20
+
21
+ // Observe parent for content changes
22
+ this.setupContentObserver();
23
+ }
24
+
25
+ override disconnectedCallback(): void {
26
+ super.disconnectedCallback();
27
+ this.contentObserver?.disconnect();
28
+ this.contentObserver = null;
29
+ }
30
+
31
+ private setupContentObserver(): void {
32
+ const menu = this.closest("ds-navigation-menu");
33
+ if (!menu) return;
34
+
35
+ // Update viewport content when menu value changes
36
+ this.contentObserver = new MutationObserver(() => {
37
+ this.updateContent();
38
+ });
39
+
40
+ this.contentObserver.observe(menu, {
41
+ attributes: true,
42
+ attributeFilter: ["value"],
43
+ });
44
+
45
+ // Initial update
46
+ this.updateContent();
47
+ }
48
+
49
+ private updateContent(): void {
50
+ const menu = this.closest("ds-navigation-menu");
51
+ if (!menu) return;
52
+
53
+ const value = menu.getAttribute("value");
54
+
55
+ // Move active content into viewport
56
+ const items = menu.querySelectorAll("ds-navigation-menu-item");
57
+
58
+ // Clear viewport
59
+ this.innerHTML = "";
60
+
61
+ for (const item of items) {
62
+ const itemValue = item.getAttribute("value");
63
+ const content = item.querySelector("ds-navigation-menu-content");
64
+
65
+ if (itemValue === value && content) {
66
+ // Clone content to viewport
67
+ const clone = content.cloneNode(true) as HTMLElement;
68
+ clone.setAttribute("data-value", itemValue || "");
69
+ this.appendChild(clone);
70
+ }
71
+ }
72
+ }
73
+
74
+ override render() {
75
+ return html`<slot></slot>`;
76
+ }
77
+ }
78
+
79
+ define("ds-navigation-menu-viewport", DsNavigationMenuViewport);
80
+
81
+ declare global {
82
+ interface HTMLElementTagNameMap {
83
+ "ds-navigation-menu-viewport": DsNavigationMenuViewport;
84
+ }
85
+ }
@@ -0,0 +1,272 @@
1
+ /**
2
+ * NavigationMenu component - mega-menu style navigation.
3
+ *
4
+ * Provides a horizontal navigation bar with dropdown content panels
5
+ * that transition smoothly between items.
6
+ *
7
+ * @element ds-navigation-menu
8
+ *
9
+ * @slot - Navigation menu content (ds-navigation-menu-list)
10
+ *
11
+ * @fires ds:value-change - Fired when active menu item changes
12
+ *
13
+ * @example
14
+ * ```html
15
+ * <ds-navigation-menu>
16
+ * <ds-navigation-menu-list>
17
+ * <ds-navigation-menu-item>
18
+ * <ds-navigation-menu-trigger>Products</ds-navigation-menu-trigger>
19
+ * <ds-navigation-menu-content>
20
+ * <ds-navigation-menu-link href="/products/a">Product A</ds-navigation-menu-link>
21
+ * </ds-navigation-menu-content>
22
+ * </ds-navigation-menu-item>
23
+ * </ds-navigation-menu-list>
24
+ * <ds-navigation-menu-viewport></ds-navigation-menu-viewport>
25
+ * </ds-navigation-menu>
26
+ * ```
27
+ */
28
+
29
+ import {
30
+ type DismissableLayer,
31
+ type RovingFocus,
32
+ createDismissableLayer,
33
+ createRovingFocus,
34
+ } from "@hypoth-ui/primitives-dom";
35
+ import { html } from "lit";
36
+ import { property } from "lit/decorators.js";
37
+ import { DSElement } from "../../base/ds-element.js";
38
+ import { emitEvent } from "../../events/emit.js";
39
+ import { define } from "../../registry/define.js";
40
+
41
+ // Import child components to ensure they're registered
42
+ import "./navigation-menu-list.js";
43
+ import "./navigation-menu-item.js";
44
+ import "./navigation-menu-trigger.js";
45
+ import "./navigation-menu-content.js";
46
+ import "./navigation-menu-link.js";
47
+ import "./navigation-menu-indicator.js";
48
+ import "./navigation-menu-viewport.js";
49
+
50
+ export class DsNavigationMenu extends DSElement {
51
+ /** Currently active item value */
52
+ @property({ type: String, reflect: true })
53
+ value = "";
54
+
55
+ /** Delay in ms before opening on hover */
56
+ @property({ type: Number, attribute: "delay-duration" })
57
+ delayDuration = 200;
58
+
59
+ /** Delay in ms before closing when pointer leaves */
60
+ @property({ type: Number, attribute: "skip-delay-duration" })
61
+ skipDelayDuration = 300;
62
+
63
+ /** Orientation (horizontal or vertical) */
64
+ @property({ type: String, reflect: true })
65
+ orientation: "horizontal" | "vertical" = "horizontal";
66
+
67
+ private rovingFocus: RovingFocus | null = null;
68
+ private dismissLayer: DismissableLayer | null = null;
69
+ private openTimer: ReturnType<typeof setTimeout> | null = null;
70
+ private closeTimer: ReturnType<typeof setTimeout> | null = null;
71
+ private previousValue = "";
72
+
73
+ override connectedCallback(): void {
74
+ super.connectedCallback();
75
+
76
+ this.setAttribute("role", "navigation");
77
+ this.setAttribute("aria-label", "Main");
78
+
79
+ // Listen for trigger interactions
80
+ this.addEventListener("ds:navigation-trigger", this.handleTriggerInteraction as EventListener);
81
+ this.addEventListener("ds:navigation-item-enter", this.handleItemEnter as EventListener);
82
+ this.addEventListener("ds:navigation-item-leave", this.handleItemLeave as EventListener);
83
+
84
+ this.updateComplete.then(() => {
85
+ this.setupRovingFocus();
86
+ });
87
+ }
88
+
89
+ override disconnectedCallback(): void {
90
+ super.disconnectedCallback();
91
+ this.removeEventListener(
92
+ "ds:navigation-trigger",
93
+ this.handleTriggerInteraction as EventListener
94
+ );
95
+ this.removeEventListener("ds:navigation-item-enter", this.handleItemEnter as EventListener);
96
+ this.removeEventListener("ds:navigation-item-leave", this.handleItemLeave as EventListener);
97
+ this.cleanup();
98
+ }
99
+
100
+ /**
101
+ * Opens a navigation item by value.
102
+ */
103
+ public open(itemValue: string): void {
104
+ if (this.value === itemValue) return;
105
+
106
+ this.clearTimers();
107
+ this.previousValue = this.value;
108
+ this.value = itemValue;
109
+ this.updateActiveItem();
110
+ this.setupDismissLayer();
111
+
112
+ emitEvent(this, "ds:value-change", {
113
+ detail: { value: this.value },
114
+ bubbles: true,
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Closes the navigation menu.
120
+ */
121
+ public close(): void {
122
+ if (!this.value) return;
123
+
124
+ this.clearTimers();
125
+ this.previousValue = this.value;
126
+ this.value = "";
127
+ this.updateActiveItem();
128
+ this.dismissLayer?.deactivate();
129
+ this.dismissLayer = null;
130
+
131
+ emitEvent(this, "ds:value-change", {
132
+ detail: { value: "" },
133
+ bubbles: true,
134
+ });
135
+ }
136
+
137
+ private clearTimers(): void {
138
+ if (this.openTimer) {
139
+ clearTimeout(this.openTimer);
140
+ this.openTimer = null;
141
+ }
142
+ if (this.closeTimer) {
143
+ clearTimeout(this.closeTimer);
144
+ this.closeTimer = null;
145
+ }
146
+ }
147
+
148
+ private handleTriggerInteraction = (
149
+ event: CustomEvent<{ value: string; type: "click" | "focus" }>
150
+ ): void => {
151
+ const { value } = event.detail;
152
+
153
+ if (this.value === value) {
154
+ // Toggle off if clicking same item
155
+ this.close();
156
+ } else {
157
+ this.open(value);
158
+ }
159
+ };
160
+
161
+ private handleItemEnter = (event: CustomEvent<{ value: string }>): void => {
162
+ const { value } = event.detail;
163
+ this.clearTimers();
164
+
165
+ // Use skip delay if switching between items
166
+ const delay = this.value ? 0 : this.delayDuration;
167
+
168
+ this.openTimer = setTimeout(() => {
169
+ this.open(value);
170
+ }, delay);
171
+ };
172
+
173
+ private handleItemLeave = (): void => {
174
+ this.clearTimers();
175
+
176
+ this.closeTimer = setTimeout(() => {
177
+ this.close();
178
+ }, this.skipDelayDuration);
179
+ };
180
+
181
+ private handleDismiss = (): void => {
182
+ this.close();
183
+ };
184
+
185
+ private setupRovingFocus(): void {
186
+ const list = this.querySelector("ds-navigation-menu-list");
187
+ if (!list) return;
188
+
189
+ this.rovingFocus = createRovingFocus({
190
+ container: list as HTMLElement,
191
+ selector: "ds-navigation-menu-trigger, ds-navigation-menu-link:not([disabled])",
192
+ direction: this.orientation === "horizontal" ? "horizontal" : "vertical",
193
+ loop: true,
194
+ skipDisabled: true,
195
+ });
196
+ }
197
+
198
+ private setupDismissLayer(): void {
199
+ if (this.dismissLayer) {
200
+ this.dismissLayer.deactivate();
201
+ }
202
+
203
+ const viewport = this.querySelector("ds-navigation-menu-viewport");
204
+ if (!viewport) return;
205
+
206
+ this.dismissLayer = createDismissableLayer({
207
+ container: viewport as HTMLElement,
208
+ excludeElements: [this],
209
+ onDismiss: this.handleDismiss,
210
+ closeOnEscape: true,
211
+ closeOnOutsideClick: true,
212
+ });
213
+ this.dismissLayer.activate();
214
+ }
215
+
216
+ private updateActiveItem(): void {
217
+ const items = this.querySelectorAll("ds-navigation-menu-item");
218
+ for (const item of items) {
219
+ const itemValue = item.getAttribute("value") || "";
220
+ const isActive = itemValue === this.value;
221
+
222
+ if (isActive) {
223
+ item.setAttribute("data-state", "open");
224
+ } else {
225
+ item.setAttribute("data-state", "closed");
226
+ }
227
+ }
228
+
229
+ // Update viewport
230
+ const viewport = this.querySelector("ds-navigation-menu-viewport") as HTMLElement | null;
231
+ if (viewport) {
232
+ if (this.value) {
233
+ viewport.removeAttribute("hidden");
234
+ viewport.setAttribute("data-state", "open");
235
+ } else {
236
+ viewport.setAttribute("data-state", "closed");
237
+ // Wait for animation before hiding
238
+ setTimeout(() => {
239
+ if (!this.value) {
240
+ viewport.setAttribute("hidden", "");
241
+ }
242
+ }, 200);
243
+ }
244
+ }
245
+ }
246
+
247
+ private cleanup(): void {
248
+ this.clearTimers();
249
+ this.rovingFocus?.destroy();
250
+ this.rovingFocus = null;
251
+ this.dismissLayer?.deactivate();
252
+ this.dismissLayer = null;
253
+ }
254
+
255
+ override updated(changedProperties: Map<string, unknown>): void {
256
+ if (changedProperties.has("value")) {
257
+ this.updateActiveItem();
258
+ }
259
+ }
260
+
261
+ override render() {
262
+ return html`<slot></slot>`;
263
+ }
264
+ }
265
+
266
+ define("ds-navigation-menu", DsNavigationMenu);
267
+
268
+ declare global {
269
+ interface HTMLElementTagNameMap {
270
+ "ds-navigation-menu": DsNavigationMenu;
271
+ }
272
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * NumberInput compound component for numeric value input.
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * // Basic number input with buttons
7
+ * <NumberInput.Root min={0} max={100} onValueChange={(v) => console.log(v)}>
8
+ * <NumberInput.Decrement>-</NumberInput.Decrement>
9
+ * <NumberInput.Input />
10
+ * <NumberInput.Increment>+</NumberInput.Increment>
11
+ * </NumberInput.Root>
12
+ *
13
+ * // Currency input
14
+ * <NumberInput.Root format="currency" currency="USD" precision={2}>
15
+ * <NumberInput.Input />
16
+ * </NumberInput.Root>
17
+ * ```
18
+ */
19
+
20
+ export { NumberInputRoot, type NumberInputRootProps } from "./number-input-root.js";
21
+ export { NumberInputField, type NumberInputFieldProps } from "./number-input-field.js";
22
+ export {
23
+ NumberInputIncrement,
24
+ type NumberInputIncrementProps,
25
+ } from "./number-input-increment.js";
26
+ export {
27
+ NumberInputDecrement,
28
+ type NumberInputDecrementProps,
29
+ } from "./number-input-decrement.js";
30
+ export {
31
+ useNumberInputContext,
32
+ type NumberInputContextValue,
33
+ type NumberInputFormat,
34
+ } from "./number-input-context.js";
35
+
36
+ export const NumberInput = {
37
+ Root: NumberInputRoot,
38
+ Input: NumberInputField,
39
+ Increment: NumberInputIncrement,
40
+ Decrement: NumberInputDecrement,
41
+ } as const;
42
+
43
+ import { NumberInputDecrement } from "./number-input-decrement.js";
44
+ import { NumberInputField } from "./number-input-field.js";
45
+ import { NumberInputIncrement } from "./number-input-increment.js";
46
+ import { NumberInputRoot } from "./number-input-root.js";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * NumberInput context for compound component pattern.
3
+ */
4
+
5
+ import type { NumberInputBehavior } from "@hypoth-ui/primitives-dom";
6
+ import { createCompoundContext } from "../../utils/create-context.js";
7
+
8
+ export type NumberInputFormat = "decimal" | "currency" | "percent";
9
+
10
+ export interface NumberInputContextValue {
11
+ /** NumberInput behavior instance */
12
+ behavior: NumberInputBehavior;
13
+ /** Current value */
14
+ value: number | null;
15
+ /** Set value */
16
+ setValue: (value: number | null) => void;
17
+ /** Min constraint */
18
+ min: number | undefined;
19
+ /** Max constraint */
20
+ max: number | undefined;
21
+ /** Step */
22
+ step: number;
23
+ /** Precision */
24
+ precision: number;
25
+ /** Disabled state */
26
+ disabled: boolean;
27
+ /** Input value string */
28
+ inputValue: string;
29
+ /** Set input value */
30
+ setInputValue: (value: string) => void;
31
+ /** Is input focused */
32
+ isFocused: boolean;
33
+ /** Set focus state */
34
+ setIsFocused: (focused: boolean) => void;
35
+ }
36
+
37
+ export const [NumberInputProvider, useNumberInputContext] =
38
+ createCompoundContext<NumberInputContextValue>("NumberInput");
@@ -0,0 +1,53 @@
1
+ /**
2
+ * NumberInput Decrement button component.
3
+ */
4
+
5
+ import { type ButtonHTMLAttributes, type MouseEvent, forwardRef, useCallback } from "react";
6
+ import { useNumberInputContext } from "./number-input-context.js";
7
+
8
+ export interface NumberInputDecrementProps extends ButtonHTMLAttributes<HTMLButtonElement> {}
9
+
10
+ /**
11
+ * Button to decrement the number input value.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <NumberInput.Decrement className="decrement-btn">-</NumberInput.Decrement>
16
+ * ```
17
+ */
18
+ export const NumberInputDecrement = forwardRef<HTMLButtonElement, NumberInputDecrementProps>(
19
+ ({ className, onClick, children, disabled: disabledProp, ...restProps }, ref) => {
20
+ const { behavior, value, min, disabled, setInputValue } =
21
+ useNumberInputContext("NumberInput.Decrement");
22
+
23
+ const isAtMin = min !== undefined && value !== null && value <= min;
24
+ const isDisabled = disabled || disabledProp || isAtMin;
25
+
26
+ const handleClick = useCallback(
27
+ (event: MouseEvent<HTMLButtonElement>) => {
28
+ if (isDisabled) return;
29
+ behavior.decrement();
30
+ setInputValue(behavior.state.inputValue);
31
+ onClick?.(event);
32
+ },
33
+ [behavior, isDisabled, setInputValue, onClick]
34
+ );
35
+
36
+ return (
37
+ <button
38
+ ref={ref}
39
+ type="button"
40
+ tabIndex={-1}
41
+ aria-label="Decrement"
42
+ disabled={isDisabled}
43
+ className={className}
44
+ onClick={handleClick}
45
+ {...restProps}
46
+ >
47
+ {children ?? "−"}
48
+ </button>
49
+ );
50
+ }
51
+ );
52
+
53
+ NumberInputDecrement.displayName = "NumberInput.Decrement";
@@ -0,0 +1,93 @@
1
+ /**
2
+ * NumberInput Field component - the input element.
3
+ */
4
+
5
+ import {
6
+ type ChangeEvent,
7
+ type FocusEvent,
8
+ type InputHTMLAttributes,
9
+ type KeyboardEvent,
10
+ forwardRef,
11
+ useCallback,
12
+ } from "react";
13
+ import { useNumberInputContext } from "./number-input-context.js";
14
+
15
+ export interface NumberInputFieldProps
16
+ extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "onChange"> {}
17
+
18
+ /**
19
+ * The input field for the number input.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <NumberInput.Input className="number-input" />
24
+ * ```
25
+ */
26
+ export const NumberInputField = forwardRef<HTMLInputElement, NumberInputFieldProps>(
27
+ ({ className, onBlur, onFocus, onKeyDown, ...restProps }, ref) => {
28
+ const { behavior, disabled, inputValue, setInputValue, setIsFocused } =
29
+ useNumberInputContext("NumberInput.Input");
30
+
31
+ const inputProps = behavior.getInputProps();
32
+
33
+ const handleChange = useCallback(
34
+ (event: ChangeEvent<HTMLInputElement>) => {
35
+ const newValue = event.target.value;
36
+ setInputValue(newValue);
37
+ behavior.handleInput(newValue);
38
+ },
39
+ [behavior, setInputValue]
40
+ );
41
+
42
+ const handleBlur = useCallback(
43
+ (event: FocusEvent<HTMLInputElement>) => {
44
+ setIsFocused(false);
45
+ behavior.commit();
46
+ setInputValue(behavior.state.inputValue);
47
+ onBlur?.(event);
48
+ },
49
+ [behavior, setInputValue, setIsFocused, onBlur]
50
+ );
51
+
52
+ const handleFocus = useCallback(
53
+ (event: FocusEvent<HTMLInputElement>) => {
54
+ setIsFocused(true);
55
+ onFocus?.(event);
56
+ },
57
+ [setIsFocused, onFocus]
58
+ );
59
+
60
+ const handleKeyDown = useCallback(
61
+ (event: KeyboardEvent<HTMLInputElement>) => {
62
+ behavior.handleKeyDown(event.nativeEvent);
63
+ setInputValue(behavior.state.inputValue);
64
+ onKeyDown?.(event);
65
+ },
66
+ [behavior, setInputValue, onKeyDown]
67
+ );
68
+
69
+ return (
70
+ <input
71
+ ref={ref}
72
+ type={inputProps.type}
73
+ inputMode={inputProps.inputMode}
74
+ role={inputProps.role}
75
+ value={inputValue}
76
+ disabled={disabled}
77
+ aria-valuemin={inputProps["aria-valuemin"]}
78
+ aria-valuemax={inputProps["aria-valuemax"]}
79
+ aria-valuenow={inputProps["aria-valuenow"]}
80
+ aria-disabled={inputProps["aria-disabled"]}
81
+ aria-invalid={inputProps["aria-invalid"]}
82
+ className={className}
83
+ onChange={handleChange}
84
+ onBlur={handleBlur}
85
+ onFocus={handleFocus}
86
+ onKeyDown={handleKeyDown}
87
+ {...restProps}
88
+ />
89
+ );
90
+ }
91
+ );
92
+
93
+ NumberInputField.displayName = "NumberInput.Input";
@@ -0,0 +1,53 @@
1
+ /**
2
+ * NumberInput Increment button component.
3
+ */
4
+
5
+ import { type ButtonHTMLAttributes, type MouseEvent, forwardRef, useCallback } from "react";
6
+ import { useNumberInputContext } from "./number-input-context.js";
7
+
8
+ export interface NumberInputIncrementProps extends ButtonHTMLAttributes<HTMLButtonElement> {}
9
+
10
+ /**
11
+ * Button to increment the number input value.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <NumberInput.Increment className="increment-btn">+</NumberInput.Increment>
16
+ * ```
17
+ */
18
+ export const NumberInputIncrement = forwardRef<HTMLButtonElement, NumberInputIncrementProps>(
19
+ ({ className, onClick, children, disabled: disabledProp, ...restProps }, ref) => {
20
+ const { behavior, value, max, disabled, setInputValue } =
21
+ useNumberInputContext("NumberInput.Increment");
22
+
23
+ const isAtMax = max !== undefined && value !== null && value >= max;
24
+ const isDisabled = disabled || disabledProp || isAtMax;
25
+
26
+ const handleClick = useCallback(
27
+ (event: MouseEvent<HTMLButtonElement>) => {
28
+ if (isDisabled) return;
29
+ behavior.increment();
30
+ setInputValue(behavior.state.inputValue);
31
+ onClick?.(event);
32
+ },
33
+ [behavior, isDisabled, setInputValue, onClick]
34
+ );
35
+
36
+ return (
37
+ <button
38
+ ref={ref}
39
+ type="button"
40
+ tabIndex={-1}
41
+ aria-label="Increment"
42
+ disabled={isDisabled}
43
+ className={className}
44
+ onClick={handleClick}
45
+ {...restProps}
46
+ >
47
+ {children ?? "+"}
48
+ </button>
49
+ );
50
+ }
51
+ );
52
+
53
+ NumberInputIncrement.displayName = "NumberInput.Increment";