@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,137 @@
1
+ /**
2
+ * NumberInput Root component - provides context to all NumberInput compound components.
3
+ */
4
+
5
+ import { createNumberInputBehavior } from "@hypoth-ui/primitives-dom";
6
+ import { type ReactNode, useCallback, useMemo, useState } from "react";
7
+ import { type NumberInputFormat, NumberInputProvider } from "./number-input-context.js";
8
+
9
+ export interface NumberInputRootProps {
10
+ /** NumberInput content */
11
+ children?: ReactNode;
12
+ /** Minimum allowed value */
13
+ min?: number;
14
+ /** Maximum allowed value */
15
+ max?: number;
16
+ /** Step increment */
17
+ step?: number;
18
+ /** Decimal precision */
19
+ precision?: number;
20
+ /** Controlled value */
21
+ value?: number | null;
22
+ /** Default value (uncontrolled) */
23
+ defaultValue?: number;
24
+ /** Called when value changes */
25
+ onValueChange?: (value: number) => void;
26
+ /** Format type */
27
+ format?: NumberInputFormat;
28
+ /** Currency code (for currency format) */
29
+ currency?: string;
30
+ /** Locale for formatting */
31
+ locale?: string;
32
+ /** Allow empty input */
33
+ allowEmpty?: boolean;
34
+ /** Disabled state */
35
+ disabled?: boolean;
36
+ }
37
+
38
+ /**
39
+ * Root component for NumberInput compound pattern.
40
+ * Provides context to Input, Increment, and Decrement components.
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * <NumberInput.Root min={0} max={100} onValueChange={(v) => console.log(v)}>
45
+ * <NumberInput.Decrement>-</NumberInput.Decrement>
46
+ * <NumberInput.Input />
47
+ * <NumberInput.Increment>+</NumberInput.Increment>
48
+ * </NumberInput.Root>
49
+ * ```
50
+ */
51
+ export function NumberInputRoot({
52
+ children,
53
+ min,
54
+ max,
55
+ step = 1,
56
+ precision = 0,
57
+ value: controlledValue,
58
+ defaultValue = 0,
59
+ onValueChange,
60
+ format = "decimal",
61
+ currency = "USD",
62
+ locale = "en-US",
63
+ allowEmpty = false,
64
+ disabled = false,
65
+ }: NumberInputRootProps) {
66
+ // Support controlled and uncontrolled modes
67
+ const [internalValue, setInternalValue] = useState<number | null>(
68
+ defaultValue ?? (allowEmpty ? null : 0)
69
+ );
70
+ const isControlled = controlledValue !== undefined;
71
+ const value = isControlled ? controlledValue : internalValue;
72
+
73
+ // Input state
74
+ const [inputValue, setInputValue] = useState("");
75
+ const [isFocused, setIsFocused] = useState(false);
76
+
77
+ const setValue = useCallback(
78
+ (nextValue: number | null) => {
79
+ if (!isControlled) {
80
+ setInternalValue(nextValue);
81
+ }
82
+ if (nextValue !== null) {
83
+ onValueChange?.(nextValue);
84
+ }
85
+ },
86
+ [isControlled, onValueChange]
87
+ );
88
+
89
+ // Create behavior instance
90
+ // biome-ignore lint/correctness/useExhaustiveDependencies: behavior is created once
91
+ const behavior = useMemo(
92
+ () =>
93
+ createNumberInputBehavior({
94
+ min,
95
+ max,
96
+ step,
97
+ precision,
98
+ defaultValue: value ?? undefined,
99
+ format,
100
+ currency,
101
+ locale,
102
+ allowEmpty,
103
+ disabled,
104
+ onValueChange: setValue,
105
+ }),
106
+ []
107
+ );
108
+
109
+ // Initialize input value - sync from behavior on mount
110
+ // biome-ignore lint/correctness/useExhaustiveDependencies: intentional one-time init
111
+ useMemo(() => {
112
+ setInputValue(behavior.state.inputValue);
113
+ // eslint-disable-next-line react-hooks/exhaustive-deps
114
+ }, []);
115
+
116
+ const contextValue = useMemo(
117
+ () => ({
118
+ behavior,
119
+ value,
120
+ setValue,
121
+ min,
122
+ max,
123
+ step,
124
+ precision,
125
+ disabled,
126
+ inputValue,
127
+ setInputValue,
128
+ isFocused,
129
+ setIsFocused,
130
+ }),
131
+ [behavior, value, setValue, min, max, step, precision, disabled, inputValue, isFocused]
132
+ );
133
+
134
+ return <NumberInputProvider value={contextValue}>{children}</NumberInputProvider>;
135
+ }
136
+
137
+ NumberInputRoot.displayName = "NumberInput.Root";
@@ -0,0 +1 @@
1
+ export { DsNumberInput, type NumberInputFormat } from "./number-input.js";
@@ -0,0 +1,283 @@
1
+ /**
2
+ * NumberInput component for numeric value input with increment/decrement controls.
3
+ *
4
+ * @element ds-number-input
5
+ * @fires ds:change - Fired on value change with { value }
6
+ *
7
+ * @example
8
+ * ```html
9
+ * <!-- Basic number input -->
10
+ * <ds-number-input min="0" max="100" value="50"></ds-number-input>
11
+ *
12
+ * <!-- With step and precision -->
13
+ * <ds-number-input step="0.01" precision="2" value="9.99"></ds-number-input>
14
+ *
15
+ * <!-- Currency format -->
16
+ * <ds-number-input format="currency" currency="USD" precision="2"></ds-number-input>
17
+ * ```
18
+ */
19
+
20
+ import { type NumberInputBehavior, createNumberInputBehavior } from "@hypoth-ui/primitives-dom";
21
+ import { html, nothing } from "lit";
22
+ import { property, state } from "lit/decorators.js";
23
+ import { DSElement } from "../../base/ds-element.js";
24
+ import { StandardEvents, emitEvent } from "../../events/emit.js";
25
+ import { define } from "../../registry/define.js";
26
+
27
+ export type NumberInputFormat = "decimal" | "currency" | "percent";
28
+
29
+ export class DsNumberInput extends DSElement {
30
+ /** Minimum allowed value */
31
+ @property({ type: Number, reflect: true })
32
+ min: number | undefined = undefined;
33
+
34
+ /** Maximum allowed value */
35
+ @property({ type: Number, reflect: true })
36
+ max: number | undefined = undefined;
37
+
38
+ /** Step increment */
39
+ @property({ type: Number, reflect: true })
40
+ step = 1;
41
+
42
+ /** Current value */
43
+ @property({ type: Number, reflect: true })
44
+ value: number | undefined = undefined;
45
+
46
+ /** Decimal precision */
47
+ @property({ type: Number, reflect: true })
48
+ precision = 0;
49
+
50
+ /** Format type */
51
+ @property({ type: String, reflect: true })
52
+ format: NumberInputFormat = "decimal";
53
+
54
+ /** Currency code (for currency format) */
55
+ @property({ type: String, reflect: true })
56
+ currency = "USD";
57
+
58
+ /** Locale for formatting */
59
+ @property({ type: String, reflect: true })
60
+ locale = "en-US";
61
+
62
+ /** Disabled state */
63
+ @property({ type: Boolean, reflect: true })
64
+ disabled = false;
65
+
66
+ /** Placeholder text */
67
+ @property({ type: String })
68
+ placeholder = "";
69
+
70
+ /** Form field name */
71
+ @property({ type: String, reflect: true })
72
+ name = "";
73
+
74
+ /** ARIA label */
75
+ @property({ type: String, attribute: "aria-label" })
76
+ override ariaLabel: string | null = null;
77
+
78
+ /** Allow empty input */
79
+ @property({ type: Boolean, attribute: "allow-empty" })
80
+ allowEmpty = false;
81
+
82
+ /** Show increment/decrement buttons */
83
+ @property({ type: Boolean, attribute: "show-buttons" })
84
+ showButtons = true;
85
+
86
+ /** Prefix text (displayed before input) */
87
+ @property({ type: String })
88
+ prefix = "";
89
+
90
+ /** Suffix text (displayed after input) */
91
+ @property({ type: String })
92
+ suffix = "";
93
+
94
+ @state()
95
+ private behavior: NumberInputBehavior | null = null;
96
+
97
+ @state()
98
+ private inputValue = "";
99
+
100
+ @state()
101
+ private isFocused = false;
102
+
103
+ override connectedCallback(): void {
104
+ super.connectedCallback();
105
+ this.initBehavior();
106
+ }
107
+
108
+ override disconnectedCallback(): void {
109
+ super.disconnectedCallback();
110
+ this.behavior?.destroy();
111
+ this.behavior = null;
112
+ }
113
+
114
+ override updated(changedProperties: Map<string, unknown>): void {
115
+ super.updated(changedProperties);
116
+
117
+ // Re-init behavior if key props change
118
+ if (
119
+ changedProperties.has("min") ||
120
+ changedProperties.has("max") ||
121
+ changedProperties.has("step") ||
122
+ changedProperties.has("precision") ||
123
+ changedProperties.has("format") ||
124
+ changedProperties.has("currency") ||
125
+ changedProperties.has("locale") ||
126
+ changedProperties.has("allowEmpty") ||
127
+ changedProperties.has("disabled")
128
+ ) {
129
+ this.initBehavior();
130
+ }
131
+ }
132
+
133
+ private initBehavior(): void {
134
+ this.behavior?.destroy();
135
+
136
+ this.behavior = createNumberInputBehavior({
137
+ min: this.min,
138
+ max: this.max,
139
+ step: this.step,
140
+ precision: this.precision,
141
+ defaultValue: this.value,
142
+ format: this.format,
143
+ currency: this.currency,
144
+ locale: this.locale,
145
+ allowEmpty: this.allowEmpty,
146
+ disabled: this.disabled,
147
+ onValueChange: (value) => {
148
+ this.value = value;
149
+ emitEvent(this, StandardEvents.CHANGE, { detail: { value } });
150
+ },
151
+ });
152
+
153
+ this.inputValue = this.behavior.state.inputValue;
154
+ }
155
+
156
+ private handleInput(event: Event): void {
157
+ if (!this.behavior) return;
158
+ const input = event.target as HTMLInputElement;
159
+ this.inputValue = input.value;
160
+ this.behavior.handleInput(input.value);
161
+ }
162
+
163
+ private handleBlur(): void {
164
+ if (!this.behavior) return;
165
+ this.isFocused = false;
166
+ this.behavior.commit();
167
+ this.inputValue = this.behavior.state.inputValue;
168
+ }
169
+
170
+ private handleFocus(): void {
171
+ this.isFocused = true;
172
+ }
173
+
174
+ private handleKeyDown(event: KeyboardEvent): void {
175
+ if (!this.behavior) return;
176
+ this.behavior.handleKeyDown(event);
177
+ this.inputValue = this.behavior.state.inputValue;
178
+ }
179
+
180
+ private handleIncrement(): void {
181
+ if (!this.behavior || this.disabled) return;
182
+ this.behavior.increment();
183
+ this.inputValue = this.behavior.state.inputValue;
184
+ }
185
+
186
+ private handleDecrement(): void {
187
+ if (!this.behavior || this.disabled) return;
188
+ this.behavior.decrement();
189
+ this.inputValue = this.behavior.state.inputValue;
190
+ }
191
+
192
+ override render() {
193
+ if (!this.behavior) return nothing;
194
+
195
+ const inputProps = this.behavior.getInputProps();
196
+ const isAtMin = this.min !== undefined && this.value !== undefined && this.value <= this.min;
197
+ const isAtMax = this.max !== undefined && this.value !== undefined && this.value >= this.max;
198
+
199
+ return html`
200
+ <div
201
+ class="ds-number-input"
202
+ data-disabled=${this.disabled || nothing}
203
+ data-focused=${this.isFocused || nothing}
204
+ data-invalid=${!this.behavior.state.isValid || nothing}
205
+ >
206
+ ${
207
+ this.showButtons
208
+ ? html`
209
+ <button
210
+ type="button"
211
+ class="ds-number-input__decrement"
212
+ aria-label="Decrement"
213
+ tabindex="-1"
214
+ ?disabled=${this.disabled || isAtMin}
215
+ @click=${this.handleDecrement}
216
+ >
217
+ <span aria-hidden="true">−</span>
218
+ </button>
219
+ `
220
+ : nothing
221
+ }
222
+
223
+ ${
224
+ this.prefix
225
+ ? html`<span class="ds-number-input__prefix" aria-hidden="true">${this.prefix}</span>`
226
+ : nothing
227
+ }
228
+
229
+ <input
230
+ type=${inputProps.type}
231
+ inputmode=${inputProps.inputMode}
232
+ role=${inputProps.role}
233
+ class="ds-number-input__field"
234
+ .value=${this.inputValue}
235
+ placeholder=${this.placeholder || nothing}
236
+ name=${this.name || nothing}
237
+ aria-label=${this.ariaLabel || nothing}
238
+ aria-valuemin=${inputProps["aria-valuemin"] ?? nothing}
239
+ aria-valuemax=${inputProps["aria-valuemax"] ?? nothing}
240
+ aria-valuenow=${inputProps["aria-valuenow"] ?? nothing}
241
+ aria-disabled=${inputProps["aria-disabled"] ?? nothing}
242
+ aria-invalid=${inputProps["aria-invalid"] ?? nothing}
243
+ ?disabled=${this.disabled}
244
+ @input=${this.handleInput}
245
+ @blur=${this.handleBlur}
246
+ @focus=${this.handleFocus}
247
+ @keydown=${this.handleKeyDown}
248
+ />
249
+
250
+ ${
251
+ this.suffix
252
+ ? html`<span class="ds-number-input__suffix" aria-hidden="true">${this.suffix}</span>`
253
+ : nothing
254
+ }
255
+
256
+ ${
257
+ this.showButtons
258
+ ? html`
259
+ <button
260
+ type="button"
261
+ class="ds-number-input__increment"
262
+ aria-label="Increment"
263
+ tabindex="-1"
264
+ ?disabled=${this.disabled || isAtMax}
265
+ @click=${this.handleIncrement}
266
+ >
267
+ <span aria-hidden="true">+</span>
268
+ </button>
269
+ `
270
+ : nothing
271
+ }
272
+ </div>
273
+ `;
274
+ }
275
+ }
276
+
277
+ define("ds-number-input", DsNumberInput);
278
+
279
+ declare global {
280
+ interface HTMLElementTagNameMap {
281
+ "ds-number-input": DsNumberInput;
282
+ }
283
+ }
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Pagination compound component exports.
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { Pagination } from "@/components/ui";
7
+ *
8
+ * <Pagination.Root page={1} totalPages={10} onPageChange={(page) => console.log(page)}>
9
+ * <Pagination.Content>
10
+ * <Pagination.Previous />
11
+ * <Pagination.Item><Pagination.Link page={1}>1</Pagination.Link></Pagination.Item>
12
+ * <Pagination.Ellipsis />
13
+ * <Pagination.Next />
14
+ * </Pagination.Content>
15
+ * </Pagination.Root>
16
+ * ```
17
+ */
18
+
19
+ import {
20
+ type HTMLAttributes,
21
+ type ReactNode,
22
+ createElement,
23
+ forwardRef,
24
+ useCallback,
25
+ useEffect,
26
+ useRef,
27
+ useState,
28
+ } from "react";
29
+
30
+ // ============================================================================
31
+ // Types
32
+ // ============================================================================
33
+
34
+ export interface PaginationRootProps extends HTMLAttributes<HTMLElement> {
35
+ children?: ReactNode;
36
+ page?: number;
37
+ defaultPage?: number;
38
+ totalPages?: number;
39
+ onPageChange?: (page: number) => void;
40
+ }
41
+
42
+ export interface PaginationContentProps extends HTMLAttributes<HTMLElement> {
43
+ children?: ReactNode;
44
+ }
45
+
46
+ export interface PaginationItemProps extends HTMLAttributes<HTMLElement> {
47
+ children?: ReactNode;
48
+ }
49
+
50
+ export interface PaginationLinkProps extends HTMLAttributes<HTMLElement> {
51
+ children?: ReactNode;
52
+ page: number;
53
+ active?: boolean;
54
+ }
55
+
56
+ export interface PaginationPreviousProps extends HTMLAttributes<HTMLElement> {
57
+ children?: ReactNode;
58
+ disabled?: boolean;
59
+ }
60
+
61
+ export interface PaginationNextProps extends HTMLAttributes<HTMLElement> {
62
+ children?: ReactNode;
63
+ disabled?: boolean;
64
+ }
65
+
66
+ export interface PaginationEllipsisProps extends HTMLAttributes<HTMLElement> {}
67
+
68
+ // ============================================================================
69
+ // Components
70
+ // ============================================================================
71
+
72
+ const PaginationRoot = forwardRef<HTMLElement, PaginationRootProps>(function PaginationRoot(
73
+ {
74
+ children,
75
+ className,
76
+ page: controlledPage,
77
+ defaultPage = 1,
78
+ totalPages = 1,
79
+ onPageChange,
80
+ ...props
81
+ },
82
+ ref
83
+ ) {
84
+ const [internalPage, setInternalPage] = useState(defaultPage);
85
+ const isControlled = controlledPage !== undefined;
86
+ const page = isControlled ? controlledPage : internalPage;
87
+ const elementRef = useRef<HTMLElement>(null);
88
+
89
+ const combinedRef = (node: HTMLElement | null) => {
90
+ (elementRef as React.MutableRefObject<HTMLElement | null>).current = node;
91
+ if (typeof ref === "function") ref(node);
92
+ else if (ref) (ref as React.MutableRefObject<HTMLElement | null>).current = node;
93
+ };
94
+
95
+ const handlePageChange = useCallback(
96
+ (event: Event) => {
97
+ const e = event as CustomEvent<{ page: number }>;
98
+ if (!isControlled) setInternalPage(e.detail.page);
99
+ onPageChange?.(e.detail.page);
100
+ },
101
+ [isControlled, onPageChange]
102
+ );
103
+
104
+ useEffect(() => {
105
+ const element = elementRef.current;
106
+ if (!element) return;
107
+ element.addEventListener("ds:page-change", handlePageChange);
108
+ return () => element.removeEventListener("ds:page-change", handlePageChange);
109
+ }, [handlePageChange]);
110
+
111
+ return createElement(
112
+ "ds-pagination",
113
+ { ref: combinedRef, class: className, page, "total-pages": totalPages, ...props },
114
+ children
115
+ );
116
+ });
117
+ PaginationRoot.displayName = "Pagination.Root";
118
+
119
+ const PaginationContent = forwardRef<HTMLElement, PaginationContentProps>(
120
+ function PaginationContent({ children, className, ...props }, ref) {
121
+ return createElement("ds-pagination-content", { ref, class: className, ...props }, children);
122
+ }
123
+ );
124
+ PaginationContent.displayName = "Pagination.Content";
125
+
126
+ const PaginationItem = forwardRef<HTMLElement, PaginationItemProps>(function PaginationItem(
127
+ { children, className, ...props },
128
+ ref
129
+ ) {
130
+ return createElement("ds-pagination-item", { ref, class: className, ...props }, children);
131
+ });
132
+ PaginationItem.displayName = "Pagination.Item";
133
+
134
+ const PaginationLink = forwardRef<HTMLElement, PaginationLinkProps>(function PaginationLink(
135
+ { children, className, page, active, ...props },
136
+ ref
137
+ ) {
138
+ return createElement(
139
+ "ds-pagination-link",
140
+ { ref, class: className, page, active: active || undefined, ...props },
141
+ children
142
+ );
143
+ });
144
+ PaginationLink.displayName = "Pagination.Link";
145
+
146
+ const PaginationPrevious = forwardRef<HTMLElement, PaginationPreviousProps>(
147
+ function PaginationPrevious({ children, className, disabled, ...props }, ref) {
148
+ return createElement(
149
+ "ds-pagination-previous",
150
+ { ref, class: className, disabled: disabled || undefined, ...props },
151
+ children
152
+ );
153
+ }
154
+ );
155
+ PaginationPrevious.displayName = "Pagination.Previous";
156
+
157
+ const PaginationNext = forwardRef<HTMLElement, PaginationNextProps>(function PaginationNext(
158
+ { children, className, disabled, ...props },
159
+ ref
160
+ ) {
161
+ return createElement(
162
+ "ds-pagination-next",
163
+ { ref, class: className, disabled: disabled || undefined, ...props },
164
+ children
165
+ );
166
+ });
167
+ PaginationNext.displayName = "Pagination.Next";
168
+
169
+ const PaginationEllipsis = forwardRef<HTMLElement, PaginationEllipsisProps>(
170
+ function PaginationEllipsis({ className, ...props }, ref) {
171
+ return createElement("ds-pagination-ellipsis", { ref, class: className, ...props });
172
+ }
173
+ );
174
+ PaginationEllipsis.displayName = "Pagination.Ellipsis";
175
+
176
+ // ============================================================================
177
+ // Compound Component
178
+ // ============================================================================
179
+
180
+ export const Pagination = {
181
+ Root: PaginationRoot,
182
+ Content: PaginationContent,
183
+ Item: PaginationItem,
184
+ Link: PaginationLink,
185
+ Previous: PaginationPrevious,
186
+ Next: PaginationNext,
187
+ Ellipsis: PaginationEllipsis,
188
+ };
189
+
190
+ export {
191
+ PaginationRoot,
192
+ PaginationContent,
193
+ PaginationItem,
194
+ PaginationLink,
195
+ PaginationPrevious,
196
+ PaginationNext,
197
+ PaginationEllipsis,
198
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Pagination component exports.
3
+ */
4
+
5
+ export { DsPagination } from "./pagination.js";
6
+ export { DsPaginationContent } from "./pagination-content.js";
7
+ export { DsPaginationItem } from "./pagination-item.js";
8
+ export { DsPaginationLink } from "./pagination-link.js";
9
+ export { DsPaginationPrevious } from "./pagination-previous.js";
10
+ export { DsPaginationNext } from "./pagination-next.js";
11
+ export { DsPaginationEllipsis } from "./pagination-ellipsis.js";
@@ -0,0 +1,30 @@
1
+ /**
2
+ * PaginationContent component - container for pagination items.
3
+ *
4
+ * @element ds-pagination-content
5
+ *
6
+ * @slot - Pagination items
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 DsPaginationContent extends DSElement {
14
+ override connectedCallback(): void {
15
+ super.connectedCallback();
16
+ this.setAttribute("role", "list");
17
+ }
18
+
19
+ override render() {
20
+ return html`<slot></slot>`;
21
+ }
22
+ }
23
+
24
+ define("ds-pagination-content", DsPaginationContent);
25
+
26
+ declare global {
27
+ interface HTMLElementTagNameMap {
28
+ "ds-pagination-content": DsPaginationContent;
29
+ }
30
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * PaginationEllipsis component - indicates more pages.
3
+ *
4
+ * @element ds-pagination-ellipsis
5
+ */
6
+
7
+ import { html } from "lit";
8
+ import { DSElement } from "../../base/ds-element.js";
9
+ import { define } from "../../registry/define.js";
10
+
11
+ export class DsPaginationEllipsis extends DSElement {
12
+ override connectedCallback(): void {
13
+ super.connectedCallback();
14
+ this.setAttribute("aria-hidden", "true");
15
+ }
16
+
17
+ override render() {
18
+ return html`<span>...</span>`;
19
+ }
20
+ }
21
+
22
+ define("ds-pagination-ellipsis", DsPaginationEllipsis);
23
+
24
+ declare global {
25
+ interface HTMLElementTagNameMap {
26
+ "ds-pagination-ellipsis": DsPaginationEllipsis;
27
+ }
28
+ }