@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,169 @@
1
+ import { type ButtonBehavior, createButtonBehavior } from "@hypoth-ui/primitives-dom";
2
+ import { type TemplateResult, html, nothing } from "lit";
3
+ import { property } from "lit/decorators.js";
4
+ import { classMap } from "lit/directives/class-map.js";
5
+ import { DSElement } from "../../base/ds-element.js";
6
+ import { StandardEvents, emitEvent } from "../../events/emit.js";
7
+ import { define } from "../../registry/define.js";
8
+ import { validateProp } from "../../utils/dev-warnings.js";
9
+
10
+ export type ButtonVariant = "primary" | "secondary" | "ghost" | "destructive";
11
+ export type ButtonSize = "sm" | "md" | "lg";
12
+
13
+ const VALID_VARIANTS: readonly ButtonVariant[] = ["primary", "secondary", "ghost", "destructive"];
14
+ const VALID_SIZES: readonly ButtonSize[] = ["sm", "md", "lg"];
15
+
16
+ /**
17
+ * A button component following WAI-ARIA button pattern.
18
+ *
19
+ * @element ds-button
20
+ * @slot - Default slot for button content
21
+ *
22
+ * @csspart button - The button element
23
+ *
24
+ * @fires ds:press - When the button is activated (click, Enter, Space)
25
+ */
26
+ export class DsButton extends DSElement {
27
+ static override styles = [];
28
+
29
+ /**
30
+ * The button variant.
31
+ */
32
+ @property({ type: String, reflect: true })
33
+ variant: ButtonVariant = "primary";
34
+
35
+ /**
36
+ * The button size.
37
+ */
38
+ @property({ type: String, reflect: true })
39
+ size: ButtonSize = "md";
40
+
41
+ /**
42
+ * Whether the button is disabled.
43
+ */
44
+ @property({ type: Boolean, reflect: true })
45
+ disabled = false;
46
+
47
+ /**
48
+ * Whether the button is in a loading state.
49
+ */
50
+ @property({ type: Boolean, reflect: true })
51
+ loading = false;
52
+
53
+ /**
54
+ * Button type attribute.
55
+ */
56
+ @property({ type: String })
57
+ type: "button" | "submit" | "reset" = "button";
58
+
59
+ /** Button behavior instance */
60
+ private behavior!: ButtonBehavior;
61
+
62
+ override connectedCallback(): void {
63
+ super.connectedCallback();
64
+ // Create behavior with current property values
65
+ this.behavior = createButtonBehavior({
66
+ disabled: this.disabled,
67
+ loading: this.loading,
68
+ type: this.type,
69
+ });
70
+
71
+ // Dev warnings: Validate variant and size
72
+ validateProp("ds-button", "variant", this.variant, VALID_VARIANTS);
73
+ validateProp("ds-button", "size", this.size, VALID_SIZES);
74
+ }
75
+
76
+ override updated(changedProperties: Map<string, unknown>): void {
77
+ super.updated(changedProperties);
78
+ // Sync behavior state with component properties
79
+ if (
80
+ changedProperties.has("disabled") ||
81
+ changedProperties.has("loading") ||
82
+ changedProperties.has("type")
83
+ ) {
84
+ this.behavior.setState({
85
+ disabled: this.disabled,
86
+ loading: this.loading,
87
+ type: this.type,
88
+ });
89
+ }
90
+ }
91
+
92
+ private handleClick(event: MouseEvent): void {
93
+ if (this.disabled || this.loading) {
94
+ event.preventDefault();
95
+ event.stopPropagation();
96
+ return;
97
+ }
98
+
99
+ // Dispatch ds:press event per standard event naming convention
100
+ emitEvent(this, StandardEvents.PRESS, {
101
+ detail: {
102
+ originalEvent: event,
103
+ target: this,
104
+ isKeyboard: false,
105
+ },
106
+ });
107
+ }
108
+
109
+ private handleKeyDown(event: KeyboardEvent): void {
110
+ // For WC compatibility, handle both Enter and Space on keydown
111
+ // The behavior only handles Enter on keydown (Space is typically keyup)
112
+ if (event.key === "Enter" || event.key === " ") {
113
+ event.preventDefault();
114
+ if (!this.disabled && !this.loading) {
115
+ // Dispatch ds:press event with keyboard flag
116
+ // Note: We do NOT call this.click() to avoid double event emission
117
+ emitEvent(this, StandardEvents.PRESS, {
118
+ detail: {
119
+ originalEvent: event,
120
+ target: this,
121
+ isKeyboard: true,
122
+ },
123
+ });
124
+ }
125
+ }
126
+ }
127
+
128
+ override render(): TemplateResult {
129
+ const classes = {
130
+ "ds-button": true,
131
+ [`ds-button--${this.variant}`]: true,
132
+ [`ds-button--${this.size}`]: true,
133
+ "ds-button--disabled": this.disabled,
134
+ "ds-button--loading": this.loading,
135
+ };
136
+
137
+ // Compute ARIA props based on current component state
138
+ const isDisabled = this.disabled || this.loading;
139
+
140
+ return html`
141
+ <button
142
+ part="button"
143
+ class=${classMap(classes)}
144
+ type=${this.type}
145
+ ?disabled=${this.disabled}
146
+ aria-disabled=${isDisabled ? "true" : nothing}
147
+ aria-busy=${this.loading ? "true" : nothing}
148
+ tabindex=${isDisabled ? -1 : 0}
149
+ @click=${this.handleClick}
150
+ @keydown=${this.handleKeyDown}
151
+ >
152
+ ${this.loading ? html`<span class="ds-button__spinner" aria-hidden="true"></span>` : null}
153
+ <span class="ds-button__content">
154
+ <slot></slot>
155
+ </span>
156
+ </button>
157
+ `;
158
+ }
159
+ }
160
+
161
+ // Register the component
162
+ define("ds-button", DsButton);
163
+
164
+ // TypeScript declaration for HTML
165
+ declare global {
166
+ interface HTMLElementTagNameMap {
167
+ "ds-button": DsButton;
168
+ }
169
+ }
@@ -0,0 +1,149 @@
1
+ "use client";
2
+
3
+ import { type HTMLAttributes, createElement, forwardRef, useEffect, useRef } from "react";
4
+ import "@hypoth-ui/wc";
5
+
6
+ export type CalendarSize = "default" | "compact";
7
+
8
+ export interface CalendarProps extends Omit<HTMLAttributes<HTMLElement>, "onChange"> {
9
+ /**
10
+ * Selected date (ISO format: YYYY-MM-DD).
11
+ */
12
+ value?: string;
13
+
14
+ /**
15
+ * Minimum selectable date (ISO format).
16
+ */
17
+ min?: string;
18
+
19
+ /**
20
+ * Maximum selectable date (ISO format).
21
+ */
22
+ max?: string;
23
+
24
+ /**
25
+ * Disabled dates (array of ISO format strings).
26
+ */
27
+ disabledDates?: string[];
28
+
29
+ /**
30
+ * Locale for month/day names.
31
+ * @default "en-US"
32
+ */
33
+ locale?: string;
34
+
35
+ /**
36
+ * Size variant.
37
+ * @default "default"
38
+ */
39
+ size?: CalendarSize;
40
+
41
+ /**
42
+ * First day of week (0 = Sunday, 1 = Monday).
43
+ * @default 0
44
+ */
45
+ firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
46
+
47
+ /**
48
+ * Callback when a date is selected.
49
+ */
50
+ onChange?: (value: string, date: Date) => void;
51
+
52
+ /**
53
+ * Callback when the displayed month changes.
54
+ */
55
+ onMonthChange?: (month: number, year: number) => void;
56
+ }
57
+
58
+ /**
59
+ * Calendar component for date selection.
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * <Calendar
64
+ * value="2024-01-15"
65
+ * min="2024-01-01"
66
+ * max="2024-12-31"
67
+ * onChange={(value, date) => console.log(value, date)}
68
+ * />
69
+ * ```
70
+ */
71
+ export const Calendar = forwardRef<HTMLElement, CalendarProps>(function Calendar(
72
+ {
73
+ value,
74
+ min,
75
+ max,
76
+ disabledDates = [],
77
+ locale = "en-US",
78
+ size = "default",
79
+ firstDayOfWeek = 0,
80
+ onChange,
81
+ onMonthChange,
82
+ className,
83
+ ...props
84
+ },
85
+ forwardedRef
86
+ ) {
87
+ const internalRef = useRef<HTMLElement>(null);
88
+
89
+ // Sync forwarded ref
90
+ useEffect(() => {
91
+ if (typeof forwardedRef === "function") {
92
+ forwardedRef(internalRef.current);
93
+ } else if (forwardedRef) {
94
+ (forwardedRef as React.MutableRefObject<HTMLElement | null>).current = internalRef.current;
95
+ }
96
+ }, [forwardedRef]);
97
+
98
+ // Set up event listeners
99
+ useEffect(() => {
100
+ const element = internalRef.current;
101
+ if (!element) return;
102
+
103
+ const handleChange = (e: Event) => {
104
+ const event = e as CustomEvent<{ value: string; date: string }>;
105
+ onChange?.(event.detail.value, new Date(event.detail.date));
106
+ };
107
+
108
+ const handleMonthChange = (e: Event) => {
109
+ const event = e as CustomEvent<{ month: number; year: number }>;
110
+ onMonthChange?.(event.detail.month, event.detail.year);
111
+ };
112
+
113
+ element.addEventListener("ds:change", handleChange);
114
+ element.addEventListener("ds:month-change", handleMonthChange);
115
+
116
+ return () => {
117
+ element.removeEventListener("ds:change", handleChange);
118
+ element.removeEventListener("ds:month-change", handleMonthChange);
119
+ };
120
+ }, [onChange, onMonthChange]);
121
+
122
+ return createElement("ds-calendar", {
123
+ ref: internalRef,
124
+ value,
125
+ min,
126
+ max,
127
+ "disabled-dates": disabledDates.join(","),
128
+ locale,
129
+ size,
130
+ "first-day-of-week": firstDayOfWeek,
131
+ class: className,
132
+ ...props,
133
+ });
134
+ });
135
+
136
+ // TypeScript declaration for JSX
137
+ declare global {
138
+ namespace JSX {
139
+ interface IntrinsicElements {
140
+ "ds-calendar": CalendarProps & {
141
+ ref?: React.Ref<HTMLElement>;
142
+ "disabled-dates"?: string;
143
+ "first-day-of-week"?: number;
144
+ "onDs-change"?: (event: CustomEvent) => void;
145
+ "onDs-month-change"?: (event: CustomEvent) => void;
146
+ };
147
+ }
148
+ }
149
+ }
@@ -0,0 +1,316 @@
1
+ import { type TemplateResult, html, nothing } from "lit";
2
+ import { property, state } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
4
+ import { DSElement } from "../../base/ds-element.js";
5
+ import { emitEvent } from "../../events/emit.js";
6
+ import { define } from "../../registry/define.js";
7
+
8
+ export type CalendarSize = "default" | "compact";
9
+
10
+ // Navigation icons
11
+ const chevronLeftIcon = html`
12
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
13
+ <path d="M15 18l-6-6 6-6" />
14
+ </svg>
15
+ `;
16
+
17
+ const chevronRightIcon = html`
18
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
19
+ <path d="M9 18l6-6-6-6" />
20
+ </svg>
21
+ `;
22
+
23
+ /**
24
+ * Calendar component for date selection.
25
+ *
26
+ * @element ds-calendar
27
+ *
28
+ * @fires ds-change - When a date is selected
29
+ * @fires ds-month-change - When the displayed month changes
30
+ *
31
+ * @cssprop --ds-calendar-width - Calendar width
32
+ * @cssprop --ds-calendar-cell-size - Day cell size
33
+ */
34
+ export class DsCalendar extends DSElement {
35
+ static override styles = [];
36
+
37
+ /**
38
+ * Selected date (ISO format: YYYY-MM-DD).
39
+ */
40
+ @property({ type: String })
41
+ value = "";
42
+
43
+ /**
44
+ * Minimum selectable date (ISO format).
45
+ */
46
+ @property({ type: String })
47
+ min = "";
48
+
49
+ /**
50
+ * Maximum selectable date (ISO format).
51
+ */
52
+ @property({ type: String })
53
+ max = "";
54
+
55
+ /**
56
+ * Disabled dates (comma-separated ISO format).
57
+ */
58
+ @property({ type: String, attribute: "disabled-dates" })
59
+ disabledDates = "";
60
+
61
+ /**
62
+ * Locale for month/day names.
63
+ */
64
+ @property({ type: String })
65
+ locale = "en-US";
66
+
67
+ /**
68
+ * Size variant.
69
+ */
70
+ @property({ type: String, reflect: true })
71
+ size: CalendarSize = "default";
72
+
73
+ /**
74
+ * First day of week (0 = Sunday, 1 = Monday).
75
+ */
76
+ @property({ type: Number, attribute: "first-day-of-week" })
77
+ firstDayOfWeek = 0;
78
+
79
+ @state()
80
+ private viewDate: Date = new Date();
81
+
82
+ private get selectedDate(): Date | null {
83
+ return this.value ? new Date(this.value) : null;
84
+ }
85
+
86
+ private get minDate(): Date | null {
87
+ return this.min ? new Date(this.min) : null;
88
+ }
89
+
90
+ private get maxDate(): Date | null {
91
+ return this.max ? new Date(this.max) : null;
92
+ }
93
+
94
+ private get disabledDateSet(): Set<string> {
95
+ if (!this.disabledDates) return new Set();
96
+ return new Set(this.disabledDates.split(",").map((d) => d.trim()));
97
+ }
98
+
99
+ private get weekdayNames(): string[] {
100
+ const formatter = new Intl.DateTimeFormat(this.locale, { weekday: "short" });
101
+ const days: string[] = [];
102
+ // Start from a known Sunday
103
+ const baseDate = new Date(2024, 0, 7); // Jan 7, 2024 is a Sunday
104
+ for (let i = 0; i < 7; i++) {
105
+ const day = new Date(baseDate);
106
+ day.setDate(baseDate.getDate() + ((i + this.firstDayOfWeek) % 7));
107
+ days.push(formatter.format(day));
108
+ }
109
+ return days;
110
+ }
111
+
112
+ private get monthYearLabel(): string {
113
+ const formatter = new Intl.DateTimeFormat(this.locale, {
114
+ month: "long",
115
+ year: "numeric",
116
+ });
117
+ return formatter.format(this.viewDate);
118
+ }
119
+
120
+ private get calendarDays(): Array<{ date: Date; isOutside: boolean }> {
121
+ const days: Array<{ date: Date; isOutside: boolean }> = [];
122
+ const year = this.viewDate.getFullYear();
123
+ const month = this.viewDate.getMonth();
124
+
125
+ // First day of the month
126
+ const firstOfMonth = new Date(year, month, 1);
127
+ // Day of week of first day (0-6)
128
+ const startDayOfWeek = firstOfMonth.getDay();
129
+ // How many days to show from previous month
130
+ const daysFromPrevMonth = (startDayOfWeek - this.firstDayOfWeek + 7) % 7;
131
+
132
+ // Add days from previous month
133
+ for (let i = daysFromPrevMonth; i > 0; i--) {
134
+ const date = new Date(year, month, 1 - i);
135
+ days.push({ date, isOutside: true });
136
+ }
137
+
138
+ // Add days of current month
139
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
140
+ for (let i = 1; i <= daysInMonth; i++) {
141
+ days.push({ date: new Date(year, month, i), isOutside: false });
142
+ }
143
+
144
+ // Add days from next month to complete grid (6 rows × 7 days = 42)
145
+ const remaining = 42 - days.length;
146
+ for (let i = 1; i <= remaining; i++) {
147
+ const date = new Date(year, month + 1, i);
148
+ days.push({ date, isOutside: true });
149
+ }
150
+
151
+ return days;
152
+ }
153
+
154
+ private isToday(date: Date): boolean {
155
+ const today = new Date();
156
+ return (
157
+ date.getDate() === today.getDate() &&
158
+ date.getMonth() === today.getMonth() &&
159
+ date.getFullYear() === today.getFullYear()
160
+ );
161
+ }
162
+
163
+ private isSelected(date: Date): boolean {
164
+ if (!this.selectedDate) return false;
165
+ return (
166
+ date.getDate() === this.selectedDate.getDate() &&
167
+ date.getMonth() === this.selectedDate.getMonth() &&
168
+ date.getFullYear() === this.selectedDate.getFullYear()
169
+ );
170
+ }
171
+
172
+ private isDisabled(date: Date): boolean {
173
+ const dateStr = date.toISOString().split("T")[0] ?? "";
174
+
175
+ // Check disabled dates
176
+ if (dateStr && this.disabledDateSet.has(dateStr)) return true;
177
+
178
+ // Check min/max bounds
179
+ if (this.minDate && date < this.minDate) return true;
180
+ if (this.maxDate && date > this.maxDate) return true;
181
+
182
+ return false;
183
+ }
184
+
185
+ private formatDateISO(date: Date): string {
186
+ return date.toISOString().split("T")[0] ?? "";
187
+ }
188
+
189
+ private handlePrevMonth(): void {
190
+ const newDate = new Date(this.viewDate);
191
+ newDate.setMonth(newDate.getMonth() - 1);
192
+ this.viewDate = newDate;
193
+
194
+ emitEvent(this, "month-change", {
195
+ detail: {
196
+ month: newDate.getMonth() + 1,
197
+ year: newDate.getFullYear(),
198
+ },
199
+ });
200
+ }
201
+
202
+ private handleNextMonth(): void {
203
+ const newDate = new Date(this.viewDate);
204
+ newDate.setMonth(newDate.getMonth() + 1);
205
+ this.viewDate = newDate;
206
+
207
+ emitEvent(this, "month-change", {
208
+ detail: {
209
+ month: newDate.getMonth() + 1,
210
+ year: newDate.getFullYear(),
211
+ },
212
+ });
213
+ }
214
+
215
+ private handleDateSelect(date: Date): void {
216
+ if (this.isDisabled(date)) return;
217
+
218
+ this.value = this.formatDateISO(date);
219
+
220
+ emitEvent(this, "change", {
221
+ detail: {
222
+ value: this.value,
223
+ date: date.toISOString(),
224
+ },
225
+ });
226
+ }
227
+
228
+ private handleKeyDown(event: KeyboardEvent, date: Date): void {
229
+ if (event.key === "Enter" || event.key === " ") {
230
+ event.preventDefault();
231
+ this.handleDateSelect(date);
232
+ }
233
+ }
234
+
235
+ override render(): TemplateResult {
236
+ const classes = {
237
+ "ds-calendar": true,
238
+ };
239
+
240
+ return html`
241
+ <div
242
+ class=${classMap(classes)}
243
+ role="application"
244
+ aria-label="Calendar"
245
+ data-size=${this.size !== "default" ? this.size : nothing}
246
+ >
247
+ <div class="ds-calendar__header">
248
+ <button
249
+ type="button"
250
+ class="ds-calendar__nav-button"
251
+ aria-label="Previous month"
252
+ @click=${this.handlePrevMonth}
253
+ >
254
+ ${chevronLeftIcon}
255
+ </button>
256
+ <span class="ds-calendar__title" aria-live="polite">
257
+ ${this.monthYearLabel}
258
+ </span>
259
+ <button
260
+ type="button"
261
+ class="ds-calendar__nav-button"
262
+ aria-label="Next month"
263
+ @click=${this.handleNextMonth}
264
+ >
265
+ ${chevronRightIcon}
266
+ </button>
267
+ </div>
268
+
269
+ <div class="ds-calendar__weekdays" role="row">
270
+ ${this.weekdayNames.map(
271
+ (day) => html`
272
+ <div class="ds-calendar__weekday" role="columnheader">${day}</div>
273
+ `
274
+ )}
275
+ </div>
276
+
277
+ <div class="ds-calendar__grid" role="grid">
278
+ ${this.calendarDays.map(({ date, isOutside }) => {
279
+ const disabled = this.isDisabled(date);
280
+ const selected = this.isSelected(date);
281
+ const today = this.isToday(date);
282
+
283
+ return html`
284
+ <button
285
+ type="button"
286
+ class="ds-calendar__day"
287
+ role="gridcell"
288
+ tabindex=${selected ? 0 : -1}
289
+ aria-selected=${selected ? "true" : "false"}
290
+ aria-disabled=${disabled ? "true" : nothing}
291
+ ?data-outside=${isOutside}
292
+ ?data-selected=${selected}
293
+ ?data-today=${today}
294
+ ?data-disabled=${disabled}
295
+ @click=${() => this.handleDateSelect(date)}
296
+ @keydown=${(e: KeyboardEvent) => this.handleKeyDown(e, date)}
297
+ >
298
+ ${date.getDate()}
299
+ </button>
300
+ `;
301
+ })}
302
+ </div>
303
+ </div>
304
+ `;
305
+ }
306
+ }
307
+
308
+ // Register the component
309
+ define("ds-calendar", DsCalendar);
310
+
311
+ // TypeScript declaration for HTML
312
+ declare global {
313
+ interface HTMLElementTagNameMap {
314
+ "ds-calendar": DsCalendar;
315
+ }
316
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Calendar component exports
3
+ */
4
+ export { DsCalendar, type CalendarSize } from "./calendar.js";